Daten vom Sunny Portal auslesen

Hi Michl
So siehts in Homematic aus
Diese Systemvariablen werden dann in Symcon angezeigt


Schönen Gruß
Egon

Vielen Dank,
sieht gut aus. Ich bin am Überlegen ob ich die API zum Abrufen der Daten ( SMA Live API ) verwenden soll? Diese sind jedoch nicht kostenlos :-/
Problem Nr.2 ist das ich mich mit der Programmierung der API nicht auskenne.

Wie oft aktualisierst du die Werte in Homematic?

Hi Michl
Alle 1 Min.
Schönen Gruß :smiley:
Egon

Schau dir mal den Thread den Bumaas verlinkt hat an!

Mit einem einfachem UDP Socket und dem Script kannst du vom Home Manager 2 die Daten per Multicast geliefert bekommen. Funktioniert einwandfrei, ist unabhängig vom Internet und muss nicht selbst abgefragt werden sondern wird vom Home Manager sowieso alle x Sekunden gesendet.

Hab ich mir bereits angesehen.
Das mit den ganzen Scripten, da hab ich ehrlich gesagt keinen Überblick :slight_smile:

Schritt 1 Anlegen des Multicast oder UDP Socket?
Schritt 2 register Variable
Schritt 3 ??? ( Scripte )

Moin,

das mit den Registervariablen muss man auch erst einmal machen, um es zu verinnerlichen.
Hier ist der Datenfluss schön mit einem Bild dokumentiert: RegisterVariable — IP-Symcon :: Automatisierungssoftware

So sollte es klappen:

  1. Multicast Socket anlegen.
    So konfigurieren:
    Host=IP vom SMA HomeManager2 / Sende-Port=9522 / Empf.Host=SymconIP / Empf.Port=9522 / Multicast=239.12.255.254
  2. RegisterVariable anlegen
    Als Gateway den MulticastSocket auswählen
    Als Ziel ein neues Script eintragen
  3. Script wie verlinkt füllen.
  4. Variablen anlegen und Id’s im Script unten anpassen.

Anbei noch mal Bilder von meiner Konfiguration.

Viel Erfolg
Philip

Script:

<?
declare(strict_types=1);


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

$type = "PQSIUC";
$part="HSL";
   

// 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 = '534D4100000402A000000001024C001060690174B3950F31AF20A0FF0001040000001DF400010800000000000C030E8800020400000000000002080000000000000953D0000304000000000000030800000000000001194000040400000011FF000408000000000007772A4800090400000022F100090800000000000EEB38A0000A040000000000000A08000000000000A514A0000D040000000359000E04000000C33E0015040000000BF30015080000000000065043C0001604000000000000160800000000000081805800170400000000000017080000000000000273300018040000000922001808000000000003DFE960001D040000000F0A001D08000000000007927FC8001E040000000000001E08000000000000AC7538001F0400000007330020040000039460002104000000031B0029040000000ECE002908000000000004BCE838002A040000000000002A0800000000000097F248002B040000000000002B080000000000000872D0002C040000000860002C08000000000002F287B0003104000000110200310800000000000602F8680032040000000000003208000000000000B9433000330400000007B90034040000038CAB0035040000000366003D040000000333003D0800000000000205FFF8003E040000000000003E08000000000000000000003F040000000000003F0800000000000002D870004004000000007D004008000000000000B15E68004504000000033D0045080000000000024554A00046040000000000004608000000000000000000004704000000018E00480400000393FE00490400000003DC900000000207055200000000';
    $hraw = '534d4100000402a000000001024c001060690174b38523f3ef157d79000104000000002000010800000000007ec294c00002040000000000000208000000000001ef88680003040000000000000308000000000007cfa088000404000000103f00040800000000004ef345f0000904000000103f0009080000000000a0cdff28000a040000000000000a08000000000006e7a530000d040000000008000e04000000c3750015040000000000001508000000000057047a4800160400000010520016080000000000046cac880017040000000000001708000000000007b2e30800180400000006ff00180800000000002c8a99a0001d040000000000001d080000000000686d4350001e0400000011c2001e08000000000005919a38001f04000000088300200400000377d900210400000003970029040000000f3e00290800000000002e897848002a040000000000002a08000000000017061960002b040000000000002b08000000000004fe88b0002c040000000829002c0800000000001f78cea8003104000000114a00310800000000003ce0f26800320400000000000032080000000000197b359000330400000007e700340400000386e60035040000000372003d040000000134003d08000000000012b7dfb0003e040000000000003e08000000000000000000003f040000000000003f080000000000001c14c00040040000000117004008000000000007edbd98004504000000019f004508000000000015c1fc6800460400000000000046080000000000000000000047040000000102004804000003856700490400000002e5900000000208055200000000';
} 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
}

//echo $hraw;

if (strlen($hraw) < 500) return;
//Zählerkennung
$offset = 0;
$len = 4;
//echo "Zählerkennung: " . hexToStr(substr($hraw, $offset * 2, $len * 2)) . PHP_EOL;

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

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

//zaehlerkennung
$offset = 18;
$len = 6;
//echo "Zählerkennung2: " . (substr($hraw, $offset * 2, $len * 2)) . PHP_EOL;

//Messzeitpunkt
$offset = 24;
$len = 4;
//echo "Messzeitpunkt: " . (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'){
        if ($_IPS['SENDER'] === 'Execute'){ echo PHP_EOL . " ende mit Id: " . $id; }
        $finished = true;
        continue;
    }
    $offset += $len;

if ($_IPS['SENDER'] === 'Execute'){
    echo PHP_EOL . "Id: " . $id;
}
    //obis Messwert
    $len = (int) substr($id, 2 * 2, 2); //die Länge entspricht der Messart (Byte 2)

    if (isset($list_sum[strtoupper($id)])){
        $value = substr($hraw, $offset * 2, $len * 2);
        $res_sum[$list_sum[strtoupper($id)]['name']] = base_convert(substr($hraw, $offset * 2, $len * 2), 16, 10) / $list_sum[strtoupper($id)]['divisor'];
    } elseif (isset($list_l1[strtoupper($id)])) {
        $value = substr($hraw, $offset * 2, $len * 2);
        $res_l1[$list_l1[strtoupper($id)]['name']] = base_convert(substr($hraw, $offset * 2, $len * 2), 16, 10) / $list_l1[strtoupper($id)]['divisor'];
    } elseif (isset($list_l2[strtoupper($id)])) {
        $value = substr($hraw, $offset * 2, $len * 2);
        $res_l2[$list_l2[strtoupper($id)]['name']] = base_convert(substr($hraw, $offset * 2, $len * 2), 16, 10) / $list_l2[strtoupper($id)]['divisor'];
    } elseif (isset($list_l3[strtoupper($id)])) {
        $value = substr($hraw, $offset * 2, $len * 2);
        $res_l3[$list_l3[strtoupper($id)]['name']] = base_convert(substr($hraw, $offset * 2, $len * 2), 16, 10) / $list_l3[strtoupper($id)]['divisor'];
    } elseif($id = '90000000') {
        $len = 4;
        $value = substr($hraw, $offset * 2, $len * 2);
        //echo sprintf('%s Softwareversion: %s', $id, $value) . PHP_EOL;
    } else {
        //echo "id unbekannt";
        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;
}

SetChangedValueFloat(23831, $res_l1['Real Power +']); //Bezug L1
SetChangedValueFloat(56797, $res_l2['Real Power +']); //Bezug L2
SetChangedValueFloat(14024, $res_l3['Real Power +']); //Bezug L3
SetChangedValueFloat(17249, $res_sum['Real Power +']); //Bezug gesamt
SetChangedValueFloat(19956, $res_sum['Counter Real Power +']); //Bezug Zähler

SetChangedValueFloat(36557, $res_l1['Real Power -']); //Einspeisung L1
SetChangedValueFloat(15632, $res_l2['Real Power -']); //Einspeisung L2
SetChangedValueFloat(49826, $res_l3['Real Power -']); //Einspeisung L3
SetChangedValueFloat(45089, $res_sum['Real Power -']); //Einspeisung gesamt
SetChangedValueFloat(53906, $res_sum['Counter Real Power -']); //Einspeisung Zähler

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

function SetChangedValueFloat(int $id, float $value){
   // echo $id . "  " . $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;
}

Vielen Danke für die Ausführliche Beschreibung :slight_smile:
Ich habe es soweit das ich die Werte nun abrufen kann.

Hätte noch einige Fragen an Dich:
Die Werte weden im Sekundentakt ausgelesen, ist das für das IPS System nicht zu viel?
Hab eine Symbox am laufen.

Was macht dieses Script genau:

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

Kann ich anhand dessen den Eigenverbrauch auslesen?

Der Wert Bezug gesamt, ist der Wert der tatsächlich vom EVU gezogen wird ( der PV eigenverbrauch ist dabei schon abgezogen ) ?

Auch ist das so beim Wert Einspeisung gesamt? PV Anlage zb. 1000 Watt, Eigenverbrauch 500 Watt, Einspeisung gesamt 500 Watt

Hmm, ich logge auch die beiden Variablen Bezugszähler und Einspeisezähler.

Bei deinem Script die Variablen:
53906
19956

Ich habe hierbei extrem hohe Werte??
Weit über 100 Kwh?

Muss ich hierbei was beachten?

Die 5 Zeile im Script if (time() % 5 != 0) return; sorgt dafür, dass nur alle 5 Sekunden ausgewertet wird und ansonsten das Script direkt wieder beendet wird. Hier kannst du auch längere Zeiten eintragen.:

Nix, da die Zeilen auskommentiert sind mit // :wink:

Korrekt. Angabe erfolgt in Watt.

Ebenfalls korrekt. Das ist die aktuelle Einspeisung in Watt.

Das müssten die Summen seit der Inbetriebnahme des HM2 sein in Wh.

Den tatsächlichen Eigenverbrauch musst du natürlich ausrechnen aus den Werten von HM2 und dem Wechselrichter.
ZB: Wechselrichter-AC Wirkleistung - HM2-Einspeisung = Direkter-Eigenverbrauch
Wenn du eine Batterie dabei hast, dann muss noch die Ladung/Entladung beachtet werden.

Blockzitat
Das müssten die Summen seit der Inbetriebnahme des HM2 sein in Wh.

Ok, muss ich diese noch umrechnen? Von Wh in Kwh?
Ich möchte den Wert in IPS Loggen, bzw. habe ich das gemacht, der Wert stimmt jedoch nicht :slight_smile:
Auch wenn ich den Wert durch 1000 teile passt dieser nicht mit dem Tageswert vom Sunny Portal überein?
Z.B.: Netzbezug Sunny Portal 3303Wh
Netzzähler IPS ( geloggt ) 11900 Wh

Uii, jetzt wird es sehr Kompliziert. Ich habe einen Sunny Boy WR den Lese ich mit ModBus aus.
Einen Sunny Boy Storage habe ich auch noch, auch diese Werte Lese ich mit Modbus aus.

Ich habe es mal aktiviert, jedoch werden die Werte nicht gefüllt.

Ich möchte gerne einen SMA Energy Meter ins Netz dazu hängen. Diesen möchte ich dann auch auslesen, müsste dann ebenfalls funktionieren?

Ich wollte gerade auch den SMA Energie Meter auslesen, leider funktioniert das nicht???
Gibt es da etwas zu beachten?

Den Multicast kann ich ja nur einmal vergeben, auch den Ausleseport 9522 für den Speedwire Port?

Habe beide Systeme im Netz.
1xHM 2
1xEM für Balkon Kraftwerk.

Danke für die Info

Hallo zusammen,
funktioniert das noch?
Ich habe alles so eingegeben, die Uhrzeiten werden auch aktualisiert aber die Werte bleiben alle auf Null.
VG
Norman

welche Hardware hast du denn ?

Hallo!
Ich habe eine Sunny Webbox.

Hallo zusammen hat jemand ein Vielleicht ein system am Laufen was die Sunny Webbox auslesen kann ?

ich wollte eigentlich eine neues Thema dafür erstellen, geht aber nicht

Ja, unter Technik geht das nicht, du muss die passende Unterkategorie auswählen :banghead:

Moin Moin,

jemand eine Idee warum ich diese Warnmeldung im Log erhalte ? Die Werte passen alle, welche das Script so ausgibt.

19.11.2023, 10:59:10 | Register Variable    | 
Notice: Undefined variable: res_l1 in /var/lib/symcon/scripts/57184.ips.php on line 165

Notice: Trying to access array offset on value of type null in /var/lib/symcon/scripts/57184.ips.php on line 165

Fatal error: Uncaught TypeError: Argument 2 passed to SetChangedValueFloat() must be of the type float, null given, called in /var/lib/symcon/scripts/57184.ips.php on line 165 and defined in /var/lib/symcon/scripts/57184.ips.php:180
Stack trace:
#0 /var/lib/symcon/scripts/57184.ips.php(165): SetChangedValueFloat(33156, NULL)
#1 {main}
  thrown in /var/lib/symcon/scripts/57184.ips.php on line 180

Zeile 165:

SetChangedValueFloat(33156, $res_l1['Real Power +']); //Bezug L1

Zeile 180:

function SetChangedValueFloat(int $id, float $value){

Danke Gruß Zeppi

Steht doch eigentlich da:
in 165 kennt er die Variable $res_l1 nicht, wo immer die auch definiert sein mag. Das zweite in 180 ist ein Folgefehler, denn wenn die Variable (oder der angesprochene Key nicht existiert ist der Wert NULL, die Funktion will aber ein Float haben

Tommi

Ich vermute definiert ist sie hier: (da es nicht viel mehr Stellen im Script dazu gibt)

 $res_l1[$list_l1[$id]['name']] = base_convert(substr($hraw, $offset * 2, $len * 2), 16, 10) / $list_l1[$id]['divisor'];

Das Ganze kommt ja von weiter oben hier im Beitrag von diesem Script

Das komische ist aber ja, die Variablen werden alle gefüllt und für mich funktioniert alles soweit. Nur diese Meldung im Log nervt halt.