[Gelöst] Ausreißer ignorieren und Mittelwert bilden?

Begonnen von Juliana, 09 Februar 2023, 23:01:37

Vorheriges Thema - Nächstes Thema

Juliana

Hallo,

ich fuxe mich gerade erst seit 2 Wochen etas in FHEM rein. Und habe eine Frage zur Bereinigung der Daten meiner Wallbox, ein go-e Charger HomeFix 11kW. Der liefert mir haufenweise Werte über MQTT. Die API-v2 Key Tabelle auf Github erschlägt mich förmlich:
https://github.com/goecharger/go-eCharger-API-v2/blob/main/apikeys-en.md
Ich möchte gern alle Anzeigen in der Smartphone App nachbauen, sodass ich das alles im FHEM sehen kann. Das große Ziel ist es am Ende, die Wallbox mit dem Wechselrichter von der Solaranlage zusammenzubringen. Ich möchte zunächst zum Beispiel gern die drei Spannungen Volt1, Volt2, Volt3 in einem Graphen darstellen und die drei Stromstärken in einem anderen. Dazu lege ich ein LogFile an, um überhaupt einen Plot machen zu können. Dass das LogFile riesengroß und das Plotten unmöglich wird, wenn viele viele Werte sekündlich kommen, habe ich bereits festgestellt. Deshalb möchte ich (a) nur die relevanten Werte loggen und (b) einen minütlichen Mittelwert in denLog schreiben. Ebenso sehe ich bei den Spannungswerten, dass es sehr häufig Ausreißer gibt. Spannung zappelt dann nicht zwischen 230-250V, sondern es gibt auch Werte von 0 oder 1.125. Man sieht dann im Lineplot eigentich nur eine fabrige Fläche zwischen 0 und 240, weil sich ständig hohe und niedrige Werte abwechseln. Deshalb ist vielleicht auch ein Mittelwert über 60 gültige Werte passend, wobei ungültige Werte <240 rausgeschmissen werden. Die Spannungsvariablen heißen 1, 2 und 3.

Meine Überlegungen:
- Eine Mittelwertbildung mit event-aggregator geht nicht wegen der Ausreißer.
- Ausreißer rausschmeißen scheint nicht mit UserReadings zu gehen, weil dabei zu jedem Zeitpunkt auch ein Wert ausgegeben werden muss.
- Ich hatte mir überlegt, für z.B. die Variable Wallbox_Volt1cleaned einen Dummy Wallbox_Volt1cleanedCounter zu nehmen, der modulo 60 die gütligen Werte mitzählen soll und einen Dummy Wallbox_Volt1cleaned, der nach und nach 60 gültige Werte summiert und beim Auftreten des 60. Wertes einfach /60 teilt und diesen Wert in eine Art Clone-FileLog namens Wallbox_cleanedAvg schreibt. Und zwar so, dass nachher noch identifizierbar ist, zu welcher der einzelnen Variablen der Wert gehört. Dann wird "event-on-update-reading 1,2,3" und ein Notify, welches Wallbox_Volt1cleaned Wallbox_Volt1cleanedCounter richtig setzt. Das wirkte auch immer richtig. Bis ich festgestellt habe, dass durch event-on-update-reading mit 3 Variablen das Notify dreimal pro Sekunde angesprochen wird, nämlich jedes Mal, wenn sich eins der drei Readings updated. Setze ich "event-on-update-reading 1", wird Notify nur einmal pro Sekunde ausgeführt. Das entspricht eher dem, was ich will. Ich vermute nur, dass es passieren kann, dass andere Werte, Volt2 und Volt3 dann vielleicht manchmal doppelt gelesen werden und manchmal gar nicht, je nach Zeitstempel.

Ich habe die Befürchtung, dass ich den way-to-go mit FHEM noch nicht verstanden habe. Was mich stört ist das Anlegen von haufenwiese Dummy-Variablen und dass die Lösung so unelegant und hemdsarmelig ist. Wie macht man sowas besser?

Vielen Dank,
Juliana
FHEM auf Debian 11, Sensoren/Aktoren, die alle ins FHEM rein sollen oder drin sind: LaCrosse Temperatur- und Feuchtigkeitssensoren, Tasmota Funksteckdosen, go-e Charger HomeFix, Heizung über RaspBerry Pi Wechselrichter für Solaranlage

Icinger

Hallo Juliana,

ich habe zwar keine Wallbox, aber vlt. kann ich dir ja doch den einen oder anderen Tip geben:

1) Es gibt für die go-e ein eigenes Modul: https://forum.fhem.de/index.php/topic,110282.0.html
2) Userreadings ginge schon, du musst halt mein den Ausreissern ein "undef" zurückgeben.
3) Mittelwerte etc. würde ich nicht selbst berechnen, sondern dazu das statistics-Modul verwenden, das ist genau für sowas gedacht :)

lg, Stefan
Verwende deine Zeit nicht mit Erklärungen. Die Menschen hören (lesen) nur, was sie hören (lesen) wollen. (c) Paulo Coelho

FHEM-User22

Moin,
Mittelwert wäre auch für mich interessant. Ich rufe mehrere Wetterstationen der Umgebung ab. Da sind immer wieder Ausreißer dabei und aus den ca. 5 Stationen einen Mittelwert zu bilden wäre super.


Beste Grüße
FHEM auf Raspberry Pi und Proxmox und... und.... und....

Damian

Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Damian

Zitat von: FHEM-User22 am 10 Februar 2023, 08:18:21
Mittelwert wäre auch für mich interessant. Ich rufe mehrere Wetterstationen der Umgebung ab. Da sind immer wieder Ausreißer dabei und aus den ca. 5 Stationen einen Mittelwert zu bilden wäre super.

Das ist eine andere Anforderung: siehe: https://fhem.de/commandref_DE.html#DOIF_aggregation
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Prof. Dr. Peter Henning

Ich kann allen Anfängern nur davon abraten, komplizierte Konstrukte mit DOIF zu bilden - das ist, vorsichtig gesagt, keine gute Praxis.

ZitatDer liefert mir haufenweise Werte über MQTT
Einmal pro Sekunde über MQTT ist ein Haufen Traffic. Anzuraten wäre hier mindestens, einen außerhalb von FHEM liegenden MQTT-Server zu verwenden, damit FHEM nicht ausgebremst wird. Ich habe keine Ahnung, wie das bei dem dezidierten Modul für diese WallBox gelöst ist - ich tippe mal, etwas intelligenter..

Und ja: Einmal pro Minute reicht für diese Anwendung eigentlich voll aus.

ZitatIch habe die Befürchtung, dass ich den way-to-go mit FHEM noch nicht verstanden habe
Ich auch nicht, immer wieder ... Schau mal auf Google Books in mein Buch aus 2019.

LG

pah







Damian

Zitat- Ausreißer rausschmeißen scheint nicht mit UserReadings zu gehen, weil dabei zu jedem Zeitpunkt auch ein Wert ausgegeben werden muss.

doch, du kannst undef angeben; damit ändert sich dein userReading nicht und liefert auch kein Event:

attr wallbox userReadings Wallbox_Volt1cleaned {ReadingsNum("wallbox","Wallbox_Volt1","") > 240 or ReadingsNum("wallbox","Wallbox_Volt1","") < 0 ? undef : ReadingsNum("wallbox","Wallbox_Volt1","")}

Gleichzeitig wird mit ReadingNum nach Zahlen gefiltert, so brauchst du keine neuen Dummys und auch kein DOIF ;)
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Juliana

#7
Ok, weitere Erkenntnisse: Das go-r-Modul macht eine sinnvolle Vorauswahl an Readings. Damit kann man zum Beispiel das Laden an- und ausschalten oder die Stromstärke setzen, mit der das Auto maximal laden darf. Die ganzen praktisch nicht so relevanten Dinge, wie aktuelle Stromstärken, Spannungen etc. gibt es hier gar nicht und werden hoffentlich nicht sekündlich durch die Gegend geschickt. In der App muss man wohl API v1 setzen, damit die JSON- Fehlermeldung weggeht, das tut sie aber irgendwie nicht. Keine Ahnung, anderes Thema.

[fig1.png]

Wenn man stattdessen über MQTT alles Mögliche ausliest (um zum Beispiel Spannungen und Stromstärken zu plotten), hat man über 20 sekündliche Werte. Hier ein Screenshot von einigen Readings.

[fig2.png]

Ich habe also ienen Log für Spannung (1,2,3) und Stromstärke (5,6,7) angelegt


define FileLog_MQTT2_go_echarger_054158 FileLog ./log/MQTT2_go_echarger_054158-%Y.log MQTT2_go_echarger_054158
attr MQTT2_go_echarger_054158 event-on-update-reading 1,2,3,5,6,7


und einfach so geplottet.


set terminal png transparent size <SIZE> crop
set output '<OUT>.png'
set xdata time
set timefmt "%Y-%m-%d_%H:%M:%S"
set xlabel " "
set title 'Spannung'
set ytics
set y2tics
set grid
set ylabel "Volt"
set y2label "Volt"

#FileLog_MQTT2_go_echarger_054158 4:MQTT2_go_echarger_054158.1\x3a::
#FileLog_MQTT2_go_echarger_054158 4:MQTT2_go_echarger_054158.2\x3a::
#FileLog_MQTT2_go_echarger_054158 4:MQTT2_go_echarger_054158.3\x3a::

plot "<IN>" using 1:2 axes x1y2 title 'Volt1' ls l0 lw 2 with lines,\
     "<IN>" using 1:2 axes x1y2 title 'Volt2' ls l1 lw 2 with lines,\
     "<IN>" using 1:2 axes x1y2 title 'Volt3' ls l2 lw 2 with lines


Das führt im Plot mit Ausreißern nach unten.

[fig3.png]

Ziel ist es, Ausreißer zu entfernen, wobei zu bedenken ist, dass es nicht immer sinnvoll ist, generell alle Spannungen unter 230V rauszufiltern, da ja vielleicht auch mal einfach keine Spannung anliegt.

Nichtsdestotrotz  könnte man das ja genauso  machen direkt beim Erzeugen des Plotfiles, indem man  unter Function überall


$fld[3]<230?undef():$fld[3]


einfügt (wenn Wert 4. Spalte < 230, dann soll der Wert nicht definiert sein.). Hübsch ist es nicht. Und Mittelwerte hat man auch nicht.

[fig4.png]

Ein Mittelwert über die Zeit wäre ganz nett. Hier ja aber im Logfile, damit das nicht so groß wird und mit ordentlicher Statistik, die die Ausreißer ignoriert.

Erkenntnisse, auch aus euren Antworten:
(1) Die Ausreißer kann man da also nicht erst im Plot entfernen, sondern bleiben als Aggregationswerten entweder drin oder man entfernt sie vor der Aggregation.
(2) Das Statisticsmodul scheint nicht für Ausreißererkennung gedacht zu sein, deswegen müsste man das separat machen. Die minimale Periodenlänge beim Statisticsmodul ist ,,Hour" bzw. ,,Day", was mir aber zu lange ist. Ansonsten immer eine gute Idee, das Rad nicht nochmal neu zu erfinden.
(3) DOIF von Damian kann auch den Mittelwert berechnen. Man könnte also in einem ersten Schritt alle Ausreißer rausschmeißen, wenn man einen eher pragmatischen Ansatz wählt, und dann mitteln. Das probiere ich man aus.

DOIF habe ich auch schon entdeckt. Das es da Glaubenkriege gibt, habe ich schon mitbekommen :-)

Ich markiere das mal aus gelöst. Und ergänze hier ggf. dann die praktische Umsetzung.
Danke für alle Antworten.
FHEM auf Debian 11, Sensoren/Aktoren, die alle ins FHEM rein sollen oder drin sind: LaCrosse Temperatur- und Feuchtigkeitssensoren, Tasmota Funksteckdosen, go-e Charger HomeFix, Heizung über RaspBerry Pi Wechselrichter für Solaranlage

Prof. Dr. Peter Henning

ZitatDas es da Glaubenkriege gibt
Nicht doch. Religiöse und sonstige Fanatiker sind mir ein Gräuel...

LG

pah