76_SMAInverter.pm - Abfrage von SMA Wechselrichter

Begonnen von sct14675, 28 Juli 2016, 11:01:16

Vorheriges Thema - Nächstes Thema

300P

#1905
Hast du für die SMA-Geräte feste IP Inder Fritzbox vermerkt ?

Wenn nicht - dann ist es logisch das irgendwann einmal (bei Fritzboxwechsel / Neustart / Stromausfall etc.) die IP-Adresse(n) evtl. neu (anderslautend) vergeben werden und danach auch nicht mehr zu den in FHEM hinterlegten IP-Adressen passen.

Vorgehensweise:
1. In der Fritzbox (oder deinem evtl. zusätzlich vorhandenen DHCP-Server) die derzeitigen aktuellen Adressen als feste IP vermerken.

2. Schreib auf welche Feste-IP (Fixed-IP) in der Fritzbox welcher Seriennummer zugeordnet hast

3. Schau in die FHEM-Device deiner SMA-Geräte und trage statt der dort stehen IP in der Definition die "richtige" IP-Adresse zu dort im FHEM-Device hinterlegten passenden Seriennummer ein.

Wenn du dann alle 3 Geräte mit der richtigen IP in deinen zugehörigen FHEM-Device eingetragen hast müsste / wird es wieder klappen ;) denn die Verbindung der Wechselrichter und dem Homemanger zu SMA klappt ja sauber.
Deshalb gibt es keinen anderen Grund warum es in deinem Heimnetz nicht klappen sollte.


Zitat von: Vorhand am 19 Mai 2026, 16:16:20Home Manager 2 638 Ser: 190170xx38  Sunny Home Manager 2.0
Mit der IP....37 scheint aktuell der EM/HM erreichbar zu sein - das ist aber ein anderes FHEM-Modul für diesen Energymeter :)
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

Vorhand

Danke, die IP-Adressen sind bereits in der FritzBox fixiert.
Es gibt aber nur 2 LAN-Verbindungen, die .37 und die .42
Das SMAInverter Programm geht nur mit der .42 und der Seriennummer des Sunny-Island.
Mit der .37 geht es nicht.
Deine Aussage "Schau in die FHEM-Device deiner SMA-Geräte"... willst du damit sagen, dass das fhem-Programm für alle Geräte definiert werden muss?
Nach meiner Fritzbox haben nur 2 Geräte eine IP - wobei nur die .42 mit dem Sunny Island geht. Der hat leider keine PV-Leistung.
Wie kann ich den Sunny Tripower erreichen?
Viele Grüße
Raspi,Homatic,ESP,Fronius,KIA-PHEV,DHW300,Mi,Shelly

300P

#1907
Zitat von: Vorhand am 19 Mai 2026, 16:16:20Die Fritzbox zeigt im Heimnetz SMA1902xxxx38 unter der IP 192.168.xx.37
Hier sagst du IP.37 für den HM20 mit der SMAXXXXX38.
Wurde denn der Wert zudem eventuell statt aus dem HM20 mit dem FHEM-SMAEM-Nodul statt von dem Wechselrichter "STP9000TL" genommen ???

Zitat von: Vorhand am 19 Mai 2026, 16:16:20Mit 192.168.xx.42 funktioniert es - allerdings steht in den Readings INV_TYPE Sunny Island 4.4M. Wo die .42 herkommt ??
Hier das die IP .42 die des SI4.4M-11 428      Ser: 126104xx28  Sunny Island 4.4M (Batterie)

Der dritte (der STP9000) ist anscheinen verloren gegangen in der Fritzbox wenn du ihn nicht siehst.
Schalte ihn einmal von Hand für ein paar Minuten spannungsfrei bzw. komplett einmal aus. Aber erst wenn die die Sonne weg ist und keine Spannung an den DC-String anliegt......
 
Prüf dann nochmals in der FB welche IP der "STP 9000TL-20 902  Ser: 305099xx02  Sunny Tripower 9000TL-20" bekommt.
Eventuell siehst du im SMA-Portal in den Geräteparametern aber auch dessen zuletzt zugeordnete Ip ?!?


Oder schau einmal ins Handtuch wie du ihn per WLAN über seinen AP direkt erreichen kannst (letzte Möglichkeit)

Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

300P

Zitat von: Vorhand am 19 Mai 2026, 16:16:20Wie komme ich an das Signal mit der PV-Leistung der Anlage??

Alles geklärt ?
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

cwagner

Mir fällt auf, dass ich jeden Tag kurz nach 3 Uhr vielfach diese Perlmeldungen im Systemlog vorfinde:
2026.08.27 03:05:53 1: PERL WARNING: Argument "-" isn't numeric in division (/) at ./FHEM/76_SMAInverter.pm line 1391.
2026.08.27 03:05:53 1: PERL WARNING: Argument "-" isn't numeric in division (/) at ./FHEM/76_SMAInverter.pm line 1392.

In den entsprechenden Zeilen wird die Ladeinformation der Batterie aufgefrischt. Vermutlich macht (neuerdings?) der Inverter (in meinem Fall ein Tri-Power 6 SE) Housekeeping und die Variable ist zu dem Zeitpunkt Null?

Kann ich etwas tun? Klar, ich könnte das mit verbose=0 unsichtbar machen, das widerstrebt mir aber. Andererseits bin ich nicht fit genug, einen Patch vorzuschlagen, der den Fall abfängt.

Christian
320 Devices in MariaDB: Lambda WP an Ecolink-Speicher, FBH, Solarthermie, kontroll. Lüftung mit WRG und Erdwärmetauscher
HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM ESP3), MQTT2, Shelly, SMA (eC2, PV, HM, HS)
DOIF (Perl/uiTable), PID20,Micropelt IRTV, SolarForecast auf PI5

300P

Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

300P

#1911
Zitat von: cwagner am 27 August 2026, 11:18:23Kann ich etwas tun? Klar, ich könnte das mit verbose=0 unsichtbar machen, das widerstrebt mir aber. Andererseits bin ich nicht fit genug, einen Patch vorzuschlagen, der den Fall abfängt.

Welche Version nutzt du ???

In der "meinen" Version V2.30.3 vom 14.05.2026 steht da :
1391             }
1392        
Das kann nicht sein ;)


In der letzten (ganz oben auf der Seite) vom 7.12.25 von MAX:
1391                 push(@row_array, ($sc?"bat_loadtoday ".($inv_BAT_LOADTODAY/1000):"BAT_LOADTODAY ".$inv_BAT_LOADTODAY)."\n") if ($inv_BAT_LOADTODAY ne "-");
1392             }


und in der aus den FHEM-SVN:
1391                                 push(@row_array, ($sc?"bat_p_charge ".($inv_BAT_P_Charge/1000):"BAT_P_CHARGE ".($inv_BAT_P_Charge))."\n"); #TTT
1392                                 push(@row_array, ($sc?"bat_p_discharge ".($inv_BAT_P_Discharge/1000):"BAT_P_DISCHARGE ".($inv_BAT_P_Discharge))."\n"); #TTT

Ich gehe mal von Version der aus dem SVN aus:
#################################################################################################################
# $Id: 76_SMAInverter.pm 30019 2025-06-02 17:58:30Z MadMax $
#################################################################################################################
Da fehlt noch die Prüfung auf "-" ;)

Sag bitte Bescheid - Danke !



EDIT:
Angepasst / geändert
->>>MadMax ist seit Januar "verschollen"

Version aus dem SVN -> angepasst (Anlage)
Version 2.30.4 angepasst (Anlage)

Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

cwagner

#1912
Vielen Dank, ja, ich hatte die Version aus dem SVN. Ich werde jetzt noch schnell die angepasste Version einspielen und dann berichten.

Christian

Edit: Heute Nacht waren damit die Log-Einträge verschwunden. Ich habe dann gleich Deine neueste Version heruntergeladen, also die 76_SMAInverter V2.30.4.pm
320 Devices in MariaDB: Lambda WP an Ecolink-Speicher, FBH, Solarthermie, kontroll. Lüftung mit WRG und Erdwärmetauscher
HMCUL, 1-Wire (FT232RL ; DS2480B), EnOcean (TCM ESP3), MQTT2, Shelly, SMA (eC2, PV, HM, HS)
DOIF (Perl/uiTable), PID20,Micropelt IRTV, SolarForecast auf PI5

300P

PS:
Daran denken das ihr die Zugriffsrechte nach dem download / kopieren für FHEM richtig setzt und ab dann jetzt mi dem hinzufügen (vorher schauen was da schon steht / stand) :

attr global exclude_from_update 76_SMAInverter.pm

das "Überbraten" der Version mit der alten Version bei den "normalen" FHEM-Update vehindern müsst ;)
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

Panzerschrauber

Im Modul für den cosPhi finde ich folgende Zeile (2178):
if($size >= 230) {
          $inv_SPOT_CosPhi = unpack("l*", substr $data, 230, 4);
          if(($inv_SPOT_CosPhi eq -2147483648) || ($inv_SPOT_CosPhi eq 0xFFFFFFFF)) {$inv_SPOT_CosPhi = "-"; } else {$inv_SPOT_CosPhi = $inv_SPOT_CosPhi / 100; }
       }
       else
       {
         $inv_SPOT_CosPhi = "-";
       }
Mein sma stp8.0-3se-40 liefert beim de-aktivierter Blindleistungsverfahren 0xFFFFFFFF. Durch die unpack Funktion $inv_SPOT_CosPhi = unpack("l*", substr $data, 230, 4); wird 0xFFF... in eine -1 umgewandelt. Damit ist die nachfolgende if Abfrage nach 0xFFFF false und die -1 wird durch 100 geteilt und in FHEM angezeigt.
Könnte das bitte korrigiert werden? 0xFFFF... mit -1 ersetzen, damit bei einer -1 "-" angezeigt wird?
Modulversion bei mir: v2.30.1-s30019/2025-06-02

300P

Zitat von: Panzerschrauber am 03 September 2026, 10:50:05Könnte das bitte korrigiert werden?

Schau mal ob es passt.
Die Anpassung ist in der letzten Version von mir erfolgt.
So müsste es bei allen anderen (STPxx.xSE...) auch bei einer De-Aktivierung der Blindleistung ebenfalls passen wenn dort eine '-1' dabei rauskommt.
Bitte kurzes Echo ob es bei dir so okay ist - ich habe keinen STP8.0 o.ä. - Danke


.....
             ## Bug de-aktiviertes Blindleistungsverfahren siehe fhem.de/index.php?msg=1368531 ->>V2.30.5 300P
             if(($INVTYPE_NAME =~ /STP(5\.0|6\.0|8\.0|10\.0)SE/xs) && ($inv_SPOT_CosPhi eq -1))
             {$inv_SPOT_CosPhi = 0xFFFFFFFF; }
             ## Bug de-aktiviertes Blindleistungsverfahren siehe fhem.de/index.php?msg=1368531 ->>V2.30.5 300P
......




PS:
Daran denken das ihr die Zugriffsrechte nach dem download / kopieren für FHEM richtig setzt und ab dann jetzt mi dem hinzufügen (vorher schauen was da schon steht / stand) :

attr global exclude_from_update 76_SMAInverter.pm

das "Überbraten" der Version mit der alten Version bei den "normalen" FHEM-Update vehindern müsst ;)
Gruß
300P

FHEM 6.4|RPi|SMAEM|SMAInverter|SolarForecast| DbLog|DbRep|MariaDB|Buderus-MQTT_EMS|
Fritzbox|fhempy|JsonMod|HTTPMOD|Modbus ser+TCP| ESP32_AI_on_the_Edge|ESP32CAM usw.

Panzerschrauber

Habe gestern festgestellt, daß beim meinem stp8.0-3se-40 am 1.9 eine neue FW eingespielt wurde (4.8.39 R). Mit der alten FW Version hat der WR auf die Abfrage "sup_BatteryInfo_2" mit Adressbereich 0x00491E00 -> 0x00495DFF mit einem Datensatz mit der ID 0x495B geantwortet. Mit der neusten FW kommt eine neue ID 0x4949. Die sieht im RAW so aus:49490020e79e6aea240000ea240000ea240000ea24000001000000094a490020e79e6ae6000000e6000000e6000000e600000001000000094b490020e79e6a9001000090010000900100009001000001000000094c490020e79e6a0000000000000000000000000000000001000000094d490020e79e6a0000000000000000000000000000000001000000094e490020e79e6a0000000000000000000000000000000001000000094f490020e79e6a0000000000000000000000000000000001000000095b494020e79e6ad2000000d2000000d2000000d200000001000000095c490020e79e6a8ac500008ac500008ac500008ac5000001000000095d494020e79e6a000000000000000000000000000000000100000000000000
Den Inhalt konnte ich teilweise im Vergleich zur Anzeige auf der Weboberläche des WR ableiten:
ID     | Rohwert    | Decimal | Faktor | Wert       | Bedeutung
4949   | ea240000   |    9450 | /100   |    94.50 % | Round Trip Wirkungsgrad
494A   | e6000000   |     230 | /100   |     2.30 % | Selbstentladungsrate
494B   | 90010000   |     400 | /1     |   400      | Innenwiderstand (mOhm)
495B   | d2000000   |     210 | /10    |    21.0 °C | Batterietemperatur (BAT_TEMP)
495C   | 8ac50000   |   50570 | /100   |   505.70 V | Batteriespannung (BAT_UDC)
2495D. | 00000000   |       0 | /1000  |    0.000 A | BAT Lade-/Entladestrom (BAT_IDC)
494C-F | 00000000   |       0 | ?      |        ?   | ?
Unter allen Ids sind 4x Werte zu finden. Ich vermute, dass dass drei davon für WRs mit drei Batterieanschlüssen sind und der vierte die Summe davon. Da der STP8 nur einen Batterieanschluss hat sind bei mir alle vier Werte identisch. Für 494C-F konnte ich nicht herausfinden was dahinter steckt. Es gibt auf der Webseite des WR vier neue Felder: Zeit unter extremen Temperaturen (oberhalb der Grenze), Zeit unter extremen Temperaturen (unterhalb der Grenze), Ladezeit unter extremen Temperaturen (oberhalb der Grenze), Ladezeit unter extremen Temperaturen (unterhalb der Grenze), sind bei mir alle 0 und daher kann ich keine Aussage treffen ob diese dahinter stecken oder nicht. Der neue Datensatz hat eine Länge von 338 Bytes. Die bisherige Definition mit $hash->{HELPER}{MAXBYTES}              = 300; habe ich auf 1024 erweitert.
Hab jetzt lokal folgende Änderungen eingefügt, damit ich die neuen Werte und BAT_UDC und BAT_IDC wieder sehe und auch den Inhalt des neuen Elementes mitverfolgen kann (nicht schön aber erfüllt seinen Zweck):

if ($data_ID == 0x4949) {
   
    Log3 $name, 1, "$name - 0x4949 Container gefunden, size=$size Version=V0";
    Log3 $name, 1, sprintf("$name - StartAddr: 0x%08X, EndAddr: 0x%08X", $first, $last);

    my $raw_4949 = unpack("H*", substr($data, 55, $size - 55));
    Log3 $name, 1, "$name - 0x4949 RAW=$raw_4949";

    Log3 $name, 1, "$name - 0x4949 Batterie-Diagnosedaten, size=$size";

    my @values;

    # 4949 bis 494F und 495B bis 495D
    # Die Objekte liegen aktuell 28 Bytes auseinander
    for (my $pos = 55; $pos + 28 <= $size; $pos += 28) {

        my $sub_ID = unpack("v", substr($data, $pos, 2));

        next unless (
            ($sub_ID >= 0x4949 && $sub_ID <= 0x494F) ||
            ($sub_ID >= 0x495B && $sub_ID <= 0x495D)
        );

        my $raw_hex = unpack("H8", substr($data, $pos + 7, 4));

        push @values, {
            id      => $sub_ID,
            raw_hex => $raw_hex,
        };
    }

    # Kopfzeile
    Log3 $name, 1,
        "$name - ID   | Rohwert    | Decimal | Faktor | Wert       | Bedeutung";

    # Bekannte Werte
    foreach my $v (@values) {

        my $id  = $v->{id};
        my $hex = $v->{raw_hex};

        if ($id == 0x4949) {

            my $dec = unpack("V", pack("H*", $hex));

            Log3 $name, 1, sprintf(
                "$name - %-4s | %-10s | %7d | %-6s | %8.2f %% | %s",
                "4949",
                $hex,
                $dec,
                "/100",
                $dec / 100,
                "Round Trip Wirkungsgrad"
            );
            $inv_BAT_ROUND_TRIP_EFFICIENCY = $dec/100;
        }

        elsif ($id == 0x494A) {

            my $dec = unpack("V", pack("H*", $hex));

            Log3 $name, 1, sprintf(
                "$name - %-4s | %-10s | %7d | %-6s | %8.2f %% | %s",
                "494A",
                $hex,
                $dec,
                "/100",
                $dec / 100,
                "Selbstentladungsrate"
            );
            $inv_BAT_SELF_DISCHARGE_RATE = $dec/100;
        }

        elsif ($id == 0x494B) {

            my $dec = unpack("V", pack("H*", $hex));

            Log3 $name, 1, sprintf(
                "$name - %-4s | %-10s | %7d | %-6s | %8d   | %s",
                "494B",
                $hex,
                $dec,
                "/1",
                $dec,
                "Innenwiderstand (mOhm)"
            );
            $inv_BAT_INTERNAL_RESISTANCE = $dec/1000;
        }

        elsif ($id == 0x495B) {

            my $dec = unpack("V", pack("H*", $hex));

            Log3 $name, 1, sprintf(
                "$name - %-4s | %-10s | %7d | %-6s | %8.1f °C | %s",
                "495B",
                $hex,
                $dec,
                "/10",
                $dec / 10,
                "Batterietemperatur"
            );
            $inv_BAT_TEMP = $dec / 10;
        }

        elsif ($id == 0x495C) {

            my $dec = unpack("V", pack("H*", $hex));

            Log3 $name, 1, sprintf(
                "$name - %-4s | %-10s | %7d | %-6s | %8.2f V | %s",
                "495C",
                $hex,
                $dec,
                "/100",
                $dec / 100,
                "Batteriespannung"
            );
            $inv_BAT_UDC = $dec / 100;
        }

        elsif ($id == 0x495D) {

            my $dec = unpack("l", pack("H*", $hex));

            Log3 $name, 1, sprintf(
                "$name - %-4s | %-10s | %7d | %-6s | %8.3f A | %s",
                "495D",
                $hex,
                $dec,
                "/1000",
                $dec / 1000,
                "Lade-/Entladestrom"
            );
            $inv_BAT_IDC = $dec / 1000;
        }
    }

    # ------------------------------------------------------------
    # 494C bis 494F
    # ------------------------------------------------------------

    my @unknown;

    foreach my $v (@values) {

        if ($v->{id} >= 0x494C && $v->{id} <= 0x494F) {
            push @unknown, $v;
        }
    }

    # Prüfen, ob alle unbekannten Werte 0 sind
    my $all_zero = 1;

    foreach my $v (@unknown) {

        my $dec = unpack("V", pack("H*", $v->{raw_hex}));

        if ($dec != 0) {
            $all_zero = 0;
            last;
        }
    }

    if ($all_zero) {

        Log3 $name, 1,
            "$name - 494C-F | 00000000   |       0 | ?      |        ? | ?";

    }
    else {

        foreach my $v (@unknown) {

            my $dec = unpack("V", pack("H*", $v->{raw_hex}));

            Log3 $name, 1, sprintf(
                "$name - %-4s | %-10s | %7d | %-6s | %8s | %s",
                sprintf("%04X", $v->{id}),
                $v->{raw_hex},
                $dec,
                "?",
                "?",
                "?"
            );
        }
    }
    return (1,$inv_BAT_TEMP,$inv_BAT_UDC,$inv_BAT_IDC,$inv_BAT_ROUND_TRIP_EFFICIENCY,$inv_BAT_INTERNAL_RESISTANCE,$inv_BAT_SELF_DISCHARGE_RATE,$inv_susyid,$inv_serial);
}
Die Abfrage für "sup_BatteryInfo_2" habe ich entsprechend erweitert, dass die neuen bekannten Werte zurückgegeben werden können.


Panzerschrauber

Zitat von: 300P am 03 September 2026, 20:39:31
Zitat von: Panzerschrauber am 03 September 2026, 10:50:05Könnte das bitte korrigiert werden?

Schau mal ob es passt.
Die Anpassung ist in der letzten Version von mir erfolgt.
So müsste es bei allen anderen (STPxx.xSE...) auch bei einer De-Aktivierung der Blindleistung ebenfalls passen wenn dort eine '-1' dabei rauskommt.
Bitte kurzes Echo ob es bei dir so okay ist - ich habe keinen STP8.0 o.ä. - Danke

Hab es getestet, mit der Korrektur kommt weiterhin ein -1.
Habe dann die if Abfrage if(($inv_SPOT_CosPhi eq -2147483648) || ($inv_SPOT_CosPhi eq 0xFFFFFFFF)) mit if(($inv_SPOT_CosPhi == -2147483648) || ($inv_SPOT_CosPhi == 0xFFFFFFFF)) ersetzt
Dann geht es.
Warum nicht "eq" mit == und ($inv_SPOT_CosPhi == 0xFFFFFFFF) mit ($inv_SPOT_CosPhi == -1) ersetzen?
Dann könnte die Änderung mit
## Bug de-aktiviertes Blindleistungsverfahren siehe fhem.de/index.php?msg=1368531 ->>V2.30.5 300P
             if(($INVTYPE_NAME =~ /STP(5\.0|6\.0|8\.0|10\.0)SE/xs) && ($inv_SPOT_CosPhi eq -1))
             {$inv_SPOT_CosPhi = 0xFFFFFFFF; }
             ## Bug de-aktiviertes Blindleistungsverfahren siehe fhem.de/index.php?msg=1368531 ->>V2.30.5 300P
wieder gelöscht werden.