Hier ist der Anteil aus der FritzBox-CallMon Logik der eine Verbindung zu einem TCP Port aufrecht erhällt und darüber Daten erhällt und sendet.
Diese Klasse Kann auch auf einem Lokalen Python getestet werden, indem sie so
aufgerufen wird. Wenn dafür dann ein kompletes Template benötigt wird, bitte PN
Code:
class KNXUF_TCP_BiDIR:
def __init__(self,logik,ip,configstr):
self.logik=logik
self.__config = {'lang':'de','maxretry':12,'waittime':30,'port':1012,}
self.setConfig(configstr)
self.i18n={}
self.i18n['de']={'TCP_CONNECT':'Verbindung zu xxxx %s:%d hergestellt','TCP_MAXFAIL':'Maximale Anzahl Fehlverbindungen zu %s','TCP_LOST':'Verbindung zu xxxx %s verloren','TCP_FAIL':'Verbindung zu xxxx %s fehlgeschlagen'}
try:
self.lang=self.i18n[self.__config['lang'].lower()]
except KeyError:
pass
self.lang=self.i18n['de']
self.__myLogID=__import__('md5').new(str(__import__('whrandom').random())).hexdigest()
self.reconTime=self.__config['waittime']
self.connectFailures=0
self.ip=ip
self.__runit=True
## Start des Threads
self.start_thread()
def start_thread(self):
###DEBUG###print "Start Thread: "+self.ip
## die Funktion __connect als Thread ausführen
self.__thread = __import__('threading').Thread(target=self.__connect,name='FBFCALLMON_'+self.ip)
self.__thread.setDaemon(True)
self.__thread.start()
def __connect(self):
try:
try:
## Kein weiterer Versuch wenn MAXRETRY erreicht ist
if self.connectFailures < self.__config['maxretry']:
## TCP-Socket erstellen
self.__socket = __import__('socket').socket(__import__('socket').AF_INET,__import__('socket').SOCK_STREAM)
## Verbinden
###DEBUG###print "Connect to FritzBox "+self.ip+":"+str(self.__config['port'])
self.__socket.connect((self.ip,self.__config['port']))
self.log(self.lang['TCP_CONNECT'] % (self.ip,self.__config['port']))
## Socketfile erstellen
self.__sockfile = self.__socket.makefile("r")
## Anzahl Fehler nach Erfolg wieder auf 0
self.connectFailures=0
## Wartezeit wieder auf Initialwert
self.reconTime = self.__config['waittime']
## Den eigentliche parser als Loop starten
self.__grabber()
else:
###DEBUG###print "Maximum Connections Retries"
self.log(self.lang['TCP_MAXFAIL'] % (self.ip),'error')
## Abbruch
return
except __import__('socket').error:
pass
###DEBUG###print "Can't connect to "+self.ip+":"+str(self.__config['port'])
self.log(self.lang['TCP_FAIL'] % (self.ip),'warning')
## Fehler einen rauf
self.connectFailures += 1
except:
###DEBUG###__import__('traceback').print_exc(file=__import__('sys').stdout)
pass
###DEBUG###print "Connection Lost to "+self.ip+":"+str(self.__config['port'])
self.log(self.lang['TCP_LOST'] % (self.ip),'warning')
## Fehler einen rauf
self.connectFailures += 1
finally:
###DEBUG###print "Closing connection to "+self.ip
try:
## File und Socket wieder schließen
self.__sockfile.close()
self.__socket.close()
except:
pass
### Reconnect nach Wartezeit
###DEBUG###print "waiting "+str(self.reconTime)+" Seconds till reconnect"
__import__('time').sleep(self.reconTime)
## Wartezeit mit Fehleranzahl multiplizieren
self.reconTime = self.reconTime*2
## Diese Funktion wieder aufrufen
return self.__connect()
### Ab hier ändern
def __grabber(self):
callinfo={}
###DEBUG###print "Grabber for "+self.ip+" started"
while self.__runit:
## Daten vom Socketfile lesen
data = self.__sockfile.readline()
if not data:
## Wenn keine Daten dann Abruch
break
## CRLF abschneiden und splitten
#raw = data[:-2].split(";",7)
## Hier jetzt irgendwas mit den eingehenden Daten machen
## z.B.
#if data=='\x44\x33':
# self.__cbfunction('VOLUP')
#elif data=='\x44\x32':
# self.__cbfunction('VOLDOWN')
def __cbfunction(self,protocol):
## alle Callback Funktionen der Liste aufrufen
###DEBUG###print "DEBUG-CALLINFO ("+self.ip+"):"+repr(protocol)
## An Ausgang 1 Senden
self.sendout(1,protocol)
### SystemLog
def log(self,msg,severity='info'):
##i18n
facility="TCP-BiDIR"
logmsg = "<log><id>"+__import__('md5').new(self.__myLogID + str(__import__('time').time())).hexdigest() +"</id><facility>"+facility+"</facility><severity>%s</severity><message>%s</message></log>" % (severity,msg)
## An Ausgang 2 senden
self.sendout(2,logmsg)
##### AB hier nix mehr ändern
##
## Configuration von String lesen
##
def setConfig(self,newconfig):
if not newconfig:
return
for option in newconfig.split('*'):
try:
key , val = option.split("=",1)
## Wert in Integer wandeln
if type(self.__config[key])==int:
val=int(val)
## Wenn gültig dann setzen sonst KeyError
self.__config[key] = val
except KeyError:
pass
###DEBUG###print "Konfig fehlgeschlagen: "+option
except ValueError:
pass
###DEBUG###print "Konfig wrong Value: "+option
###DEBUG###print "Konfig: "+repr(self.__config)
## Senden auf die AUsgänge aus dem Thread heraus
def sendout(self,out,wert):
## Der Index der Ausgänge fängt bei 0 und nicht bei 1 an
###DEBUG###print "Write "+repr(wert)+" auf Ausgang "+str(out)
out=out-1
## Auf iKO's schreiben
for iko in self.logik.Ausgang[out][1]:
try:
iko.setWert(out,wert)
iko.checkLogik(out)
except:
###DEBUG###print "Error writing to iko: "+str(wert)
###DEBUG###__import__('traceback').print_exc(file=__import__('sys').stdout)
pass
## Logiken ausführen
for logik in self.logik.Ausgang[out][3]:
try:
logik[0].LogikItem.calc(logik[0],logik[1],wert,0,__import__('time').time())
except:
###DEBUG###print "Error writing Outputs: "+str(wert)
###DEBUG###__import__('traceback').print_exc(file=__import__('sys').stdout)
pass
def TCPsend(self,msg):
self.__socket.send(msg)
Code:
KNXUF_TCP_BiDIR(False,"192.168.178.1","")
__import__('time').sleep(10)


Kommentar