Ankündigung

Einklappen
Keine Ankündigung bisher.

TCP BiDir, Python ByteCode Logikbaustein

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

    HS/FS TCP BiDir, Python ByteCode Logikbaustein

    Hallo Zusammen,

    ich betreibe 3 APC-USVen, welche ich über 3 Stück Wiznet110SR per Ethernet seriell auslesen und im HS darstellen möchte. (Wie Moxa, bloss preiswerter und für mich einfacher zu handhaben)

    Dank der unendlich vielen Informationen in diesem Form, insbesondere Makki´s 4 Jahre alter hslib, den Threads dazu und zum Thema "parallele bidirektionale TCP-Kommunikation des HS" war mir schnell klar, dass es so nicht gehen wird (der HS braucht dann zum darstellen der je 6 Werte der 3 USVen ca. 2h)

    Ich habe vegeblich versucht, Nils LogikGenerator zu verstehen um mir einen Logikbaustein mit Python zu bauen.
    Dennoch habe ich es irgendwie geschafft, nicht schön, aber m.E. dem Thema und meinem Können angemessen, da die USVen mit 2400Bd kommunizieren und die Abfrage der ganzen Betriebsparameter eben 1sek braucht, in der der Homeserver halt warten muss.
    Besser er 1s als ich 2h
    Alle Fliesskommawerte bekomme ich mittels Send-by-change geliefert und dargestellt - schön! Die 3 Abfragen laufen parallel, also nur 1s HS-Stop für alle 3 - sehr schön!

    Mein Problem:
    Die Strings für
    - Grund der letzen Umschaltung (transfer)
    - Status
    sehe ich in Nils Debugger wunderbar als 'S' und '08' (APC-üblich für OK), bekomme sie aber ebenso wie die Fertigmeldung des Bausteins (Done!), der immer am Ende ein 1-Telegramm schicken soll, nicht im HS zu sehen.
    Dazu habe ich den iKOs Gruppenadressen verpasst und im EIB Monitor beguckt.

    Hier mein Python-Versuch:
    Code:
    import sys
    import os
    import base64 
    import marshal
    import re
    import md5
    import inspect
    import time
    import socket
    import tempfile
    import popen2
    import zlib
    import zipfile
    
    ##############
    ### Config ###
    ##############
    
    ## Name der Logik
    LOGIKNAME="USV-APC-Abfrage"
    ## Logik ID
    LOGIKID="16408"
    
    ## Ordner im GLE
    LOGIKCAT="www.knx-user-forum.de"
    
    ## Beschreibung
    LOGIKDESC="""
    Fragt unter der angegeben IP im SmartMode die 10 wichtigsten Werte ab
    """
    VERSION="V0.1"
    
    ## Bedingung wann die kompilierte Zeile ausgeführt werden soll
    BEDINGUNG="EN[1] or EN[2] or EN[3] or EI"
    ## Formel die in den Zeitspeicher geschrieben werden soll
    ZEITFORMEL=""
    ## Nummer des zu verwenden Zeitspeichers
    ZEITSPEICHER="0"
    
    ## AUF True setzen um Binären Code zu erstellen
    doByteCode=False
    #doByteCode=True
    
    ## Base64Code über SN[x] cachen
    doCache=False
    
    ## Doku erstellen Ja/Nein
    doDoku=True
    
    debug=False
    livedebug=False
    showList=False
    
    
    #############################
    ########## Logik ############
    #############################
    LOGIK = '''# -*- coding: iso8859-1 -*-
    
    
    5000|"'''+LOGIKCAT+'''\\'''+LOGIKNAME+'''_'''+VERSION+'''"|0|2|"IP-Addr."|"Trigger"|12|"Bat-Volt"|"Temperatur"|"Transfer"|"In Volt"|"max Volt"|"min Volt"|"Out Volt"|"Load %"|"Bat %"|"Runtime"|"Status"|"Done!"
    
    
    # 5001|Anzahl Eingänge|Ausgänge|Zeitspeicher|Speicher|Berechnung bei Init
    5001|2|12|0|0|0        
    # 2 Eingänge, 12 Ausgänge, 0 Timer, 0 Speicher, keine Berechnung bei Initialisierung
    
    #################################################
    ### 5002 Definition der Eingänge EN[x]
    #################################################
    # 5002|Index Eingang|Default Wert|Datenformat 0=numerisch 1=alphanummerisch
    5002|1|""|1   # IP-Adresse
    5002|2|0|0    # Trigger
    # IP Adresse des Serial-TCP Wandlers und Trigger-Eingang
    
    #################################################
    ### 5004 Definition der Ausgänge AN[x]
    #################################################
    # 5004|Index Ausgang|Initwert|Runden binär|Typ (1-send/2-sbc)|Datenformat 0=numerisch 1=alphanummerisch
    5004|1|0|0|2|0   # Battery Voltage
    5004|2|0|0|2|0   # Internal Temperature
    5004|3|""|0|1|1   # Reason for last Transfer
    5004|4|0|0|2|0   # Input Line Voltage
    5004|5|0|0|2|0   # maximum input Line Voltage
    5004|6|0|0|2|0   # minimum Input Line Voltage
    5004|7|0|0|2|0   # Output Voltage
    5004|8|0|0|2|0   # Power Load %
    5004|9|0|0|2|0   # Battery Level %
    5004|10|0|0|2|0  # estimated runtime
    5004|11|""|0|1|1  # Status Byte
    5004|12|0|0|1|0   # Abfrage beendet
    #################################################
    
    ## Inkompatible Version 
    5012|1|"(__import__('sys').version[:3]!='2.2') and (__import__('sys').version[:3]!='2.4')"|"'Firmware inkompatibel'"|""|1|0|0|0
    '''
    #####################
    #### Python Code ####
    #####################
    
    code=[]
    
    code.append([3,"","""
    
    if not EI and EN[1] != '' and EN[2] == 1:      # nur wenn Trigger und IP-Adresse vorhanden.
      s = __import__('socket').socket(__import__('socket').AF_INET,__import__('socket').SOCK_STREAM)
      s.settimeout(2.0)
      s.connect((EN[1], 5000))         # IP und Port
    
      try: 
    # force USV to SmartMode
        s.send("Y") 
        ret = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '':
                break
            else:
                ret += c
    
    # Battery Voltage
        s.send("B") 
        ret = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '\\r' or c == '':
                c = s.recv(1)
                break
            else:
                ret += c
        AN[1] = float(ret)
    
    # internal Temperature
        s.send("C") 
        ret = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '\\r' or c == '':
                c = s.recv(1)
                break
            else:
                ret += c
        AN[2] = float(ret)
    
    # reason for last switch
        s.send("G") 
        ret = ''
        reason = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '\\r' or c == '':
                c = s.recv(1)
                break
            else:
                ret += c
        AN[3] = ret
    
    # Line Voltage
        s.send("L") 
        ret = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '\\r' or c == '':
                c = s.recv(1)
                break
            else:
                ret += c
        AN[4] = float(ret)
    
    # maximum Line Voltage
        s.send("M") 
        ret = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '\\r' or c == '':
                c = s.recv(1)
                break
            else:
                ret += c
        AN[5] = float(ret)
    
    # minimum Line Voltage
        s.send("N") 
        ret = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '\\r' or c == '':
                c = s.recv(1)
                break
            else:
                ret += c
        AN[6] = float(ret)
    
    #  Output Voltage
        s.send("O") 
        ret = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '\\r' or c == '':
                c = s.recv(1)
                break
            else:
                ret += c
        AN[7] = float(ret)
    
    # Power Load
        s.send("P") 
        ret = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '\\r' or c == '':
                c = s.recv(1)
                break
            else:
                ret += c
        AN[8] = float(ret)
    
    # Battery capacity
        s.send("f") 
        ret = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '\\r' or c == '':
                c = s.recv(1)
                break
            else:
                ret += c
        AN[9] = float(ret)
    
    # Status-Byte
        s.send("Q") 
        ret = ''
        status = ''
        while True:
            c = s.recv(1)
            if c == '\\n' or c == '\\r' or c == '':
                break
            else:
                ret += c
        AN[11] = ret
    
    # estimated runtime
        s.send("j") 
        ret = ''
        while True:
            c = s.recv(1)
            if c == ':':
                break
            else:
                ret += c
        AN[10] = float(ret)
    
      finally: 
          s.close()
          AN[12] = 1
    
      try:
        for i in rage(1,len(AA)+1):
          if AN[i]!=AA[i]:
            AC[i]=1
      except:
        pass
    
    """])
    
    postlogik=[0,"","""
    ## in der Init-Phase einfach erbrechen, da nix zu tun...
    5012|1|"EI"|""|""|0|0|0|0
    """]
    Ich hoffe, mir kann jemand weiterhelfen, denn nur darauf zu vertrauen, die "Input-Line-Voltage" auszuwerten, ist mir etwas wenig.
    In den vergangenen Jahren waren bei mir die Stromausfälle verursacht durch EVU und USVen nahezu gleich häufig.

    Abschließend meinen Dank an alle. die diese unendliche Menge an Informationen zusammen getragen haben.

    Viele Grüße
    Nick
    GIRA HS3, HS2, Mobotix, Shuttle X50, Selve SMI-Antriebe, GEZE-Tür- & Fenster Antriebe, Siemens-, ABB- & Eigenbau-Aktoren, GIRA TS2, Jung RCD 3096, Hoppe enOcean Fenstergriffe mit Schlaps-GW, Bluetooth-Türöffner, MicroVis II, Elsner Suntracer, Hager Stellantriebe, KOSTAL PV-WR, u.v.a.m...
Lädt...
X