2016-05-06 8 views
0

現在、私はRaspi IOを監視し、メッセージをチャネルに送るPython Telegramボットを作成しています。したがって、基本的には、ロギング変数llogを更新する関数があります。Python:オブジェクトのグローバルリストを印刷するときにprint関数がハングします

この機能(logUpdate)は、この名前のとおり、5分以上経過したエントリを削除します。その中で、私はグローバル変数の内容をチェックしようとしました。印刷すると、ハングするだけです。

これは他のボットコマンドを呼び出すことができるので、ボットの他の機能をブロックしているようには見えません。

私はそれがボットだとは思わない。それはある種のデータアクセスの問題でなければなりません。

#!usr/bin/python 

## 
### RF Security bot start script 
## 

## 
### Imports 
## 
import telegram  as tg 
import telegram.ext as tgExt 
import RPi.GPIO  as gpio 
import time 
from datetime import datetime as dt 

## 
### Common variables 
## 
NULLSENSOR = 0 
PRESSENSOR = 1 
MAGSENSOR = 2 

sensDict = {NULLSENSOR:"No sensor", 
      PRESSENSOR:"Pressure sensor", 
      MAGSENSOR:"Magnetic sensor"} 

# Event class 
class ev(object): 

     timestamp = 0 
     sType  = NULLSENSOR 

     def __init__(self, ts=0, st=NULLSENSOR): 
       self.timestamp = ts 
       self.sType  = st 


     def toString(self): 

       if(sType == PRESSENSOR): 
         return str("-> @"+timestamp.strftime('%c')+ 
            ": Pressure sensor triggered\n") 
       elif(sType == MAGSENSOR): 
         return str("-> @"+timestamp.strftime('%c')+ 
            ": Magnetic sensor triggered\n") 
       else: 
         return "" 


# Report log 
llog = []  # Data log 
lmutex = True # Log mutex for writing 

## 
### Hardware configuration 
## 

# GPIO callbacks 
def pressureCallback(channel): 
     global llog 
     global lmutex 
     global trigCntGlobal 
     global trigCntPress 

     ep = ev(ts=dt.now(), st=PRESSENSOR) 

     print("---> Pressure sensor triggered at "+ 
       ep.timestamp.strftime("%c")) 

     rfSecuBot.sendMessage('@channel', "Pressure sensor "+ 
         "triggered.") 

     while(not lmutex): 
       pass 

     lmutex = False 

     llog.insert(0, ep) 
     trigCntGlobal = trigCntGlobal + 1 
     trigCntPress = trigCntPress + 1 

     lmutex = True 


def magneticCallback(channel): 
     global llog 
     global lmutex 
     global trigCntGlobal 
     global trigCntMag 
     global rfSecuBot 

     em = ev(ts=dt.now(), st=PRESSENSOR) 

     print("---> Magnetic sensor triggered at "+ 
       em.timestamp.strftime("%c")) 

     rfSecuBot.sendMessage('@channel', "Magnetic sensor "+ 
         "triggered.") 

     while(not lmutex): 
       pass 

     lmutex = False 

     llog.insert(0, em) 
     trigCntGlobal = trigCntGlobal + 1 
     trigCntMag = trigCntMag + 1 

     lmutex = True 


# Periodic logging function 
def logUpdate(): 
     global llog 
     global lmutex 

     updTime = dt.now() 
     print("---> Updating log\n") 
     while(not lmutex): 
       pass 

     lmutex = False 

     for i in llog:       ########### STUCK HERE 
       print(i.toString())    ########### 

     # Check log timestamps 
     for i in llog: 
       if((updTime - i.timestamp).total_seconds() > 300): 
         llog.remove(i) 

     for i in llog:       ########### WAS STUCK HERE 
       print(i.toString())    ########### TOO 

     lmutex = True 

     print("---> Log updated\n") 


# Formatting function 
def logFormat(): 
     global llog 
     global lmutex 

     logUpdate() # Asynchronous call to logUpdate to make sure 
        # that the log has been updated at the time 
        # of formatting 

     while(not lmutex): 
       pass 

     lmutex = False 

     flog = [] 
     cnt = 0 

     for i in llog: 
       if(cnt < 10): 
         flog.append(i.toString()) 
         cnt = cnt + 1 
       else: 
         break 

     lmutex = True 

     print("----> Formatted string:") 
     print(flog+"\n") 
     return flog 


def listFormat(): 
     global llog 
     global lmutex 

     logUpdate() # Asynchronous call to logUpdate to make sure 
        # that the log has been updated at the time 
        # of formatting 

     while(not lmutex): 
       pass 

     lmutex = False 

     flog = [] 
     flog.append("  Sensors  \n") 

     dLen = len(sensDict.keys()) 

     if(dLen <= 1): 
       flog.append(sensDict.get(NULLSENSOR)) 
     else: 
       sdItr = sensDict.iterkeys() 
       st = sdItr.next() # Had to add extra var 
       while(dLen > 1): 
         st = sdItr.next() 
         trigCnt = 0 

         for i in llog: 
           if(i.sType == st): 
             trigCnt = trigCnt + 1 

         if(trigCnt < 1): 
           pass 
         else: 
           flog.append("-> "+st+"\n") 
           flog.append(" No. of times tripped: "+ 
              trigCnt+"\n") 

     lmutex = True 

     print("----> Formatted string:") 
     print(flog+"\n") 
     return flog 


## 
### Software configuration 
## 

def blist(bot, update): 
     print("--> List command received\n") 

     listString = "List of sensor trips in the last 5 minutes:\n" 
     listString = listString+listFormat() 

     print("> "+listString+"\n") 
    bot.sendMessage('@channel', listString) 


def log(bot, update): 
     print("--> Log command received\n") 

     logString = "Log of last 10 occurrences:\n" 
     logString = logString+logFormat() 

     print("> "+logString+"\n") 
    bot.sendMessage('@channel', logString) 


rfSecuBotUpd.start_polling(poll_interval=1.0,clean=True) 

while True: 
     try: 
       time.sleep(1.1) 
     except KeyboardInterrupt: 
       print("\n--> Ctrl+C key hit\n") 
       gpio.cleanup() 
       rfSecuBotUpd.stop() 
       rfSecuBot = 0 
       quit() 
       break 

## Callback registration and handlers are inserted afterwards 

# Just in case... 
print("--> Bot exiting\n") 
gpio.cleanup() 
rfSecuBotUpd.stop() 
rfsecuBot = 0 
print("\n\n\t *** EOF[] *** \t\n\n") 
quit() 

# EOF [] 

P.S.:

は、私は以下のいくつかのコードスニペットを添付します私は誰かがこれの 'クラス'バージョンを提案するかもしれないと思う。それは動作すると思いますか?値が返された理由を

def toString(self): 

      if(sType == PRESSENSOR): 
        return str("-> @"+timestamp.strftime('%c')+ 
           ": Pressure sensor triggered\n") 
      elif(sType == MAGSENSOR): 
        return str("-> @"+timestamp.strftime('%c')+ 
           ": Magnetic sensor triggered\n") 
      else: 
        return "" 

は常に空の文字列だった:

+0

ハング可能な 'logUpdate'内の唯一の場所は' while(not lmutex):pass'です。あなたはそれをチェックしましたか? ( 'while'ループの直後に' print( "---> lmutex \ n") 'を追加するだけです)。 – Ilya

+0

「印刷するとちょうどハングする」:正確にはどういう意味ですか?印刷してから停止するか、何も印刷しません。 'while(not lmutex):pass'は永遠にループするので、最初のオプションは驚きではありません。このプロセスは 'lmutex'の値を変更する意味はありません。 – zezollo

+0

グローバル変数の使用は難しい場合があります。時間の経過とともにその価値をチェックする方法を見つけるべきです。たとえば、どこかで変更されるたびにstderrに書き込むことができます。したがって、 'logUpdate'が' lmutex'の更新された値を取得するかどうかを確認することができます。 – zezollo

答えて

1

toString機能では、私は、あるべきメンバーsTypetimestampの前にselfを入れるのを忘れていました。

注:変数を確認してください!

このように、スレッドをブロックしていないような理由が説明されています。

+1

この回答にあなたの質問に答えてください。ありがとう! – Oleiade

関連する問題