Ankündigung

Einklappen
Keine Ankündigung bisher.

LBS Resol VBus / Viessmann Vitosol 200

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

    LBS Resol VBus / Viessmann Vitosol 200

    Hi,

    ich habe angefangen einen Baustein für das Resol VBus Protokoll in php zu schreiben.
    Das Protokoll ist sehr universell - ich habe mich gegen einen universellen Baustein für alles entschieden und zunächst die Viessmann Vitosol 200 Regelung (Solarthermie) und Viessmann Vitotrans (Frischwasserstation) umgesetzt. Viessmann setzt direkt die Resol Steuerungen mit deren Protokoll ein.
    Für andere Geräte ist die zukünftige Anpassung aber nicht so arg aufwändig.

    Ich habe nur die Datenauswertung in Protokoll 1.0, damit gibt es keine Möglichkeit die Geräte zu beeinflussen (und Störungen sind unwahrscheinlich).
    Elektrisch habe ich mich an die Schaltung aus der Resol VBus Protokollbeschreibung gehalten.

    UPDATE:
    Weiter unten gibt es funktionierenden Code

    Offene Punkte:
    - der LBS blinkt im Live Modus rot - ist gefixt
    - mein LBS Account ist gesperrt - drum hier direkt mal der Code, später kommt das natürlich rein in die Downloads
    - Umrechnung und Auswertung mancher Daten ist noch falsch, beispielsweise der Systemzeit, Drehzahlen passen jetzt

    ich freue mich über weitere Tester!

    Zuletzt geändert von schobi; 01.09.2017, 21:43. Grund: update für neue Version

    #2
    Du solltest in der Deklaration eine Variable deklarieren:

    Code:
    [v#1 = 0]
    Dann solltest du das

    PHP-Code:
      if (getLogicElementStatus($id) == 0

    durch ein

    PHP-Code:
      if (logic_getVar($id,1) == 0

    ersetzen. Und das

    PHP-Code:
      setLogicElementStatus($id,1); 

    durch ein

    PHP-Code:
      logic_setVar($id,1,1); 

    ersetzen.

    Dann sollte es nicht mehr blinken.

    Hinter der while Schleife im EXEC solltest du dann ein

    PHP-Code:
      logic_setVar($id,1,0); 

    machen. Das setzt den Status wieder zurück, wenn der EXEC Daemon beendet ist.

    Kommentar


      #3
      Hallo,
      klingt interessant.
      Über welche Steuerung gehst Du und welche Schnittstelle hast Du im Einsatz?

      Danke und Grüße,
      Lio

      Kommentar


        #4
        jonofe super - das werde ich noch umbauen! Heute war leider noch keine Zeit ...

        @Iio123 Zu meinem Aufbau:
        Ich habe eine kleine Schaltung aus der resol Protokollbeschreibung gelötet und diese über einen max232 Wandler (1 €) an einen USR TCP232-302 wandler (< 20€) an mein Netzwerk angeschlossen.
        der LBS verbindet sich als TCP Client mit der USR Gerät.

        ​​​​​​​Meine Solar-Steuerung ist eine vitosol 200, die auch baugleich mit Resol Geräten ist. Der Vbus Ausgang verhält sich wie erwartet.

        Kommentar


          #5
          schobi
          Danke für die Info. Ich hatte ein Wandler gebaut, der mittlerweile seinen Geist aufgegeben hat. Könntest Du mir Deine Schaltung zur Verfügung stellen? Gibt es gar ein Layout?

          Danke und Grüße,
          Lio

          Kommentar


            #6
            Aktuell habe ich eine Schaltung auf Lochraster gelötet. Direkt nach einem Schaltplan von Resol. Den Teil der Schaltung mit Ansteuerung des Bus habe ich weggelassen.
            Inzwischen sind davon 2 Stück aufgebaut (einer für die Solarthermie, einer für die Frischwasserstation) und damit läuft es.

            Mittelfristig möchte ich dafür kleine Platinen machen lassen und direkt auch ein USR-TCP232-T2 Modul einlöten - aber das wird noch dauern...


            Es gibt noch weitere Herausforderungen:
            - IP Adresse ändern erfordert noch einen Edomi Neustart damit was passiert
            - da kommen alle 2 Sekunden neue Werte raus - ein 2-tages Diagramm lädt damit schon echt lange. Man bräuchte noch einen Baustein der über n=30 Werte mittelt und erst dann einen Ausgabewert weiterschickt


            aktueller Code für den Vitosol 200 Regler
            Code:
            ###[DEF]###
            [name        = Resol VBUS Vitosol 200 Regler ]
            
            [e#1    IMPORTANT    = IP_Adresse     ]
            [e#2    IMPORTANT    = Port #init=8234    ]
            [e#5    OPTION      = Loglevel #init=3 ]
            
            
            [a#1        = Temperatur Sensor 1 ]
            [a#2        = Temperatur Sensor 2 ]
            [a#3        = Temperatur Sensor 3 ]
            [a#4        = Temperatur Sensor 4 ]
            [a#5        = Temperatur Sensor 5 ]
            [a#6        = Temperatur Sensor 6 ]
            [a#7        = Temperatur Sensor 7 ]
            [a#8        = Temperatur Sensor 8 ]
            [a#9        = Temperatur Sensor 9 ]
            [a#10        = Temperatur Sensor 10 ]
            [a#11        = Temperatur Sensor 11 ]
            [a#12        = Temperatur Sensor 12 ]
            [a#13        = SZ Eintrahlung ]
            [a#14        = SZ Spannung ]
            [a#15        = Impulszähler 1]
            [a#16        = Impulszähler 2]
            [a#17        = Sensor Unterbrechung ]
            [a#18        = Sensor benutzt ]
            [a#20        = Drehzahl Relais 1 ]
            [a#21        = Drehzahl Relais 2 ]
            [a#22        = Drehzahl Relais 3 ]
            [a#23        = Drehzahl Relais 4 ]
            [a#24        = Drehzahl Relais 5 ]
            [a#25        = Drehzahl Relais 6 ]
            [a#26        = Drehzahl Relais 7 ]
            
            [a#27        = Lasterkennung Relais ]
            [a#28        = Fehler Lasterkennung Relais ]
            [a#29        = Relaisbenutzungsmaske ]
            [a#30        = Fehlermaske ]
            [a#31        = Warnmaske ]
            [a#32        = SW Version ]
            [a#33        = Minorversion ]
            [a#34        = Systemzeit ]
            [a#35        = Fehler Solarzelle ]
            
            [a#40        = WMZ Gesamt [Wh] ]
            [a#41        = WMZ heute [Wh] ]
            [a#42        = WMZ gestern [Wh] ]
            [a#43        = WMZ Woche [Wh] ]
            
            [v#1 = 0]
            
            ###[/DEF]###
            
            
            ###[HELP]###
            Vorlage: LBS mit EXEC-Script
            
            Resol VBUS Decoder
            verbindet zu einer IP/Port um die seriellen Daten zu empfangen
            
            Changelog:
            0.1:
            -initiale Version
            
            ###[/HELP]###
            
            
            ###[LBS]###
            <?
            
            function LB_LBSID($id) {
                if ($E=logic_getInputs($id)) {
            
            
                    // EXEC-Script starten
                    if (logic_getVar($id,1) == 0) {
                        logic_setVar($id,1,1); 
                        LB_LBSID_debug($id," function LB_LBSID starting EXEC",7);
                        logic_callExec(LBSID,$id);
                    }
            
                }
            }
            
            
            function LB_LBSID_debug($id, $s, $l) {
                $E=logic_getInputs($id);
                $DEBUG=$E[5]['value'];
                $l<=$DEBUG && writeToCustomLog("LBSLBSID",$l,"(ID$id): ".$s);
            }
            
            
            ?>
            ###[/LBS]###
            
            
            ###[EXEC]###
            <?
            
            
            
            
            require(dirname(__FILE__)."/../../../../main/include/php/incl_lbsexec.php");
            
            //bei Bedarf kann hier die maximale Ausführungszeit des Scripts angepasst werden (Default: 30 Sekunden)
            //Beispiele:
            set_time_limit(0);    //Script soll unendlich laufen (kein Timeout)
            //set_time_limit(60);    //Script soll maximal 60 Sekunden laufen
            
            sql_connect();
            
            
            // turn off the errors
            $error_handler = set_error_handler("myErrorHandler");
            error_reporting(0);
            
            
            
            
            if ($E=getLogicEingangDataAll($id)) {
                debug($id,"Baustein startet ",7);
            
                $connection = new stdClass;
            
            
                if(!empty($E[1]['value'])){
                    $ipadresse=$E[1]['value'];
                } else {
                    debug($id, "Keine IP Adresse angegeben, Abbruch",2);
                    finish();
                    exit();
                }
            
                if(!empty($E[2]['value'])){
                    $port=$E[2]['value'];
                } else {
                    debug($id, "Keinen Port angegeben, Abbruch",2);
                    finish();
                    exit();
                }   
            
                  while (true) { 
            
                    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
                    $connection->target = $socket; 
            
                    if ($socket === false) {
                        debug($id, "socket_create() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error()) . ", Abbruch",4);
                        if (is_object($socket)) 
                            socket_shutdown($connection->target, 2);
                        break;
                    } else {
                        debug($id,"socket_create() OK.",7);
                       }
            
                    debug($id, "Versuche mit IP '".$ipadresse."' auf Port '".$port."' zu verbinden ...",6);
                    $result = socket_connect($socket, $ipadresse, $port);
                    if ($result === false) {
                        debug($id,"socket_connect() fehlgeschlagen. Grund: ($result) " . socket_strerror(socket_last_error($socket)) . ", Abbruch",4);
                        if (is_object($socket)) 
                            socket_shutdown($connection->target, 2);
                        break;
                    } else {
                        debug($id,"socket_connect() OK",7);
                    }
            
            
            
                    read_from_bus($id, $connection);
            
                    // connection has problems, maybe try again with some waiting?
                    usleep(10*1000*1000);
            
                    if (is_object($connection->target)) {
                         debug($id,"closing sockets", 5);
                           socket_shutdown($connection->target, 2);
                    }
                }
            
            
                debug($id,"EXEC des Bausteins wird beendet", 4);
                finish();
            
                exit();
            
            }
            
            
            
            
            function finish() {
                logic_setVar($id,1,0); 
            
                // turn errors back on
                restore_error_handler();
                error_reporting(E_ALL);
            
                sql_disconnect();
            
            }
            
            
            
            function read_from_bus($id, $connection) {
            
                $e_nonblocking = 11; // Error code for  EAGAIN or EWOULDBLOCK
            
                if (!is_object($connection)) {
                    debug($id, "Fehler in read_from_bus() Parameter, Abbruch", 3);
                    finish();
                }
            
            
                $decoderstate = new StdClass();
                $decoderstate->state = STATE_WAIT_FOR_SYNC_BYTE_AA;
                $decoderstate->destaddr = "";
                $decoderstate->sourceaddr = "";
            
            
                while (true) {
                    $sin = "";
                    $reciv = "";
                    $bytes = socket_recv($connection->target, $sin, 45, MSG_DONTWAIT);
                    if (false === $bytes) {  
                        // no data, just wait and try again
                        usleep(100*1000);
            
                    }
                    else if (0 === $bytes) {  
                        // some error has happened
                        if (socket_last_error() == $e_nonblocking) {
                            // non blocking socket has not returned anything, try again later
                            usleep(100*1000);
                            continue;
                        }
                        else {
                               debug($id, "socket_recv() failed; reason: ".socket_last_error()." " . socket_strerror(socket_last_error($connection->target)), 3);
                            debug($id, "connection seems broken/closed/aborted", 4);
                            usleep(1000*1000);
                            return 0;
            
                        }
                    }
                    else {
                           $reciv = strtoupper(array_shift(unpack("H*", $sin)));
                        debug($id, "read $bytes bytes from bus, data: " . $reciv, 7);
            
                        $inbytearray = unpack("C*", $sin);
            
                        while (count($inbytearray) > 0) {
                            // process each byte seperately
                            $currentbyte = array_shift($inbytearray);
                            state_machine_parse_data($id, $currentbyte, $decoderstate);
                        }
                        usleep(10*1000);
                    }
            
                }
                return 0;
            
            }
            
            
            define("STATE_WAIT_FOR_SYNC_BYTE_AA", 1);
            define("STATE_DEST_BYTE_L", 2);
            define("STATE_DEST_BYTE_H", 3);
            define("STATE_SOURCE_BYTE_L", 4);
            define("STATE_SOURCE_BYTE_H", 5);
            define("STATE_PROTOCOL", 6);
            define("STATE_COMMAND_BYTE_L", 7);
            define("STATE_COMMAND_BYTE_H", 8);
            define("STATE_NUM_FRAMES", 9);
            define("STATE_HEADER_CHECKSUM", 10);
            define("STATE_RECEIVE_DATA_FRAMES", 11);
            define("STATE_DATA_CHECKSUM", 12);
            //define("STATE_PROTOCOL", 13);
            //define("STATE_PROTOCOL", 14);
            
            
            function state_machine_parse_data($id, $currentbyte, & $decoderstate) {
            
                $newstate = $decoderstate->state;  // in case nothing changes
            
                switch($decoderstate->state) {
                    case STATE_WAIT_FOR_SYNC_BYTE_AA:
                        if ($currentbyte == 0xAA) {
                            $newstate = STATE_DEST_BYTE_L;    
                            $decoderstate->crc = 0x7F;  // reset crc
                        }
                        break;
            
                    case STATE_DEST_BYTE_L: 
                        $decoderstate->destaddr = $currentbyte;
                        update_crc($decoderstate, $currentbyte);
                        $newstate = STATE_DEST_BYTE_H;    
                        break;
            
                    case STATE_DEST_BYTE_H: 
                        $decoderstate->destaddr += $currentbyte<<8;
                        update_crc($decoderstate, $currentbyte);
                        $newstate = STATE_SOURCE_BYTE_L;    
                        break;
            
                    case STATE_SOURCE_BYTE_L:
                        $decoderstate->sourceaddr = $currentbyte;
                        update_crc($decoderstate, $currentbyte);
                        $newstate = STATE_SOURCE_BYTE_H;    
                        break;
            
                    case STATE_SOURCE_BYTE_H:
                        $decoderstate->sourceaddr += $currentbyte<<8;
                        update_crc($decoderstate, $currentbyte);
                        $newstate = STATE_PROTOCOL;
                        break;
            
                    case STATE_PROTOCOL:
                        if ($currentbyte == 0x10) { // Protocol version 1.0
                            $newstate = STATE_COMMAND_BYTE_L;
                            update_crc($decoderstate, $currentbyte);
                        }
                        else { // protocol version not supported, wait for next sync
                            $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;    
                        }
                        break;
            
                    case STATE_COMMAND_BYTE_L:
                        $decoderstate->command = $currentbyte;
                        update_crc($decoderstate, $currentbyte);
                        $newstate = STATE_COMMAND_BYTE_H;
                        break;
            
                    case STATE_COMMAND_BYTE_H:
                        $decoderstate->command += $currentbyte<<8;
                        if ($decoderstate->command = 0x0100) { // "Paket enthält Daten für Slave"
                            $newstate = STATE_NUM_FRAMES;
                            update_crc($decoderstate, $currentbyte);
                        }
                        else {  // command not supported, wait for next sync
                            $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                        }
                        break;
            
                    case STATE_NUM_FRAMES:
                        $decoderstate->num_frames_expected = $currentbyte;
                        update_crc($decoderstate, $currentbyte);
                        debug($id, "expecting ". $decoderstate->num_frames_expected ." frames destination 0x". dechex($decoderstate->destaddr) ." and source 0x". dechex($decoderstate->sourceaddr), 6);
                        $newstate = STATE_HEADER_CHECKSUM;
                        break;
            
                    case STATE_HEADER_CHECKSUM:
                        if ($decoderstate->crc == $currentbyte) { // crc ok
                            $newstate = STATE_RECEIVE_DATA_FRAMES;
                            $decoderstate->crc = 0x7F; // reset crc
                            $decoderstate->num_frames_received = 0;
                            $decoderstate->received_bytes = array();
                        }
                        else {
                            debug($id, "crc error, received 0x". dechex($currentbyte) ." but expected 0x". dechex($decoderstate->crc) .", skipping frame", 4);
                            $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                        }
                        break;
            
                    case STATE_RECEIVE_DATA_FRAMES;
                        if ($currentbyte == 0xAA) { // this should not happen!
                            $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                            debug($id, "unexpected AA in datastream - skipping ", 4);
                        }
                        else {
                            update_crc($decoderstate, $currentbyte);
            
                            if (count($decoderstate->received_bytes) >= 4) { // process septett
                                if ($currentbyte & 0x01)   $decoderstate->received_bytes[0] += 128;
                                if ($currentbyte & 0x02)   $decoderstate->received_bytes[1] += 128;
                                if ($currentbyte & 0x04)   $decoderstate->received_bytes[2] += 128;
                                if ($currentbyte & 0x08)   $decoderstate->received_bytes[3] += 128;
                                $decoderstate->num_frames_received += 1;
                                $newstate = STATE_DATA_CHECKSUM;
                            }
                            else {
                                array_push($decoderstate->received_bytes, $currentbyte);
                            }
            
                        }
                        break;
            
                    case STATE_DATA_CHECKSUM:
                        debug($id, count($decoderstate->received_bytes) ." bytes collected ", 8);
                        if ($decoderstate->crc == $currentbyte) { // crc ok
                            debug($id, "crc ok, received ". count($decoderstate->received_bytes) ." bytes", 8);
            
                            // do something with the data
                            process_data($id, $decoderstate->destaddr, $decoderstate->sourceaddr, $decoderstate->num_frames_received, $decoderstate->received_bytes);
            
                            if ($decoderstate->num_frames_received < $decoderstate->num_frames_expected) { 
                                // prepare for receiving next frame
                                $newstate = STATE_RECEIVE_DATA_FRAMES;
                                $decoderstate->crc = 0x7F; // reset crc
                                $decoderstate->received_bytes = array();
                            }
                            else {
                                $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                            }
                        }
                        else {
                            debug($id, "crc error, received 0x". dechex($currentbyte) ." but expected 0x". dechex($decoderstate->crc) .", skipping frame", 4);
                            $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                        }
                        break;
            
                    default:
                        $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;    
                        break;
            
                }
            
                if ($newstate != $decoderstate->state)
                    debug($id, "was in state $decoderstate->state and went to $newstate", 7);
                $decoderstate->state = $newstate;
            
                return $newstate;
            
            }
            
            
            
            function process_data($id, $dest_addr, $source_addr, $num_frames_received, $received_bytes) {
            debug($id, "received parameters: dest_addr $dest_addr, source_addr $source_addr, num_frames_received $num_frames_received", 7);
            
                switch($dest_addr) {
                    case 0x0010: { // DFR
                        debug($id, "destination DFR detected", 7);
                        switch($source_addr) {
                            case 0x1060: {  // Vitosolic 200 Regler
                                debug($id, "source Vitosolic 200 Regler detected", 7);
                                switch($num_frames_received) {
                                    case 1: {
                                        setLogicLinkAusgang($id, 1, ($received_bytes[0] + $received_bytes[1] * 256)/10); 
                                        debug($id, "Temperatur 1: ".($received_bytes[0] + $received_bytes[1] * 256)/10 ." °C", 6);
                                        setLogicLinkAusgang($id, 2, ($received_bytes[2] + $received_bytes[3] * 256)/10);
                                        debug($id, "Temperatur 2: ".($received_bytes[2] + $received_bytes[3] * 256)/10 ." °C", 6);
                                        break;
                                    }
                                    case 2: {
                                        setLogicLinkAusgang($id, 3, ($received_bytes[0] + $received_bytes[1] * 256)/10); 
                                        debug($id, "Temperatur 3: ".($received_bytes[0] + $received_bytes[1] * 256)/10 ." °C", 6);
                                        setLogicLinkAusgang($id, 4, ($received_bytes[2] + $received_bytes[3] * 256)/10); 
                                        debug($id, "Temperatur 4: ".($received_bytes[2] + $received_bytes[3] * 256)/10 ." °C", 6);
                                        break;
                                    }
                                    case 3: {
                                        setLogicLinkAusgang($id, 5, ($received_bytes[0] + $received_bytes[1] * 256)/10); 
                                        debug($id, "Temperatur 5: ".($received_bytes[0] + $received_bytes[1] * 256)/10 ." °C", 6);
                                        setLogicLinkAusgang($id, 6, ($received_bytes[2] + $received_bytes[3] * 256)/10); 
                                        debug($id, "Temperatur 6: ".($received_bytes[2] + $received_bytes[3] * 256)/10 ." °C", 6);
                                        break;
                                    }
                                    case 4: {
                                        setLogicLinkAusgang($id, 7, ($received_bytes[0] + $received_bytes[1] * 256)/10); 
                                        debug($id, "Temperatur 7: ".($received_bytes[0] + $received_bytes[1] * 256)/10 ." °C", 6);
                                        setLogicLinkAusgang($id, 8, ($received_bytes[2] + $received_bytes[3] * 256)/10); 
                                        debug($id, "Temperatur 8: ".($received_bytes[2] + $received_bytes[3] * 256)/10 ." °C", 6);
                                        break;
                                    }
                                    case 5: {
                                        setLogicLinkAusgang($id, 9, ($received_bytes[0] + $received_bytes[1] * 256)/10); 
                                        debug($id, "Temperatur 9: ".($received_bytes[0] + $received_bytes[1] * 256)/10 ." °C", 6);
                                        setLogicLinkAusgang($id, 10, ($received_bytes[2] + $received_bytes[3] * 256)/10); 
                                        debug($id, "Temperatur 10: ".($received_bytes[2] + $received_bytes[3] * 256)/10 ." °C", 6);
                                        break;
                                    }
                                    case 6: {
                                        setLogicLinkAusgang($id, 11, ($received_bytes[0] + $received_bytes[1] * 256)/10); 
                                        debug($id, "Temperatur 11: ".($received_bytes[0] + $received_bytes[1] * 256)/10 ." °C", 6);
                                        setLogicLinkAusgang($id, 12, ($received_bytes[2] + $received_bytes[3] * 256)/10); 
                                        debug($id, "Temperatur 12: ".($received_bytes[2] + $received_bytes[3] * 256)/10 ." °C", 6);
                                        break;
                                    }
                                    case 7: {
                                        setLogicLinkAusgang($id, 13, ($received_bytes[0] + $received_bytes[1] * 256)); 
                                        debug($id, "SZ Einstrahlung: ".($received_bytes[0] + $received_bytes[1] * 256) ." W/m^2", 6);
                                        setLogicLinkAusgang($id, 14, ($received_bytes[2] + $received_bytes[3] * 256)); 
                                        debug($id, "SZ Spannung: ".($received_bytes[2] + $received_bytes[3] * 256) ." V", 6);
                                        break;
                                    }
                                    case 8: {
                                        setLogicLinkAusgang($id, 15, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Impulszähler 1: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." l/min", 6);
                                        break;
                                    }
                                    case 9: {
                                        setLogicLinkAusgang($id, 16, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Impulszähler 2: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." l/min", 6);
                                        break;
                                    }
                                    case 10: {
                                        setLogicLinkAusgang($id, 17, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Sensor Unterbrechung/Kurzschluss Maske: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) , 6);
                                        break;
                                    }
                                    case 11: {
                                        setLogicLinkAusgang($id, 18, ($received_bytes[0] + $received_bytes[1] * 256)); 
                                        debug($id, "Sensor benutzt Maske: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256), 6);
                                        debug($id, "unbekannte Bedeutung: ". $received_bytes[2] ." und ". $received_bytes[3], 6);
                                        break;
                                    }
                                    case 12: {
                                        setLogicLinkAusgang($id, 20, ($received_bytes[0]) ); 
                                        debug($id, "Drehzahl Relais 1: ". ($received_bytes[0]) ." %", 6);
                                        setLogicLinkAusgang($id, 21, ($received_bytes[1]) ); 
                                        debug($id, "Drehzahl Relais 2: ". ($received_bytes[1]) ." %", 6);
                                        setLogicLinkAusgang($id, 22, ($received_bytes[2]) ); 
                                        debug($id, "Drehzahl Relais 3: ". ($received_bytes[2]) ." %", 6);
                                        setLogicLinkAusgang($id, 23, ($received_bytes[3]) ); 
                                        debug($id, "Drehzahl Relais 4: ". ($received_bytes[3]) ." %", 6);
                                        break;
                                    }
                                    case 13: {
                                        setLogicLinkAusgang($id, 24, ($received_bytes[0]) ); 
                                        debug($id, "Drehzahl Relais 5: ". ($received_bytes[0]) ." %", 6);
                                        setLogicLinkAusgang($id, 25, ($received_bytes[1]) ); 
                                        debug($id, "Drehzahl Relais 6: ". ($received_bytes[1]) ." %", 6);
                                        setLogicLinkAusgang($id, 26, ($received_bytes[2]) ); 
                                        debug($id, "Drehzahl Relais 7: ". ($received_bytes[2]) ." %", 6);
                                        debug($id, "unbekannte Bedeutung: ". $received_bytes[3], 6);
                                        break;
                                    }
                                    case 14: {
            //                            debug($id, "unbekannte Bedeutung: ". $received_bytes[0] ." und ". $received_bytes[1] ." und ". $received_bytes[2] ." und ". $received_bytes[3], 6);
                                        break;
                                    }
                                    case 15: {
                                        setLogicLinkAusgang($id, 27, ($received_bytes[0]) ); 
                                        debug($id, "Lasterkennung Relais: ". ($received_bytes[0]), 6);
                                        setLogicLinkAusgang($id, 28, ($received_bytes[1]) ); 
                                        debug($id, "Fehler Lasterkennung Relais: ". ($received_bytes[1]), 6);
                                        setLogicLinkAusgang($id, 29, ($received_bytes[2] + $received_bytes[3] * 256) ); 
                                        debug($id, "Relaisbenutzungsmaske: ". ($received_bytes[2] + $received_bytes[3] * 256), 6);
                                        break;
                                    }
                                    case 16: {
                                        setLogicLinkAusgang($id, 30, ($received_bytes[0] + $received_bytes[1] * 256) ); 
                                        debug($id, "Fehlermaske: ". ($received_bytes[0] + $received_bytes[1] * 256), 6);
                                        setLogicLinkAusgang($id, 31, ($received_bytes[2] + $received_bytes[3] * 256) ); 
                                        debug($id, "Warnmaske: ". ($received_bytes[2] + $received_bytes[3] * 256), 6);
                                        break;
                                    }
                                    case 17: {
                                        setLogicLinkAusgang($id, 32, ($received_bytes[0]) ); 
                                        debug($id, "SW Version: ". ($received_bytes[0]), 6);
                                        setLogicLinkAusgang($id, 33, ($received_bytes[1]) ); 
                                        debug($id, "Minorversion: ". ($received_bytes[1]), 6);
                                        setLogicLinkAusgang($id, 34, ($received_bytes[2] + $received_bytes[3] * 256) ); 
                                        debug($id, "Systemzeit: ". ($received_bytes[2] + $received_bytes[3] * 256), 6);
                                        break;
                                    }
                                    case 18: {
                                        debug($id, "unbekannte Bedeutung: ". $received_bytes[0] ." und ". $received_bytes[1] ." und ". $received_bytes[2] ." und ". $received_bytes[3], 6);
                                        break;
                                    }
                                    case 19    : {
                                        setLogicLinkAusgang($id, 35, ($received_bytes[0]) ); 
                                        debug($id, "Fehler Solarzelle: ". ($received_bytes[0]), 6);
                                        debug($id, "unbekannte Bedeutung: ". $received_bytes[1] ." und ". $received_bytes[2] ." und ". $received_bytes[3], 6);
                                        break;
                                    }
                                    default: {
                                        debug($id, "Error: I'm not expecting any more frames here! got this: " . $received_bytes[0] ." und ". $received_bytes[1] ." und ". $received_bytes[2] ." und ". $received_bytes[3], 4);
                                    }
                                }
                                break;
                            }
            
                            case 0x1065: {  // Vitosolic 200 WMZ 1
                                debug($id, "source Vitosolic 200 WMZ 1 detected", 7);
                                switch($num_frames_received) {
                                    case 1: {
                                        setLogicLinkAusgang($id, 40, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] *256*256 + $received_bytes[3] * 256*256*256)/100); 
                                        debug($id, "WMZ 1:". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] *256*256 + $received_bytes[3] * 256*256*256)/100, 6);
                                        break;
                                    }
                                    case 2: {
                                        setLogicLinkAusgang($id, 41, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] *256*256 + $received_bytes[3] * 256*256*256)/100); 
                                        debug($id, "WMZ 2:". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] *256*256 + $received_bytes[3] * 256*256*256)/100, 6);
                                        break;
                                    }
                                    case 3: {
                                        setLogicLinkAusgang($id, 42, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] *256*256 + $received_bytes[3] * 256*256*256)/100); 
                                        debug($id, "WMZ 3:". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] *256*256 + $received_bytes[3] * 256*256*256)/100, 6);
                                        break;
                                    }
                                    case 4: {
                                        setLogicLinkAusgang($id, 43, $received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] *256*256 + $received_bytes[3] * 256*256*256); 
                                        debug($id, "WMZ 4:". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] *256*256 + $received_bytes[3] * 256*256*256)/100, 6);
                                        break;
                                    }
                                    default: {
                                        debug($id, "Error: I'm not expecting any more frames here!", 4);
                                    }
                                }
                                break;
                            }
                            default: {
                                debug($id, "source addr $source_addr not implemented", 4);
                            }
                        }
                        break;
                    }                
                    default: {
                        debug($id, "destination addr $dest_addr not implemented", 4);
                    }
                }
            
            
            
            }
            
            
            
            
            
            // Note: for init, use $decoderstate->crc = 0x7F;  // reset the crc
            function update_crc(& $decoderstate, $currentbyte) {
                $decoderstate->crc = (256 + $decoderstate->crc - $currentbyte) & 0x7F;
            }
            
            
            
            function myErrorHandler($errno, $errstr, $errfile, $errline) {
            //    debug($id, "File: $errfile | Error: $errno | Line: $errline | $errstr ");
            }
            
            
            
            function debug($id,$s,$l) {
                $E=logic_getInputs($id);
                $DEBUG=$E[5]['value'];
                $l<=$DEBUG && writeToCustomLog("LBSLBSID", $l, "(ID$id) : ".$s);
            }
            
            
            
            ?>
            ###[/EXEC]###


            und hier noch Code für Vitotrans

            Code:
            ###[DEF]###
            [name        = Resol VBUS vitotrans ]
            
            [e#1    IMPORTANT    = IP_Adresse     ]
            [e#2    IMPORTANT    = Port #init=8234    ]
            [e#5    OPTION      = Loglevel #init=3 ]
            
            
            [a#1        = Temperatur Sensor 1 ]
            [a#2        = Temperatur Sensor 2 ]
            [a#3        = Temperatur Sensor 3 ]
            [a#4        = Temperatur Sensor 4 ]
            [a#5        = Temperatur Sensor 5 ]
            [a#6        = Temperatur Sensor 6 ]
            [a#7        = Temperatur Sensor VFS/US ]
            [a#8        = Durchfluss VFS/US ]
            [a#9        = Drehzahl Relais 1 ]
            [a#10        = Drehzahl Relais 2 ]
            [a#11        = Drehzahl Relais 3 ]
            [a#12        = Drehzahl Relais potfrei ]
            [a#13        = Drehzahl Ausgang PWM 1 ]
            [a#14        = Drehzahl Ausgang PWM 2 ]
            [a#15        = Betriebssekunden Relais 1 ]
            [a#16        = Betriebssekunden Relais 2 ]
            [a#17        = Betriebssekunden Relais 3 ]
            [a#18        = Betriebssekunden Relais potfrei ]
            [a#19        = Betriebssekunden Ausgang PWM 1 ]
            [a#20        = Betriebssekunden Ausgang PWM 2 ]
            [a#21        = Wärmemenge ]
            [a#22        = Fehler ]
            [a#23        = Version ]
            [a#24        = Systemdatum ]
            
            
            [v#1 = 0]
            
            ###[/DEF]###
            
            
            ###[HELP]###
            Vorlage: LBS mit EXEC-Script
            
            Resol VBUS Decoder
            verbindet zu einer IP/Port um die seriellen Daten zu empfangen
            
            Changelog:
            0.1:
            -initiale Version
            
            ###[/HELP]###
            
            
            ###[LBS]###
            <?
            
            function LB_LBSID($id) {
                if ($E=logic_getInputs($id)) {
            
            
                    // EXEC-Script starten
                    if (logic_getVar($id,1) == 0) {
                        logic_setVar($id,1,1); 
                        LB_LBSID_debug($id," function LB_LBSID starting EXEC",7);
                        logic_callExec(LBSID,$id);
                    }
            
                }
            }
            
            
            function LB_LBSID_debug($id, $s, $l) {
                $E=logic_getInputs($id);
                $DEBUG=$E[5]['value'];
                $l<=$DEBUG && writeToCustomLog("LBSLBSID",$l,"(ID$id): ".$s);
            }
            
            
            ?>
            ###[/LBS]###
            
            
            ###[EXEC]###
            <?
            
            
            
            
            require(dirname(__FILE__)."/../../../../main/include/php/incl_lbsexec.php");
            
            //bei Bedarf kann hier die maximale Ausführungszeit des Scripts angepasst werden (Default: 30 Sekunden)
            //Beispiele:
            set_time_limit(0);    //Script soll unendlich laufen (kein Timeout)
            //set_time_limit(60);    //Script soll maximal 60 Sekunden laufen
            
            sql_connect();
            
            
            // turn off the errors
            $error_handler = set_error_handler("myErrorHandler");
            error_reporting(0);
            
            
            
            
            if ($E=getLogicEingangDataAll($id)) {
                debug($id,"Baustein startet ",7);
            
                $connection = new stdClass;
            
            
                if(!empty($E[1]['value'])){
                    $ipadresse=$E[1]['value'];
                } else {
                    debug($id, "Keine IP Adresse angegeben, Abbruch",2);
                    finish();
                    exit();
                }
            
                if(!empty($E[2]['value'])){
                    $port=$E[2]['value'];
                } else {
                    debug($id, "Keinen Port angegeben, Abbruch",2);
                    finish();
                    exit();
                }   
            
                  while (true) { 
            
                    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
                    $connection->target = $socket; 
            
                    if ($socket === false) {
                        debug($id, "socket_create() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error()) . ", Abbruch",4);
                        if (is_object($socket)) 
                            socket_shutdown($connection->target, 2);
                        break;
                    } else {
                        debug($id,"socket_create() OK.",7);
                       }
            
                    debug($id, "Versuche mit IP '".$ipadresse."' auf Port '".$port."' zu verbinden ...",6);
                    $result = socket_connect($socket, $ipadresse, $port);
                    if ($result === false) {
                        debug($id,"socket_connect() fehlgeschlagen. Grund: ($result) " . socket_strerror(socket_last_error($socket)) . ", Abbruch",4);
                        if (is_object($socket)) 
                            socket_shutdown($connection->target, 2);
                        break;
                    } else {
                        debug($id,"socket_connect() OK",7);
                    }
            
            
            
                    read_from_bus($id, $connection);
            
                    // connection has problems, maybe try again with some waiting?
                    usleep(10*1000*1000);
            
                    if (is_object($connection->target)) {
                         debug($id,"closing sockets", 5);
                           socket_shutdown($connection->target, 2);
                    }
                }
            
            
                debug($id,"EXEC des Bausteins wird beendet", 4);
                finish();
            
                exit();
            
            }
            
            
            
            
            function finish() {
                logic_setVar($id,1,0); 
            
                // turn errors back on
                restore_error_handler();
                error_reporting(E_ALL);
            
                sql_disconnect();
            
            }
            
            
            
            function read_from_bus($id, $connection) {
            
                $e_nonblocking = 11; // Error code for  EAGAIN or EWOULDBLOCK
            
                if (!is_object($connection)) {
                    debug($id, "Fehler in read_from_bus() Parameter, Abbruch", 3);
                    finish();
                }
            
            
                $decoderstate = new StdClass();
                $decoderstate->state = STATE_WAIT_FOR_SYNC_BYTE_AA;
                $decoderstate->destaddr = "";
                $decoderstate->sourceaddr = "";
            
            
                while (true) {
                    $sin = "";
                    $reciv = "";
                    $bytes = socket_recv($connection->target, $sin, 45, MSG_DONTWAIT);
                    if (false === $bytes) {  
                        // no data, just wait and try again
                        usleep(100*1000);
            
                    }
                    else if (0 === $bytes) {  
                        // some error has happened
                        if (socket_last_error() == $e_nonblocking) {
                            // non blocking socket has not returned anything, try again later
                            usleep(100*1000);
                            continue;
                        }
                        else {
                               debug($id, "socket_recv() failed; reason: ".socket_last_error()." " . socket_strerror(socket_last_error($connection->target)), 3);
                            debug($id, "connection seems broken/closed/aborted", 4);
                            usleep(1000*1000);
                            return 0;
            
                        }
                    }
                    else {
                           $reciv = strtoupper(array_shift(unpack("H*", $sin)));
                        debug($id, "read $bytes bytes from bus, data: " . $reciv, 7);
            
                        $inbytearray = unpack("C*", $sin);
            
                        while (count($inbytearray) > 0) {
                            // process each byte seperately
                            $currentbyte = array_shift($inbytearray);
                            state_machine_parse_data($id, $currentbyte, $decoderstate);
                        }
                        usleep(10*1000);
                    }
            
                }
                return 0;
            
            }
            
            
            define("STATE_WAIT_FOR_SYNC_BYTE_AA", 1);
            define("STATE_DEST_BYTE_L", 2);
            define("STATE_DEST_BYTE_H", 3);
            define("STATE_SOURCE_BYTE_L", 4);
            define("STATE_SOURCE_BYTE_H", 5);
            define("STATE_PROTOCOL", 6);
            define("STATE_COMMAND_BYTE_L", 7);
            define("STATE_COMMAND_BYTE_H", 8);
            define("STATE_NUM_FRAMES", 9);
            define("STATE_HEADER_CHECKSUM", 10);
            define("STATE_RECEIVE_DATA_FRAMES", 11);
            define("STATE_DATA_CHECKSUM", 12);
            //define("STATE_PROTOCOL", 13);
            //define("STATE_PROTOCOL", 14);
            
            
            function state_machine_parse_data($id, $currentbyte, & $decoderstate) {
            
                $newstate = $decoderstate->state;  // in case nothing changes
            
                switch($decoderstate->state) {
                    case STATE_WAIT_FOR_SYNC_BYTE_AA:
                        if ($currentbyte == 0xAA) {
                            $newstate = STATE_DEST_BYTE_L;    
                            $decoderstate->crc = 0x7F;  // reset crc
                        }
                        break;
            
                    case STATE_DEST_BYTE_L: 
                        $decoderstate->destaddr = $currentbyte;
                        update_crc($decoderstate, $currentbyte);
                        $newstate = STATE_DEST_BYTE_H;    
                        break;
            
                    case STATE_DEST_BYTE_H: 
                        $decoderstate->destaddr += $currentbyte<<8;
                        update_crc($decoderstate, $currentbyte);
                        $newstate = STATE_SOURCE_BYTE_L;    
                        break;
            
                    case STATE_SOURCE_BYTE_L:
                        $decoderstate->sourceaddr = $currentbyte;
                        update_crc($decoderstate, $currentbyte);
                        $newstate = STATE_SOURCE_BYTE_H;    
                        break;
            
                    case STATE_SOURCE_BYTE_H:
                        $decoderstate->sourceaddr += $currentbyte<<8;
                        update_crc($decoderstate, $currentbyte);
                        $newstate = STATE_PROTOCOL;
                        break;
            
                    case STATE_PROTOCOL:
                        if ($currentbyte == 0x10) { // Protocol version 1.0
                            $newstate = STATE_COMMAND_BYTE_L;
                            update_crc($decoderstate, $currentbyte);
                        }
                        else { // protocol version not supported, wait for next sync
                            $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;    
                        }
                        break;
            
                    case STATE_COMMAND_BYTE_L:
                        $decoderstate->command = $currentbyte;
                        update_crc($decoderstate, $currentbyte);
                        $newstate = STATE_COMMAND_BYTE_H;
                        break;
            
                    case STATE_COMMAND_BYTE_H:
                        $decoderstate->command += $currentbyte<<8;
                        if ($decoderstate->command = 0x0100) { // "Paket enthält Daten für Slave"
                            $newstate = STATE_NUM_FRAMES;
                            update_crc($decoderstate, $currentbyte);
                        }
                        else {  // command not supported, wait for next sync
                            $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                        }
                        break;
            
                    case STATE_NUM_FRAMES:
                        $decoderstate->num_frames_expected = $currentbyte;
                        update_crc($decoderstate, $currentbyte);
                        debug($id, "expecting ". $decoderstate->num_frames_expected ." frames destination 0x". dechex($decoderstate->destaddr) ." and source 0x". dechex($decoderstate->sourceaddr), 6);
                        $newstate = STATE_HEADER_CHECKSUM;
                        break;
            
                    case STATE_HEADER_CHECKSUM:
                        if ($decoderstate->crc == $currentbyte) { // crc ok
                            $newstate = STATE_RECEIVE_DATA_FRAMES;
                            $decoderstate->crc = 0x7F; // reset crc
                            $decoderstate->num_frames_received = 0;
                            $decoderstate->received_bytes = array();
                        }
                        else {
                            debug($id, "crc error, received 0x". dechex($currentbyte) ." but expected 0x". dechex($decoderstate->crc) .", skipping frame", 4);
                            $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                        }
                        break;
            
                    case STATE_RECEIVE_DATA_FRAMES;
                        if ($currentbyte == 0xAA) { // this should not happen!
                            $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                            debug($id, "unexpected AA in datastream - skipping ", 4);
                        }
                        else {
                            update_crc($decoderstate, $currentbyte);
            
                            if (count($decoderstate->received_bytes) >= 4) { // process septett
                                if ($currentbyte & 0x01)   $decoderstate->received_bytes[0] += 128;
                                if ($currentbyte & 0x02)   $decoderstate->received_bytes[1] += 128;
                                if ($currentbyte & 0x04)   $decoderstate->received_bytes[2] += 128;
                                if ($currentbyte & 0x08)   $decoderstate->received_bytes[3] += 128;
                                $decoderstate->num_frames_received += 1;
                                $newstate = STATE_DATA_CHECKSUM;
                            }
                            else {
                                array_push($decoderstate->received_bytes, $currentbyte);
                            }
            
                        }
                        break;
            
                    case STATE_DATA_CHECKSUM:
                        debug($id, count($decoderstate->received_bytes) ." bytes collected ", 8);
                        if ($decoderstate->crc == $currentbyte) { // crc ok
                            debug($id, "crc ok, received ". count($decoderstate->received_bytes) ." bytes", 8);
            
                            // do something with the data
                            process_data($id, $decoderstate->destaddr, $decoderstate->sourceaddr, $decoderstate->num_frames_received, $decoderstate->received_bytes);
            
                            if ($decoderstate->num_frames_received < $decoderstate->num_frames_expected) { 
                                // prepare for receiving next frame
                                $newstate = STATE_RECEIVE_DATA_FRAMES;
                                $decoderstate->crc = 0x7F; // reset crc
                                $decoderstate->received_bytes = array();
                            }
                            else {
                                $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                            }
                        }
                        else {
                            debug($id, "crc error, received 0x". dechex($currentbyte) ." but expected 0x". dechex($decoderstate->crc) .", skipping frame", 4);
                            $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                        }
                        break;
            
                    default:
                        $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;    
                        break;
            
                }
            
                if ($newstate != $decoderstate->state)
                    debug($id, "was in state $decoderstate->state and went to $newstate", 7);
                $decoderstate->state = $newstate;
            
                return $newstate;
            
            }
            
            
            
            function process_data($id, $dest_addr, $source_addr, $num_frames_received, $received_bytes) {
            debug($id, "received parameters: dest_addr $dest_addr, source_addr $source_addr, num_frames_received $num_frames_received", 7);
            
                switch($dest_addr) {
                    case 0x0010: { // DFR
                        debug($id, "destination DFR detected", 7);
                        switch($source_addr) {
                            case 0x5251: {  // Vitotrans Regler
                                debug($id, "source Vitotrans Regler detected", 7);
                                switch($num_frames_received) {
                                    case 1: {   // 0 1 2 3
                                        setLogicLinkAusgang($id, 1, ($received_bytes[0] + $received_bytes[1] * 256)/10); 
                                        debug($id, "Temperatur 1: ".($received_bytes[0] + $received_bytes[1] * 256)/10 ." °C", 6);
                                        setLogicLinkAusgang($id, 2, ($received_bytes[2] + $received_bytes[3] * 256)/10);
                                        debug($id, "Temperatur 2: ".($received_bytes[2] + $received_bytes[3] * 256)/10 ." °C", 6);
                                        break;
                                    }
                                    case 2: {   // 4 5 6 7
                                        setLogicLinkAusgang($id, 3, ($received_bytes[0] + $received_bytes[1] * 256)/10); 
                                        debug($id, "Temperatur 3: ".($received_bytes[0] + $received_bytes[1] * 256)/10 ." °C", 6);
                                        setLogicLinkAusgang($id, 4, ($received_bytes[2] + $received_bytes[3] * 256)/10); 
                                        debug($id, "Temperatur 4: ".($received_bytes[2] + $received_bytes[3] * 256)/10 ." °C", 6);
                                        break;
                                    }
                                    case 3: {   // 8 9 10 11
                                        setLogicLinkAusgang($id, 5, ($received_bytes[0] + $received_bytes[1] * 256)/10); 
                                        debug($id, "Temperatur 5: ".($received_bytes[0] + $received_bytes[1] * 256)/10 ." °C", 6);
                                        setLogicLinkAusgang($id, 6, ($received_bytes[2] + $received_bytes[3] * 256)/10); 
                                        debug($id, "Temperatur 6: ".($received_bytes[2] + $received_bytes[3] * 256)/10 ." °C", 6);
                                        break;
                                    }
                                    case 4: {    // 12 13 14 15
                                        break;
                                    }
                                    case 5: {    // 16 17 18 19
                                        break;
                                    }
                                    case 6: {    // 20 21 22 23
                                        setLogicLinkAusgang($id, 7, ($received_bytes[2] + $received_bytes[3] * 256)/10); 
                                        debug($id, "Temperatur VFS/US: ".($received_bytes[2] + $received_bytes[3] * 256)/10 ." °C", 6);
                                        break;
                                    }
                                    case 7: {    // 24 25 26 27
                                        break;
                                    }
                                    case 8: {    // 28 29 30 31
                                        break;
                                    }
                                    case 9: {     // 32 33 34 35
                                        break;
                                    }
                                    case 10: {    // 36 37 38 39
                                        setLogicLinkAusgang($id, 8, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Durchfluss Sensor VFS/US: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." l/min", 6);
                                        break;
                                    }
                                    case 11: {     // 40 41 42 43
                                        break;
                                    }
                                    case 12: {     // 44 45 46 47
                                        break;
                                    }
                                    case 13: {     // 48 49 50 51   
                                        setLogicLinkAusgang($id, 9, ($received_bytes[1]) ); 
                                        debug($id, "Drehzahl Relais 1: ". ($received_bytes[1]) ." %", 6);
                                        setLogicLinkAusgang($id, 10, ($received_bytes[2]) ); 
                                        debug($id, "Drehzahl Relais 2: ". ($received_bytes[2]) ." %", 6);
                                        setLogicLinkAusgang($id, 11, ($received_bytes[3]) ); 
                                        debug($id, "Drehzahl Relais 3: ". ($received_bytes[3]) ." %", 6);
                                        break;
                                    }
                                    case 14: {     // 52 53 54 55
                                        setLogicLinkAusgang($id, 12, ($received_bytes[0]) ); 
                                        debug($id, "Drehzahl Relais potfrei: ". ($received_bytes[0]) ." %", 6);
                                        break;
                                    }
                                    case 15: {     // 56 57 58 59
                                        setLogicLinkAusgang($id, 13, ($received_bytes[0]) ); 
                                        debug($id, "Drehzahl Ausgang PWM 1: ". ($received_bytes[0]) ." %", 6);
                                        setLogicLinkAusgang($id, 14, ($received_bytes[1]) ); 
                                        debug($id, "Drehzahl Ausgang PWM 2: ". ($received_bytes[1]) ." %", 6);
                                        break;
                                    }
                                    case 16: {     // 60 61 62 63
                                        break;
                                    }
                                    case 17: {     // 64 65 66 67
                                        setLogicLinkAusgang($id, 15, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Betriebssekunden Relais 1: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." sek", 6);
                                        break;
                                    }
                                    case 18: {     // 68 69 70 71
                                        setLogicLinkAusgang($id, 16, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Betriebssekunden Relais 2: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." sek", 6);
                                        break;
                                    }
                                    case 19: {     // 72 73 74 75
                                        setLogicLinkAusgang($id, 17, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Betriebssekunden Relais 3: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." sek", 6);
                                        break;
                                    }
                                    case 20: {     // 76 77 78 79
                                        setLogicLinkAusgang($id, 18, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Betriebssekunden Relais potfrei: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." sek", 6);
                                        break;
                                    }
                                    case 21: {     // 80 81 82 83
                                        setLogicLinkAusgang($id, 19, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Betriebssekunden Ausgang PWM 1: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." sek", 6);
                                        break;
                                    }
                                    case 22: {     // 84 85 86 87
                                        setLogicLinkAusgang($id, 20, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Betriebssekunden Ausgang PWM 2: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." sek", 6);
                                        break;
                                    }
                                    case 23: {     // 88 89 90 91
                                        break;
                                    }
                                    case 24: {     // 92 93 94 95
                                        break;
                                    }
                                    case 25: {     // 96 97 98 99
                                        setLogicLinkAusgang($id, 21, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Wärmemenge: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." Wh", 6);
                                        break;
                                    }
                                    case 26: {     // 100 101 102 103
                                        setLogicLinkAusgang($id, 22, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Fehler: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256), 6);
                                        break;
                                    }
                                    case 27: {     // 104 105 106 107
                                        break;
                                    }
                                    case 28: {     // 108 109 110 111
                                        setLogicLinkAusgang($id, 23, ($received_bytes[0] + $received_bytes[1] * 256) ); 
                                        debug($id, "Version: ". ($received_bytes[0] + $received_bytes[1] * 256), 6);
                                        break;
                                    }
                                    case 29: {     // 112 113 114 115
                                        setLogicLinkAusgang($id, 24, ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256)); 
                                        debug($id, "Systemdatum: ". ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 256*256 + $received_bytes[3] * 256 * 256 * 256) ." sek", 6);
                                        break;
                                    }
                                    default: {
                                        debug($id, "Error: I'm not expecting any more frames here! got this: " . $received_bytes[0] ." und ". $received_bytes[1] ." und ". $received_bytes[2] ." und ". $received_bytes[3], 4);
                                    }
                                }
                                break;
                            }
            
                            default: {
                                debug($id, "source addr $source_addr not implemented", 4);
                            }
                        }
                        break;
                    }                
                    default: {
                        debug($id, "destination addr $dest_addr not implemented", 4);
                    }
                }
            
            
            
            }
            
            
            
            
            
            // Note: for init, use $decoderstate->crc = 0x7F;  // reset the crc
            function update_crc(& $decoderstate, $currentbyte) {
                $decoderstate->crc = (256 + $decoderstate->crc - $currentbyte) & 0x7F;
            }
            
            
            
            function myErrorHandler($errno, $errstr, $errfile, $errline) {
            //    debug($id, "File: $errfile | Error: $errno | Line: $errline | $errstr ");
            }
            
            
            
            function debug($id,$s,$l) {
                $E=logic_getInputs($id);
                $DEBUG=$E[5]['value'];
                $l<=$DEBUG && writeToCustomLog("LBSLBSID", $l, "(ID$id) : ".$s);
            }
            
            
            
            ?>
            ###[/EXEC]###

            Kommentar


              #7
              Hallo schobi,

              danke für deinen sehr guten LBS! Ich habe einen DeltaSol SLL Regler mit der VBus/LAN-Schnittstelle und mein Regler hat völlig andere Parameter als der von Dir, aber mit der Doku hier und deinem LBS habe ich diesen schnell in EDOMI einbinden können.

              Die VBus/LAN-Schnittstelle nutzt ein Passwort um die Datenübertragung zu initialisieren, dass habe ich bei mir noch ergänzt (vielleicht auch was für deinen).

              Wenn Du nichts dagegen hast, würde ich meinen LBS gerne ins Download-Portal stellen.

              Ansonsten ist hier der LBS:
              PHP-Code:
              ###[DEF]###
              [name        = Resol DeltaSol SLL (VBus)]

              [e#1    important    = IP-Adresse          ]
              [e#2    important    = Port     #init=7053 ]
              [e#3    important    = Passwort #init=vbus ]
              [e#5    option       = Loglevel #init=3    ]

              [a#1        = Systemdatum         ]
              [a#2        = &thetasym; Sensor 1 ]
              [a#3        = &thetasym; Sensor 2 ]
              [a#4        = &thetasym; Sensor 3 ]
              [a#5        = &thetasym; Sensor 4 ]
              [a#6        = TAGE                ]
              [a#7        = Volumenstrom V40    ]
              [a#8        = Drehzahl Relais 1   ]
              [a#9        = Drehzahl Relais 2   ]
              [a#10        = Drehzahl Relais 3  ]
              [a#11        = Wärmemenge         ]
              [a#12        = SW-Version         ]
              [a#13        = Betriebsstunden Relais 1 ]
              [a#14        = Betriebsstunden Relais 2 ]
              [a#15        = Betriebsstunden Relais 3 ]
              [a#16        = Urlaubsfunktion    ]
              [a#17        = Blockierschutz 1   ]
              [a#18        = Blockierschutz 2   ]
              [a#19        = Blockierschutz 3   ]
              [a#20        = Initialisieren     ]
              [a#21        = Befüllung          ]
              [a#22        = Stabilisieren      ]
              [a#23        = Pumpenverzögerung  ]
              [a#24        = Überwärmeabfuhr    ]
              [a#25        = Nachlauf           ]
              [a#26        = Thermische Desinfektion ]
              [a#27        = Speicherkühlung    ]
              [a#28        = Systemkühlung      ]
              [a#29        = Spreizung          ]
              [a#30        = Frostschutz        ]
              [a#31        = Kollektorkühlung   ]
              [a#32        = Speichermaximaltemp. ]
              [a#33        = Neustarts          ]
              [a#34        = Sensorfehler       ]
              [a#35        = Fehlermaske        ]

              [v#1 = 0] // Exec gestartet
              [v#2 = 0] // Zeitpunkt der letzten Daten
              [v#3 = 0] // Send by Change Array
              ###[/DEF]###


              ###[HELP]###
              Resol VBus-Decoder für Resol DeltaSol SLL und baugleiche Regler (z. B. Stiebel Eltron SOM 7 E plus)

              Dieser LBS basiert nahezu vollständig auf dem <a href='https://knx-user-forum.de/forum/projektforen/edomi/1125369-lbs-resol-vbus-viessmann-vitosol-200#post1125369' target='_blank'>Resol VBus LBS</a> von Michael Schöberl (schobi) mit angepassten Ausgängen 
              und Dekodierung.

              Nur getestet mit der Resol VBus/LAN-Schnittstelle.

              Die Bennenung der Ausgänge entspricht dem Resol Service Center Tool

              Changelog:
              0.1:
              -initiale Version

              0.2:
              - Send by Change integriert

              ###[/HELP]###


              ###[LBS]###
              <?
              function LB_LBSID($id) {
                  if ($E=logic_getInputs($id)) {

                      $V = explode('|', logic_getVar($id,3));
                      // Initalisierung der Variablen, wenn nicht vorhanden
                      for ($i=1;$i<=35;$i++) {
                          if (!isset($V[$i])) $V[$i] = -999;
                      }
                      logic_setVar($id,3,implode('|',$V));

                      // EXEC-Script starten
                      if (logic_getVar($id,1) == 0) {
                          logic_setVar($id,1,1); 
                          LB_LBSID_debug($id," function LB_LBSID starting EXEC",7);
                          logic_callExec(LBSID,$id);
                      }

                  }
              }


              function LB_LBSID_debug($id, $s, $l) {
                  $E=logic_getInputs($id);
                  $DEBUG=$E[5]['value'];
                  $l<=$DEBUG && writeToCustomLog("DeltaSol SLL (LBSLBSID)",$l,"(ID$id): ".$s);
              }
              ?>
              ###[/LBS]###


              ###[EXEC]###
              <?
              require(dirname(__FILE__)."/../../../../main/include/php/incl_lbsexec.php");
              //bei Bedarf kann hier die maximale Ausführungszeit des Scripts angepasst werden (Default: 30 Sekunden)
              //Beispiele:
              set_time_limit(0);    //Script soll unendlich laufen (kein Timeout)
              //set_time_limit(60);    //Script soll maximal 60 Sekunden laufen

              sql_connect();

              // turn off the errors
              $error_handler = set_error_handler("myErrorHandler");
              error_reporting(0);

              // Globale Konstanten
              define("STATE_WAIT_FOR_SYNC_BYTE_AA", 1);
              define("STATE_DEST_BYTE_L", 2);
              define("STATE_DEST_BYTE_H", 3);
              define("STATE_SOURCE_BYTE_L", 4);
              define("STATE_SOURCE_BYTE_H", 5);
              define("STATE_PROTOCOL", 6);
              define("STATE_COMMAND_BYTE_L", 7);
              define("STATE_COMMAND_BYTE_H", 8);
              define("STATE_NUM_FRAMES", 9);
              define("STATE_HEADER_CHECKSUM", 10);
              define("STATE_RECEIVE_DATA_FRAMES", 11);
              define("STATE_DATA_CHECKSUM", 12);
              //define("STATE_PROTOCOL", 13);
              //define("STATE_PROTOCOL", 14);

              if ($E=logic_getInputs($id)) {
                  debug($id,"Baustein startet ",7);

                  $connection = new stdClass;

                  if(!empty($E[1]['value'])){
                      $ipadresse=$E[1]['value'];
                  } else {
                      debug($id, "Keine IP Adresse angegeben, Abbruch",2);
                      finish();
                      exit();
                  }

                  if(!empty($E[2]['value'])){
                      $port=$E[2]['value'];
                  } else {
                      debug($id, "Keinen Port angegeben, Abbruch",2);
                      finish();
                      exit();
                  }   

                  if(!empty($E[3]['value'])){
                      $pass=$E[3]['value'];
                  } else {
                      debug($id, "Kein Passwort angegeben setze auf vbus",2);
                      $pass = 'vbus';
                  } 

                  while (getSysInfo(1)>=1) {    //Hauptschleife (wird beim Beenden oder Neustart von EDOMI verlassen)
                      //Wichtig: getSysInfo(1) sorgt zudem dafür, dass die Datenbank-Verbindung aufrechterhalten wird!

                      $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
                      $connection->target = $socket; 

                      if ($socket === false) {
                          debug($id, "socket_create() fehlgeschlagen: Grund: " . socket_strerror(socket_last_error()) . ", Abbruch",4);
                          if (is_object($socket)) 
                              socket_shutdown($connection->target, 2);
                          break;
                      } else {
                          debug($id,"socket_create() OK.",7);
                         }

                      debug($id, "Versuche mit IP '".$ipadresse."' auf Port '".$port."' zu verbinden ...",6);
                      $result = socket_connect($socket, $ipadresse, $port);
                      if ($result === false) {
                          debug($id,"socket_connect() fehlgeschlagen. Grund: ($result) " . socket_strerror(socket_last_error($socket)) . ", Abbruch",4);
                          if (is_object($socket)) 
                              socket_shutdown($connection->target, 2);
                          break;
                      } else {
                          debug($id,"socket_connect() OK",4);
                      }

                      read_from_bus($id, $connection, $pass);

                      // connection has problems, maybe try again with some waiting?
                      usleep(10*1000*1000);

                      if (is_object($connection->target)) {
                           debug($id,"closing sockets", 5);
                             socket_shutdown($connection->target, 2);
                      }
                  }


                  debug($id,"EXEC des Bausteins wird beendet", 4);
                  finish();

                  exit();

              }


              function finish() {
                  logic_setVar($id,1,0); 
                  logic_setState($id,1,300,true);
                  // turn errors back on
                  restore_error_handler();
                  error_reporting(E_ALL);
                  sql_disconnect();

              }


              function read_from_bus($id, $connection, $pass) {
                  $e_nonblocking = 11; // Error code for  EAGAIN or EWOULDBLOCK

                  if (!is_object($connection)) {
                      debug($id, "Fehler in read_from_bus() Parameter, Abbruch", 3);
                      finish();
                  }

                  $decoderstate = new StdClass();
                  $decoderstate->state = STATE_WAIT_FOR_SYNC_BYTE_AA;
                  $decoderstate->destaddr = "";
                  $decoderstate->sourceaddr = "";

                  while (getSysInfo(1)>=1) {
                      $sin = "";
                      $reciv = "";

                      if (false === ($bytes = socket_recv($connection->target, $sin, 45, MSG_DONTWAIT))) {
                          // no data, just wait and try again
                          usleep(100*1000);

                      } elseif (0 === $bytes) {  
                          // some error has happened
                          if (socket_last_error() == $e_nonblocking) {
                              // non blocking socket has not returned anything, try again later
                              usleep(100*1000);
                              continue;
                          }
                          else {
                              debug($id, "socket_recv() failed; reason: ".socket_last_error()." " . socket_strerror(socket_last_error($connection->target)), 3);
                              debug($id, "connection seems broken/closed/aborted", 4);
                              usleep(1000*1000);
                              return 0;

                          }
                      } else {
                          $reciv = strtoupper((array_shift((unpack('H*', $sin)))));
                          debug($id, "read $bytes bytes from bus, data: " . $reciv, 7);

                          // Netzwerkverbindung initialisieren
                          if ($reciv == '2B48454C4C4F0A') { // +HELLO[LF]
                              $data = 'PASS '.$pass."\n";
                              socket_write($connection->target, $data, strlen($data));
                              debug($id, "password send: " . $data, 7);
                          } elseif ($reciv == '2B4F4B3A2050617373776F72642061636365707465640A') { // +OK: Password accepted[LF]
                              $data = "DATA\n";
                              socket_write($connection->target, $data, strlen($data));
                              debug($id, "password OK, request data: " . $data, 7);
                          } elseif ($reciv == '2B4F4B3A204461746120696E636F6D696E672E2E2E0A') { // +OK: Data incoming...[LF]
                              debug($id, "OK, data incoming...", 4);        
                          } elseif ($reciv == '2D4552524F523A2050617373776F72642072656A65637465640A') { // -ERROR: Password rejected[LF]
                              debug($id, "password error", 4);
                          } else {
                              $inbytearray = unpack("C*", $sin);

                              while (count($inbytearray) > 0) {
                                  // process each byte seperately
                                  $currentbyte = array_shift($inbytearray);
                                  state_machine_parse_data($id, $currentbyte, $decoderstate);
                              }
                              usleep(10*1000);

                          }
                      }
                  }
                  return 0;

              }


              function state_machine_parse_data($id, $currentbyte, & $decoderstate) {
                  $newstate = $decoderstate->state;  // in case nothing changes

                  switch($decoderstate->state) {
                      case STATE_WAIT_FOR_SYNC_BYTE_AA:
                          if ($currentbyte == 0xAA) {
                              $newstate = STATE_DEST_BYTE_L;    
                              $decoderstate->crc = 0x7F;  // reset crc
                                  debug($id, "statemachine - Syncbyte:" . $newstate, 7);
                          }
                          break;

                      case STATE_DEST_BYTE_L: 
                          $decoderstate->destaddr = $currentbyte;
                          update_crc($decoderstate, $currentbyte);
                          $newstate = STATE_DEST_BYTE_H;    
                          break;

                      case STATE_DEST_BYTE_H: 
                          $decoderstate->destaddr += $currentbyte<<8;
                          update_crc($decoderstate, $currentbyte);
                          $newstate = STATE_SOURCE_BYTE_L;    
                          break;

                      case STATE_SOURCE_BYTE_L:
                          $decoderstate->sourceaddr = $currentbyte;
                          update_crc($decoderstate, $currentbyte);
                          $newstate = STATE_SOURCE_BYTE_H;    
                          break;

                      case STATE_SOURCE_BYTE_H:
                          $decoderstate->sourceaddr += $currentbyte<<8;
                          update_crc($decoderstate, $currentbyte);
                          $newstate = STATE_PROTOCOL;
                          break;

                      case STATE_PROTOCOL:
                          if ($currentbyte == 0x10) { // Protocol version 1.0
                              $newstate = STATE_COMMAND_BYTE_L;
                              update_crc($decoderstate, $currentbyte);
                          }
                          else { // protocol version not supported, wait for next sync
                              $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;    
                          }
                          break;

                      case STATE_COMMAND_BYTE_L:
                          $decoderstate->command = $currentbyte;
                          update_crc($decoderstate, $currentbyte);
                          $newstate = STATE_COMMAND_BYTE_H;
                          break;

                      case STATE_COMMAND_BYTE_H:
                          $decoderstate->command += $currentbyte<<8;
                          if ($decoderstate->command = 0x0100) { // "Paket enthält Daten für Slave"
                              $newstate = STATE_NUM_FRAMES;
                              update_crc($decoderstate, $currentbyte);
                          }
                          else {  // command not supported, wait for next sync
                              $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                          }
                          break;

                      case STATE_NUM_FRAMES:
                          $decoderstate->num_frames_expected = $currentbyte;
                          update_crc($decoderstate, $currentbyte);
                          debug($id, "expecting ". $decoderstate->num_frames_expected ." frames destination 0x". dechex($decoderstate->destaddr) ." and source 0x". dechex($decoderstate->sourceaddr), 6);
                          $newstate = STATE_HEADER_CHECKSUM;
                          break;

                      case STATE_HEADER_CHECKSUM:
                          if ($decoderstate->crc == $currentbyte) { // crc ok
                              $newstate = STATE_RECEIVE_DATA_FRAMES;
                              $decoderstate->crc = 0x7F; // reset crc
                              $decoderstate->num_frames_received = 0;
                              $decoderstate->received_bytes = array();
                          }
                          else {
                              debug($id, "crc error, received 0x". dechex($currentbyte) ." but expected 0x". dechex($decoderstate->crc) .", skipping frame", 4);
                              $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                          }
                          break;

                      case STATE_RECEIVE_DATA_FRAMES;
                          if ($currentbyte == 0xAA) { // this should not happen!
                              $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                              debug($id, "unexpected AA in datastream - skipping ", 4);
                          }
                          else {
                              update_crc($decoderstate, $currentbyte);

                              if (count($decoderstate->received_bytes) >= 4) { // process septett
                                  if ($currentbyte & 0x01)   $decoderstate->received_bytes[0] += 128;
                                  if ($currentbyte & 0x02)   $decoderstate->received_bytes[1] += 128;
                                  if ($currentbyte & 0x04)   $decoderstate->received_bytes[2] += 128;
                                  if ($currentbyte & 0x08)   $decoderstate->received_bytes[3] += 128;
                                  $decoderstate->num_frames_received += 1;
                                  $newstate = STATE_DATA_CHECKSUM;
                              }
                              else {
                                  array_push($decoderstate->received_bytes, $currentbyte);
                              }

                          }
                          break;

                      case STATE_DATA_CHECKSUM:
                          debug($id, count($decoderstate->received_bytes) ." bytes collected ", 8);
                          if ($decoderstate->crc == $currentbyte) { // crc ok
                              debug($id, "crc ok, received ". count($decoderstate->received_bytes) ." bytes", 8);

                              // do something with the data
                              process_data($id, $decoderstate->destaddr, $decoderstate->sourceaddr, $decoderstate->num_frames_received, $decoderstate->received_bytes);

                              if ($decoderstate->num_frames_received < $decoderstate->num_frames_expected) { 
                                  // prepare for receiving next frame
                                  $newstate = STATE_RECEIVE_DATA_FRAMES;
                                  $decoderstate->crc = 0x7F; // reset crc
                                  $decoderstate->received_bytes = array();
                              }
                              else {
                                  $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                              }
                          }
                          else {
                              debug($id, "crc error, received 0x". dechex($currentbyte) ." but expected 0x". dechex($decoderstate->crc) .", skipping frame", 4);
                              $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;
                          }
                          break;

                      default:
                          $newstate = STATE_WAIT_FOR_SYNC_BYTE_AA;    
                          break;

                  }

                  if ($newstate != $decoderstate->state)
                      debug($id, "was in state $decoderstate->state and went to $newstate", 7);
                  $decoderstate->state = $newstate;

                  return $newstate;

              }


              function process_data($id, $dest_addr, $source_addr, $num_frames_received, $received_bytes) {
                  debug($id, "received parameters: dest_addr $dest_addr, source_addr $source_addr, num_frames_received $num_frames_received", 7);

                  switch($dest_addr) {
                      case 0x0010: { // DFR
                          debug($id, "destination DFR detected", 7);
                          switch($source_addr) {                
                              case 0x2271: {  // Resol DeltaSol SLL und Stiebel Eltron SOM 7 E plus Regler
                                  debug($id, "source Resol DeltaSol SLL Regler detected", 7);
                                  logic_setVar($id,2,microtime(true));
                                  $V = explode('|', logic_getVar($id,3));                   
                                  switch($num_frames_received) {
                                      case 1: {
                                          date_default_timezone_set('UTC'); // Notwendig da schon die korrekte Zeit inkl. Zeitzone übertreagen wird
                                          $date = date("d.m.Y H:i", ($received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 65536 + $received_bytes[3] * 16777216 + 978307200));
                                          if ($date != $V[1]) logic_setOutput($id, 1, $date);
                                          debug($id, "Systemdatum ($V[1]): ".$date, 6);
                                          $V[1] = $date;
                                          break;
                                      }
                                      case 2: {
                                          $temp1 = ($received_bytes[0] + $received_bytes[1] * 256)/10;
                                          debug($id, "Temperatur 1 ($V[2]): ".$temp1." °C", 6);
                                          if (abs($temp1-$V[2]) >= 0.5) {
                                              logic_setOutput($id, 2, $temp1);
                                              $V[2] = $temp1;
                                          }    

                                          $temp2 = ($received_bytes[2] + $received_bytes[3] * 256)/10;
                                          debug($id, "Temperatur 2 ($V[3]): ".$temp2." °C", 6);
                                          if (abs($temp2-$V[3]) >= 0.5) {
                                              logic_setOutput($id, 3, $temp2);
                                              $V[3] = $temp2; 
                                          }
                                          break;
                                      }
                                      case 3: {
                                          $temp3 = ($received_bytes[0] + $received_bytes[1] * 256)/10;
                                          debug($id, "Temperatur 3 ($V[4]): ".$temp3." °C", 6);
                                          if (abs($temp3-$V[4]) >= 0.5) {
                                              logic_setOutput($id, 4, $temp3);
                                              $V[4] = $temp3;
                                          }

                                          $temp4 = ($received_bytes[2] + $received_bytes[3] * 256)/10;
                                          debug($id, "Temperatur 4 ($V[5]): ".$temp4." °C", 6);
                                          if (abs($temp4-$V[5]) >= 0.5) {
                                              logic_setOutput($id, 5, $temp4);
                                              $V[5] = $temp4;
                                          } 
                                          break;
                                      }
                                      case 4: {
                                          $tage = $received_bytes[0] + $received_bytes[1] * 256;
                                          if ($tage != $V[6]) logic_setOutput($id, 6, $tage);
                                          debug($id, "TAGE ($V[6]): ".$tage, 6);
                                          $V[6] = $tage; 
                                          break;
                                      }
                                      case 5: {
                                          $volumen = $received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 65536 + $received_bytes[3] * 16777216;
                                          debug($id, "Volumenstrom V40 ($V[7]): ".$volumen." l/h", 6);
                                          if (abs($volumen-$V[7]) >= 0.5) { 
                                              logic_setOutput($id, 7, $volumen); 
                                              $V[7] = $volumen;
                                          }
                                          break;
                                      }
                                      case 6: {
                                          if ($received_bytes[0] != $V[8]) logic_setOutput($id, 8, $received_bytes[0]);
                                          debug($id, "Drehzahl Relais 1 ($V[8]): ".$received_bytes[0]." %", 6);
                                          $V[8] = $received_bytes[0];
                                          if ($received_bytes[1] != $V[9]) logic_setOutput($id, 9, $received_bytes[1]);
                                          debug($id, "Drehzahl Relais 2 ($V[9]): ".$received_bytes[1]." %", 6);
                                          $V[9] = $received_bytes[1];
                                          if ($received_bytes[2] != $V[10]) logic_setOutput($id, 10, $received_bytes[2]); 
                                          debug($id, "Drehzahl Relais 3 ($V[10]): ".$received_bytes[2]." %", 6);
                                          $V[10] = $received_bytes[2];
                                          break;
                                      }
                                      case 7: {
                                          $waerme = $received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 65536 + $received_bytes[3] * 16777216;
                                          debug($id, "Wärmemenge ($V[11]): ".$waerme." Wh", 6);
                                          if (abs($waerme-$V[11]) >= 0.5) {
                                              logic_setOutput($id, 11, $waerme);
                                              $V[11] = $waerme;
                                          } 
                                          break;
                                      }
                                      case 8: {
                                          $sw = $received_bytes[0] * 0.01 + $received_bytes[1] * 2.56;
                                          if ($sw != $V[12]) logic_setOutput($id, 12, $sw); 
                                          debug($id, "SW-Version ($V[12]): ".$sw, 6);
                                          $V[12] = $sw;
                                          break;
                                      }
                                      case 9: {
                                          $betrieb_r1 = $received_bytes[0] + $received_bytes[1] *  256 + $received_bytes[2] * 65536 + $received_bytes[3] * 16777216;
                                          if ($betrieb_r1 != $V[13]) logic_setOutput($id, 13, $betrieb_r1); 
                                          debug($id, "Betriebsstunden Relais 1 ($V[13]): ".$betrieb_r1." h", 6);
                                          $V[13] = $betrieb_r1;
                                          break;
                                      }
                                      case 10: {
                                          $betrieb_r2 = $received_bytes[0] + $received_bytes[1] *  256 + $received_bytes[2] * 65536 + $received_bytes[3] * 16777216;
                                          if ($betrieb_r2 != $V[14])logic_setOutput($id, 14, $betrieb_r2); 
                                          debug($id, "Betriebsstunden Relais 2 ($V[14]): ".$betrieb_r2." h", 6);
                                          $V[14] = $betrieb_r2;
                                          break;
                                      }
                                      case 11: {
                                          $betrieb_r3 = $received_bytes[0] + $received_bytes[1] *  256 + $received_bytes[2] * 65536 + $received_bytes[3] * 16777216;
                                          if ($betrieb_r3 != $V[15]) logic_setOutput($id, 15, $betrieb_r3); 
                                          debug($id, "Betriebsstunden Relais 3 ($V[15]): ".$betrieb_r3." h", 6);
                                          $V[15] = $betrieb_r3;
                                          break;
                                      }
                                      case 12: {
                                          if ($received_bytes[0] != $V[16]) logic_setOutput($id, 16, $received_bytes[0]); 
                                          $V[16] = $received_bytes[0];
                                          debug($id, "Urlaubsfunktion: ".$received_bytes[0], 6);
                                          if ($received_bytes[1] != $V[17]) logic_setOutput($id, 17, $received_bytes[1]);
                                          $V[17] = $received_bytes[1];
                                          debug($id, "Blockierschutz 1: ".$received_bytes[1]."%", 6);
                                          if ($received_bytes[2] != $V[18]) logic_setOutput($id, 18, $received_bytes[2]);
                                          $V[18] = $received_bytes[2];
                                          debug($id, "Blockierschutz 2: ".$received_bytes[2]."%", 6);
                                          if ($received_bytes[3] != $V[19]) logic_setOutput($id, 19, $received_bytes[3]);
                                          $V[19] = $received_bytes[3];
                                          debug($id, "Blockierschutz 3: ".$received_bytes[3]."%", 6);
                                          break;
                                      }
                                      case 13: {
                                          $initialisieren = $received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 65536 + $received_bytes[3] * 16777216;
                                          if ($initialisieren != $V[20]) logic_setOutput($id, 20, $initialisieren);
                                          $V[20] = $initialisieren; 
                                          debug($id, "Initialisieren: ".$initialisieren, 6);
                                          break;
                                      }
                                      case 14: {
                                          $befuellung = $received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 65536 + $received_bytes[3] * 16777216;
                                          if ($befuellung != $V[21]) logic_setOutput($id, 21, $befuellung); 
                                          $V[21] = $befuellung;
                                          debug($id, "Befüllung: ".$befuellung, 6);                        
                                          break;
                                      }
                                      case 15: {
                                          $stabilisieren = $received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 65536 + $received_bytes[3] * 16777216;
                                          if ($stabilisieren != $V[22]) logic_setOutput($id, 22, $stabilisieren); 
                                          $V[22] = $stabilisieren;
                                          debug($id, "Stabilisieren: ".$stabilisieren, 6);
                                          break;
                                      }
                                      case 16: {
                                          if ($received_bytes[0] != $V[23]) logic_setOutput($id, 23, $received_bytes[0]); 
                                          $V[23] = $received_bytes[0];
                                          debug($id, "Pumpenverzögerung: ".$received_bytes[0], 6);
                                          if ($received_bytes[1] != $V[24]) logic_setOutput($id, 24, $received_bytes[1]); 
                                          $V[24] = $received_bytes[1];
                                          debug($id, "Überwärmeabfuhr: ".$received_bytes[1], 6);
                                          if ($received_bytes[2] != $V[25]) logic_setOutput($id, 25, $received_bytes[2]); 
                                          $V[25] = $received_bytes[2];
                                          debug($id, "Nachlauf: ".$received_bytes[2], 6);
                                          if ($received_bytes[3] != $V[26]) logic_setOutput($id, 26, $received_bytes[3]); 
                                          $V[26] = $received_bytes[3];
                                          debug($id, "Thermische Desinfektion: ".$received_bytes[3], 6);                            
                                          break;
                                      }
                                      case 17: {
                                          if ($received_bytes[0] != $V[27]) logic_setOutput($id, 27, $received_bytes[0]); 
                                          $V[27] = $received_bytes[0];
                                          debug($id, "Speicherkühlung: ".$received_bytes[0], 6);
                                          if ($received_bytes[1] != $V[28]) logic_setOutput($id, 28, $received_bytes[1]); 
                                          $V[28] = $received_bytes[1];
                                          debug($id, "Systemkühlung: ".$received_bytes[1], 6);
                                          if ($received_bytes[2] != $V[29]) logic_setOutput($id, 29, $received_bytes[2]); 
                                          $V[29] = $received_bytes[2];
                                          debug($id, "Spreizung: ".$received_bytes[2], 6);
                                          if ($received_bytes[3] != $V[30]) logic_setOutput($id, 30, $received_bytes[3]); 
                                          $V[30] = $received_bytes[3];
                                          debug($id, "Frostschutz: ".$received_bytes[3], 6);
                                          break;
                                      }
                                      case 18: {
                                          if ($received_bytes[0] != $V[31]) logic_setOutput($id, 31, $received_bytes[0]);
                                          $V[31] = $received_bytes[0];
                                          debug($id, "Kollektorkühlung: ".$received_bytes[0], 6);
                                          if ($received_bytes[1] != $V[32]) logic_setOutput($id, 32, $received_bytes[1]);
                                          $V[32] = $received_bytes[1]; 
                                          debug($id, "Speichermaximaltemperatur: ".$received_bytes[1], 6);
                                          if ($received_bytes[2] != $V[33]) logic_setOutput($id, 33, $received_bytes[2]);
                                          $V[33] = $received_bytes[2];
                                          debug($id, "Neustarts: ".$received_bytes[2], 6);
                                          if ($received_bytes[3] != $V[34]) logic_setOutput($id, 34, $received_bytes[3]);
                                          $V[34] = $received_bytes[3]; 
                                          debug($id, "Sensorfehler: ".$received_bytes[3], 6);
                                          break;
                                      }
                                      case 19: {
                                          $fehler = $received_bytes[0] + $received_bytes[1] * 256 + $received_bytes[2] * 65536 + $received_bytes[3] * 16777216;
                                          if ($fehler != $V[35]) logic_setOutput($id, 35, $fehler); 
                                          $V[35] = $fehler;
                                          debug($id, "Fehlermaske: ".$fehler, 6);
                                          break;
                                      }
                                      default: {
                                          debug($id, "Error: I'm not expecting any more frames here! got this: " . $received_bytes[0] ." und ". $received_bytes[1] ." und ". $received_bytes[2] ." und ". $received_bytes[3], 3);
                                      }
                                  }
                                  logic_setVar($id,3,implode('|',$V));
                                  break;
                              }
                              default: {
                                  debug($id, "source addr $source_addr not implemented", 4);
                              }
                          }
                          break;
                      }                
                      default: {
                          debug($id, "destination addr $dest_addr not implemented", 7);
                      }
                  }



              }


              // Note: for init, use $decoderstate->crc = 0x7F;  // reset the crc
              function update_crc(& $decoderstate, $currentbyte) {
                  $decoderstate->crc = (256 + $decoderstate->crc - $currentbyte) & 0x7F;
              }


              function myErrorHandler($errno, $errstr, $errfile, $errline) {
                  // debug($id, "File: $errfile | Error: $errno | Line: $errline | $errstr ");
              }


              function debug($id,$s,$l) {
                  $E=logic_getInputs($id);
                  $DEBUG=$E[5]['value'];
                  $l<=$DEBUG && writeToCustomLog("DeltaSol SLL (LBSLBSID)", $l, "(ID$id) : ".$s);
              }


              sql_disconnect();
              ?>
              ###[/EXEC]###
              Noch als Hinweis: Ich konnte nicht alle Parameter auf Funktion testen, weil diese nicht in meiner Anlage benötigt werden (und daher 0 sind), aber zumindest theoretisch sollte die Umsetzung stimmen
              Zuletzt geändert von panzaeron; 02.11.2017, 01:42.

              Kommentar


                #8
                Ich habe den Code oben editiert, da jetzt auch ein Send by Change integriert ist ohne diesen wird der KNX-Bus geflutet mit neuen Werten die sich häufig nicht oder nur wenig geändert haben.

                Kommentar


                  #9
                  Zitat von schobi Beitrag anzeigen
                  Offene Punkte:
                  - der LBS blinkt im Live Modus rot - ist gefixt
                  - mein LBS Account ist gesperrt - drum hier direkt mal der Code, später kommt das natürlich rein in die Downloads
                  - Umrechnung und Auswertung mancher Daten ist noch falsch, beispielsweise der Systemzeit, Drehzahlen passen jetzt
                  Hallo schobi,

                  konntest du den LBS schon ins Download-Portal hochladen.
                  Ich habe hier eine Solaranlage von Sonnenkraft. Diese hat auch einen Resol-Regler verbaut. Es müsste sich dabei um eine DeltaSol CS handeln. Ist dieser mit deinem Baustein kompatibel?

                  Funtioniert das ganze auch mit dem Resol Schnittstellenadapter VBUS / LAN?

                  Gruß Christian

                  Kommentar


                    #10
                    hochladen war noch nicht - hatte noch keine Zeit für Doku... Baustein läuft bei mir aber problemlos.
                    Wenn du in ein Archiv schreiben willst, dann solltest du die Anzahl der Telegramme noch reduzieren, siehe hier

                    Kommentar


                      #11
                      Meine Version habe ich jetzt in das Download-Portal (LBS 19000665) hochgeladen, danke schobi für die gute Arbeit,
                      läuft bei mir mit der LAN-Schnittstelle seit Monaten problemlos.

                      Kommentar


                        #12
                        Zitat von panzaeron Beitrag anzeigen
                        Meine Version habe ich jetzt in das Download-Portal (LBS 19000665) hochgeladen, danke schobi für die gute Arbeit,
                        läuft bei mir mit der LAN-Schnittstelle seit Monaten problemlos.
                        Hallo panzaeron,
                        mir ist aufgefallen, dass der Baustein im Download-Bereich nicht identisch zu dem von dir hier geposteten code ist.
                        Gibt es dafür einen Grund oder ist das einfach nur eine ältere Version?

                        Gruß Christian

                        Kommentar


                          #13
                          ChrisChros
                          Sorry, du hast recht, ich habe die erste Version ohne Send-By-Change hochgeladen, die aktuelle (aus dem Post) ist jetzt verfügbar.

                          Kommentar


                            #14
                            Anstelle des Send-by-Change könnte man da nicht auch einen Trigger integrieren der z.B. alle Minute die Werte abfragt? So wie bei diesem LBS für die KWL http://service.knx-user-forum.de/?co...ad&id=19000680

                            Kommentar


                              #15
                              Könnte man machen, aber die Kommunikation benötigt nur wenige Bytes und belastet das Netz praktisch nicht, so dass die Lösung mit Send-By-Change für mich eine bessere ist.
                              Edit: Weil so auch nur die Daten weitergeleitet werden wenn sich wirklich was ändert...
                              Zuletzt geändert von panzaeron; 03.01.2018, 12:06.

                              Kommentar

                              Lädt...
                              X