Sunny Home Manager 2.0 - Problem bei der Abfrage

Ich habe einen Sunny Home Manager 2 den ich gerne auslesen möchte.
Ich habe dazu den Beitrag aus dem Archiv genommen. sma-energy-meter
Da ich dort nix schreiben kann mach ich hier nun was neues auf, hoffe das so richtig.

Die IP des Gerätes habe ich ermittelt und mit 192.168.178.91/legal_notices.txt geprüft das die IP richtig ist.
Ich habe ein Multicast Socket angelegt mit dem Port 9522 und Aktiven Brodcast.
Daten erhalte ich auch aber nur mit einer Länge von 58.

09.02.2022, 09:57:28 | RECEIVED [192.168.178.91:9522] | 53 4D 41 00 00 04 02 A0 00 00 00 01 00 26 00 10 60 65 09 A0 FF FF FF FF FF FF 00 00 74 01 1B ED 56 B3 00 00 00 00 00 00 7F B8 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Die Auswertung per Register Variable und Script laufen aber die Daten sind nicht vorhanden bzw richtig. Ich hatte in dem Beitrag gesehen das die länge bei anderen über 600 ist also ist was falsch bei mir. Was kann das Problem sein?
Ich hoffe jemand hat das gleich schon mal lösen müssen und kann mir etwas helfen.

Vielen Dank im Vorraus, Gruß Daniel

1 „Gefällt mir“

Hi Daniel, zeig mal wie der Multicast Socket konfiguriert ist.
Ich hab den SHM2.0 auch bei mir laufen, evtl. kann ich dir helfen…

Also ich habe auch den SHM2.0 laufen. Ich kann auch unterstützen.

richimaint

image

Das ist die einstellung. Die .91 ist der Home Manager die .10 ist die Symbox.

Registervariable habe ich die beiden Skripte zum Testen genommen

<?PHP
declare(strict_types=1);

// OBIS Parameter
$list_sum   = []; //Summen
$list_sum['00010400'] = ['OBIS' => '0140', 'divisor' => 10, 'name' => 'Real Power +'];
$list_sum['00010800'] = ['OBIS' => '0180', 'divisor' => 3600000, 'name' => 'Counter Real Power +'];
$list_sum['00020400'] = ['OBIS' => '0240', 'divisor' => 10, 'name' => 'Real Power -'];
$list_sum['00020800'] = ['OBIS' => '0280', 'divisor' => 3600000, 'name' => 'Counter Real Power -'];
$list_sum['00030400'] = ['OBIS' => '0340', 'divisor' => 10, 'name' => 'Reactive Power +'];
$list_sum['00030800'] = ['OBIS' => '0380', 'divisor' => 3600000, 'name' => 'Counter ReReactive Power +'];
$list_sum['00040400'] = ['OBIS' => '0440', 'divisor' => 10, 'name' => 'Reactive Power -'];
$list_sum['00040800'] = ['OBIS' => '0480', 'divisor' => 3600000, 'name' => 'Counter ReReactive Power -'];
$list_sum['00090400'] = ['OBIS' => '0940', 'divisor' => 10, 'name' => 'Apparent Power +'];
$list_sum['00090800'] = ['OBIS' => '0980', 'divisor' => 3600000, 'name' => 'Counter Apparent Power +'];
$list_sum['000a0400'] = ['OBIS' => '1040', 'divisor' => 10, 'name' => 'Apparent Power -'];
$list_sum['000a0800'] = ['OBIS' => '1080', 'divisor' => 3600000, 'name' => 'Counter Apparent Power -'];
$list_sum['000d0400'] = ['OBIS' => '1340', 'divisor' => 1000, 'name' => 'Power Faktor'];
$list_sum['000e0400'] = ['OBIS' => '1440', 'divisor' => 1000, 'name' => 'Network Frequency'];

$list_l1   = []; //Phase 1
$list_l1['00150400'] = ['OBIS' => '2140', 'divisor' => 10, 'name' => 'Real Power +'];
$list_l1['00150800'] = ['OBIS' => '2180', 'divisor' => 3600000, 'name' => 'Counter Real Power +'];
$list_l1['00160400'] = ['OBIS' => '2240', 'divisor' => 10, 'name' => 'Real Power -'];
$list_l1['00160800'] = ['OBIS' => '2280', 'divisor' => 3600000, 'name' => 'Counter Real Power -'];
$list_l1['00170400'] = ['OBIS' => '2340', 'divisor' => 10, 'name' => 'Reactive Power +'];
$list_l1['00170800'] = ['OBIS' => '2380', 'divisor' => 3600000, 'name' => 'Counter ReReactive Power +'];
$list_l1['00180400'] = ['OBIS' => '2440', 'divisor' => 10, 'name' => 'Reactive Power -'];
$list_l1['00180800'] = ['OBIS' => '2480', 'divisor' => 3600000, 'name' => 'Counter ReReactive Power -'];
$list_l1['001d0400'] = ['OBIS' => '2940', 'divisor' => 10, 'name' => 'Apparent Power +'];
$list_l1['001d0800'] = ['OBIS' => '2980', 'divisor' => 3600000, 'name' => 'Counter Apparent Power +'];
$list_l1['001e0400'] = ['OBIS' => '3040', 'divisor' => 10, 'name' => 'Apparent Power -'];
$list_l1['001e0800'] = ['OBIS' => '3080', 'divisor' => 3600000, 'name' => 'Counter Apparent Power -'];
$list_l1['001f0400'] = ['OBIS' => '3140', 'divisor' => 1, 'name' => 'Power'];
$list_l1['00200400'] = ['OBIS' => '3240', 'divisor' => 1000, 'name' => 'Voltage'];
$list_l1['00210400'] = ['OBIS' => '3340', 'divisor' => 1000, 'name' => 'Network Frequency'];

$list_l2   = []; //Phase 2
$list_l2['00290400'] = ['OBIS' => '4140', 'divisor' => 10, 'name' => 'Real Power +'];
$list_l2['00290800'] = ['OBIS' => '4180', 'divisor' => 3600000, 'name' => 'Counter Real Power +'];
$list_l2['002a0400'] = ['OBIS' => '4240', 'divisor' => 10, 'name' => 'Real Power -'];
$list_l2['002a0800'] = ['OBIS' => '4280', 'divisor' => 3600000, 'name' => 'Counter Real Power -'];
$list_l2['002b0400'] = ['OBIS' => '4340', 'divisor' => 10, 'name' => 'Reactive Power +'];
$list_l2['002b0800'] = ['OBIS' => '4380', 'divisor' => 3600000, 'name' => 'Counter ReReactive Power +'];
$list_l2['002c0400'] = ['OBIS' => '4440', 'divisor' => 10, 'name' => 'Reactive Power -'];
$list_l2['002c0800'] = ['OBIS' => '4480', 'divisor' => 3600000, 'name' => 'Counter ReReactive Power -'];
$list_l2['00310400'] = ['OBIS' => '4940', 'divisor' => 10, 'name' => 'Apparent Power +'];
$list_l2['00310800'] = ['OBIS' => '4980', 'divisor' => 3600000, 'name' => 'Counter Apparent Power +'];
$list_l2['00320400'] = ['OBIS' => '5040', 'divisor' => 10, 'name' => 'Apparent Power -'];
$list_l2['00320800'] = ['OBIS' => '5080', 'divisor' => 3600000, 'name' => 'Counter Apparent Power -'];
$list_l2['00330400'] = ['OBIS' => '5140', 'divisor' => 1, 'name' => 'Power'];
$list_l2['00340400'] = ['OBIS' => '5240', 'divisor' => 1000, 'name' => 'Voltage'];
$list_l2['00350400'] = ['OBIS' => '5340', 'divisor' => 1000, 'name' => 'Network Frequency'];

$list_l3   = []; //Phase 3
$list_l3['003d0400'] = ['OBIS' => '4140', 'divisor' => 10, 'name' => 'Real Power +'];
$list_l3['003d0800'] = ['OBIS' => '4180', 'divisor' => 3600000, 'name' => 'Counter Real Power +'];
$list_l3['003e0400'] = ['OBIS' => '4240', 'divisor' => 10, 'name' => 'Real Power -'];
$list_l3['003e0800'] = ['OBIS' => '4280', 'divisor' => 3600000, 'name' => 'Counter Real Power -'];
$list_l3['003f0400'] = ['OBIS' => '4340', 'divisor' => 10, 'name' => 'Reactive Power +'];
$list_l3['003f0800'] = ['OBIS' => '4380', 'divisor' => 3600000, 'name' => 'Counter ReReactive Power +'];
$list_l3['00400400'] = ['OBIS' => '4440', 'divisor' => 10, 'name' => 'Reactive Power -'];
$list_l3['00400800'] = ['OBIS' => '4480', 'divisor' => 3600000, 'name' => 'Counter ReReactive Power -'];
$list_l3['00450400'] = ['OBIS' => '4940', 'divisor' => 10, 'name' => 'Apparent Power +'];
$list_l3['00450800'] = ['OBIS' => '4980', 'divisor' => 3600000, 'name' => 'Counter Apparent Power +'];
$list_l3['00460400'] = ['OBIS' => '5040', 'divisor' => 10, 'name' => 'Apparent Power -'];
$list_l3['00460800'] = ['OBIS' => '5080', 'divisor' => 3600000, 'name' => 'Counter Apparent Power -'];
$list_l3['00470400'] = ['OBIS' => '5140', 'divisor' => 1, 'name' => 'Power'];
$list_l3['00480400'] = ['OBIS' => '5240', 'divisor' => 1000, 'name' => 'Voltage'];
$list_l3['00490400'] = ['OBIS' => '5340', 'divisor' => 1000, 'name' => 'Network Frequency'];

if ($_IPS['SENDER'] === 'Execute'){
    //zum Testen
    $hraw = '534d4100000402a000000001024c001060690174b33a68d524a6a271000104000000000000010800000000005628897000020400000075be00020800000000037a39805000030400000000000003080000000000657b04c0000404000000093d0004080000000000436dbad00009040000000000000908000000000065e92c48000a04000000761b000a08000000000388d3e3f8000d0400000003e5000e04000000c359001504000000000000150800000000000deb6e9800160400000029d8001608000000000145ab1fd00017040000000000001708000000000020aa986000180400000003c700180800000000001e3635d0001d040000000000001d08000000000017db2560001e040000002a04001e0800000000014b33af58001f0400000012710020040000037ecc00210400000003e4002904000000000000290800000000003c4ae980002a040000002524002a0800000000010e795978002b040000000000002b0800000000002cedd9c0002c04000000023f002c08000000000012d341d800310400000000000031080000000000407691a80032040000002535003208000000000115096da0003304000000109a0034040000037fbc00350400000003e6003d040000000000003d0800000000001747a358003e0400000026c3003e080000000001316a7908003f040000000000003f0800000000002142e340004004000000033700400800000000001bc49530004504000000000000450800000000001fa4e6a000460400000026e5004608000000000136d71f6800470400000011340048040000037b7200490400000003e5900000000203055200000000';
} else {
    // Prepare data
    $hraw = bin2hex(RegVar_GetBuffer($_IPS['INSTANCE']) . $_IPS['VALUE']); // im Puffer der Instanz vorhandene Daten holen und um die letzten Werte ergänzen
}

//Zählerkennung
$offset = 0;
$len = 4;
//echo hexToStr(substr($hraw, $offset * 2, $len * 2)) . PHP_EOL;

//ProtokollID
$offset = 16;
$len = 2;
//echo (substr($hraw, $offset * 2, $len * 2)) . PHP_EOL;

//gruppe
$offset = 8;
$len = 2;
//echo (substr($hraw, $offset * 2, $len * 2)) . PHP_EOL;

//zaehlerkennung
$offset = 18;
$len = 6;
//echo (substr($hraw, $offset * 2, $len * 2)) . PHP_EOL;

//Messzeitpunkt
$offset = 24;
$len = 4;
//echo (substr($hraw, $offset * 2, $len * 2)) . PHP_EOL;

$offset += $len;
$finished = false;

while (!$finished){

    //obis Id
    $len = 4;
    $id = substr($hraw, $offset * 2, $len * 2);
    if ($id === '00000000'){
        $finished = true;
        continue;
    }
    $offset += $len;


    //obis Messwert
    $len = (int) substr($id, 2 * 2, 2); //die Länge entspricht der Messart (Byte 2)

    if (isset($list_sum[$id])){
        $value = substr($hraw, $offset * 2, $len * 2);
        $res_sum[$list_sum[$id]['name']] = base_convert(substr($hraw, $offset * 2, $len * 2), 16, 10) / $list_sum[$id]['divisor'];
    } elseif (isset($list_l1[$id])) {
        $value = substr($hraw, $offset * 2, $len * 2);
        $res_l1[$list_l1[$id]['name']] = base_convert(substr($hraw, $offset * 2, $len * 2), 16, 10) / $list_l1[$id]['divisor'];
    } elseif (isset($list_l2[$id])) {
        $value = substr($hraw, $offset * 2, $len * 2);
        $res_l2[$list_l2[$id]['name']] = base_convert(substr($hraw, $offset * 2, $len * 2), 16, 10) / $list_l2[$id]['divisor'];
    } elseif (isset($list_l3[$id])) {
        $value = substr($hraw, $offset * 2, $len * 2);
        $res_l3[$list_l3[$id]['name']] = base_convert(substr($hraw, $offset * 2, $len * 2), 16, 10) / $list_l3[$id]['divisor'];
    } elseif($id = '90000000') {
        $len = 4;
        $value = substr($hraw, $offset * 2, $len * 2);
        //echo sprintf('%s Softwareversion: %s', $id, $value) . PHP_EOL;
    } else {
        trigger_error ("$id unbekannt");
        $finished = true;
    }
    $offset += $len;

}

// zum Testen
if ($_IPS['SENDER'] === 'Execute'){

    print_r($res_sum);
    print_r($res_l1);
    print_r($res_l2);
    print_r($res_l3);
    return;
}
 SetValueFloat(50729,  $res_l1['Real Power +']);
//SetChangedValueFloat(50729, $res_l1['Real Power +']); //Bezug L1
//SetChangedValueFloat(55046, $res_l2['Real Power +']); //Bezug L2
//SetChangedValueFloat(59773, $res_l1['Real Power +']); //Bezug L3
//SetChangedValueFloat(13109, $res_sum['Real Power +']); //Bezug gesamt
//SetChangedValueFloat(17496, $res_sum['Counter Real Power +']); //Bezug Zähler

//SetChangedValueFloat(39349, $res_l1['Real Power -']); //Einspeisung L1
//SetChangedValueFloat(49089, $res_l2['Real Power -']); //Einspeisung L2
//SetChangedValueFloat(10996, $res_l3['Real Power -']); //Einspeisung L3
//SetChangedValueFloat(11435, $res_sum['Real Power -']); //Einspeisung gesamt
//SetChangedValueFloat(56489, $res_sum['Counter Real Power -']); //Einspeisung Zähler

//SetChangedValueFloat(22959, max(GetValueFloat(21200) - $res_sum['Real Power -'], 0)); //Eigenversorgung
//SetChangedValueFloat(59462, max(GetValueFloat(21200) + $res_sum['Real Power +'] - $res_sum['Real Power -'], 0)); //Verbrauch


function SetChangedValueFloat(int $id, float $value){
    if (GetValueFloat($id) !== $value){
        SetValueFloat($id, $value);
    }
}


function hexToStr($hex){
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2){
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}
<?

if ($_IPS["SENDER"] == "RegisterVariable")                               // über Register Var ausgeführt
{
    $Data  = RegVar_GetBuffer($_IPS["INSTANCE"]);                 // im Puffer der Instanz vorhandene Daten in $data kopieren
    $Data .= $_IPS["VALUE"];                                                        // neu empfangene Daten an $data anhängen
    $CRLF  = ",
";
    $HexData = bin2hex($Data);
   // SetValue(23057 /*[Energie Zähler\SMA Home Manager	xt]*/, substr($HexData,417, 16 ));

    //SetValue(15785 /*[Energie Zähler\SMA Home Manager\Bezug - Summe]*/,/*[Energie Zähler\SMA Home Manager\Bezug - Summe]*/(float)hexdec(substr($HexData,64, 8 ))/10);
    //SetValue(29836 /*[Energie Zähler\SMA Home Manager\Einspeisung - Summe]*/,(float)hexdec(substr($HexData,104, 8 ))/10);

    SetValue(50729,(float)hexdec(substr($HexData,320, 8 ))/10);
    SetValue(55046,(float)hexdec(substr($HexData,608, 8 ))/10-(float)hexdec(substr($HexData,648, 8 ))/10);
    SetValue(59773,(float)hexdec(substr($HexData,896, 8 ))/10);
	//SetValue(22869 /*[Energie Zähler\SMA Home Manager\Bezogene Energie]*/,(float)hexdec(substr($HexData,80, 16 ))/3600000);
    //SetValue(35980 /*[Energie Zähler\SMA Home Manager\Eingespeiste Energie]*/,(float)hexdec(substr($HexData,120, 16 ))/3600000);




       // SetValue(50729,(float)hexdec(substr($HexData,336, 8 ))/10);
   // SetValue(55046,(float)hexdec(substr($HexData,624, 8 ))/10);
   // SetValue(59773,(float)hexdec(substr($HexData,912, 8 ))/10);
   // SetValue(39349,(float)hexdec(substr($HexData,376, 8 ))/10);
   // SetValue(49089,(float)hexdec(substr($HexData,664, 8 ))/10);
   // SetValue(10996,(float)hexdec(substr($HexData,952, 8 ))/10);
   // SetValue(13109,(float)hexdec(substr($HexData,80, 16 ))/3600000);
   // SetValue(11435,(float)hexdec(substr($HexData,120, 16 ))/3600000);
}
?>


die Multicast Adresse ist 239.12.255.254

1 „Gefällt mir“

Das ist es nun kommen mehr Daten an :smiley:, welches Skript hast du für die Auswertung genommen?
Kannst du das eventuell reinstellen, da gab es auch so viele verschiedene.

Das 2. Skript

<?

if ($_IPS["SENDER"] == "RegisterVariable")                               // über Register Var ausgeführt
{
    $Data  = RegVar_GetBuffer($_IPS["INSTANCE"]);                 // im Puffer der Instanz vorhandene Daten in $data kopieren
    $Data .= $_IPS["VALUE"];                                                        // neu empfangene Daten an $data anhängen
    $CRLF  = ",
";
    $HexData = bin2hex($Data);
   // SetValue(23057 /*[Energie Zähler\SMA Home Manager	xt]*/, substr($HexData,417, 16 ));

    //SetValue(15785 /*[Energie Zähler\SMA Home Manager\Bezug - Summe]*/,/*[Energie Zähler\SMA Home Manager\Bezug - Summe]*/(float)hexdec(substr($HexData,64, 8 ))/10);
    //SetValue(29836 /*[Energie Zähler\SMA Home Manager\Einspeisung - Summe]*/,(float)hexdec(substr($HexData,104, 8 ))/10);
*
*
*
*

richimaint

1 „Gefällt mir“

Bei mir läuft das erste Skript. Kann da auch gerne helfen.

1 „Gefällt mir“

Danke das läuft nun alles super, ich habe noch eingebaut das der Multicast nur alle 10s aktiviert wird.

Noch mal vielen Dank

Das habe ich nun auch am laufen, ist super!

Hallo Bumaas,

ich habe ebenfalls ein SHM 2 in Betrieb und dein Skript in den letzten Tagen getestet. Vorneweg, Dankeschön für die Bereitstellung deines Skripts. Ich bin Programier- bzw. php-Laie und habe bisher nur zum Teil die Funktion der einzelnen Codezeilen durchblickt. Per Multicast kommen Daten an. In der Regel haben diese eine Länge von 608 Zeichen. Allerdings ist ca. alle 30s ein Datensatz mit 58 Zeichen dabei, welcher dann zu einer entsprechenden Fehlermeldung führt. Nach einer Weile wird das Skript dann auch nicht mehr ausgeführt.

Wenn ich die Fehlermeldung richtig verstehe, wird der Datensatz nicht richtig ausgewertet und gibt bereits den ersten Wert Bezug L1 nicht in der erwarteten Form als Float aus. Wenn ich es richtig verstanden habe fordert dies aber die codezeile declare(strict_types=1);.

Nach meiner Auffassung müsste ich somit eine Prüfung der Zeichenlänge im Skript ergänzen, so dass Datensätze mit nur z.B. 58 Zeichen, verworfen werden.
Könnte mir hier jemand mit den entsprechenden Codezeilen in bumaas Skript behilflich sein?

Auch das zweite Skript stellt den Dienst, vermutlich aufgrund der gleichen Ursache, nach einiger Zeit ein.

Bin für jede Hilfe dankbar.

Grüße,
chhub

Versuche es mal mit

if (strlen($hraw) < 600){
  return;
}

Hallo bumaas,

danke für die schnelle Rückmeldung und den Vorschlag.
Habe die Zeilen ins Skript eingefügt. Vor der if-Abfrage für die Ausgabe der Daten bei Start des Skripts aus der Verwaltungskonsole, d.h. also vor if ($_IPS[‚SENDER‘] === ’ Execute’). Ob die Position aus Programmierersicht sinnvoll ist, keine Ahnung? Damit ist die Fehlermeldung zumindest erstmal nicht wieder aufgetaucht. Werde mich wohl doch mit dem Thema php in Zukunft etwas mehr beschäftigen müssen. :slight_smile:
Danke Dir.

Grüße,
chhub

Vor dem If-Konstrukt ist es zu früh. Da wird $hraw ja erst ermittelt.

Also am besten hinter

$hraw = …

Habe es verschoben.
Werde nun versuchen die Funktion der anderen Zeilen aus dem Skript nach und nach zu verstehen.
Dankeschön.

Hallo,
ich habe gerade den SMA HM2 in mein Netz eingebunden.

Mit dem ersten der oberen Scripte kann ich schon mal super die meisten Werte auslesen.

Nur weiß ich nicht genau wie ich an den „Eigenverbrauch“ => in o.g. Script ID22959 an den wert von 21200 komme (was ist das für ein wert?). Genauso in der Scriptzeile darunter „Verbrauch“(59462) was steckt hinter der Variable 21200?

Danke
hardlog

Hier wird der Eigenverbrauch ermittelt :
Eigenverbrauch = AC Wirkleistung des Wechselrichters - Einspeisung gesamt

Darunter wird der Verbrauch ermittelt:
Verbrauch = AC Wirkleistung des Wechselrichters + Bezug gesamt - Einspeisung gesamt

Also hinter 21200 verbirgt sich der Leistung des Wechselrichters. Die kommt nicht vom HM2, sondern vom Wechselrichter.

Alles Klar,
Danke!

hardlog

Danke, auch bei mir funktioniert es :slight_smile:

Jedoch startet das Script alle Sekunden, ist das nicht zu viel für IPS?
Die Variablen werden alle 5 Sekunden vom Script her befüllt mit

if (time() % 5 != 0) return;

Kann ich das so einstellen, das das Script nur alle 5 Sekunden startet?

Magst du das finale Script Posten? :slight_smile: