SMA Energymeter liefert einzelne, viel zu große Werte

Allgemeine Informationen zum Nachbau und zum Forum.
PV-Monitorung / PV Überwachung

Moderator: Ulrich

ksapp
Beiträge: 42
Registriert: Di 27. Jul 2021, 21:17
Hat sich bedankt: 4 Mal
Danksagung erhalten: 5 Mal
Kontaktdaten:

Re: SMA Energymeter liefert einzelne, viel zu große Werte

Beitrag von ksapp »

Hi, eine Lösung hab ich dazu noch nicht gefunden.
Gemäß dem was ich bisher gesehen habe, ist das Telegramm vom Aufbau immer gleich.
Demnach müsste es gehen, explizit die x-te Stelle im Telegramm abzufragen.
Mir ist allerdings nicht klar, ob es Ausnahmen gibt, wo das Telegramm dann anders aussieht und die Abfrage an einer fixen Stelle wieder einen falschen Wert liefert.

Gruß
Oliver
SMA Tripower 5.0 STP - SMA Energymeter - Raspberrby Pi Zero - LAN alles an einem Switch

Benutzeravatar
Ulrich
Administrator
Beiträge: 2878
Registriert: Sa 7. Nov 2015, 10:33
Wohnort: Essen
Hat sich bedankt: 32 Mal
Danksagung erhalten: 183 Mal
Kontaktdaten:

Re: SMA Energymeter liefert einzelne, viel zu große Werte

Beitrag von Ulrich »

Hallo Oliver,

super, deine Analyse! So wie es aussieht kommen zufällig Zahlenkonstellationen in den ersten 50 Bytes vor, nach denen danach gesucht wird.

Kannst Du bitte einmal folgendes prüfen:

Da, wo der php Befehl "strpos" benutzt wird die 0 mit 70 zu ersetzen. (In allen Zeilen)

Code: Alles auswählen

$aktuelleDaten["Wh_Bezug"]  = (hexdec(substr($Daten,strpos($Daten,"00010800",0)+8,16))/3600); 

=> strpos($Daten,"00010800",0)      =>  strpos($Daten,"00010800",70)

Damit würde das Programm erst nach den ersten 70 Zeichen anfangen zu suchen. Eventuell tritt das Problem dann nicht mehr auf.
Bitte gebe Bescheid, ob das hilft. Ich habe so ein Gerät nicht im Zugriff und kann es nicht testen.

70 ist jetzt grob geschätzt von mir. Das müsste man näher untersuchen, welcher Wert genau eingetragen werden muss.
--------------------------------------
Ulrich [Admin]

Benutzeravatar
Ulrich
Administrator
Beiträge: 2878
Registriert: Sa 7. Nov 2015, 10:33
Wohnort: Essen
Hat sich bedankt: 32 Mal
Danksagung erhalten: 183 Mal
Kontaktdaten:

Re: SMA Energymeter liefert einzelne, viel zu große Werte

Beitrag von Ulrich »

So müsste es ungefähr aussehen:

Code: Alles auswählen

  $Daten = bin2hex($buf);

  $aktuelleDaten["SMA"] = trim($funktionen->Hex2String(substr($Daten,0,8)));
  $aktuelleDaten["TAG0"] = substr($Daten,12,4);
  $aktuelleDaten["Gruppe"] = substr($Daten,16,8);
  $aktuelleDaten["Datenlaenge"] = hexdec(substr($Daten,24,4));
  $aktuelleDaten["SMA_NET_2"] = substr($Daten,28,4);
  $aktuelleDaten["Protokoll_ID"] = substr($Daten,32,4);
  $aktuelleDaten["Susy-ID"] = hexdec(substr($Daten,36,4));
  $aktuelleDaten["SerNo"] = hexdec(substr($Daten,40,8));
  $aktuelleDaten["Ticker_ms"] = hexdec(substr($Daten,48,8));
  // Ab 56 Zeichen
  $aktuelleDaten["Wh_Bezug"]  = (hexdec(substr($Daten,strpos($Daten,"00010800",56)+8,16))/3600);
  $aktuelleDaten["Wh_Einspeisung"]  = (hexdec(substr($Daten,strpos($Daten,"00020800",56)+8,16))/3600);
  $aktuelleDaten["PF_Leistung"]  = (hexdec(substr($Daten,strpos($Daten,"000d0400",56)+8,8))/1000);
  $aktuelleDaten["Frequenz"]  = round((hexdec(substr($Daten,strpos($Daten,"000e0400",56)+8,8))/1000),2);

  // Ab 310 Zeichen
  $aktuelleDaten["BezugPhase_R"]  = (hexdec(substr($Daten,strpos($Daten,"00150400",310)+8,8))/10);
  $aktuelleDaten["EinspeisungPhase_R"]  = (hexdec(substr($Daten,strpos($Daten,"00160400",310)+8,8))/10);
  $aktuelleDaten["AC_Leistung_R"]  = ((hexdec(substr($Daten,strpos($Daten,"00150400",310)+8,8))/10) - (hexdec(substr($Daten,strpos($Daten,"00160400",0)+8,8))/10));
  $aktuelleDaten["AC_Strom_R"]  = (hexdec(substr($Daten,strpos($Daten,"001f0400",310)+8,8))/1000);
  $aktuelleDaten["AC_Spannung_R"]  = round((hexdec(substr($Daten,strpos($Daten,"00200400",0)+8,8))/1000),2);
  $aktuelleDaten["PF_R"]  = (hexdec(substr($Daten,strpos($Daten,"00210400",310)+8,8))/1000);
  // Ab 560 Zeichen
  $aktuelleDaten["BezugPhase_S"]  = (hexdec(substr($Daten,strpos($Daten,"00290400",560)+8,8))/10);
  $aktuelleDaten["EinspeisungPhase_S"]  = (hexdec(substr($Daten,strpos($Daten,"002a0400",560)+8,8))/10);
  $aktuelleDaten["AC_Leistung_S"]  = ((hexdec(substr($Daten,strpos($Daten,"00290400",560)+8,8))/10) - (hexdec(substr($Daten,strpos($Daten,"002a0400",0)+8,8))/10));
  $aktuelleDaten["AC_Strom_S"]  = (hexdec(substr($Daten,strpos($Daten,"00330400",560)+8,8))/1000);
  $aktuelleDaten["AC_Spannung_S"]  = round((hexdec(substr($Daten,strpos($Daten,"00340400",560)+8,8))/1000),2);
  $aktuelleDaten["PF_S"]  = (hexdec(substr($Daten,strpos($Daten,"00350400",560)+8,8))/1000);
  // Ab 800 Zeichen
  $aktuelleDaten["BezugPhase_T"]  = (hexdec(substr($Daten,strpos($Daten,"003d0400",800)+8,8))/10);
  $aktuelleDaten["EinspeisungPhase_T"]  = (hexdec(substr($Daten,strpos($Daten,"003e0400",800)+8,8))/10);
  $aktuelleDaten["AC_Leistung_T"]  = ((hexdec(substr($Daten,strpos($Daten,"003d0400",800)+8,8))/10) - (hexdec(substr($Daten,strpos($Daten,"003e0400",0)+8,8))/10));
  $aktuelleDaten["AC_Strom_T"]  = (hexdec(substr($Daten,strpos($Daten,"00470400",800)+8,8))/1000);
  $aktuelleDaten["AC_Spannung_T"]  = round((hexdec(substr($Daten,strpos($Daten,"00480400",800)+8,8))/1000),2);
  $aktuelleDaten["PF_T"]  = (hexdec(substr($Daten,strpos($Daten,"00490400",800)+8,8))/1000);
--------------------------------------
Ulrich [Admin]

ksapp
Beiträge: 42
Registriert: Di 27. Jul 2021, 21:17
Hat sich bedankt: 4 Mal
Danksagung erhalten: 5 Mal
Kontaktdaten:

Re: SMA Energymeter liefert einzelne, viel zu große Werte

Beitrag von ksapp »

Hi,

Ich werde mir das die Tage nochmal angucken und melde mich dann.

Gruß
Oliver
SMA Tripower 5.0 STP - SMA Energymeter - Raspberrby Pi Zero - LAN alles an einem Switch

ksapp
Beiträge: 42
Registriert: Di 27. Jul 2021, 21:17
Hat sich bedankt: 4 Mal
Danksagung erhalten: 5 Mal
Kontaktdaten:

Re: SMA Energymeter liefert einzelne, viel zu große Werte

Beitrag von ksapp »

Hi,

wir haben das mal so wie oben von dir beschrieben eingebaut. Folgende Zeilen waren darunter noch enthalten, die wir sinngemäß angepasst haben.

Code: Alles auswählen

 //$aktuelleDaten["Bezug"]  = ((hexdec(substr($Daten,strpos($Daten,"00150400",0)+8,8))/10) + (hexdec(substr($Daten,strpos($Daten,"00290400",0)+8,8))/10) + (hexdec(substr($Daten,strpo$
  //$aktuelleDaten["Einspeisung"]  = ((hexdec(substr($Daten,strpos($Daten,"00160400",0)+8,8))/10) + (hexdec(substr($Daten,strpos($Daten,"002a0400",0)+8,8))/10) + (hexdec(substr($Daten$
  //$aktuelleDaten["AC_Strom"]  = ((hexdec(substr($Daten,strpos($Daten,"001f0400",0)+8,8))/1000) + (hexdec(substr($Daten,strpos($Daten,"00330400",0)+8,8))/1000) + (hexdec(substr($Date$

  $aktuelleDaten["Bezug"] = $aktuelleDaten["BezugPhase_R"] + $aktuelleDaten["BezugPhase_S"] + $aktuelleDaten["BezugPhase_T"];
  $aktuelleDaten["Einspeisung"]  = $aktuelleDaten["EinspeisungPhase_R"] + $aktuelleDaten["EinspeisungPhase_S"] + $aktuelleDaten["EinspeisungPhase_T"];
  $aktuelleDaten["AC_Strom"] = $aktuelleDaten["AC_Strom_R"] + $aktuelleDaten["AC_Strom_S"] + $aktuelleDaten["AC_Strom_T"];
Mal sehen, was passiert. Ich denke allerdings, das das Thema damit noch nicht 100% beseitigt ist.

Wenn zum Beispiel der Messwert der ersten Zeile:
$aktuelleDaten["Wh_Bezug"] = (hexdec(substr($Daten,strpos($Daten,"00010800",56)+8,16))/3600);

zufällig "00020800" in Hex ergibt, wird bei "Wh_Einspeisung" der falsche Wert eingetragen werden, weil diese Abfrage dann zuschlägt:

$aktuelleDaten["Wh_Einspeisung"] = (hexdec(substr($Daten,strpos($Daten,"00020800",56)+8,16))/3600);

Was spräche dagegen, das noch etwas genauer auszuzählen ?

Gruß
Oliver
SMA Tripower 5.0 STP - SMA Energymeter - Raspberrby Pi Zero - LAN alles an einem Switch

Benutzeravatar
Ulrich
Administrator
Beiträge: 2878
Registriert: Sa 7. Nov 2015, 10:33
Wohnort: Essen
Hat sich bedankt: 32 Mal
Danksagung erhalten: 183 Mal
Kontaktdaten:

Re: SMA Energymeter liefert einzelne, viel zu große Werte

Beitrag von Ulrich »

Hallo Oliver,

kannst Du gerne machen. Ich habe kein Gerät, dass ich es überprüfen könnte. Je genauer um so besser.
--------------------------------------
Ulrich [Admin]

ksapp
Beiträge: 42
Registriert: Di 27. Jul 2021, 21:17
Hat sich bedankt: 4 Mal
Danksagung erhalten: 5 Mal
Kontaktdaten:

Re: SMA Energymeter liefert einzelne, viel zu große Werte

Beitrag von ksapp »

Hi,

bisher läuft alles ohne Probleme. Der Debugger hat nicht mehr zugeschlagen.

So sieht es jetzt aus:

Code: Alles auswählen

  $aktuelleDaten["SMA"] = trim($funktionen->Hex2String(substr($Daten,0,8)));
  $aktuelleDaten["TAG0"] = substr($Daten,12,4);
  $aktuelleDaten["Gruppe"] = substr($Daten,16,8);
  $aktuelleDaten["Datenlaenge"] = hexdec(substr($Daten,24,4));
  $aktuelleDaten["SMA_NET_2"] = substr($Daten,28,4);
  $aktuelleDaten["Protokoll_ID"] = substr($Daten,32,4);
  $aktuelleDaten["Susy-ID"] = hexdec(substr($Daten,36,4));
  $aktuelleDaten["SerNo"] = hexdec(substr($Daten,40,8));
  $aktuelleDaten["Ticker_ms"] = hexdec(substr($Daten,48,8));

  $aktuelleDaten["Wh_Bezug"]  = (hexdec(substr($Daten,strpos($Daten,"00010800",72)+8,16))/3600);
  $aktuelleDaten["Wh_Einspeisung"]  = (hexdec(substr($Daten,strpos($Daten,"00020800",112)+8,16))/3600);
  $aktuelleDaten["PF_Leistung"]  = (hexdec(substr($Daten,strpos($Daten,"000d0400",296)+8,8))/1000);
  $aktuelleDaten["Frequenz"]  = round((hexdec(substr($Daten,strpos($Daten,"000e0400",312)+8,8))/1000),2); 

  $aktuelleDaten["BezugPhase_R"]  = (hexdec(substr($Daten,strpos($Daten,"00150400",312)+8,8))/10);
  $aktuelleDaten["EinspeisungPhase_R"]  = (hexdec(substr($Daten,strpos($Daten,"00160400",352)+8,8))/10);
  $aktuelleDaten["AC_Leistung_R"]  = ((hexdec(substr($Daten,strpos($Daten,"00150400",312)+8,8))/10) - (hexdec(substr($Daten,strpos($Daten,"00160400",352)+8,8))/10));
  $aktuelleDaten["AC_Strom_R"]  = (hexdec(substr($Daten,strpos($Daten,"001f0400",552)+8,8))/1000);
  $aktuelleDaten["AC_Spannung_R"]  = round((hexdec(substr($Daten,strpos($Daten,"00200400",568)+8,8))/1000),2);
  $aktuelleDaten["PF_R"]  = (hexdec(substr($Daten,strpos($Daten,"00210400",584)+8,8))/1000);

  $aktuelleDaten["BezugPhase_S"]  = (hexdec(substr($Daten,strpos($Daten,"00290400",600)+8,8))/10);
  $aktuelleDaten["EinspeisungPhase_S"]  = (hexdec(substr($Daten,strpos($Daten,"002a0400",640)+8,8))/10);
  $aktuelleDaten["AC_Leistung_S"]  = ((hexdec(substr($Daten,strpos($Daten,"00290400",600)+8,8))/10) - (hexdec(substr($Daten,strpos($Daten,"002a0400",640)+8,8))/10));
  $aktuelleDaten["AC_Strom_S"]  = (hexdec(substr($Daten,strpos($Daten,"00330400",840)+8,8))/1000);
  $aktuelleDaten["AC_Spannung_S"]  = round((hexdec(substr($Daten,strpos($Daten,"00340400",856)+8,8))/1000),2);
  $aktuelleDaten["PF_S"]  = (hexdec(substr($Daten,strpos($Daten,"00350400",872)+8,8))/1000);

  $aktuelleDaten["BezugPhase_T"]  = (hexdec(substr($Daten,strpos($Daten,"003d0400",888)+8,8))/10);
  $aktuelleDaten["EinspeisungPhase_T"]  = (hexdec(substr($Daten,strpos($Daten,"003e0400",928)+8,8))/10);
  $aktuelleDaten["AC_Leistung_T"]  = ((hexdec(substr($Daten,strpos($Daten,"003d0400",888)+8,8))/10) - (hexdec(substr($Daten,strpos($Daten,"003e0400",928)+8,8))/10));
  $aktuelleDaten["AC_Strom_T"]  = (hexdec(substr($Daten,strpos($Daten,"00470400",1128)+8,8))/1000);
  $aktuelleDaten["AC_Spannung_T"]  = round((hexdec(substr($Daten,strpos($Daten,"00480400",1144)+8,8))/1000),2);
  $aktuelleDaten["PF_T"]  = (hexdec(substr($Daten,strpos($Daten,"00490400",1160)+8,8))/1000);

  $Firmware  = substr($Daten,strpos($Daten,"007f0400",0)+8,8); // gibt es nicht im Protokoll
  $aktuelleDaten["Firmware"] = substr($Firmware,4,1).".".substr($Firmware,5,1).".".strtoupper(substr($Firmware,6,1)).".".substr($Firmware,7,1); // gibt es nicht im Protokoll

  $aktuelleDaten["AC_Leistung"]  = ($aktuelleDaten["AC_Leistung_R"] + $aktuelleDaten["AC_Leistung_S"] + $aktuelleDaten["AC_Leistung_T"]);
  $aktuelleDaten["GesamterLeistungsbedarf"]  = ($aktuelleDaten["Wh_Bezug"] + $aktuelleDaten["Wh_Einspeisung"]);

  //$aktuelleDaten["Bezug"]  = ((hexdec(substr($Daten,strpos($Daten,"00150400",0)+8,8))/10) + (hexdec(substr($Daten,strpos($Daten,"00290400",0)+8,8))/10) + (hexdec(substr($Daten,strpos($Daten,"003d0400",0)+8,8))/10));
  //$aktuelleDaten["Einspeisung"]  = ((hexdec(substr($Daten,strpos($Daten,"00160400",0)+8,8))/10) + (hexdec(substr($Daten,strpos($Daten,"002a0400",0)+8,8))/10) + (hexdec(substr($Daten,strpos($Daten,"003e0400",0)+8,8))/10));
  //$aktuelleDaten["AC_Strom"]  = ((hexdec(substr($Daten,strpos($Daten,"001f0400",0)+8,8))/1000) + (hexdec(substr($Daten,strpos($Daten,"00330400",0)+8,8))/1000) + (hexdec(substr($Daten,strpos($Daten,"00470400",0)+8,8))/1000));

  $aktuelleDaten["Bezug"] = $aktuelleDaten["BezugPhase_R"] + $aktuelleDaten["BezugPhase_S"] + $aktuelleDaten["BezugPhase_T"];
  $aktuelleDaten["Einspeisung"]  = $aktuelleDaten["EinspeisungPhase_R"] + $aktuelleDaten["EinspeisungPhase_S"] + $aktuelleDaten["EinspeisungPhase_T"];
  $aktuelleDaten["AC_Strom"] = $aktuelleDaten["AC_Strom_R"] + $aktuelleDaten["AC_Strom_S"] + $aktuelleDaten["AC_Strom_T"];
Viele Grüße
Oliver

P.S. - ich hänge die PHP zur Sicherheit nochmal an. Ab Zeile 190 sind die Sachen, die ich zum Debugging eingebaut hatte.
Dateianhänge
sma_energy.php
(17.95 KiB) 9-mal heruntergeladen
SMA Tripower 5.0 STP - SMA Energymeter - Raspberrby Pi Zero - LAN alles an einem Switch

Antworten