2016-07-19 35 views
0

Ich bin mir nicht sicher, der beste Weg, dies zu tun, und funktioniert nicht für meine, wie es das Programm auf, wenn es schläft nicht sicher, wie es richtig funktioniert ...Countdown Thread RPi Stop wenn GPIO Eingabe ändern

Ich versuche zu überwachen, wenn eine Tür öffnet und schließt mit einem Raspberry Pi, wenn die Tür mehr als x Zeit geöffnet ist senden Sie eine Art von Alarm (wie und E-Mail), habe ich das Problem, wenn die Tür vorher geschlossen Der Countdown beendet den Countdown nicht, wodurch der Thread angehalten wird. Auch die Alarmseite wurde nicht implementiert, aber wenn der Code wie im Moment ist, wird der Alarm ausgelöst, auch wenn sich die Tür vor dem Countdown schließt.

Im Moment benutze ich einen Druckknopf anstelle eines Türsensors zum Testen, werde ich auch irgendwann das Öffnen und Schließen der Tür protokollieren, aber für den Moment möchte ich wissen, ob es einen schöneren Weg gibt dies zu tun, habe ich den Code im von diesem post

mit meinem Code als

folgt
#!/usr/bin/python 

import threading, subprocess, sys, time, syslog 
import RPi.GPIO as GPIO 

lim = 2 # seconds until warning 

# thread for countdown (should be interruptable) 
class CountdownTask: 
    global dooropen 
    global countdone 

    def __init__(self): 
     #print("thread in") 
     self._running = True 

    def start(self): 
     print("thread in") 
     self._running = True 

    def terminate(self): 
     print("thread killed") 
     self._running = False 

    def run(self, n): 
     while True: 
      global countdone 

      while self._running and dooropen == False and countdone: 
       pass 

      while self._running and dooropen == False and countdone == False: 
       pass 

      while self._running and dooropen and countdone: 
       pass 

      while self._running and dooropen and countdone == False: 
       print("start timer") 
       time.sleep(5) 
       if dooropen: 
        ## action when timer isup 
        print("timer ended, send notify") 
        countdone = True 


c = CountdownTask() 
t = threading.Thread(target=c.run, args=(lim,)) 
t.daemon = True 

REED = 23 # data pin of reed sensor (in) 

# GPIO setup 
GPIO.setwarnings(False) 
GPIO.setmode(GPIO.BCM) 
GPIO.setup(REED, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 

dooropen = False # assuming door's closed when starting 
countdone = True 


def edge(channel): 
    global dooropen 
    global countdone 

    if GPIO.input(REED): # * no longer reached 
     if dooropen == False: # catch fridge compressor spike 
      print("Detect open") 
      countdone = False 
      dooropen = True 
     else: 
      print("Door closed") 
      dooropen = False 

def main(): 
    GPIO.add_event_detect(REED, GPIO.RISING, callback=edge, bouncetime=300) 
    t.start() 
    while True: 
     pass 

#------------------------------------------------------------ 

if __name__ == "__main__": main() 

Update:

Sieht aus wie ich threading.Event mit müssen und COU warten Kann mir jemand raten, wie ich das auf meinem Code implementiere?

Antwort

0

Ich glaube, ich habe ein funktionierendes Skript

#!/usr/bin/python 

import threading 
import time 
import logging 
import RPi.GPIO as GPIO 
import smtplib 
from email.MIMEMultipart import MIMEMultipart 
from email.MIMEText import MIMEText 

logging.basicConfig(level=logging.DEBUG,format='(%(threadName)-9s) %(message)s',) 

# GPIO setup 
Input = 23 # data pin of Input sensor (in) 

GPIO.setwarnings(False) 
GPIO.setmode(GPIO.BCM) 
GPIO.setup(Input, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 

global button 
button = False 
global count 
count = 1 
#global t 
t = 1 
countdown = 5 

def sendmail(): 
    fromaddr = "email" 
    toaddr = "tomail" 
    msg = MIMEMultipart() 
    msg['From'] = fromaddr 
    msg['To'] = toaddr 
    msg['Subject'] = "DoorAlarm" 

    body = "This is a test mail generated with python on a RPi" 
    msg.attach(MIMEText(body, 'plain')) 

    server = smtplib.SMTP('smtp.gmail.com', 587) 
    server.starttls() 
    server.login("username", "password") 
    text = msg.as_string() 
    server.sendmail(fromaddr, toaddr, text) 
    server.quit() 


def timeout(e, t): 
    global count 
    global button 

    while True: 
     while button: 
      while not e.isSet() and count <= countdown: 
       if count == 1: logging.debug('starting counter') 
       event_is_set = e.wait(t) 
       if event_is_set: 
        count = 1 
        logging.debug('Door closed before countdown') 
       else: 
        count += 1 
       if count == countdown: 
        logging.debug('countdown completed - notify') 
        #sendmail() 

def edge(channel): 
    global button 
    global count 

    if button == False: # catch fridge compressor spike 
     button = True 
     e.clear() 
     print("log door open") 
     if count != 1: 
      count = 1 

    else: 
     button = False 
     e.set() 
     print("log door closed") 

if __name__ == '__main__': 
    e = threading.Event() 

    t = threading.Thread(name='non-blocking',target=timeout,args=(e, t)) 
    t.start() 

    logging.debug('Waiting before calling Event.set()') 
    GPIO.add_event_detect(Input, GPIO.RISING, callback=edge, bouncetime=300)