Neues Plugin: Smartmeter - Stromzähler auslesen

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • Gregor
    Dumb Home'r
    • 21.12.2018
    • 28

    Ich habe das # weggeben, die datei hochgeladen und den loxberry neu gestartet.
    dann mehrere abfragen mit unterschiedlichen configs gestartet. das ergebnis war überall unterschiedlich...
    Angehängte Dateien
    Hardware: Loxone mit 5 Extensions und Loxberry.
    Automatisierung: Komplette Hausbeschattung bei Nutzung der Wetterdaten, Lüftersteuerung der dezentralen M-WRG von Meltem, Lichtsteuerung gesamtes Haus, vieles über LED und 1-wire, Abwesenheitssimulation, Stromzähler auslesen, Wetterdaten über Loxberry
    In Planung: WLAN an und aus über Loxone/Loxberry

    Kommentar

    • blacksun
      MS Profi
      • 20.01.2016
      • 557

      Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 1111.png Ansichten: 0 Größe: 22,7 KB ID: 206331

      Mach mal bitte bei echo "MATCH:...." auch noch das # weg. Eine Datei reicht vollkommen. Neustarten brauchst eigentlich auch nicht. Nur speichern. Dann nochmal abfragen. Wir nähern uns dem Problem :-)

      Kommentar

      • Gregor
        Dumb Home'r
        • 21.12.2018
        • 28

        done
        Angehängte Dateien
        Hardware: Loxone mit 5 Extensions und Loxberry.
        Automatisierung: Komplette Hausbeschattung bei Nutzung der Wetterdaten, Lüftersteuerung der dezentralen M-WRG von Meltem, Lichtsteuerung gesamtes Haus, vieles über LED und 1-wire, Abwesenheitssimulation, Stromzähler auslesen, Wetterdaten über Loxberry
        In Planung: WLAN an und aus über Loxone/Loxberry

        Kommentar

        • blacksun
          MS Profi
          • 20.01.2016
          • 557

          Bist du sicher, das es bei dir so aussieht?

          Code:
           function debug($text,$showhexdata=true) {
          #        return; # ggfs. auskommentieren.
                  echo "DEBUG: '$text'";
                  if($showhexdata) echo " : ". substr($this->data,0,150);
                  echo "\n";
              }
          und

          Code:
           private function parse_sml_message() {
                  $this->debug('ENTER parse_sml_message');
                  $this->crc16_message = 0xFFFF; # Pruefsumme zuruecksetzen
                  $this->match('76');       # 76 = List of 6 items
                  $result['transactionId'] = $this->readOctet();
                  $this->debug('TRANSACID ('.$result['transactionId'].')');
                  $result['groupNo']       = $this->readUnsigned();
                  $this->debug('groupNo ('.$result['groupNo'].')');
                  $result['abortOnError']  = $this->readUnsigned();
                  $this->debug('abortOnError ('.$result['abortOnError'].')');
                  $result['messageBody']   = $this->readMessageBody();
                  $this->debug('messageBody ('.$result['messageBody'].')');
                  $crc_calc = strtoupper(substr('000'.dechex(($this->crc16_message ^ 0xffff)),-4));
                  $result['crc_calc'] = substr($crc_calc,-2).substr($crc_calc,0,2); # Wert 4-stellig ausgeben
                  $this->debug('crc_calc ('.$result['crc_calc'].')');
                  $result['crc16']         = $this->readUnsigned();
                  $this->debug('crc16 ('.$result['crc16'].')');
                  $this->match('00');       # endOfSmlMsg = 00
                  $result['crcMsgCheck'] = ($result['crc_calc'] == $result['crc16']);
                  $this->debug('EXIT parse_sml_message. CRC='.(($result['crcMsgCheck'])?'OK':'FAIL'),false);
                  $this->debug('--------------------------------',false);
                  return $result;
              }

          Kommentar

          • blacksun
            MS Profi
            • 20.01.2016
            • 557

            Nach einer Teamviewer Session, wurde der Fehler gefunden aber ich konnte ihn leider nicht ganz beheben :-)

            Code:
            Setting up port /dev/serial/smartmeter/DN03UR40: Baudrate:9600/9600 Databits:8 Stopbits:1 Parity:none Handshake:none
            00801B1B1B1B01010101760400000162006200726500000101760101070000000570950B0A01484C59020001CB55010163B03E0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201010101010104484C590177070100600100FF010101010B0A01484C59020001CB550177070100010800FF65001C01046500057095621E52FF65000840080177070100020800FF65001C01046500057095621E52FF62000177070100000200000101010109312E30322E3030370177070100605A02010101010105413031410177070100600500FF0101010165001C010401010163F36200760400000362006200726500000201710163EBF4001B1B1B1B1A00EC561B1B1B1B01010101760400000162006200726500000101760101070000000570970B0A01484C59020001CB550101634DEA0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201010101010104484C590177070100600100FF010101010B0A01484C59020001CB550177070100010800FF65001C01046500057097621E52FF65000840120177070100020800FF65001C01046500057097621E52FF62000177070100000200000101010109312E30322E3030370177070100605A02010101010105413031410177070100600500FF0101010165001C0104010101631F5700760400000362006200726500000201710163EBF4001B1B1B1B1A0038AC1B1B1B1B01010101760400000162006200726500000101760101070000000570980B0A01484C59020001CB55010163D20E0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201010101010104484C590177070100600100FF010101010B0A01484C59020001CB550177070100010800FF65001C01046500057098621E52FF650008401D0177070100020800FF65001C01046500057098621E52FF62000177070100000200000101010109312E30322E3030370177070100605A02010101010105413031410177070100600500FF0101010165001C010401010163113300760400000362006200726500000201710163EBF4001B1B1B1B1A00E03C
            Save raw buffer to /var/run/shm/smartmeter/DN03UR40.dump
            Parse /var/run/shm/smartmeter/DN03UR40.dump as SML-Protocol.
            Buffer:
            4 bytes skipped at begining!
            MATCH: 1B1B1B1B01010101
            DEBUG: 'ENTER parse_sml_message' : 760400000162006200726500000101760101070000000570950B0A01484C59020001CB55010163B03E0076040000026200620072650000070177010B0A01484C59020001CB550101777707
            MATCH: 76
            DEBUG: 'TRANSACID (000001)' : 62006200726500000101760101070000000570950B0A01484C59020001CB55010163B03E0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201
            DEBUG: 'groupNo (00)' : 6200726500000101760101070000000570950B0A01484C59020001CB55010163B03E0076040000026200620072650000070177010B0A01484C59020001CB55010177770701006032010101
            DEBUG: 'abortOnError (00)' : 726500000101760101070000000570950B0A01484C59020001CB55010163B03E0076040000026200620072650000070177010B0A01484C59020001CB550101777707010060320101010101
            MATCH: 72
            DEBUG: 'PROCESS OpenRequest' : 760101070000000570950B0A01484C59020001CB55010163B03E0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201010101010104484C5901
            MATCH: 76
            DEBUG: 'messageBody (Array)' : 63B03E0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201010101010104484C590177070100600100FF010101010B0A01484C59020001CB55
            DEBUG: 'crc_calc (B3B5)' : 63B03E0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201010101010104484C590177070100600100FF010101010B0A01484C59020001CB55
            DEBUG: 'crc16 (B03E)' : 0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201010101010104484C590177070100600100FF010101010B0A01484C59020001CB55017707
            MATCH: 00
            DEBUG: 'EXIT parse_sml_message. CRC=FAIL'
            Die CRC wird falsch berechnet oder es wird die falsche CRC übermittelt. Das kann ich nicht sagen. Wie man sieht ist crc_calc (B3B5) und crc16 (B03E). Somit ist der Vergleich falsch --> FAIL. Komischerweise passen die übertragenen Werte, also kWh usw. Auch das Verschieben des Lesekopfes brauchte nichts. Das USB Kabel 3m lang. Ist somit auch ok.

            Berechnet wird die CRC in der Function "parse_sml_message".

            Code:
            $crc_calc = strtoupper(substr('000'.dechex(($this->crc16_message ^ 0xffff)),-4));
                    $result['crc_calc'] = substr($crc_calc,-2).substr($crc_calc,0,2); # Wert 4-stellig ausgeben
            Ich weiß allerdings nicht, was diese Befehle genau machen. Wie wird die CRC hier berechnet? Kann da jemand helfen?

            Da die CRC jedesmal falsch berechnet wird, habe ich Gregor jetzt beholfen mit einer Änderungen im Vergleicher.

            Code:
             $result['crcMsgCheck'] = ($result['crc_calc'] != $result['crc16']);
            Ja ich weiß, nicht schön, aber es funktioniert zumindestens momentan.

            Hat jemand von euch einen Schimmer, was hier bei der Berechnung der CRC falsch läuft?

            Ich hänge euch auch noch die letzte Logdatei mit an.

            Vielen Dank schonmal.

            Gruß
            Michael
            Angehängte Dateien

            Kommentar


            • Gregor
              Gregor kommentierte
              Kommentar bearbeiten
              Hammermäßig - danke für die Teamviewer-Session an einem Samstag Abend! Tolle Hilfe!
          • blacksun
            MS Profi
            • 20.01.2016
            • 557

            Hallo Gregor,
            hallo Gast ,

            die Checksummenberechnung durch das Smartmeterplugin passt. Die übermittelte CRC im Telegrammstrom ist entweder falsch oder wird anders berechnet.

            Hier ein Datenstrom meines Zählers:
            Code:
            7605052E31EC62006200726301017601010501BA10A40B0A0149534B0004403BB97262016501BA1087620163[COLOR=#FF0000][B]2680[/B][/COLOR]00
            Checksumme ist laut Telegrammstrom 2680.

            Geht man nun auf die Seite http://www.sunshine2k.de/coding/javascript/crc/crc_js.html und man kopiert den Telegrammstrom
            Code:
            7605052E31EC62006200726301017601010501BA10A40B0A0149534B0004403BB97262016501BA10876201
            in das Feld CRC Input Data und hakt die Einstellungen so an wie auf dem Bild zu sehen, gibt dieses Tool zur Berechnung der CRC "8026" aus. Durch drehen von Little und Big Endian erhält man die korrekte CRC von "2680".

            Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 1.png Ansichten: 0 Größe: 27,0 KB ID: 206815
            -----------------------------------------

            Machen wir jetzt das gleiche mit dem Telegrammstrom von Gregors Zähler (Datenstrom aus oben angehängter Datei) erhält man folgende CRC.

            Code:
            760400000162006200726500000101760101070000000570950B0A01484C59020001CB55010163[B][COLOR=#FF0000]B03E[/COLOR][/B]00
            Checksumme ist laut Telegrammstrom B03E.

            Datenstrom
            Code:
            760400000162006200726500000101760101070000000570950B0A01484C59020001CB550101
            wieder im CRC Berechnungstool einsetzen.

            Tool gibt CRC "B5B3" aus. Little und Big Endian muss noch gedreht werden. --> B3B5 ist die berechnete CRC.

            Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 2.png Ansichten: 0 Größe: 26,5 KB ID: 206814

            Berechnete CRC B3B5 <> übermittelte CRC im Telegrammstrom B03E. Deshalb kam richtigerweise vom Plugin Smartmeter CRC FAIL.

            Auch die CRC über das ganze Telegramm stimmt nicht.
            Code:
            1B1B1B1B01010101760400000162006200726500000101760101070000000570950B0A01484C59020001CB55010163B03E0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201010101010104484C590177070100600100FF010101010B0A01484C59020001CB550177070100010800FF65001C01046500057095621E52FF65000840080177070100020800FF65001C01046500057095621E52FF62000177070100000200000101010109312E30322E3030370177070100605A02010101010105413031410177070100600500FF0101010165001C010401010163F36200760400000362006200726500000201710163EBF4001B1B1B1B1A00EC56
            CRC im Telegramm wäre EC56. Berechnet ergibt die CRC FF67.
            ---------------------------------------

            Entweder gibt es noch eine andere erlaubte Möglichkeit die CRC im Zähler vor Übermittlung zu berechnen oder die CRC wurde im Zähler falsch berechnet.

            So wie ich das jetzt verstanden habe, ist Gast einer der Entwickler von diesem Zähler oder?

            Viele Grüße
            Michael
            Zuletzt geändert von blacksun; 19.07.2019, 09:05.

            Kommentar


            • Gast
              Gast kommentierte
              Kommentar bearbeiten
              Hi, I'am holley meter engineer,
              0x8026, 0xB5B3 use CRC16_X_25
              0xB03E use CRC16_KERMIT

              '1B1B1B1B010101017604000.....' It is a lot of frame messages
              Zuletzt geändert von Gast; 19.07.2019, 06:17.
          • blacksun
            MS Profi
            • 20.01.2016
            • 557

            Hallo,

            okay, ich habe diesen Teil des Telegramms nochmal durch das Tool geschickt und CRC16_KERMIT ausgewählt. Ergebnis ist dann die korrekte CRC.

            Telegrammframe inklusive CRC.
            Code:
            760400000162006200726500000101760101070000000570950B0A01484C59020001CB55010163[B][COLOR=#FF0000]B03E[/COLOR][/B]00
            Ergebnis müsste somit B03E sein.

            Telegrammframe ohne CRC für das Tool zur Berechnung:
            Code:
            760400000162006200726500000101760101070000000570950B0A01484C59020001CB550101
            Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 1.png Ansichten: 0 Größe: 30,5 KB ID: 206885
            Ergebnis passt.

            Zum weiteren Test das ganze Telegramm in das Tool zur Berechnung:
            Code:
            1B1B1B1B01010101760400000162006200726500000101760101070000000570950B0A01484C59020001CB55010163B03E0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201010101010104484C590177070100600100FF010101010B0A01484C59020001CB550177070100010800FF65001C01046500057095621E52FF65000840080177070100020800FF65001C01046500057095621E52FF62000177070100000200000101010109312E30322E3030370177070100605A02010101010105413031410177070100600500FF0101010165001C010401010163F36200760400000362006200726500000201710163EBF4001B1B1B1B1A00[B][COLOR=#FF0000]EC56[/COLOR][/B]
            CRC müsste also EC56 sein.

            Telegramm ohne CRC (ohne die letzten 2 Bytes) in das Tool zur Berechnung:
            Code:
            1B1B1B1B01010101760400000162006200726500000101760101070000000570950B0A01484C59020001CB55010163B03E0076040000026200620072650000070177010B0A01484C59020001CB5501017777070100603201010101010104484C590177070100600100FF010101010B0A01484C59020001CB550177070100010800FF65001C01046500057095621E52FF65000840080177070100020800FF65001C01046500057095621E52FF62000177070100000200000101010109312E30322E3030370177070100605A02010101010105413031410177070100600500FF0101010165001C010401010163F36200760400000362006200726500000201710163EBF4001B1B1B1B1A00
            Ergebnis EC56. Passt somit auch.

            Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 3.png Ansichten: 0 Größe: 31,6 KB ID: 206887

            Dann sind dann anscheinend die ersten Zähler (Holley DTZ541), die die Checksumme nach CRC16_Kermit ausgeben und nicht CRC16_X25.

            Aber wer kann die Logik abhängig vom Zählertyp ins Skript übernehmen?

            Könntest du da was zaubern? Prof.Mobilux Müsste man was variables programmieren, z. B. was die Checksummenberechnung betrifft, da jetzt die DTZ541 nicht nach CRC16_X25 sondern nach CRC16_KERMIT berechnet werden müssen.

            Viele Grüße
            Michael
            Zuletzt geändert von blacksun; 19.07.2019, 09:10.

            Kommentar


            • heilmoa
              heilmoa kommentierte
              Kommentar bearbeiten
              Hallo blacksun,

              durch deine Anleitung konnte ich herausfinden, dass mein DTZ541 ebenfalls die Checksumme CRC16_KERMIT verwendet.


              Ich konnte leider euren Schilderungen nicht ganz folgen, welche Anpassungen nun im Loxberry gemacht werden müssen, um korrekte Daten zu erhalten.

              Mit dem Tool von Honey (SML Analyse V 06) kann ich auch den Zählerstand abfragen, ich muss nur dem Loxberry noch beibringen richtig zu "rechnen", oder?

              Und Danke schon einmal für die großartige Vorarbeit!!


              EDIT:
              Habe die Parse_SML_Message angepasst, diese sieht nun so aus:
              private function parse_sml_message() {
              $this->debug('ENTER parse_sml_message');
              $this->crc16_message = ($result['crc_calc'] != $result['crc16']);
              $this->match('76'); # 76 = List of 6 itemssdasd
              $result['transactionId'] = $this->readOctet();
              $this->debug('TRANSACID ('.$result['transactionId'].')');
              $result['groupNo'] = $this->readUnsigned();
              $this->debug('groupNo ('.$result['groupNo'].')');
              $result['abortOnError'] = $this->readUnsigned();
              $this->debug('abortOnError ('.$result['abortOnError'].')');
              $result['messageBody'] = $this->readMessageBody();
              $this->debug('messageBody ('.$result['messageBody'].')');
              $crc_calc = strtoupper(substr('000'.dechex(($this->crc16_message ^ 0xffff)),-4));
              $result['crc_calc'] = substr($crc_calc,-2).substr($crc_calc,0,2); # Wert 4-stellig ausgeben
              $this->debug('crc_calc ('.$result['crc_calc'].')');
              $result['crc16'] = $this->readUnsigned();
              $this->debug('crc16 ('.$result['crc16'].')');
              $this->match('00'); # endOfSmlMsg = 00
              $result['crcMsgCheck'] = ($result['crc_calc'] == $result['crc16']);
              $this->debug('EXIT parse_sml_message. CRC='.(($result['crcMsgCheck'])?'OK':'FAIL'),false);
              $this->debug('--------------------------------',false);
              return $result;




              VG Michael
              Zuletzt geändert von heilmoa; 23.08.2019, 20:41. Grund: Quellcode entfernt

            • blacksun
              blacksun kommentierte
              Kommentar bearbeiten
              Servus @heilmoa,

              kein Problem.

              Du öffnest auf dem Loxberry unter /opt/loxberry/webfrontend/cgi/plugins/smartmeter/bin/ die Datei "php_sml_parser.class.php". Am besten mit Notepad++.

              Dann suchst du dir in dieser Datei die Function "parse_sml_message".

              In der findest du dann diese Zeile:
              $result['crcMsgCheck'] = ($result['crc_calc'] == $result['crc16']);

              Diese änderst du ab in:
              $result['crcMsgCheck'] = ($result['crc_calc'] != $result['crc16']);

              Die Datei anschließend abspeichern. Anschließend kannst den Zähler nochmal abfragen. Müsste somit erledigt sein. Eigentlich bräuchte man für diesen Zähler noch ein Auswahlfeld, mit welcher Methode die Checksumme überprüft werden soll, da ja die nachfolgenden Zähler schon mit der X25 Methode ausgeliefert worden sind. Da fehlen mit aber Programmierkenntnisse, was PHP angeht.

              Gib mir bitte trotzdem Bescheid.

              Gruß
              Michael
              Zuletzt geändert von blacksun; 23.08.2019, 17:42.

            • heilmoa
              heilmoa kommentierte
              Kommentar bearbeiten
              Vielen lieben Dank! Hat einwandfrei funktioniert!
          • blacksun
            MS Profi
            • 20.01.2016
            • 557

            Also hat Gregor einen Zähler bekommen der früheren Charge mit CRC16 Kermit. Heißen die Zähler der 2. Charge aber trotzdem noch DTZ451? Kann man von außen erkennen, ob CRC16 Kermit oder X25 verwendet wird?
            Zuletzt geändert von blacksun; 19.07.2019, 12:40.

            Kommentar

            • Gregor
              Dumb Home'r
              • 21.12.2018
              • 28

              Hallo an alle,

              ich habe soeben vom Hersteller (Holleytech) folgende Info erhalten (nachdem ich ihn über unsere / meine Probleme informiert hatte):

              Sehr geehrter Herr

              vielen Dank für Ihren Hinweis!

              Für erste einige Zählerlieferung in 2018 wurde die CRC-Checksumme der SML-Nachricht gemäß „CCITT“ gerechnet, danach wurde es schon als „X25“ korrigiert.

              Nochmal Dank für Ihre Unterstützung und bei weiteren Fragen stehe ich Ihnen gerne zur Verfügung!

              Mit freundlichen Grüßen! / Best regards! / 致以最美好的祝愿!


              Hier ist ein Foto vom Zähler, rechts unter dem Kabel steht "2018".
              Klicke auf die Grafik für eine vergrößerte Ansicht

Name: IMG_3082 (2).JPG
Ansichten: 3540
Größe: 439,8 KB
ID: 207022
              Zuletzt geändert von Gregor; 19.07.2019, 22:12.
              Hardware: Loxone mit 5 Extensions und Loxberry.
              Automatisierung: Komplette Hausbeschattung bei Nutzung der Wetterdaten, Lüftersteuerung der dezentralen M-WRG von Meltem, Lichtsteuerung gesamtes Haus, vieles über LED und 1-wire, Abwesenheitssimulation, Stromzähler auslesen, Wetterdaten über Loxberry
              In Planung: WLAN an und aus über Loxone/Loxberry

              Kommentar

              • whe
                Smart Home'r
                • 18.10.2018
                • 32

                Ich habe ein Problem mit einem EMH Zähler: ED300L

                laut emlog liefert der Zähler über den Lesekopf unter OBIS 1.7.0 die Wirkleistung, jeweils als positiven oder negativen Wert, abhängig ob Strom bezogen oder eingespeist wird.

                Die Smartmeter Software auf dem Loxberry liefert jedoch diesen Wert nicht. lediglich unter OBIS_1.99.0 wenn er positiv ist.

                Ich erwarte den Einspeisewert entweder bei OBIS_2.99.0 oder 2.7.0.

                wo und wie kann ich das anpassen ?

                Klicke auf die Grafik für eine vergrößerte Ansicht

Name: Weidmann2.jpg
Ansichten: 1989
Größe: 71,7 KB
ID: 209857

                Klicke auf die Grafik für eine vergrößerte Ansicht

Name: file3.jpg
Ansichten: 2003
Größe: 113,5 KB
ID: 209856

                Kommentar

                • blacksun
                  MS Profi
                  • 20.01.2016
                  • 557

                  „Inf „ für vollständigen Datensatz im Zähler eingeschaltet? Vermutlich schon, da Kommastellen ausgegeben werden.

                  Ansonsten en schau ich morgen nochmal genauer, da ich heute keine Zeit habe.

                  Vermutlich muss am Anfang des die Obis Kennzahl 1.7.0 noch hinzugefügt werden, da der Zähler die Leistung über 1.7.0 ausgibt.

                  1.99 sowie 2.99 wird vom Skript berechnet.

                  Update: Es liegt daran, das das Skript nicht umgehen kann mit Zahlen, die mit 55 übertragen werden.

                  Ich habe aber das bei meinem Skript schon angepasst. Morgen kann ich mehr schreiben.

                  Gruß
                  Michael
                  Zuletzt geändert von blacksun; 17.08.2019, 17:03.

                  Kommentar

                  • blacksun
                    MS Profi
                    • 20.01.2016
                    • 557

                    Servus, so jetzt gibts ein Update zu deinem Problem whe

                    Öffne die Datei "php_sml_parser.class.php" auf deinem Loxberry mittels Notepad++.

                    Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 11.png Ansichten: 0 Größe: 43,9 KB ID: 209916

                    Füge in der Function parse_sml_data folgendes ein.

                    Code:
                    case '5x': # Integer
                                    if ($LEN==2) {
                                        # 8 Bit signed Integer
                                        $temp = hexdec($this->read($LEN-1));
                                        $this->debug('Value: ('.$temp.')');
                                        if($temp & 0x80) {
                                            # negativer Wert, Umrechnung 2er Komplement    
                                            $temp -= pow(2,8); # 256
                                            $this->debug('Value mit Vorzeichenbetrachtung: ('.$temp.')');
                                            return $temp;
                                        }
                                        else{
                                            return $temp;
                                        }
                                    }
                                    if ($LEN==3) {
                                        # 16 Bit signed Integer
                                        $temp = hexdec($this->read($LEN-1));
                                        $this->debug('Value Rohwert: ('.$temp.')');
                                        if($temp & 0x8000) {
                                            # negativer Wert, Umrechnung 2er Komplement    
                                            $temp -= pow(2,16); # 65536
                                            $this->debug('Value mit Vorzeichenbetrachtung: ('.$temp.')');
                                            return $temp;
                                        }
                                        else{
                                            return $temp;
                                        }
                                    }
                                    if ($LEN==5) {
                                        # 32 Bit signed Integer
                                        $temp = hexdec($this->read($LEN-1));
                                        $this->debug('Value Rohwert: ('.$temp.')');
                                        if($temp & 0x80000000) {
                                            # negativer Wert, Umrechnung 2er Komplement    
                                            $temp -= pow(2,32); # 4294967296
                                            $this->debug('Value mit Vorzeichenbetrachtung: ('.$temp.')');
                                            return $temp;
                                        }
                                        else{
                                            return $temp;
                                        }
                                    }
                                    if ($LEN==9) {
                                        # 64 Bit signed Integer
                                        $temp = hexdec($this->read($LEN-1));
                                        $this->debug('Value Rohwert: ('.$temp.')');
                                        if($temp & 0x8000000000000000) {
                                            # negativer Wert, Umrechnung 2er Komplement    
                                            $temp -= pow(2,64); # 18446744073709551616
                                            $this->debug('Value mit Vorzeichenbetrachtung: ('.$temp.')');
                                            return $temp;
                                        }
                                        else{
                                            return $temp;
                                        }
                                    }
                                    break;
                    So soll nun die komplette Function aussehen.
                    Code:
                    private function parse_sml_data($list_item=0) {
                            global $list_indent;
                            $TYPE_LEN = $this->read(1);
                            if($TYPE_LEN=='00') {
                                return $TYPE_LEN; # EndOfSmlMessage
                            }
                            $TYPE = $TYPE_LEN{0}.'x';     # only high-nibble
                            $LEN  = hexdec($TYPE_LEN{1}); # only low-nibble
                            while($TYPE{0} &0x8) {  # Multi-Byte TypeLen-Field
                                $LEN = $LEN * 0x10;
                                $TYPE_LEN = $this->read(1);
                                $TYPE = $TYPE_LEN{0}.'x';     # only high-nibble
                                $LEN  += hexdec($TYPE_LEN{1}); # only low-nibble
                                $LEN--; # 1 abziehen wegen zusätzlichem TL-Byte
                            }
                            if($LEN==1) return;
                            switch($TYPE) {
                                case '0x': # Octet
                                    #return $this->hex2bin($this->read($LEN-1));
                                    return $this->read($LEN-1);
                                    break;
                                case '5x': # Integer
                                    if ($LEN==2) {
                                        # 8 Bit signed Integer
                                        $temp = hexdec($this->read($LEN-1));
                                        $this->debug('Value: ('.$temp.')');
                                        if($temp & 0x80) {
                                            # negativer Wert, Umrechnung 2er Komplement    
                                            $temp -= pow(2,8); # 256
                                            $this->debug('Value mit Vorzeichenbetrachtung: ('.$temp.')');
                                            return $temp;
                                        }
                                        else{
                                            return $temp;
                                        }
                                    }
                                    if ($LEN==3) {
                                        # 16 Bit signed Integer
                                        $temp = hexdec($this->read($LEN-1));
                                        $this->debug('Value Rohwert: ('.$temp.')');
                                        if($temp & 0x8000) {
                                            # negativer Wert, Umrechnung 2er Komplement    
                                            $temp -= pow(2,16); # 65536
                                            $this->debug('Value mit Vorzeichenbetrachtung: ('.$temp.')');
                                            return $temp;
                                        }
                                        else{
                                            return $temp;
                                        }
                                    }
                                    if ($LEN==5) {
                                        # 32 Bit signed Integer
                                        $temp = hexdec($this->read($LEN-1));
                                        $this->debug('Value Rohwert: ('.$temp.')');
                                        if($temp & 0x80000000) {
                                            # negativer Wert, Umrechnung 2er Komplement    
                                            $temp -= pow(2,32); # 4294967296
                                            $this->debug('Value mit Vorzeichenbetrachtung: ('.$temp.')');
                                            return $temp;
                                        }
                                        else{
                                            return $temp;
                                        }
                                    }
                                    if ($LEN==9) {
                                        # 64 Bit signed Integer
                                        $temp = hexdec($this->read($LEN-1));
                                        $this->debug('Value Rohwert: ('.$temp.')');
                                        if($temp & 0x8000000000000000) {
                                            # negativer Wert, Umrechnung 2er Komplement    
                                            $temp -= pow(2,64); # 18446744073709551616
                                            $this->debug('Value mit Vorzeichenbetrachtung: ('.$temp.')');
                                            return $temp;
                                        }
                                        else{
                                            return $temp;
                                        }
                                    }
                                    break;
                                case '6x': # UnsignedInt
                                    return hexdec($this->read($LEN-1));
                                    break;
                                case '7x': # List
                                    $list_indent++;
                                    for($i=1;$i<=$LEN;$i++) $this->parse_sml_data($i);
                                    $list_indent--;
                                    break;
                                default :
                                    $this->error("Error, unexpected type '$TYPE' TL=$TYPE_LEN ".$this->data);
                            }
                            #echo "\n";
                            return $TYPE_LEN;
                        }
                    Dann wirds wohl funktionieren.

                    Erklärung: Im Datenstrom findet man 55FFFFB5AA. 5x = Integer, x5=32 Bit = 4294967296.
                    FFFFB5AA = 4.294.948.266 dez, 4.294.948.266- 4.294.967.296 = -19.030. Im Telegramm steht auch noch irgendwo der Faktor 0,1, mit dem die Zahl multipliziert werden muss, somit kommen wir dann auf die angezeigte -1903,0 Watt.

                    Kommentar

                    • whe
                      Smart Home'r
                      • 18.10.2018
                      • 32

                      sorry, konnte das erst heute morgen bei meiner Tochter einbauen und testen.
                      scheint aber weiter ein Problem zu geben, habe das log mal angehängt.
                      habe ich da beim Einbau etwas falsch gemacht ? die Einrückungen habe ich schon kontrolliert.
                      Angehängte Dateien

                      Kommentar

                      • whe
                        Smart Home'r
                        • 18.10.2018
                        • 32

                        ich habe mich jetzt mal mit dem SML Protokoll befasst und Deine neue Routine analysiert.
                        m.E. fehlt da die alte Routine für das unsigned integer: if ($len==6)

                        meine Daten sehen doch so aus:

                        Code:
                           77
                            070100010802FF  1.8.2
                            01
                            01
                            621E
                            52FF
                            560000000000
                            01
                           77
                            070100020802FF  2.8.2
                            01
                            01
                            621E
                            52FF
                            560000000000
                            01
                           77
                            070100100700FF  1.7.0
                            01
                            01
                            621B
                            52FF
                            55FFFFAAC6
                            01

                        Kommentar

                        • blacksun
                          MS Profi
                          • 20.01.2016
                          • 557

                          Ja da hast du recht. Ist aber in der Spezifikation auf der BSI Seite nicht spezifiziert. Länge 6-1, da ja da Längenangabebyte auch mitgezählt wird, ergibt 5. Gibt aber Zahlen im 1, 2, 4, 8 Byte usw. Ich schick dir da mal einen Auszug.

                          Ich würd sagen, das das Protokoll nicht korrekt umgesetzt worden ist vom Hersteller. Mach zur Abhilfe dann für dich noch eine Abfrage für Len 6 rein.

                          Kommentar

                          Lädt...