Smartmeter auslesen - Verschlüsselung

Hmmm…die Einstellungen stimmen schon, aber ich hab meinen Lesekopf über einen Moxa Serial Konverter angeschlossen, welcher einen TCP Server zur Verfügung stellt. IPS greift dann per Client Socket auf den TCP Port des Moxa zu. Ob ich hier vielleicht ein Problem habe?

Hi hofimax,
kann schon sein dass hier das Problem liegt.

Dann gib mir mal als erstes die Version vom Typenschilds des Zählers durch, ich vergleich dies dann mit meinem Zähler. Gleiche Zähler sollten auch gleich funktionieren (sollte sogar bei Siemens-Geräten so sein :D)

Alternativ zum Testen ein Kabel zu deinem Server legen und den IR-Kopf direkt anschließen? Bei RS232 bringt man eine Kommunikation auch mit viel Kabel dazwischen noch hin.

Gruß
Bikasso

Das mit dem direkt Anstecken des RS232 war auch mein erster Gedanke, ist allerdings bei meinem Raspberry auch nicht Plug&Play :smiley:

Habe übrigens definitiv einen TD-3511! Steht so am Typenschild. Einziger Unterschied könnte noch der sein, daß ich den Strom auf diesem Zähler von der Enamo beziehe, wobei ich ja nicht glaube das sich deswegen etwas am Aufbau der Daten ändern sollte :D:D Der Zähler kommt ja trotzdem von der Netz OÖ!

Braucht der Lesekopf eventuell irgendwelche Steuersignale ? (DTR?)
Schau mal hier:
EX-6030 - Ethernet zu 1 x Seriell RS-232 - Anbindung für Zählerabfrage

Diese wirst du per TCP wohl leider kaum ‚setzen‘ können.

Michael

Servus hofimax,

ich weiß, du hast diesen TD3511, da gibt es auch verschiedene Versionen. Dies steht auf dem Typenschild. Ich z.b. hab bei mir daheim 2 Zähler verbaut mit verschiedenen Revisionen, die muss man unterschiedlich auslesen.

Hat ein Raspberry keine USBb-Schnittstelle? (Stichwort USB-RS232 Adapter)

Gruß
Bikasso

Hi Bikasso!

Also eigentlich sollten seit letztem Jahr alle Zähler gleich auszulesen sein auf der Kundenschnittstelle. Die Beschreibung die ich dazu bekommen habe bestätigt dies. Allerdings würde sie mir dann auch sagen das mein Interface nicht das Richtige ausspuckt, deines aber schon :confused: Ich glaube ich erkundige mich da mal!

Zwei Zähler habe ich ebenfalls verbaut, bei einem ist die Schnittstelle noch gar nicht aktiviert. In Zukunft supportet wird meines Wissens nach nur die Variante die du umgesetzt hast, die passt auch mit der offiziellen Beschreibung der Kundenschnittstelle zusammen. Sobald ich Zeit habe, klemme ich mal mein Notebook an und sehe nach ob die Daten dann so rauskommen wie sie sollen und wenn nicht, dann wende ich mich an die Netz OÖ. Ich halte euch auf dem Laufenden!

Servus,

ist dein 2ter Zähler auch ein TD3511?
Ich habe heute morgen bei meinem Zähler die Artikelnummer mit Revision von meinem Zähler abgelesen:
6MF8101-0AA11-0BA1/F

Der Letzte Buchstabe hinten ist die Revision. Ab Rev. F gibt der Zähler verschlüsselte MBUS-Frames aus.
Frühere Revisionsstände, also E und kleiner, kannst du übrigens auch auslesen, diese Zähler blubbern die Daten unverschlüsselt raus nachdem man ihnen eine Anforderung schickt. Da hätt ich auch ein passendes Script wenn du Interesse dran hast :slight_smile:

Gruß
Bikasso

Hi Bikasso!

Alles klar, hab nachgesehen. Mein Hauptzähler ist Revision E und mein Zweitzähler für die Wärmepumpe ist Revision F. Getestet habe ich jetzt immer auf meinem Zweitzähler.

Gerne nehme ich das Script für die Rev. E auch entgegegen :smiley: Wie kann ich mich da mal revanchieren? Da du auch bei der Netz OÖ bist, können wir ja nicht weit ausseinander sein oder :slight_smile:

Servus hofimax,

naja, weit auseinander ist relativ, OÖ ist groß, ich denke wenn du einen elektronischen Zähler hast für eine Wärmepumpe dann steht deine Hütte in nem „Ballungszentrum“ und bist du aus der Linzer Gegend, ab ich recht?
Nach Linz sind’s von mir aus 150km.
Aber Grundsätzlich bin ich für a Bier immer motiviert :smiley:

Das Script für deinen „alten“ Zähler stell ich demnächst hier zur Verfügung. Dieses habe ich eh irgendwo hier im Forum gefunden und auf diesen Zähler angepasst. Hardware, d.h. Auslesekopf kannst du die gleiche verwenden wie beim neuen Zähler.

Gruß
Bikasso

Hihi, nö weit gefehlt. Von Linz wohne ich selbst 80km weg :smiley: Gott sei Dank! Mich und meine Hütte findest du eher im wunderschönen Hausruckviertel :slight_smile:

Servus Hofimax,

stimmt, im Hausruckviertel is schön. Im Innviertel aber auch ;).

Wie versprochen der Code für den Zähler bis Rev. E. Ich hab, wie schon geschrieben, den Code irgendwo aus dem Forum, und nur für unseren Zähler angepasst. d.h. der Dank gebührt nicht (nur) mir.

 <?
//Hier die Instanz wo das alles rein soll. z.B. eure RegisterVariable
$ParentID = 42416 /*[Energie\Energiezähler_Haus]*/  ;

// Archiv Handler damit das Logging eingeschaltet werden kann.
$arhid = 44704 /*[Archive Handler]*/  ;

//Hier die COM-Port Instanz
$com_Port = 19969 /*[Serial Port_COM4_EnergieAG_Zähler]*/  ;

if ($_IPS['SENDER'] == "RegisterVariable")
{
    $content = $IPS_VALUE;

 // Hier sind die werte die abgefragt werden sollen.

        anfrage('Zaehlerstand Einkauf','1.8.0(','*kWh)',$content,3,'',$arhid,$ParentID);
        anfrage('Zaehlerstand PV Verkauf','2.8.0(','*kWh)',$content,3,'',$arhid,$ParentID);
        anfrage('Wirkleistung Einkauf','1.7.0(','*kW)',$content,2,'~Power',$arhid,$ParentID);
        anfrage('Wirkleistung Verkauf','2.7.0(','*kW)',$content,2,'~Power',$arhid,$ParentID);
        anfrage('Blindleistung Einkauf','3.7.0(','*kvar)',$content,2,'',$arhid,$ParentID);
        anfrage('Blindleistung Verkauf','4.7.0(','*kvar)',$content,2,'',$arhid,$ParentID);
        anfrage('Blindenergie Einkauf','3.8.1(','*kvarh)',$content,2,'',$arhid,$ParentID);
        anfrage('Blindenergie Verkauf','4.8.1(','*kvarh)',$content,2,'',$arhid,$ParentID);
        anfrage('Frequenz','14.7(','*Hz)',$content,2,'',$arhid,$ParentID);
        anfrage('Spannung L1','32.7(','*V)',$content,2,'~Volt.230',$arhid,$ParentID);
        anfrage('Spannung L2','52.7(','*V)',$content,2,'~Volt.230',$arhid,$ParentID);
        anfrage('Spannung L3','72.7(','*V)',$content,2,'~Volt.230',$arhid,$ParentID);
        anfrage('Strom L1','31.7(','*A)',$content,2,'~Ampere',$arhid,$ParentID);
        anfrage('Strom L2','51.7(','*A)',$content,2,'~Ampere',$arhid,$ParentID);
        anfrage('Strom L3','71.7(','*A)',$content,2,'~Ampere',$arhid,$ParentID);
        anfrage('Strom N','91.7(','*A)',$content,2,'~Ampere',$arhid,$ParentID);
        anfrage('Phasenwinkel U1-I1','81.7.4(','*Deg)',$content,2,'',$arhid,$ParentID);
     //   anfrage('cos phi L2','53.7(','*cos)',$content,3,'',$arhid,$ParentID);
    //    anfrage('cos phi L3','73.7(','*cos)',$content,3,'',$arhid,$ParentID);

         echo "Zähler Haus ausgelesen!";
}else{
    COMPort_SetDTR($com_Port , true);
    COMPort_SendText($com_Port ,"\x2F\x3F\x21\x0D\x0A");
};

function anfragezahlernr($varname,$anfang,$ende,$content){
    $zaehler_nr_ist = Auswerten($content,$anfang,$ende);
    return $zaehler_nr_ist;
};

function anfrage($varname, $anfang, $ende, $content, $vartyp, $VariProfile, $arhid, $ParentID){
    $wert = Auswerten($content, $anfang, $ende);
    vars($arhid, $ParentID, $varname, $wert, $vartyp, $VariProfile);
};

function Auswerten($content,$anfang,$ende){
 $result_1 = explode($anfang,$content);
 $result_2 = explode($ende,$result_1[1]);
 $wert = str_replace(".", ",", $result_2[0]);
 return $wert;
};


function vars($arhid,$ParentID, $varname, $wert, $vartyp, $VariProfile)
  {
$VariID = IPS_GetVariableIDByName($varname, $ParentID);
    if ($VariID == false)
    {
        $VariID = IPS_CreateVariable ($vartyp);
        IPS_SetVariableCustomProfile($VariID, $VariProfile);
        IPS_SetName($VariID,$varname);
          AC_SetLoggingStatus($arhid, $VariID, true);
        IPS_SetParent($VariID,$ParentID);
    }
    SetValue($VariID, $wert);
  };

?>

Oben die IDs auf dein IPS anpassen, Variablen musst du nicht anlegen, macht alles das Script.

Cutter wird eingestellt auf:
Linke Trennzeichen: 53 41 54 36 33 35 31 31 43 30 31 32 34 38 30 30 34 32 32 39
rechte trennzeichen: 21

Com-Schnittstelle wird eingestellt auf:
Baud: 300
Datenbit: 7
Stopbit: 1
Parität: Even

Ein Ereignis musst du erstellen das alle 5 Minuten o.g. Script aufruft.

Du könntest das Script noch erweitern, da könnte man noch viele andere Werte auslesen, leider ist damals, als ich das gemacht hab „Gras drüber gewachsen“, ausserdem hat man mit den Werten die schon drin sind alles Wichtige erschlagen.

Viel Erfolg!
Schöner Gruß

Hallo Bikasso!

Ich habe mir mittlerweile meinen Hauptzähler austauschen lassen und vor allem USB/RS232 Konverter direkt an meinen Raspberry gesteckt und siehe da, nun funktioniert das Auslesen der Zähler auch bei mir. Vielen Dank nochmal an der Stelle für die Arbeit, ich denke das wird für einige andere Netz OÖ bzw. Energie AG Kunden sicherlich auch noch interessant :D:loveips:

Oje, zu Früh gefreut :o Bei meinem zweiten Zähler für die Wärmepumpe siehts nicht so gut aus. Hab alles angepasst, Key stimmt, Script wird ausgeführt, Inkasso Variable ändert sich, sonst leider nix. Aber: gestern Abend wurde einmal der Wert des Zählers ausgelesen, dann nicht mehr! Kannst du mehr bei der Fehlersuche helfen?

Anbei ein Bild der Variablen:

Ich weiß nicht warum, ich habe auch nichts geändert, aber es geht jetzt…hmmm…schön langsam glaube ich der Zähler spuckt keine Daten aus wenn keine Leistung anliegt, ich bin mir eigentlich sogar ziemlich sicher. Jetzt läuft die WP nämlich zum Warmwasser machen und es kommen Daten an! Darauf sollte man also achten bei reinen WP-Tarif Zählern!

Dank nochmal für alles Bikasso!!!

@Bikasso
Ich habe ja nen eigenen Zähler für meine Wärmepumpe, auf dem die Werte Tag- und Nachtstrom auch verfügbar wären. Wäre es eine Hexerei das auch noch in dein Script einzubauen?

Hallo Hofimax,

du hast ja weiter oben geschrieben dass du für die Wärmepumpe einen Zähler mit Revision F hast, also einen „neuen“ Zähler der M-Bus Frames ausgibt. Ich habe in meinem Script bereits alle (sinnvollen) Daten extrahiert. Das einzige was noch möglich wäre, wäre das Datum und die Uhrzeit aus dem Zähler auszulesen, das hab ich mir jedoch gespart, da diese Info in Kombination mit IPS sinnlos ist.
Mit dem Alten Zähler könnte man alle im Zähler hinterlegten OBIS-Kennzahlen auslesen, mit dem neuen nur ein paar ausgewählte, dafür aber um vieles schneller.
-> wenn bis jetzt die Daten im IPS nicht eh noch nicht angezeigt werden, hast du Pech.

Rein Interessehalber: Um Welche OBIS Kennzahlen geht’s da bei Nacht/Tagstrom?

Gruß
Bikasso

Hi!

Es geht um die OBIS Kennzahlen 1.8.1 und 1.8.2, wobei die erste Nachtstrom ist und die zweite Tagstrom.

Dachte eigentlich ja schon das dies gehen müsste :frowning:

Hallo hofimax,
da hast du leider keine Chance, die zwei Kennzahlen werden über den Mbus-Frame nicht übertragen.
Du könntest bei der Energie AG anfragen warum sie das nicht gscheid gemacht haben, wär ja ansich kein Problem gewesen das mit zu übertragen.
Schöner Gruß

Hallo,

Vorweg - ihr leistet hier tolle Arbeit :slight_smile:

Ich versuche seit mehreren Tagen meinen neuen SmartMeter TD-3511 Version F auszulesen
Verschiedene Einstellungen und auch einen anderen Lesekopf wurde getestet
IPS ist bei mir auf einen Windows 10, Ubunu 16.04 LTS, und einmal auf einem ESX Host als VM Windows 10 installiert
immer das selbe

I/O Instanzen - Client Socket hinzugefügt Port ttyUSB0 / 9600 / 8 / 1 / N

Eine Register Variable angelegt - Zeil: das Auslesescript - Übergeordnete Instanz: den Client Socket ausgewählt

Key von der Netz Oberösterreich heruntergeladen (auch schon nachgefragt ob dieser falsch berechnet worden ist) -er passt

Zähler schickt nach ca 1min 10 40 F0 C1 B2 FC das dann mit E5 quittiert wird danach sprudeln Daten aus dem Zähler

laut Forum sollte ein M-BUS mit 68 beginnen und danach zwei mal 5F kommen - das es bei mir nicht tut

hier mein Auslesescript:


<?php
   $IDEnergieAP = 52689 /*[Zähler\Register Variable\IDEnergieAP]*/;//0403 (Energie A+ 1.8.0) [kWh]
   $IDEnergieAM = 20728 /*[Zähler\Register Variable\IDEnergieAM]*/;//04833C (Energie A- Obis 2.8.0)[kWh]
   $IDEnergieRP = 22319 /*[Zähler\Register Variable\IDEnergieRP]*/;//8410FB8273 (Energie R+ Obis 3.8.1)[kvarh]
   $IDEnergieRM = 24238 /*[Zähler\Register Variable\IDEnergieRM]*/;//8410FB82F33C (Energie R- Obis 4.8.1)[kvarh]
   $IDWirkleistungPP = 25172 /*[Zähler\Register Variable\IDWirkleistungPP]*/;//042B (Wirkleistung P+ Obis 1.7.0)kW
   $IDWirkleistungPM = 30476 /*[Zähler\Register Variable\IDWirkleistungPM]*/;//04AB3C (Wirkleistung P- Obis 2.7.0)kW
   $IDBlindleistungQP = 43566 /*[Zähler\Register Variable\IDBlindleistungQP]*/;//04FB14 (Blindleistung Q+ Obis 3.7.0)kvar
   $IDBlindleistungQM = 49671 /*[Zähler\Register Variable\IDBlindleistungQM]*/;//04FB943C (Blindleistung Q- Obis 4.7.0)kvar
   $IDInkasso = 15292 /*[Zähler\Register Variable\IDInkasso]*/;//0483FF04 (Inkasso Obis 1.128.0 ) kWh
   $IDRegistervariable = 20067 /*[Zähler\Register Variable]*/;
   $key_hex = "7**************mein Key******************D";

  if ($_IPS['SENDER'] == "RegisterVariable"){
        $VarTrigger = IPS_GetVariable($IDInkasso);
        //Wenn über 50 sec  die Variable nicht aktualisiert wurde
        if(($VarTrigger['VariableUpdated']  + 50) < (time())) {

            // bereits im Puffer der Instanz vorhandene Daten in $data kopieren
            $data  = RegVar_GetBuffer($_IPS['INSTANCE']);
            // neu empfangene Daten an $data anhängen
            $data .= $_IPS['VALUE'];
         if (substr($data,0,1) == "\x10"){
                
                // wenn die Zeichen in $data der Anfrage vom MBUS-Master entsprechen
                if ($data == "\x10\x40\xF0\xC1\xB2\xFC"){
                    RegVar_SetBuffer($_IPS['INSTANCE'], "");
                    RegVar_SendText($_IPS['INSTANCE'],"\xe5");
                }else{ 
                    if (strlen ($data ) > 5 ) {//datenstring fehler, löschen
                        RegVar_SetBuffer($_IPS['INSTANCE'], "");
                    }else{//datenstring noch nicht vollständig in buffer schreiben
                  RegVar_SetBuffer($_IPS['INSTANCE'], $data);
                    }
                }
            }elseif (substr($data,0,1) == "\x68"){
            RegVar_SetBuffer($_IPS['INSTANCE'], $data);
                $key = hex2bin ($key_hex);

                //$data = "\x68\x5F\x5F\x68\x53\xF0\x5B\x00\x00\x00\x00\x2D\x4C\x01\x0E\x0D\x00\x50\x05\x3F\xD0\xFE\xB7\x26\x76\x0C\xC7\xAA\xF0\xB5\x2B\x41\xF0\xC5\x41\xBD\x63\x06\xDC\xD8\xB9\x1B\x3D\xA2\x31\x1E\xF1\x3D\x25\x14\xD0\x96\x00\x82\x16\x1E\xFE\xC4\xB6\xCB\x1E\x0B\x33\x28\xBE\x61\x77\xDC\xA5\x94\xC1\x28\x00\x24\xA8\x35\xF1\xD6\x55\xBA\x71\x82\xB2\x56\xE9\x4B\xD3\x3A\xC0\xA6\xB0\x8D\xA4\x67\x81\xEB\x4E\x91\xE0\x12\x16";

                //$dataVolkszaehler = "685F5F6853F05B000000002D4C010E0D0050053FD0FEB726760CC7AAF0B52B41F0C541BD6306DCD8B91B3DA2311EF13D2514D0960082161EFEC4B6CB1E0B3328BE6177DCA594C1280024A835F1D655BA7182B256E94BD33AC0A6B08DA46781EB4E91E01216";
                //$data = hex2bin ($dataVolkszaehler);

                //$dataM21 = "685F5F6873F05B000000002D4C010E08005005BBF0C8BECA58A381934365227669CB5AA8E73778E5EABB317B76A0430DF8C505BFC03BBB782607DC3741C2028F90C09A9C6E10B08F1B3FBE5A0C91D3D6A7A462D7E78F8AACDDAC5B5B3608C7DB27574CEC16";
                //$data = hex2bin ($dataM21);


                //hex_dump ($string);

                $MBUS_FRAME_FIXED_SIZE_LONG     = 6;
                $dataarray = byteStr2byteArray ($data);
                $dataarray_len = count($dataarray);
                if ($dataarray_len < 3) {
                    echo ("Got a valid long/control packet start, but we need data to determine the length!");
                }else{

                    $start1 = $dataarray[0];
                    $length1 = $dataarray[1];
                    $length2 = $dataarray[2];

                    if ( $length1 != $length2) {
                        echo ("Not a valid M-bus frame. Buffer von IPS wird vorsichtshalber gelöscht");
                        RegVar_SetBuffer($_IPS['INSTANCE'], "");
                    }else{

                        if ($dataarray_len < ($MBUS_FRAME_FIXED_SIZE_LONG + $length1)) {
                            echo ("Length of packet incorrect, we need more data! ");

                        }else{

                            $start2   = $dataarray[3];
                            $control  = $dataarray[4];
                            $address  = $dataarray[5];
                            $control_information = $dataarray[6];
                            $IdentNr1 = $dataarray[7];
                            $IdentNr2 = $dataarray[8];
                            $IdentNr3 = $dataarray[9];
                            $IdentNr4 = $dataarray[10];
                            $ManufacCode1 = $dataarray[11];
                            $ManufacCode2 = $dataarray[12];
                            $Version = $dataarray[13];
                            $DeviceType = $dataarray[14];
                            $AcessNr = $dataarray[15];
                            $MBusState = $dataarray[16];
                            $ConfigWord1 = $dataarray[17];
                            $ConfigWord2 = $dataarray[18];

                            $checksum = $dataarray[$MBUS_FRAME_FIXED_SIZE_LONG + $length1-2];
                            $stop     = $dataarray[$MBUS_FRAME_FIXED_SIZE_LONG + $length1-1];

                            /**
                             * Calcuate checksum
                             */
                            $calculated_checksum = $control;
                            $calculated_checksum += $address;
                            $calculated_checksum += $control_information;

                            for ($i = 7; $i < $dataarray_len - 2; $i++) {
                                $calculated_checksum += $dataarray[$i];
                                $calculated_checksum = $calculated_checksum % 256;
                            }

                            if ($checksum != $calculated_checksum ) {
                                echo("Checksums do not match!! Buffer von IPS wird vorsichtshalber gelöscht");
                                RegVar_SetBuffer($_IPS['INSTANCE'], "");
                            }else{
                                $encryptedData = "";
                                for ($i = 19; $i < $MBUS_FRAME_FIXED_SIZE_LONG + $length1-2; $i++) {
                                    $encryptedData .= pack ("C",$dataarray[$i]);
                                }
                                echo "Daten zum Entschlüsseln:
";
                                hex_dump ($encryptedData);

                                 // folgenden Block auskommentieren wenn abfragezyklus 1x pro Minute sein soll, wenn auskommentierung weggenommen wird erfolgt die Variablenaktualisierung 1x pro Sekunde!
                                if ($dataarray_len > $MBUS_FRAME_FIXED_SIZE_LONG + $length1) {
                                    //reset buffer
                                    $DataAnBuffer = "";
                                    for ($i = $MBUS_FRAME_FIXED_SIZE_LONG + $length1; $i < $dataarray_len; $i++) { //überschüssige daten in den buffer zurückschreiben
                                        $DataAnBuffer .= pack ("C",$dataarray[$i]);
                                    }

                                    RegVar_SetBuffer($_IPS['INSTANCE'], $DataAnBuffer);
                                    //RegVar_SendText($_IPS['INSTANCE'],"\xe5");
                                }elseif($dataarray_len = $MBUS_FRAME_FIXED_SIZE_LONG + $length1){
                            RegVar_SetBuffer($_IPS['INSTANCE'], "");
                                    //RegVar_SendText($_IPS['INSTANCE'],"\xe5");

                                }


                                /* Open module, and create IV */
                                $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
                                //$iv_size = mcrypt_enc_get_iv_size($td);
                                //$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
                                $iv = pack("C*", $ManufacCode1, $ManufacCode2, 0 , 0 , 0 , 0 , $Version , $DeviceType , $AcessNr , $AcessNr, $AcessNr, $AcessNr, $AcessNr, $AcessNr, $AcessNr, $AcessNr);
                                echo "IV:
";
                                hex_dump ($iv);
                                /* Initialize encryption handle */
                                if (mcrypt_generic_init($td, $key, $iv) != -1) {

                                    /* Reinitialize buffers for decryption */
                                    mcrypt_generic_init($td, $key, $iv);
                                    $decryptedData = mdecrypt_generic($td, $encryptedData);
                                    mcrypt_generic_deinit($td);

                                    /* Encrypt data */
                                    mcrypt_generic_init($td, $key, $iv);
                                    $encryptedData_Kontrolle = mcrypt_generic($td, $decryptedData);

                                    /* Clean up */
                                    mcrypt_generic_deinit($td);
                                    mcrypt_module_close($td);
                                }

                                if (strncmp($encryptedData, $encryptedData_Kontrolle, strlen($encryptedData)) == 0) {
                                    echo "Entschlüsselung ok
";
                                } else {
                                    echo "Entschlüsselung error
";
                                }

                                echo "Entschlüsselte Daten:
";
                                hex_dump ($decryptedData);

                                $decrArray = byteStr2byteArray ($decryptedData);
                                $decrArray_len = count($decrArray);
                                if ($decrArray_len  != 80) {
                                    echo ("Die Länge der entschlüsselten Daten passt nicht!");
                                }else{
                                    if ( $decrArray [0]. $decrArray [1] != $decrArray [$decrArray_len-2]. $decrArray [$decrArray_len-1]) {
                                        echo ("keine validen entschlüsselten Daten!");
                                        hex_dump ($decrArray [0]. $decrArray [1]);

                                    }else {
                                        //0403 (Energie A+ Obis 1.8.0) [Wh]
                                        $KontrolleObis = ByteToHex($decrArray[10]) .ByteToHex($decrArray[11]);
                                        $Byte1   = $decrArray[12];
                                        $Byte2   = $decrArray[13];
                                        $Byte3   = $decrArray[14];
                                        $Byte4   = $decrArray[15];
                                        $EnergieAP = hexdec(ByteToHex($Byte4).ByteToHex($Byte3).ByteToHex($Byte2).ByteToHex($Byte1));
                                        //$EnergieAP = unpack ("L*",pack ("C*",$Byte4,$Byte3,$Byte2,$Byte1));
                                        //$EnergieAP = pack ("C*",$Byte4,$Byte3,$Byte2,$Byte1);
                                        echo "
Energie A+ Obis 1.8.0: ".$EnergieAP;

                                        //04833C (Energie A- Obis 2.8.0)[Wh]
                                        $KontrolleObis .= ByteToHex($decrArray[16]) .ByteToHex($decrArray[17]) . ByteToHex($decrArray[18]);
                                        $Byte1   = $decrArray[19];
                                        $Byte2   = $decrArray[20];
                                        $Byte3   = $decrArray[21];
                                        $Byte4   = $decrArray[22];
                                        $EnergieAM = hexdec(ByteToHex($Byte4).ByteToHex($Byte3).ByteToHex($Byte2).ByteToHex($Byte1));
                                        echo "
Energie A- Obis 2.8.0: ".$EnergieAM;

                                        //8410FB8273 (Energie R+ Obis 3.8.1)[varh]
                                        $KontrolleObis .= ByteToHex($decrArray[23]) .ByteToHex($decrArray[24]) . ByteToHex($decrArray[25]) . ByteToHex($decrArray[26]). ByteToHex($decrArray[27]);
                                        $Byte1   = $decrArray[28];
                                        $Byte2   = $decrArray[29];
                                        $Byte3   = $decrArray[30];
                                        $Byte4   = $decrArray[31];
                                        $EnergieRP = hexdec(ByteToHex($Byte4).ByteToHex($Byte3).ByteToHex($Byte2).ByteToHex($Byte1));
                                        echo "
Energie R+ Obis 3.8.1: ".$EnergieRP;

                                        //8410FB82F33C (Energie R- Obis 4.8.1)[varh]
                                        $KontrolleObis .= ByteToHex($decrArray[32]) .ByteToHex($decrArray[33]) . ByteToHex($decrArray[34]). ByteToHex($decrArray[35]). ByteToHex($decrArray[36]). ByteToHex($decrArray[37]);
                                        $Byte1   = $decrArray[38];
                                        $Byte2   = $decrArray[39];
                                        $Byte3   = $decrArray[40];
                                        $Byte4   = $decrArray[41];
                                        $EnergieRM = hexdec(ByteToHex($Byte4).ByteToHex($Byte3).ByteToHex($Byte2).ByteToHex($Byte1));
                                        echo "
Energie R- Obis 4.8.1: ".$EnergieRM;

                                        //042B (Wirkleistung P+ Obis 1.7.0)W
                                        $KontrolleObis .= ByteToHex($decrArray[42]) .ByteToHex($decrArray[43]);
                                        $Byte1   = $decrArray[44];
                                        $Byte2   = $decrArray[45];
                                        $Byte3   = $decrArray[46];
                                        $Byte4   = $decrArray[47];
                                        $WirkleistungPP = hexdec(ByteToHex($Byte4).ByteToHex($Byte3).ByteToHex($Byte2).ByteToHex($Byte1));
                                        echo "
Wirkleistung P+ Obis 1.7.0: ".$WirkleistungPP;

                                        //04AB3C (Wirkleistung P- Obis 2.7.0)W
                                        $KontrolleObis .= ByteToHex($decrArray[48]) .ByteToHex($decrArray[49]) . ByteToHex($decrArray[50]);
                                        $Byte1   = $decrArray[51];
                                        $Byte2   = $decrArray[52];
                                        $Byte3   = $decrArray[53];
                                        $Byte4   = $decrArray[54];
                                        $WirkleistungPM = hexdec(ByteToHex($Byte4).ByteToHex($Byte3).ByteToHex($Byte2).ByteToHex($Byte1));
                                        echo "
Wirkleistung P- Obis 2.7.0: ".$WirkleistungPM;

                                        //04FB14 (Blindleistung Q+ Obis 3.7.0)var
                                        $KontrolleObis .= ByteToHex($decrArray[55]) .ByteToHex($decrArray[56]) . ByteToHex($decrArray[57]);
                                        $Byte1   = $decrArray[58];
                                        $Byte2   = $decrArray[59];
                                        $Byte3   = $decrArray[60];
                                        $Byte4   = $decrArray[61];
                                        $BlindleistungQP = hexdec(ByteToHex($Byte4).ByteToHex($Byte3).ByteToHex($Byte2).ByteToHex($Byte1));
                                        echo "
Blindleistung Q+ Obis 3.7.0: ".$BlindleistungQP;

                                        //04FB943C (Blindleistung Q- Obis 4.7.0)var
                                        $KontrolleObis .= ByteToHex($decrArray[62]) .ByteToHex($decrArray[63]) . ByteToHex($decrArray[64]). ByteToHex($decrArray[65]);
                                        $Byte1   = $decrArray[66];
                                        $Byte2   = $decrArray[67];
                                        $Byte3   = $decrArray[68];
                                        $Byte4   = $decrArray[69];
                                        $BlindleistungQM = hexdec(ByteToHex($Byte4).ByteToHex($Byte3).ByteToHex($Byte2).ByteToHex($Byte1));
                                        echo "
Blindleistung Q- Obis 4.7.0: ".$BlindleistungQM;

                                        //0483FF04 (Inkasso Obis 1.128.0 ) Wh
                                        $KontrolleObis .= ByteToHex($decrArray[70]) .ByteToHex($decrArray[71]) . ByteToHex($decrArray[72]). ByteToHex($decrArray[73]);
                                        $Byte1   = $decrArray[74];
                                        $Byte2   = $decrArray[75];
                                        $Byte3   = $decrArray[76];
                                        $Byte4   = $decrArray[77];
                                        $Inkasso = hexdec(ByteToHex($Byte4).ByteToHex($Byte3).ByteToHex($Byte2).ByteToHex($Byte1));
                                        echo "
Inkasso Obis 1.128.0: ".$Inkasso;

                               if ($KontrolleObis  = "040304833C8410FB82738410FB82F33C042B04AB3C04FB1404FB943C0483FF04") {
                                  echo "
OBIS-Kennzahlen stimmen überein";

                                            $IPSEnergieAP = GetValue($IDEnergieAP);
                                            $IPSEnergieAM = GetValue($IDEnergieAM);
                                 if (($IPSEnergieAP <= round($EnergieAP * 0.001,2)) AND ($IPSEnergieAM <= round($EnergieAM * 0.001,2))) {
                                                //Daten (endlich :-))in IPS-Variablen schreiben (und umrechnen)!
                                                Schreiben($IDEnergieAP, round($EnergieAP * 0.001,2));
                                                Schreiben($IDEnergieAM, round($EnergieAM * 0.001,2));  
                                                Schreiben($IDEnergieRP, round($EnergieRP * 0.001,2));
                                                Schreiben($IDEnergieRM, round($EnergieRM * 0.001,2));
                                                Schreiben($IDWirkleistungPP, round($WirkleistungPP * 0.001,2));
                                                Schreiben($IDWirkleistungPM, round($WirkleistungPM * 0.001,2));
                                                Schreiben($IDBlindleistungQP, round($BlindleistungQP * 0.001,2));
                                                Schreiben($IDBlindleistungQM, round($BlindleistungQM * 0.001,2));
                                                SetValue($IDInkasso, round($Inkasso * 0.001,2)); //dieser Wert wird immer geschrieben damit die auslesung alle 60s möglich ist. sonst auslesen alle 1s
                                                echo "
Werte wurden geschrieben, falls sie sich in der Zwischenzeit geändert haben.";
                                            }else{
                                    echo "
Werte wurden nicht geschrieben, fehlerhafte Werte, ausgelesener Zählerwert niedriger als Wert im IPS";
                                            }

                                        }else{
                                           echo "
Fehler bei den OBIS-Kennzahlen (evtl. defekter Frame)";
                                        }
                                    }
                                }
                     }
                        }
                    }
                }
            }else{
               RegVar_SetBuffer($_IPS['INSTANCE'], "");
            }
        }
    }else{
    RegVar_SetBuffer($IDRegistervariable, "");
    }

   function byteStr2byteArray($s) {
            return array_slice(unpack("C*", "\0".$s), 1);
    }

    function outputByteString($s) {
        $out = "";
        $bufArr = byteStr2byteArray($s);
        foreach( $bufArr as $char ) {
            $out .= "\\";
            $out .= "x";
            if ( intval($char) < 16 ) {
                $out .= "0";
            }
            $out .= dechex($char) . "";
        }
        echo "

" . $out . "
";

    }

    function ByteToHex($byte) {
        //$retval = "0x";
        $retval = "";
        if ( $byte <= 0x0F ) {
            $retval .= "0" . strtoupper(dechex($byte));
        } else {
            $retval .= strtoupper(dechex($byte));
        }
        return $retval;// . " ";
    }
    
    function returnByteString($byteString) {
        $out = "";
        $byteArr = byteStr2byteArray($byteString);
        foreach( $byteArr as $byte ) {
            //$out .= "\\x";

            if ( intval($byte) < 16 ) {
                $out .= "0";
            }
            $out .= dechex($byte) . " ";
        }
        return strtoupper($out);
    }

    function hex_dump($data, $newline="
"){
        static $from = '';
        static $to = '';

        static $width = 16; # number of bytes per line

        static $pad = '.'; # padding for non-visible characters

        if ($from==='')
        {
        for ($i=0; $i<=0xFF; $i++)
        {
          $from .= chr($i);
          $to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;
        }
        }

        $hex = str_split(bin2hex($data), $width*2);
        $chars = str_split(strtr($data, $from, $to), $width);

        $offset = 0;
        foreach ($hex as $i => $line)
        {
        echo sprintf('%6X',$offset).' : '.implode(' ', str_split($line,2)) . ' [' . $chars[$i] . ']' . $newline;
        $offset += $width;
        }
    }
    
    function Schreiben ($ID, $Wert){
        $AktuellerWert = GetValue($ID);
        if ($AktuellerWert<> $Wert){
          SetValue ($ID , $Wert);
        }
    }
?>

von Register Variable Debug:

unter Meldungen kommen diese Medungen
15.02.2017 06:54:35*| Register Variable*| Got a valid long/control packet start, but we need data to determine the length!
15.02.2017 06:54:35*| Register Variable*| Not a valid M-bus frame. Buffer von IPS wird vorsichtshalber gelöscht

mfg
pesensie