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