I have a Raspberry Pi running the Flask framework to make a very application-specific http server. Doing an HTTP GET of a particular page on the Pi server triggers a GPIO action (e.g.: check if button is pressed, LED on, LED off and so on). Because I will poll the /status page to see if the button is pressed at 250ms intervals, I do not want the polling of the /unlock page to use timer.sleep(0.25) to close a relay for 250ms.
I want to set up an action that when called, will wait 250ms, turn the LED off then quietly go away. I tried both threading and sched. Threading works ONCE and throws an error when I pass through the code a second time (raise RuntimeError("threads can only be started once")).
#
# lots of other defines and includes
#
import threading
# set up function to turn de-energize relay (and Green LED)
def LED_Off_Wait():
GPIO.output(GREEN, False)
# set up timed thread
LED_Off = threading.Timer(0.25, LED_Off_Wait)
#
# flask framework page definitions go here
#
# unlock page where we energize and de-energize a lock
@app.route('/unlock')
def thing_unlock():
GPIO.output(GREEN, True) # energize the relay (and green LED)
# time.sleep(0.25) # don't want to do this
# GPIO.output(GREEN, False) #don't want to do this
LED_Off.start() # trigger the non-blocking thread to turn off
# the GPIO pin in 0.25s
# more flask stuff...
response = make_response(render_template('body.html', response='unlocked'))
response.headers['Access-Control-Allow-Origin'] = '*'
return response
I tried sched as well and it does not work for me, although it may be because I'm programming from the inside-out, learning by doing:
import sched
def LED_Off():
GPIO.output(GREEN, False)
# set up scheduled action, as nearly as I can determine from my reading
LED_ON_Delay = sched.scheduler(time.time, time.sleep) # set up scheduler (no sleep!)
LED_ON_Delay.enter( 1, 1, LED_Off,()) # schedule LED_Off for 0.25s in the future
#
# again, more Flask stuff here
#
@app.route('/unlock')
def thing_unlock():
GPIO.output(GREEN, True)
# time.sleep(0.25) # don't want to do this
# GPIO.output(GREEN, False) # don't want to do this
LED_ON_Delay.run() #trigger "non-blocking sleep"
response = make_response(render_template('body.html', response='unlocked'))
response.headers['Access-Control-Allow-Origin'] = '*'
return response
# more Flask stuff...
Bottom Line: how do I spin off a task that will turn the GPIO off after a certain time (or do anything else for that matter) without an error if I try to do it twice?