Ich verstehe "monotonic" nicht

Begonnen von Motivierte linke Hände, 14 August 2022, 00:29:49

Vorheriges Thema - Nächstes Thema

Motivierte linke Hände

Hi, ich habe hier einen Shelly3EM, der den Stromverbrauch im Haus misst. Da er auf 3 Phasen getrennt misst, ich aber nur einen Gesamtwert loggen möchte, habe ich mir dafür ein Userreading erzeugt:

userReadings emeter_sum_total:emeter_._total:.* monotonic {ReadingsNum("$name",'emeter_0_total',0)+ReadingsNum("$name",'emeter_1_total',0)+ReadingsNum("$name",'emeter_2_total',0)}

Monotonic habe verwendet, falls irgendwelche Zähler beim Stromausfall auf 0 landen sollten.

Nachdem das einige Zeit lief, habe ich festgestellt, dass der Wert des Userreadings nicht mehr der Summe der Einzelwerte entsprach, sondern dahinter zurückblieb. Da ich mir nicht erklären konnte, wodran das lag, habe ich testweise zwei Userreadings angelegt, eines mit monotonic und eines ohne:

userReadings emeter_sum_total:emeter_._total:.* {ReadingsNum("$name",'emeter_0_total',0)+ReadingsNum("$name",'emeter_1_total',0)+ReadingsNum("$name",'emeter_2_total',0)}, emeter_sum_total_mono:emeter_._total:.* monotonic {ReadingsNum("$name",'emeter_0_total',0)+ReadingsNum("$name",'emeter_1_total',0)+ReadingsNum("$name",'emeter_2_total',0)},

Interessant: Beide Readings laufen innerhalb von einer Stunde, in der fhem einfach durchläuft, auseinander:

   READINGS:
     2022-08-14 00:22:01   emeter_sum_total 495034.2
     2022-08-14 00:22:01   emeter_sum_total_mono 495027.7


Ich wäre dankbar, wenn mir jemand erklären könnte, wo mein Denkfehler liegt, der dazu führt, dass der monotonic-Zähler hinter der eigentlichen Summe zurückbleibt (der Wert des Zählers ohne monotonic ist mathematisch korrekt).
FHEM 6 in einer KVM VM mit Ubuntu
HM-CFG-USB2, 2xHM-CFG-HMLAN, HM-HMUARTLGW mit 100+ HomeMatic Devices, Geofencing, Fritzbox, Unifi, HUE, Harmony-Hub, Denon-Receiver-Modul, Calendar, GardenaSmartDevice, Shelly, MQTT (zigbee2mqtt, Tasmota und Shelly) und ein wenig 1Wire.

Nobbynews

#1
Lt. commandref
Zitatmonotonic: wenn die Differenz zw. dem aktuellen und dem vorherigen Wert positiv ist wird diese Differenz zum Reading addiert. Damit lässt sich von einem Zähler der bei Stromverlust zurückgesetzt wird ein monoton wachsender Zähler ableiten   
Das verstehe ich so, dass die Differenz des eigentlichen reading zum vorherigen Wert positiv sein muss und nicht aus einer Summe aus mehreren readings. Die Differenz bezieht sich mMn. nicht auf das userReading. Ich vermute daher, dass die Differenz nicht so wie erwartet berechnet wird.
Also würde ich mal 3 getrennte userReadings mit monotonic anlegen und dann über ein 4. userReading daraus die Summe bilden.

Edit:
Oder alternativ erst über ein userReading die 3 Einzelwerte summieren und mit diesem reading dann das userReading mit monotonic.
Kommt halt drauf an, ob die 3 Einzelwerte für sich interessant sind oder nur der Summenwert.

DetlefR

Hallo,

kann es sein, dass "reactive power" da etwas durcheinander bringt.
Nur eine Vermutung. Die Summe der drei Phasen ist noch monoton. Aber ein den einzelnen Werten kann es durchaus "Rückläufer" geben.

Motivierte linke Hände

Die "Einspeisung" misst der Shelly in anderen Readings. Das Total zählt meiner Beobachtung nach immer hoch.
FHEM 6 in einer KVM VM mit Ubuntu
HM-CFG-USB2, 2xHM-CFG-HMLAN, HM-HMUARTLGW mit 100+ HomeMatic Devices, Geofencing, Fritzbox, Unifi, HUE, Harmony-Hub, Denon-Receiver-Modul, Calendar, GardenaSmartDevice, Shelly, MQTT (zigbee2mqtt, Tasmota und Shelly) und ein wenig 1Wire.

DetlefR

ZitatDie "Einspeisung" misst der Shelly in anderen Readings. Das Total zählt meiner Beobachtung nach immer hoch.
Stimmt.
Ich habe das ganze interessehalber mal ein paar Tage laufen lassen. Solange es "läuft" ist alles gut. Aber jedes "stolpern" bringt eine Differenz zwischen monotonic_sum und sum. Wobei "stolpern" ein editieren der Konfig bzw. ein reboot von FHEM ist.
Dabei habe ich mir auch die Frage nach der Sinnhaftigkeit gestellt. Während beim 3EM die total Werte nichtflüchtig sind, sind in FHEM alle Readings erst mal flüchtig. Bis zum nächsten save.

Motivierte linke Hände

Ja, beim 3EM sind die Werte nicht flüchtig, können aber im Gerät durch Nutzereingriff oder Bug zurückgesetzt werden. Sowas könnte man durch monotonic verhindern, wenn man ihn ansonsten zum richtigen Mitzählen brächte...

Ich habe es hier inzwischen getrennt: Ein Userreading rechnet, das zweite ist nur monotonic:

energy_total_kWh:aenergy_total.* {round(ReadingsNum($name,'aenergy_total',0)/1000, 3)},
energy_total:energy_total_kWh.* monotonic {ReadingsNum($name,'energy_total_kWh',0)}


Nach 24h hinkt monotonic schon hinterher:

2022-08-17 23:45:40   energy_total    1.682
2022-08-17 23:46:00   energy_total_kWh 1.684


(Auch bei den anderen Shellies, die ich hier habe.)

Mir scheint, dass monotonic irgendwelche Erhöhungen nicht mitbekommt und dann beim nächsten Mal aber auch nicht einfach den höheren Wert des Readings übernimmt, auch wenn der Abstand - wie im Beispiel oben - gering ist.
FHEM 6 in einer KVM VM mit Ubuntu
HM-CFG-USB2, 2xHM-CFG-HMLAN, HM-HMUARTLGW mit 100+ HomeMatic Devices, Geofencing, Fritzbox, Unifi, HUE, Harmony-Hub, Denon-Receiver-Modul, Calendar, GardenaSmartDevice, Shelly, MQTT (zigbee2mqtt, Tasmota und Shelly) und ein wenig 1Wire.

Nobbynews

#6
Zitat von: Motivierte linke Hände am 17 August 2022, 23:53:41
energy_total_kWh:aenergy_total.* {round(ReadingsNum($name,'aenergy_total',0)/1000, 3)},
energy_total:energy_total_kWh.* monotonic {ReadingsNum($name,'energy_total_kWh',0)}


Nach 24h hinkt monotonic schon hinterher:

2022-08-17 23:45:40   energy_total    1.682
2022-08-17 23:46:00   energy_total_kWh 1.684

Wundert mich bei dieser Vorgehensweise nicht im Geringsten.

- aenergy ist der Datenursprung mit einer Zahl >= 4 Stellen vor dem Komma.
- energy_total_kWh ist um 3 Zehnerpotenzen kleiner und dann noch auf 3 Nachkommastellen gerundet
- daher min delta 0.001 oder 0.5xyz bis 0.9xyz bezogen auf aenergy (wg. Rundung auf 3 Nachkommastellen, hier Aufrundung, Abrundung erzeugt kein delta)
- monotonic wird mit einem kleinen gerundeten und damit ungenauen Wert gefüttert
- energy_total_kWh wird im Vergleich zu energy_total immer aus einem aktuellen genauen Wert gebildet

Also würde ich mal sagen: Die Ungenauigkeit beim monotonic ist selbst verschuldet.

Motivierte linke Hände

Ich sag ja, ich verstehe nicht, wie "monotonic" funktioniert. Und ich habe das absichtlich in "Anfängerfragen" gepostet.  :)

Ich sehe, dass in meiner Variante gerundete und damit ungenaue Zahlen in monotonic gefüttert werden. Aber diese Zahlen schwanken nicht positiv/negativ, sondern sind stetig positiv. D.h. die Differenz...

Zitatmonotonic: wenn die Differenz zw. dem aktuellen und dem vorherigen Wert positiv ist wird diese Differenz zum Reading addiert. Damit lässt sich von einem Zähler der bei Stromverlust zurückgesetzt wird ein monoton wachsender Zähler ableiten

...der Werte sollte entweder 0 oder positiv sein. Zu einer "Rückwärtsbewegung" der gelieferten Werte dürfte es nicht kommen. Von daher verstehe ich nicht(!), warum monotonic hinter dem (ebenfalls gerundeten) Wert zurückhängt...

Ich habe es nun mal umgedreht und mache "aenergy_total" monotonic, rechne danach erst in kWh um. Mal gucken, ob das was ändert (auch wenn ich nicht verstehen würde, warum.).
FHEM 6 in einer KVM VM mit Ubuntu
HM-CFG-USB2, 2xHM-CFG-HMLAN, HM-HMUARTLGW mit 100+ HomeMatic Devices, Geofencing, Fritzbox, Unifi, HUE, Harmony-Hub, Denon-Receiver-Modul, Calendar, GardenaSmartDevice, Shelly, MQTT (zigbee2mqtt, Tasmota und Shelly) und ein wenig 1Wire.

Nobbynews

#8
Zitat von: Motivierte linke Hände am 18 August 2022, 09:34:54
warum monotonic hinter dem (ebenfalls gerundeten) Wert zurückhängt...
Das liegt daran, dass der gerundete Wert von einem aktuellen genauen Wert jedesmal neu ermittelt wird.
Wenn du die kleinen gerundeten Werte über monotonic aufsummierst, gibt es halt jedesmal ungenaue delta-Werte, die aufsummiert werden.
Und ungenau + ungenau wird nicht genau. Du addierst also die jeweiligen Rundungsfehler mit auf. Daher vermutlich die Abweichungen zwischen den beiden Werten.
Es kommt auch nicht zu einer "Rückwärstbewegung". Der delta-Wert wird durch das Abrunden im reading energy_total_kWh halt auf 0 gesetzt.

Oder anders ausgedrückt: Durch die Rundung veränderst Du die Datenbasis und damit erhälst Du kein vergleichbares Ergebnis.


Motivierte linke Hände

Ich gebe das mit dem Verständnis auf: Solange die Rundung zu konsequent steigenden Werten führt, verstehe ich nicht, warum monotonic da irgenwann zurückbleibt.

Aber nun zu meinem alternativen Ansatz: monotonic direct auf das Reading angewendet. Läuft jetzt (ein bisschen mehr als) 24 Stunden, und:

2022-08-19 19:07:44   aenergy_total   11056.322
     2022-08-19 19:07:44   calc_aenergy_total_mono 11055.97
     2022-08-19 19:07:44   calc_energy_total_kWh 11.056
     2022-08-19 18:58:49   energy_total    11.056


Es geht um calc_aenergy_total_mono - der macht nichts anderes als ein monotonic auf das aenergy_total Reading. Und der Shelly hatte durchgehend Strom. Warum also schon wieder diese Differenz? Und vor allem: Wenn monotonic negative Differenzen rausfiltert, wie kann es dann sein, dass monotonic GERINGER ist als das eigentliche Reading?

userReadings:

userReadings calc_aenergy_total_mono:aenergy_total.* monotonic {ReadingsNum($name,'aenergy_total',0)},
calc_energy_total_kWh:aenergy_total.* {round(ReadingsNum($name,'aenergy_total',0)/1000, 3)},
energy_total:calc_energy_total_kWh.* {ReadingsNum($name,'calc_energy_total_kWh',0)}


(energy_total bringt nichts Neues, schleppe ich nur mit, weil das das Reading ist, das für die Statistik geloggt wird.)

Nun sind doch keine Rundungen etc. dabei. Warum klappt das mit monotonic trotzdem nicht?

Ich versuche es jetzt mal im Vergleich auch mit meinem eigenen monotonic:

sub myMonotonic ($$) {
  my ($device, $reading) = @_;
  my $newVal = ReadingsVal($device, $reading, 0);
  my $lastVal = ReadingsVal('dum_Cfg_Diverses', 'myMonotonicLast_'.$device.'_'.$reading, 0);
  my $monoVal = ReadingsVal('dum_Cfg_Diverses', 'myMonotonic_'.$device.'_'.$reading, 0);
  my $diff = $newVal - $lastVal;
 
  if ($diff >= 0) {
    $monoVal += $diff;
    fhem("setreading dum_Cfg_Diverses myMonotonic_".$device." ".$reading." $monoVal");
  } else {
    Log 1, ("myMonotonic: $lastVal > $newVal, $newVal ignored");
  }
  return $monoVal;
}


calc_energy_total_mono:aenergy_total.* monotonic {ReadingsNum($name,'aenergy_total',0)},
calc_energy_total_mymono:aenergy_total.* {myMonotonic($name,'aenergy_total')},
calc_energy_total_kWh:aenergy_total.* {round(ReadingsNum($name,'aenergy_total',0)/1000, 3)},
energy_total:calc_energy_total_kWh.* {ReadingsNum($name,'calc_energy_total_kWh',0)}


Mal gucken, wie das im Vergleich morgen aussieht.
FHEM 6 in einer KVM VM mit Ubuntu
HM-CFG-USB2, 2xHM-CFG-HMLAN, HM-HMUARTLGW mit 100+ HomeMatic Devices, Geofencing, Fritzbox, Unifi, HUE, Harmony-Hub, Denon-Receiver-Modul, Calendar, GardenaSmartDevice, Shelly, MQTT (zigbee2mqtt, Tasmota und Shelly) und ein wenig 1Wire.

Motivierte linke Hände

Ok: Die Differenz tritt auf, wenn fhem neu gestartet wird. Nach dem Neustart hat monotonic einen niedrigeren Wert als das zum Test angelegte myMonotonic Reading. D.h. die internen Werte für das userreading, die monotonic nutzt, werden offenbar nicht ganz aktuell gespeichert (wo auch immer, in fhem.save und in fhem.cfg konnte ich nichts finden, was darauf hindeuten würde, dass es für monotonic genutzt wird).

FHEM 6 in einer KVM VM mit Ubuntu
HM-CFG-USB2, 2xHM-CFG-HMLAN, HM-HMUARTLGW mit 100+ HomeMatic Devices, Geofencing, Fritzbox, Unifi, HUE, Harmony-Hub, Denon-Receiver-Modul, Calendar, GardenaSmartDevice, Shelly, MQTT (zigbee2mqtt, Tasmota und Shelly) und ein wenig 1Wire.

Damian

#11
Es ist grundsätzlich keine gute Idee aus Leistung eines Gerätes in FHEM auf die Energie zu schließen (monotonic)

Energie (total-Reading) ist ein Integral der Leistung über die Zeit. Wenn ein Messgerät es bestimmt, dann kann es das öfters pro Sekunde tun, damit stimmt die entnommene Energie einigermaßen.

Wenn jemand auf die Idee kommt in FHEM aus Leistung die Energie zu bestimmen, dann wird es nie genau sein, denn die Update-Intervalle (senden der aktuellen Leistung) viel zu groß sind (größer als eine Sekunde). Wie die momentane Leistung zwischen den Sendezeitpunkten aussah, weiß man nicht. Hier fehlen einfach die Informationen um genau die Energiemenge zu bestimmen - das sollte man besser dem Gerät überlassen.
Programmierte FHEM-Module: DOIF-FHEM, DOIF-Perl, DOIF-uiTable, THRESHOLD, FHEM-Befehl: IF

Motivierte linke Hände

Der Shelly misst aenergy. Ich rechne die nur in kWh um. (durch 1000)

Worum es mir geht, ist Folgendes:

Shelly liefert das Reading "aenergy_total". Dieses enthält den Wert "2170.697"

Die Userreadings dazu enthalten die entsprechenden Werte:
calc_energy_total_kWh 2.171
calc_energy_total_mono 2170.697
calc_energy_total_mymono 2170.697


Dann beende ich fhem und starte es wieder:

/etc/init.d/fhem stop && sleep 1 && /etc/init.d/fhem start

Es kommt ein neuer aenergy_total-Wert vom Shelly.
Neue Readings:

aenergy_total: 2171.195
setstate EM_Shelly_UG10 2022-08-20 11:00:01 calc_energy_total_kWh 2.172
setstate EM_Shelly_UG10 2022-08-20 11:00:01 calc_energy_total_mono 2171.027
setstate EM_Shelly_UG10 2022-08-20 11:00:01 calc_energy_total_mymono 2171.195


D.h. nur weil ich FHEM neugestartet habe, weicht das monotonic-Reading (calc_energy_total_mono) plötzlich vom tatsächlichen Reading ab. Für mich scheint bei monotonic in FHEM was nicht richtig gespeichert zu werden/beim Neustart verloren zu gehen.

Userreadings:

calc_energy_total_mono:aenergy_total.* monotonic {ReadingsNum($name,'aenergy_total',0)},
calc_energy_total_mymono:aenergy_total.* {myMonotonic($name,'aenergy_total')},
calc_energy_total_kWh:aenergy_total.* {round(ReadingsNum($name,'aenergy_total',0)/1000, 3)},
energy_total:calc_energy_total_kWh.* {ReadingsNum($name,'calc_energy_total_kWh',0)}


FHEM 6 in einer KVM VM mit Ubuntu
HM-CFG-USB2, 2xHM-CFG-HMLAN, HM-HMUARTLGW mit 100+ HomeMatic Devices, Geofencing, Fritzbox, Unifi, HUE, Harmony-Hub, Denon-Receiver-Modul, Calendar, GardenaSmartDevice, Shelly, MQTT (zigbee2mqtt, Tasmota und Shelly) und ein wenig 1Wire.

justme1968

monotonic hat mit leistung oder energie erst mal nichts zu tun. es ist nur dazu da im rahmen des möglichen zu verhindern das ein (impuls) zähler rückwärts läuft oder wieder bei 0 beginnt wenn fhem neu gestartet wird. das ist prinzipiell nicht genau da zum einen grundsätzlich impulse verloren gehen wenn fhem nicht läuft und/oder die implementierte erkennung mindestens einen impuls braucht um wieder zu synchronisieren.

monotonic berücksichtigt auch keine zeitabhängigkeit. im gegensatz zu integral das dafür gemacht ist.

aus diesen gründen ist es immer besser das zählen in hardware umzusetzen. z.b. per one wire counter oder arducounter.

wenn das aus irgendwelchen gründen nicht möglich ist und die impuls häufigkeit hoch genug ist oder mit der leistung korreliert ist dann kann das zählen und integrieren per fhem eine durchaus sinnvolle und genaue option sein. monotonic kommt dann aber erst in einem zweiten schritt zum aufsummieren der integrale ins spiel.

hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Motivierte linke Hände

#14
Und warum zählt monotonic über einen Neustart von FHEM die eingehenden Daten falsch?

Der Zähler läuft vorwärts, aber nach einem Neustart zählt das monotonic-Reading weniger weit vorwärts als das eigentliche Reading (und als mein selbstbgebautes monotonic-Reading).

Siehe mein Beispiel oben:
Shelly-Zähler vor dem FHEM-Neustart 2170.697
monotonic-Zähler vor dem FHEM-Neustart 2170.697
(letztes Readings vor dem Neustart - entspricht dem Inhalt von fhem.save)

Shelly-Zähler nach dem FHEM-Neustart: 2171.195
monotonic-Zähler nach dem FHEM-Neustart: 2171.027
(erstes neues Reading nach dem FHEM-Neustart)
FHEM 6 in einer KVM VM mit Ubuntu
HM-CFG-USB2, 2xHM-CFG-HMLAN, HM-HMUARTLGW mit 100+ HomeMatic Devices, Geofencing, Fritzbox, Unifi, HUE, Harmony-Hub, Denon-Receiver-Modul, Calendar, GardenaSmartDevice, Shelly, MQTT (zigbee2mqtt, Tasmota und Shelly) und ein wenig 1Wire.