2016-07-19 9 views
0

これを行う最善の方法はわかりませんし、睡眠がうまくいかないときにプログラムをロックするように私のために働いていません...GPIO入力が変更された場合のカウントダウンスレッドRPiの停止

私はドアが開かれている時間がx時間以上であれば、ドアが開かれてラズベリーパイで閉じられるのを監視しようとしています。カウントダウンが終了してカウントダウンを止めずにスレッドを停止させ、アラート側を実装していますが、コードが現時点ではカウントダウン前にドアが閉じてもアラートをトリガーします。

私はテストのためにドアセンサーの代わりにプッシュボタンを使用していますが、最終的に私はドアの開閉を記録しますが、今のところIDはもっと良い方法があるかどうかを知りたいこれをやって、私はこのpost

から使用してコードイムを持っ

#!/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() 

を更新、次のように私のコードは次のとおりです。

私はthreading.Eventを使用する必要があるように見えるとCOUを待つが、誰かが私のコードにこれを実装する方法をアドバイスしてくれましたか?

答えて

0

は、私は私が働いてスクリプトを得たと思う

#!/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) 
関連する問題