SMA Energymeter liefert einzelne, viel zu große Werte
Moderator: Ulrich
-
- Beiträge: 54
- Registriert: Di 27. Jul 2021, 21:17
- Hat sich bedankt: 5 Mal
- Danksagung erhalten: 7 Mal
Re: SMA Energymeter liefert einzelne, viel zu große Werte
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
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, ESP 32 für Erfassung der Vor- Rücklauf und Aussentemperatur.
- Ulrich
- Administrator
- Beiträge: 5587
- Registriert: Sa 7. Nov 2015, 10:33
- Wohnort: Essen
- Hat sich bedankt: 125 Mal
- Danksagung erhalten: 838 Mal
Re: SMA Energymeter liefert einzelne, viel zu große Werte
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)
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.
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 . . . . . . . . [Projekt Administrator]
Ulrich . . . . . . . . [Projekt Administrator]
- Ulrich
- Administrator
- Beiträge: 5587
- Registriert: Sa 7. Nov 2015, 10:33
- Wohnort: Essen
- Hat sich bedankt: 125 Mal
- Danksagung erhalten: 838 Mal
Re: SMA Energymeter liefert einzelne, viel zu große Werte
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 . . . . . . . . [Projekt Administrator]
Ulrich . . . . . . . . [Projekt Administrator]
-
- Beiträge: 54
- Registriert: Di 27. Jul 2021, 21:17
- Hat sich bedankt: 5 Mal
- Danksagung erhalten: 7 Mal
Re: SMA Energymeter liefert einzelne, viel zu große Werte
Hi,
Ich werde mir das die Tage nochmal angucken und melde mich dann.
Gruß
Oliver
Ich werde mir das die Tage nochmal angucken und melde mich dann.
Gruß
Oliver
SMA Tripower 5.0 STP - SMA Energymeter - Raspberrby Pi Zero, ESP 32 für Erfassung der Vor- Rücklauf und Aussentemperatur.
-
- Beiträge: 54
- Registriert: Di 27. Jul 2021, 21:17
- Hat sich bedankt: 5 Mal
- Danksagung erhalten: 7 Mal
Re: SMA Energymeter liefert einzelne, viel zu große Werte
Hi,
wir haben das mal so wie oben von dir beschrieben eingebaut. Folgende Zeilen waren darunter noch enthalten, die wir sinngemäß angepasst haben.
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
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"];
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, ESP 32 für Erfassung der Vor- Rücklauf und Aussentemperatur.
- Ulrich
- Administrator
- Beiträge: 5587
- Registriert: Sa 7. Nov 2015, 10:33
- Wohnort: Essen
- Hat sich bedankt: 125 Mal
- Danksagung erhalten: 838 Mal
Re: SMA Energymeter liefert einzelne, viel zu große Werte
Hallo Oliver,
kannst Du gerne machen. Ich habe kein Gerät, dass ich es überprüfen könnte. Je genauer um so besser.
kannst Du gerne machen. Ich habe kein Gerät, dass ich es überprüfen könnte. Je genauer um so besser.
-----------------------------------------------------
Ulrich . . . . . . . . [Projekt Administrator]
Ulrich . . . . . . . . [Projekt Administrator]
-
- Beiträge: 54
- Registriert: Di 27. Jul 2021, 21:17
- Hat sich bedankt: 5 Mal
- Danksagung erhalten: 7 Mal
Re: SMA Energymeter liefert einzelne, viel zu große Werte
Hi,
bisher läuft alles ohne Probleme. Der Debugger hat nicht mehr zugeschlagen.
So sieht es jetzt aus:
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.
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"];
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) 197-mal heruntergeladen
SMA Tripower 5.0 STP - SMA Energymeter - Raspberrby Pi Zero, ESP 32 für Erfassung der Vor- Rücklauf und Aussentemperatur.
Wer ist online?
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast