Also ich finde in deiner Doku keine Obis Nummer bezogen auf L1-L3, das Script selbst ist ja sehr komplex.
Vielleicht kennt sich ja wer aus damit
Danke:)
<?php
$IDEnergieAP = 35173;//0403 (Energie A+ Obis 1.8.0) [kWh]
$IDEnergieAM = 24712;//04833C (Energie A- Obis 2.8.0)[kWh]
$IDEnergieRP = 23687;//8410FB8273 (Energie R+ Obis 3.8.1)[kvarh]
$IDEnergieRM = 35022;//8410FB82F33C (Energie R- Obis 4.8.1)[kvarh]
$IDWirkleistungPP = 38134;//042B (Wirkleistung P+ Obis 1.7.0)kW
$IDWirkleistungPM = 42238;//04AB3C (Wirkleistung P- Obis 2.7.0)kW
$IDBlindleistungQP = 44895;//04FB14 (Blindleistung Q+ Obis 3.7.0)kvar
$IDBlindleistungQM = 18298;//04FB943C (Blindleistung Q- Obis 4.7.0)kvar
$IDInkasso = 24414;//0483FF04 (Inkasso Obis 1.128.0 ) kWh
$IDRegistervariable = 20211;
$key_hex= "xxxxxx";
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\x30\x16"){
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");
}
$iv = pack("C*", $ManufacCode1, $ManufacCode2, 0 , 0 , 0 , 0 , $Version , $DeviceType , $AcessNr , $AcessNr, $AcessNr, $AcessNr, $AcessNr, $AcessNr, $AcessNr, $AcessNr);
$decryptedData = openssl_decrypt(base64_encode($encryptedData), 'aes-128-cbc', $key, OPENSSL_ZERO_PADDING, $iv);
$encryptedData_Kontrolle = base64_decode(openssl_encrypt($decryptedData, 'aes-128-cbc', $key, OPENSSL_ZERO_PADDING, $iv));
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);
}
}
?>