現在、私は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 ""
は常に空の文字列だった:
ハング可能な 'logUpdate'内の唯一の場所は' while(not lmutex):pass'です。あなたはそれをチェックしましたか? ( 'while'ループの直後に' print( "---> lmutex \ n") 'を追加するだけです)。 – Ilya
「印刷するとちょうどハングする」:正確にはどういう意味ですか?印刷してから停止するか、何も印刷しません。 'while(not lmutex):pass'は永遠にループするので、最初のオプションは驚きではありません。このプロセスは 'lmutex'の値を変更する意味はありません。 – zezollo
グローバル変数の使用は難しい場合があります。時間の経過とともにその価値をチェックする方法を見つけるべきです。たとえば、どこかで変更されるたびにstderrに書き込むことができます。したがって、 'logUpdate'が' lmutex'の更新された値を取得するかどうかを確認することができます。 – zezollo