FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: andies am 21 Oktober 2022, 16:09:36

Titel: Verständnis event-aggregator erneut
Beitrag von: andies am 21 Oktober 2022, 16:09:36
Ich verstehe den Event-aggregator anscheinend nicht. Im Wiki (gleich kommt noch commandref) steht
Method const: Annahme, dass zwischen den zwei Messpunkten keine Veränderung stattgefunden hat
Wenn zwischen zwei Messpunkten keine Veränderung (Veränderung von was?) stattgefunden hat, ist dann der Messwert gleich? Das ergibt doch keinen Sinn? Also ist etwas anderes gemeint, nur was?

In der commandref steht
If method is none, then that's all there is.
OK, also das erklärt wenig. Muss man weiterlesen
If method is const or linear, the time-weighted series of values is taken into account instead.
Und vermutlich brauche ich das in meinem Fall, weil bei mir Gasverbräuche nicht in festem zeitlichen Abstand eintreffen, sondern dann, wenn Gas verbraucht wird und zudem erscheinen in dem Gerät nullen, wenn ein davon unabhängiges Reading (Messung, ob der Boden nass ist) aktualisiert wird. Damit ich das aggregieren kann, muss ich vermutlich zeitlich gewichten.

With the const method, the value is the value of the reading at the beginning of the timespan; with the linear method, the value is the arithmetic average of the values at the beginning and the end of the timespan.    
Da steht jetzt zweimal Value drin. Ich vermute, es heißt ungefähr das hier:
Bei der const-Methode ist der Wert, der in die Aggregation eingeht, der Messwert zu Beginn der Zeitspanne; bei der linearen Methode ist der Wert, der in die Aggregation eingeht, das arithmetische Mittel der Werte am Anfang und am Ende der Zeitspanne.
Wo aber ist dann da die zeitliche Gewichtung? Die müsste sich doch an der Länge der Zeitspanne orientieren und davon ist gar nicht die Rede?

Da bei mir zudem jede einzelne Erhöhung des Gaszählers gemessen werden kann, dachte ich zuerst, dass ich statt "integral" besser "count" nehmen kann. Da kam aber nur Unsinn heraus.

Ich will einfach nur verstehen, ob das Gerät hier wirklich den Durchschnittsverbrauch über 5 minuten misst:
Internals:
   CFGFN     
   NAME       Heizungskeller
   NR         248067
   STATE      Woche 42
   TYPE       dummy
   eventCount 2037
   Helper:
     DBLOG:
       Gasverbrauch:
         DbLog:
           TIME       1666361320.07258
           VALUE      0.0999999999985448
       Gasverbrauch_aggregiert:
         DbLog:
           TIME       1666361320.07258
           VALUE      0.0999999999985448
       wasser:
         DbLog:
           TIME       1666361149.34924
           VALUE      1975
   READINGS:
     2022-10-21 16:08:40   Gasverbrauch    0.0999999999985448
     2022-10-21 16:08:40   Gasverbrauch_aggregiert 0.0999999999985448
     2022-10-21 16:08:40   Zaehlerstand    6504.96
     2022-10-21 16:08:40   gas             650496
     2022-10-21 16:05:49   wasser          1975
Attributes:
   comment   Wasser wird ca alle 5 Minuten geprueft
Gas wird sofort uebermittelt
   event-aggregator Gasverbrauch_aggregiert::none:integral:300
   group      Messen
   room       Info
   sortby     01
   stateFormat {if (ReadingsNum($name, "wasser", 0) < 1000) {return "Wasser ausgelaufen!!"} else {return "Woche ".ReadingsVal("DOIFweek", "state", "")}}
   userReadings Gasverbrauch difference {ReadingsVal($name,"gas",0)/10;;},
Zaehlerstand {ReadingsVal($name,"gas",0)/100;;},
Gasverbrauch_aggregiert {ReadingsVal($name, "Gasverbrauch",0);;}
Titel: Antw:Verständnis event-aggregator erneut
Beitrag von: andies am 21 Oktober 2022, 16:27:33
Jetzt habe ich auch die Definition gefunden, in TimeSeries.pm:
  # we must have an assumption about how the value varies between
  # two data points in the time series (discretization method).
  # The const method assumes, that the value was constant
  # since the previous one.
  # The linear method assumes, that the value changed linearly
  # from the previous one to the current one.

Das ist vermutlich nicht meine Situation. Denn hier steht ein Modell dahinter, in dem es eine stetig veränderbare Größe gibt, die man nur in bestimmten Zeitabständen erfasst (Temperaturen, Luftfeuchtigkeiten zB). Ich habe aber diskrete Werte: Nämlich die Zeitpunkte, an der die Ziffer 6 an meinem Gaszähler vorbeirauscht. Dann passt das Modul gar nicht?!
Titel: Antw:Verständnis event-aggregator erneut
Beitrag von: andies am 23 Oktober 2022, 09:48:16
Also bei so lautem Schweigen (bis jetzt 77 Aufrufe) kann die Schlussfolgerung nur sein: Ich habe mich nicht verständlich gemacht. Ein neuer Versuch.

Es gibt kontinuierliche Daten, die ständig anfallen und nur zu bestimmten Zeitpunkten gelesen werden: Temperatur, Luftfeuchtigkeit, Feinstaubbelastung, Lichtstärke... Anscheinend ist das Modul TimeSeries.pm dafür gemacht, denn wenn man diese Daten zu bestimmten Zeitpunkten liest muss man ja sicherstellen, dass man die dahinter liegenden wahren Daten korrekt erfasst. Denkbar wäre zB, dass die Daten sinusförmig schwanken und man blöderweise immer im Tal misst oÄ Probleme. Genau diese Fragen interessieren mich hier gar nicht.

Ich habe nämlich diskrete Daten, die nur an gewissen Zeitpunkten anfallen und dann auch vollständig gelesen werden:
10:10:11 => 1m^3 Gas
10:12:39 => 0m^3 Gas  <== so was erscheint auch, obwohl logisch unsinnig
10:13:13 => 2m^3 Gas
10:15:19 => 1m^3 Gas

Diese Werte will ich auswerten. Ich will wissen, wie viel Gas in einem bestimmten Zeitraum verbraucht wurde. Mir ist nicht klar, ob das Modul TimeSeries.pm bzw der event-aggregator das machen. Zum einen sind die Zeitabstände zwischen den Verbrauchszeitpunkten unterschiedlich und dann kann es sein, dass die Verbrauchsmengen auch schwanken, so wie im Beispiel. (Bei mir scheint das aber eher nicht der Fall zu sein, da ich jede Umdrehung des Gaszählers erfasse.)

Ich weiß nun nicht, wie ich zB die Summe aller Verbräuche der letzten X Sekunden messen kann. Wären die Zeitabstände konstant, dann wäre das einfach: man zählt diejenigen Einträge, die ungleich null sind. Wegen der verschiedenen Zeitabstände geht das aber nicht. Die Länge der Zeitabstände spielt auch keine Rolle, so dass eine zeitliche Gewichtung nicht in Frage kommt - die erfassten Daten sind diskret und da passiert "dahinter" nichts, was auch noch beachtet werden müsste.

Ich verstehe leider den Programmcode von TimeSeries.pm nicht, sonst hätte ich versucht mir was eigenes zu bauen. Im Grunde muss es ja irgendwie so sein. Ich definiere eine Variable "Summe" und schleppe die gesamte Zeit eine Liste mit den alten Werten mit (Zeitpunkt und Verbrauch). Wenn ein Wert einen Zeitstempel hat, der  außerhalb des zu erfassenden Bereiches liegt, fliegt er aus der Liste. Zeitgleich wird die Summe um den dazugehörigen Verbrauchswert gemindert. Wenn ein neuer Wert eintrifft, wird Zeitpunkt und Verbrauch der Liste dazugefügt; parallel wird Summe um Verbrauch erhöht. Das klingt alles plausibel - ist das irgendwo schon in TimeSeries umgesetzt? Macht das vielleicht auch event-aggrgeator? Sehe ich hier was elementares nicht?!
Titel: Antw:Verständnis event-aggregator erneut
Beitrag von: andies am 24 Oktober 2022, 14:26:31
Langsam steige ich durch den Code durch. Also die statistischen Kenngrößen werden hier berechnet
sub _updatestat($$) {
  my ($self, $V)= @_;
  my $n= ++$self->{n};
  if($n> 1) {
    my $M= $self->{_M};
    $self->{_M}= $M + ($V - $M) / $n;
    $self->{_S}= $self->{_S} + ($V - $M) * ($V - $self->{_M});
    $self->{integral}+= $V;
    #main::Debug("V= $V M= $M _M= ".$self->{_M}." _S= " .$self->{_S}." int= ".$self->{integral});
  } else {
    $self->{_M}= $V;
    $self->{_S}= 0;
    $self->{integral}= $V;
  }

Man sieht deutlich, dass das Integral eine Addition aller $V ist und bei den $V handelt es sich um die Messwerte (_M scheinen Mittelwert und _S Standardabweichung zu sein).  ). Ohne Zeitgewichtung ist das gleich
  if($self->{method} eq "none") {
          # no time-weighting
          $self->_updatestat($vn);

und mit Zeitgewichtung
if($self->{method} eq "const") {
              # steps
              $self->_updatestat($vo * $dt);
            } else {
              # linear interpolation 
              $self->_updatestat(0.5 * ($vo + $vn) * $dt);


Passt also zu meinem Problem! Ich denke, meine Version leistet doch das, was ich brauche. Also for the record, ich nehme
defmod Heizungskeller dummy
attr Heizungskeller event-aggregator Gasverbrauch_aggregiert:300:none:integral:300
attr Heizungskeller userReadings Gasverbrauch difference {ReadingsVal($name,"gas",0)/10}, \
Zaehlerstand {ReadingsVal($name,"gas",0)/100;;;;},\
Gasverbrauch_aggregiert {ReadingsVal($name, "Gasverbrauch",0);;;;}

Ich bastle mal ein wenig an dem Wikipedia Artikel, um den etwas aufzuhübschen.
Titel: Antw:Verständnis event-aggregator erneut
Beitrag von: Reinhard.M am 05 November 2022, 15:41:34
Hallo andies,

erst einmal nur als Feedback: ich habe gerade diesen Thread gefunden da ich die aggregator Funktion verwenden wollte. Allerdings ist die Commandref dazu eine Katastrophe. Die versteht nur derjenige der sie geschrieben hat. Wenn überhaupt. Für mich ist jedenfalls weder die Beschreibung noch die darin aufgeführten Beispiele nachvollziehbar und somit werde ich die Funktion erst einmal nicht verwenden. Würde mich freuen, wenn du weiter am Ball bleibst. Helfen kann ich dir leider nicht aber ich hoffe, dass ich mit dem von dir überarbeiteten Wiki Artikel dann besser zurecht komme.

Gruß Reinhard
Titel: Antw:Verständnis event-aggregator erneut
Beitrag von: andies am 05 November 2022, 15:43:02
Schreib mal, was du möchtest und dann probieren wir gemeinsam. Ist für mich eine ,,challenge", wie meine pubertierenden Kinder sagen würden ;-)
Titel: Antw:Verständnis event-aggregator erneut
Beitrag von: andies am 05 November 2022, 15:44:54
PS Evtl ist auch das wichtig  https://forum.fhem.de/index.php/topic,129920.0.html (https://forum.fhem.de/index.php/topic,129920.0.html)
Titel: Antw:Verständnis event-aggregator erneut
Beitrag von: Reinhard.M am 05 November 2022, 16:17:50
Zitat von: andies am 05 November 2022, 15:43:02
Schreib mal, was du möchtest und dann probieren wir gemeinsam. Ist für mich eine ,,challenge", wie meine pubertierenden Kinder sagen würden ;-)
Na ja, für die "challenge" brauch ich nicht einmal pubertierende Kinder, das kommt auch täglich über das Business-Bullshit-Bingo ;)
Eigentlich ist mein Thema recht trivial und lässt sich sicherlich mit "userReadings" einfacher lösen. Ich habe eine DECT200 Steckdose die kontinuierlich Power und Total Energy anzeigt. Meine Tasmota Steckdosen verfügen darüber hinaus über "EnergyToday" und "EnergyYesterday". Ich hatte erst überlegt das Integral über Power zu bilden. Viel leichter dürfte es aber sein, über "userReadings" um Mitternacht den aktuellen Energy Wert abzuspeichern und den "Today" Wert aus der Differenz des aktuellen Energy Wertes und dem Mitternachtswert zu bilden. Der Yesterday Wert ergibt sich dann von selbst.
Gut möglich, dass ich in Zukunft die Funktion benötige, die Idee ist mir immer wieder mal gekommen. Bislang gab es für mich aber noch keinen konkreten Anlass bei dem ich es zwingend gebraucht hätte. Auf dein Angebot komme ich aber gerne wieder zurück wenn es soweit ist, vielen Dank :)
Titel: Antw:Verständnis event-aggregator erneut
Beitrag von: andies am 05 November 2022, 16:43:28
Ich habe so was ähnliches für die Verbräuche bei Gas, Strom und Wasser gemacht. In 99_myUtils.pm, etwas abgekürzt (bei mir steht da noch mehr drin)
sub VerbrauchswerteSpeichern(){
my  $Daten = ReadingsVal("Gasrechner", "Heizungskeller_GesamtGas_EnergyCostDayLast","").;
   fhem("setreading FileLog_GasTemperaturRegression logEntry ".$Daten);
   fhem("setreading Gasrechner Normverbrauch ".sprintf "%.1f", $Daten);   
}

und dieser Befehl wird dann mit einem notify (eigentlich mit YAAHM, https://wiki.fhem.de/wiki/Modul_YAAHM (https://wiki.fhem.de/wiki/Modul_YAAHM)) Mitternachts ausgelöst.