I am developing a motion detector with a default audio playback once motion is detected with Raspberry Pi.
However when consecutive motion are detected, the next audio will start playing and begin to overlap when the previous one have not even ended.
Any loop I can implement to do this in python?
Currently, I am using a timer loop with the total length of the audio before playing another. However I believe there are better solutions. Any idea?
import sched, time
s = sched.scheduler(time.time, time.sleep)
print "Doing stuff..."
# do your stuff
sc.enter(10, 1, do_something, (sc,))
s.enter(10, 1, do_something, (s,))
This is just an idea, but easier to write as an answer instead of in the comments. A workaround could be to set a state, where each time the function is running it is 1 higher. If it is over 1, wait until the end of the function, then run the function again, otherwise just run the function normally.
If it doesn't work I'll delete the answer, but I think it might do (though possibly with a couple of tweaks).
import sched, time s = sched.scheduler(time.time, time.sleep) state = 0 def do_something(sc): global state #increase the state, and cancel if it's over 1 (already running) state += 1 if state > 1: return original_state = state print "Doing stuff..." # do your stuff sc.enter(10, 1, do_something, (sc,)) #Run again if the state has changed during the function if original_state != state: s.run() state -= 1 state -= 1
Edit: Made my own function that seems to work. It executes in the background and queues them up using the state idea. The
time.sleep(0.01) part is just because the end seemed to overlap with the start of the next one. With
kwargs, it'll pass them even if it's empty, so you've gotta allow for them in your function.
import time from threading import Thread class ThreadHelper(Thread): def __init__(self, function, *args, **kwargs): self.args = args self.kwargs = kwargs Thread.__init__(self) self.function = function def run(self): self.function(*self.args, **self.kwargs) def run_once(func, *args, **kwargs): global state state += 1 original_state = state if state > 1: return func(*args, **kwargs) time.sleep(0.01) while state != original_state: state -= 1 func(*args, **kwargs) time.sleep(0.01) state -= 1
How you use it:
def dosomething(*args, **kwargs): print 'start' time.sleep(0.5) print 'end' state =  ThreadHelper(run_once, dosomething, _state=state).start() ThreadHelper(run_once, dosomething, _state=state).start() ThreadHelper(run_once, dosomething, _state=state).start()