Ankündigung

Einklappen
Keine Ankündigung bisher.

ByteCode: TCP-BiDir Klasse für eigene Logiken

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    HS/FS ByteCode: TCP-BiDir Klasse für eigene Logiken

    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.


    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)
    Diese Klasse Kann auch auf einem Lokalen Python getestet werden, indem sie so

    Code:
    KNXUF_TCP_BiDIR(False,"192.168.178.1","")
    __import__('time').sleep(10)
    aufgerufen wird. Wenn dafür dann ein kompletes Template benötigt wird, bitte PN
    Nils

    aktuelle Bausteine:
    BusAufsicht - ServiceCheck - Pushover - HS-Insight

    #2
    ...Tada, schon ist die Verbindung zur Fritzbox hergestellt...

    Fritzbox.png

    Kommentar

    Lädt...
    X