2014-04-03 84 views
0

我有一個紅外傳感器的樹莓派。在我的Python腳本中,有一個線程類監聽一個imap服務器(捕獲像START或STOP之類的指令)。我的想法是現在通過電子郵件發送命令,一旦腳本收到命令,應該禁用某些功能,直到收到新命令。但主要問題是現在我不知道如何實現它。 謝謝你提供有用和有用的建議。Python:如何啓用和禁用函數?

def take_picture(): 
    ... 

def take_video(): 
    ... 

class EmailThread(threading.Thread): 

    def __init__(self): 
     threading.Thread.__init__(self) 

    def run(self): 
     while True: 
     .... 
       if get_mail == 1: 
        if var_subject == 'STOP': 
         #TODO: stop take_picture(), take_video() 
         pass 

        elif var_subject == 'START': 
        #TODO: start take_picture(), take_video() 
         pass 
        else: 
         print u'Wrong command' 

     time.sleep(600) #google doesn't like many connections within 10min 

def main(): 
    # Start eMail Thread 
    email = EmailThread() 
    email.start() 
    try: 
     print "Waiting for PIR to settle ..." 
     # Loop until PIR output is 0 
     while GPIO.input(GPIO_PIR) == 1: 
      Current_State = 0 
     print "Ready" 
     # Loop until threadingusers quits with CTRL-C 
     while True : 
      # Read PIR state 
      Current_State = GPIO.input(GPIO_PIR) 
      if Current_State == 1 and Previous_State == 0: 
       counter = counter + 1 
       # PIR is triggered 
       start_time = time.time() 

       log_to_file('Motion Nr. %s detected!' % counter) 
       take_picture() 

       # Record previous state 
       Previous_State = 1 

      elif Current_State == 0 and Previous_State == 1: 
       # PIR has returned to ready state 
       stop_time=time.time() 
       print " Ready ", 
       elapsed_time=int(stop_time-start_time) 
       print " (Elapsed time : " + str(elapsed_time) + " secs)" 
       Previous_State = 0 

    except KeyboardInterrupt: 
     print "Quit " 
     # Reset GPIO settings 
     GPIO.cleanup() 

if __name__ == '__main__': 
    main() 
+0

我使用'python3'來獲取,除非你有特殊的理由使用'python2'。即使你決定使用'python2',我建議使用'print'作爲一個函數。 –

+0

我使用python2.7,因爲一些模塊只能在python2下運行,比如picamera – Seppo

+0

你是否在尋找一些奇特的建築物?我只需在電子郵件線程中設置一個布爾標誌,並在主循環中放入一個'if email.enable_picture:'。 – dornhege

回答

1

我認爲你的問題標題是嚴重選擇。我認爲你要做的是啓動/停止線程正在運行的功能。啓動一個線程很容易,停止它稍微困難一些,取決於函數內部的功能。

你會想看看線程間的通信方法,尤其是condition variables。一般來說,一個線程只能在它允許你這樣做的時候被正常地停下來,例如在一個條件變量上休眠時。

如果你真的不想使用線程,而是定期要運行當前活動的功能,你需要實現調度 - 在最簡單的情況下,調度將通過名單只是反覆循環活動函數,並調用它們。

我推薦後者,因爲線程大多隻是引入了不必要的複雜性和錯誤來源,但是從你的問題來看,你聽起來像是你決定做第一個。

1

在初始化,您可以添加地圖功能裁判來布爾值,像這樣

class ClassWithTheFunctions: 
    def __init__(self): 
     import types 
     #... 
     self.funcMap = {} 
     for o in self.__dict__: 
      if type(self.__dict__[o]) == types.FunctionType or type(self.__dict__[o]) == types.MethodType: 
       self.funcMap[self.__dict__[o]] = True 

當你要調用一個函數,你選擇了它第一

if instanceOfTheClassWithTheFunctions.funcMap[funcIWantToCall] : 
    funcIWantToCall() 

,如果你想禁用功能:

instanceOfTheClassWithTheFunctions.funcMap[funcIWantToCall] = False 

或啓用:

instanceOfTheClassWithTheFunctions.funcMap[funcIWantToCall] = True