Erweiterung: 19_Revolt.pm

Begonnen von mumpitzstuff, 11 Mai 2017, 22:56:46

Vorheriges Thema - Nächstes Thema

sash.sc

#15
Lasse erst einmal die Anführungszeichen bei der 10.0 weg.

DOELSE brauchst du auch nicht.

Dann probiere mal aus.

Hier meine einfache Definition


defmod WaMa_fertig DOIF ([WaMa:power] < 5)


Habe noch das wait Attribut gesetzt mit 240:600

Heißt das das Reading Power für 4 Minuten unter 5 Watt sein muss, dann wird die Meldung ausgelöst. Und die 10 Minuten über 5 Watt wenn die Maschine läuft.

Gruß Sascha

Gesendet von meinem E6653 mit Tapatalk
Raspi 4B+ Bullseye ;LaCrosse; HomeMatic; MapleCUL; ZigBee; Signalduino ESP32 ; Shellys; MQTT2; Grafana mit Influxdb

misux

Zitat von: sash.sc am 17 Mai 2018, 18:34:41
Lasse erst einmal die Anführungszeichen bei der 10.0 weg.

DOELSE brauchst du auch nicht.

Dann probiere mal aus.

Hier meine einfache Definition


defmod WaMa_fertig DOIF ([WaMa:power] < 5)


Habe noch das wait Attribut gesetzt mit 240:600

Heißt das das Reading Power für 4 Minuten unter 5 Watt sein muss, dann wird die Meldung ausgelöst. Und die 10 Minuten über 5 Watt wenn die Maschine läuft.

Gruß Sascha

Gesendet von meinem E6653 mit Tapatalk

OKAY, vielen Dank erstmal! Bin gespannt!

yoda_gh

Hallo mumpitzstuff!

Ich hatte mit Deiner Version von 19_Revolt.pm aus dem initialen Post in der letzten Woche zweimal einen FHEM-Totalabsturz mit

Illegal division by zero at ./FHEM/19_Revolt.pm line 115.

Die einzige Division, die ich in der Zeile (bzw. in der Fortsetzung in der nächsten Zeile) sehe, ist die hier:

($power / $voltage / $pf) > 0.00999

Bei $pf stellst Du direkt drüber sicher, dass das nicht 0 ist, also wird wohl $voltage schuld sein. Mein Vorschlag:


--- /root/19_Revolt.pm 2018-05-11 20:10:49.531467823 +0200
+++ /opt/fhem/FHEM/19_Revolt.pm 2018-05-17 20:36:58.388468523 +0200
@@ -112,7 +112,7 @@
   if (0 == $pf) {
     $pf = 0.0001;
   }
-  if (($freq > 55) || ($power > 3650) || ($current > 16) ||
+  if (($voltage < 80) || ($freq > 65) || ($power > 3650) || ($current > 16) ||
       ((($power / $voltage / $pf) > 0.00999) && (0 == $current)) ||
       ($energydiff > $maxenergy)) {
     $isInvalid = 1;


Laut Wikipedia ist in Japan die Netzspannung mit 100 V am Kleinsten, also sollten wir mit 80 V als Untergrenze auf der sicheren Seite sein. Bei der Gelegenheit habe ich die Obergrenze der Frequenz auf 65 angehoben (USA!).

Nebenbei: hast Du Dir schon überlegt, ob Du das Modul nun übernehmen möchtest? Falls Du in absehbarer Zeit kein Interesse hast, würde ich das machen, bevor es ganz anstaubt... Ich gebe auch gerne wieder ab, wenn Du später Interesse hast... :)

mumpitzstuff

Kannst du gern haben, ich habe keine Zeit dafür. Das mit der Division ist komisch und sollte ja unter normalen Umständen nicht auftreten. Deine Änderung sollte das dann aber zuverlässig abfangen.

yoda_gh

Zitat von: mumpitzstuff am 17 Mai 2018, 21:21:54
Kannst du gern haben, ich habe keine Zeit dafür. Das mit der Division ist komisch und sollte ja unter normalen Umständen nicht auftreten. Deine Änderung sollte das dann aber zuverlässig abfangen.

Wirklich Zeit für die Weiterentwicklung habe ich auch nicht - ich könnte halt zumindest Deine und ggf. weitere Patches einbringen, immer noch besser als der aktuelle Zustand, denke ich... Ich versuche mal nochmal die Original-Autoren zu erreichen und kündige die Übernahme an...

yoda_gh

#20
Hallo!

Zitat von: mumpitzstuff am 17 Mai 2018, 21:21:54
Kannst du gern haben, ich habe keine Zeit dafür. Das mit der Division ist komisch und sollte ja unter normalen Umständen nicht auftreten. Deine Änderung sollte das dann aber zuverlässig abfangen.

Kannst Du mir bitte mal die magische Division erklären? Woher kommt die Konstante 0.00999?

($power / $voltage / $pf) > 0.00999

Außerdem bin ich über folgendes Problem gestolpert:

$maxenergy = 3.65 * ($timediff / 3600.0);
[...]
if ... ($energydiff > $maxenergy)) {
    $isInvalid = 1;


Bei mir ist wohl durch einen Übertragungsfehler einmalig ein viel zu kleiner Energy-Wert gespeichert worden. energydiff war wohl negativ und damit hat die Prüfung nicht zugeschlagen.  Ab dann hat sie aber jedesmal zugeschlagen und effektiv verhindert, dass weitere Werte angezeigt wurden. Ich habe schon Antenne und alles mögliche überprüft, bis ich dahinter gekommen bin, dass das Modul jetzt alle empfangenen Werte als ungültig verworfen hat, da ein zu kleiner Energy-Wert gespeichert war und damit energydiff immer zu groß war.

Ein naheliegender Fix wäre, mit Beträgen zu arbeiten und damit auch negative $energydiff-Werte abzufangen.

Ich fürchte aber, dass man durch Anpassen vom EnergyAdjustValue in ähnliche Situationen laufen kann. Generell ist das eine m.E. heikle Prüfung, da sie sich nicht auf "absolute" Wahrheiten bezieht, sondern gegen die lokal gespeicherte Historie prüft, die durch alles mögliche verfälscht werden könnte. Daher würde ich dazu tendieren, die energydiff-Prüfung ersatzlos zu streichen. Was meinst Du?

mumpitzstuff

Ich habe noch nicht ganz verstanden weshalb das dann dauerhaft zu einem Problem werden könnte. energydiff rechnet dir immer die Differenz von aktuellem Wert zum letzten Energy wert. Das kann ein positiver oder negativer wert sein. Da ich jetzt immer Ausschläge nach oben hatte, wurden diese Werte damit gefiltert. Mir ist unklar wie ein kleiner Energy Wert dazu führt, dass nichts mehr durch geht. Gib mir mal ein Beispiel in Zahlenwerten bitte.

Die Formel und die Prüfung der Konstante wusste ich mal bzw. habe mir dafür eine Erklärung hergeleitet gehabt, die ich ehrlich gesagt wieder vergessen habe. Diese Prüfung hatte ich aber von hier übernommen:

http://www.sknorrell.de/blog/energiemesssung-mit-revolt-nc-5462/

yoda_gh

Zitat von: mumpitzstuff am 21 Mai 2018, 22:08:19
Ich habe noch nicht ganz verstanden weshalb das dann dauerhaft zu einem Problem werden könnte. energydiff rechnet dir immer die Differenz von aktuellem Wert zum letzten Energy wert. Das kann ein positiver oder negativer wert sein. Da ich jetzt immer Ausschläge nach oben hatte, wurden diese Werte damit gefiltert. Mir ist unklar wie ein kleiner Energy Wert dazu führt, dass nichts mehr durch geht. Gib mir mal ein Beispiel in Zahlenwerten bitte.

Ich habe es noch nicht im Detail im Code nachvollzogen, aber bei mir ist das Energy-Reading vor drei Tagen von c.a.. 597 auf 100 gesprungen. (Wie es der Zufall wollte natürlich genau in einem Zeitraum, wo ich sowohl an der Hardware etwas geändert als auch mit dem event-aggregator gespielt hatte). Vermutlich ein einmaliger Fehler im Empfang, der aber wohl nicht abgefangen wurde, da der Code auf den ersten Blick nur Sprünge nach oben erkennt, richtig?

Und ab dann wurde scheinbar nichts mehr empfangen, weswegen ich alles mögliche überprüft hatte. Bis ich durch Zufall gesehen hab, dass der Zeitstempel der empfangenen Telegramme in den Internals sehr wohl aktualisiert wurde, nur nicht die readings. Nach kurzem Debugging war dann klar, dass jedes neue Telegramm für den Code ungültig war, da der neue Wert 597,x eben ein unzulässiger Sprung nach oben von dem letzten Energy-Reading 100 war. Und siehe da, nach einem "deletereading ... energy" kamen die Daten wieder...

Zitat von: mumpitzstuff am 21 Mai 2018, 22:08:19
Die Formel und die Prüfung der Konstante wusste ich mal bzw. habe mir dafür eine Erklärung hergeleitet gehabt, die ich ehrlich gesagt wieder vergessen habe. Diese Prüfung hatte ich aber von hier übernommen:

http://www.sknorrell.de/blog/energiemesssung-mit-revolt-nc-5462/

Ah, danke! Dann werde ich das mal als Kommentar hinterlegen. :-) Weiß Michael Bescheid, dass Du seinen Code übernommen hast?

mumpitzstuff

Der Code ist nicht übernommen worden. Lediglich der eine Check dort. Ansonsten sollte sich der Code stark unterscheiden.

Das mit dem Energy Reading schau ich mir noch mal an, konnte aber gestern keinen Punkt erkennen, bei dem die Werte wegen einem Reading von 100 gefiltert werden könnten.

yoda_gh

#24
Zitat von: mumpitzstuff am 22 Mai 2018, 09:16:33
Der Code ist nicht übernommen worden. Lediglich der eine Check dort. Ansonsten sollte sich der Code stark unterscheiden.

Ah, ok, gut. :)

Zitat von: mumpitzstuff am 22 Mai 2018, 09:16:33
Das mit dem Energy Reading schau ich mir noch mal an, konnte aber gestern keinen Punkt erkennen, bei dem die Werte wegen einem Reading von 100 gefiltert werden könnten.

Vielleicht habe ich auch einen Denkfehler?

Meine Theorie:


  • Messwerte treffen ein mit langsam steigenden energy-Werten 597,0x Wh -> alles gut
  • Übertragungsfehler: Messwert trifft ein mit energy-Wert 120. Der isInvalid-Check schlägt nicht zu, denn energydiff=120-597, also -477. Und die Bedingung prüft nur, ob  energydiff>maxenergy - und der negative Wert ist eben kleiner als die maxenergy-Grenze.
  • Reading wird gespeichert, energy ist jetzt 120.
  • korrekter Messwert trifft ein mit energy=597,0x Wh. Jetzt ergibt sich: energydiff=597-Reading, also 597-120, also 477. Und das ist größer als das maximal erlaubte Delta für die vergangene Zeitspanne seit dem Übertragungsfehler. isInvalid=1 und der Messwert wird stillschweigend verworfen.
  • Dasselbe passiert ab jetzt für alle eintreffenden Messwerte.

Leider sieht man es im Log nicht ganz klar, weil ich zu dem Zeitpunkt mit einem "linear:mean"-event-aggregator für die Werte gespielt habe und damit die Events nur Mittelwerte waren:


2018-05-20_18:40:55 Revolt_Heizung energy: 597.02
2018-05-20_18:40:59 Revolt_Heizung power: 8.70769230769231
2018-05-20_18:40:59 Revolt_Heizung energy: 597.02
2018-05-20_18:41:06 Revolt_Heizung power: 18.05
2018-05-20_18:41:06 Revolt_Heizung energy: 581.332857142857
# Ich denke, hier ist der Wert von ca. 120 Wh reingekommen. Das ist nur einmal passiert, daher sieht man im Log nur
# die geringe Abweichung im Mittelwert nach unten, aber ich habe im Reading einen Wert irgendwas um 100 gesehen.
# Ab hier kommen keine Werte mehr rein.

# Am nächsten Abend bin ich dann draufgekommen und habe das energy-Reading gelöscht. Und sofort ging's weiter.
2018-05-21_20:51:53 Revolt_Heizung power: 8.6
2018-05-21_20:51:53 Revolt_Heizung energy: 597.68
2018-05-21_20:52:58 Revolt_Heizung power: 8.6
2018-05-21_20:52:58 Revolt_Heizung energy: 597.68


Zum Debuggen habe ich am 21.05. auch eine Log-Ausgabe eingebaut:


2018.05.21 20:51:05 5: Revolt_Heizung: received invalid sample: 228 V 50 Hz 8.7 W 597.68 Wh energydiff: 477.68 maxenergy: 1.51326887975468


mumpitzstuff

#25
Okay verstanden. Gute Analyse.

Dann sollte man tatsächlich die Abfrage hinzufügen, ob $energydiff positiv also größer 0 ist. Tendenziell darf der Wert ja nur 0 sein oder größer sein als 0. Richtig? Ausbauen würde ich den Check nicht. Ohne diesen Check hatte ich immer recht große Sprünge in den Werten. Zwar immer im erlaubten Rahmen, aber sie haben mir trotzdem die Charts kaputt gemacht. An der Stelle muss man dann vielleicht auch noch aufpassen was passiert, wenn man den Wert mal auf 0 setzen sollte. Da hatte ich doch auch so ein Attribut mit drin...

yoda_gh

Ja, mir ist klar, warum Du den Check haben möchtest und die Prüfung auf negative Werte macht auf den ersten Blick Sinn. Aber was ist mit Änderungen vom EnergyAdjustValue? Oder vielleicht vergessen die Steckdosen doch ab und zu den gespeicherten Wert und zählen wieder ab 0? Das würde auch zu Sprüngen im energy-Readung und ggf. zu ähnlichen Fehlern führen, oder? Trauen wir uns zu, hier alle Fälle, die das Reading beeinflussen könnten, zu bedenken und korrekt abzufangen?

Ich finde es unglücklich, dass durch solche einmaligen Fehler, woher sie auch immer kommen mögen, dauerhaft und stillschweigend keine Werte mehr angezeigt werden und der User sich einen Ast sucht nach der Ursache. Ich habe in meiner Verzweiflung, weil plötzlich keine Werte mehr kamen, angefangen, Türen im Keller (dort ist die Revolt-Steckdose) systematisch auf und zu zu machen, weil das ja vielleicht Funk-Reflexionen verändert haben könnte... Dann doch lieber ab und zu ein kaputter Chart...

Wenn wir so einen Check haben, dann sollten wir wenigstens einen Error-Counter in den Internals haben, der dem User deutlich zeigt, dass zwar Nachrichten empfangen werden, aber diese verworfen werden - am besten mit einem String in einem weiteren Internal, der ihm erklärt, warum...

mumpitzstuff

Das mit dem Error gefällt mir gut. Allerdings würde ich da keinen Counter hinterlegen, sondern lediglich filtered oder so rein schreiben. An dem Zeitstempel sieht man dann sehr schnell das da ständig was gefiltert wird. Das ist dann aber lediglich ein Indikator das was schief läuft, die Ursache ist dadurch ja nicht behoben.

Ich muss gucken wann ich etwas Zeit finde mich da mal wieder genauer rein zu denken. Ist auf jeden Fall irgendwie alles Kacke mit dem filtern und rumrechnen. Da ich den Adjust Wert nie gesetzt hatte ist mir damals leider nicht aufgefallen, dass das gar nicht mehr richtig geht. Wenn nicht, dann wirf die Prüfung erst mal raus und guck was dann bei dir passiert. Vielleicht sind ja die Sprünge auch gar nicht mehr so groß bzw. werden durch den Event Aggregator bereits gefiltert. Ich habe damals die ganzen Filter schrittweise implementiert und der Eventfilter kam als letztes. Kann sein das der allein bereits ausreichend ist oder du einfach die Zeit etwas hoch setzen musst und damit alle Probleme erschlagen kannst.

yoda_gh

So, ich habe Deine Änderungen jetzt mal ins SVN übernommen, danke nochmal, mumpitzstuff! Nur den Plausi-Check für die Energy-Sprünge habe ich aus den hier diskutierten Gründen erstmal entfernt.

Nebenbei habe ich auch die avgpower-Readings entsorgt.

mumpitzstuff

Super. Das Attribut war eh der größte Müll. :)