[commandref fehlerhaft] Zum Verständnis von grafana und event-aggregator

Begonnen von andies, 27 Oktober 2022, 20:56:41

Vorheriges Thema - Nächstes Thema

andies

Ich habe nach wie vor Schwierigkeiten, MYSQL, grafana und event-aggregator zu verstehen. Vielleicht kann mir jemand mithelfen. Was ich liefern kann ist ein eindeutiger Datensatz.

Ich messe meinen Gasverbrauch und die Konstruktion bringt es mit sich, dass ich jedes Hinaufzählen des Gaszählers erfasse. Das sah vor einigen Tagen so aus:
16:31:25 0,01
16:31:48 0,01
16:32:05 0,01
16:32:24 0,01
16:32:39 0,01
16:32:56 0,01
16:33:10 0,01
16:33:26 0,01
16:33:40 0,01
16:33:55 0,01
16:34:09 0,01
16:34:23 0,01
16:34:37 0,01
16:34:51 0,01
16:35:05 0,01
16:35:19 0,01
16:35:33 0,01
16:35:47 0,01
16:36:01 0,01
16:36:16 0,01
16:36:30 0,01
16:36:46 0,01
16:37:01 0,01
16:37:17 0,01
16:37:34 0,01
16:37:50 0,01
16:38:07 0,01
16:38:25 0,01
16:38:42 0,01
16:38:59 0,01
16:39:17 0,01
16:39:36 0,01
16:39:54 0,01
16:40:12 0,01
16:40:32 0,01
16:40:52 0,01
16:41:11 0,01
16:41:31 0,01
16:41:52 0,01
16:42:13 0,01
16:42:33 0,01
16:42:55 0,01
16:43:18 0,01
16:43:40 0,01
16:44:03 0,01
16:44:28 0,01
16:44:51 0,01
16:45:15 0,01
16:45:40 0,01
16:46:06 0,01
16:46:32 0,01
16:46:59 0,01
16:47:26 0,01
16:47:54 0,01
16:48:22 0,01
16:48:51 0,01
16:49:21 0,01
16:49:52 0,01
16:50:24 0,01
16:50:57 0,01
16:51:31 0,01
16:52:06 0,01
16:52:41 0,01
16:53:17 0,01
16:53:54 0,01
16:54:33 0,01
16:55:14 0,01
16:55:55 0,01
16:56:36 0,01
16:57:21 0,01
16:58:06 0,01
16:58:52 0,01
16:59:39 0,01
17:00:31 0,01
17:01:23 0,01
17:02:16 0,01
17:03:08 0,01
17:04:01 0,01
17:04:54 0,01

Das mit dem 0,01 muss man ignorieren, es ist genau eine Umdrehung, die zu dem Zeitpunkt (der links steht) stattfand. Mit so einem exakten Datensatz kann man wenig anfangen. Ich habe ihn trotzdem geplottet, siehe Rohdaten.

Ein wenig klarer wird, was da passiert, wenn man die zeitlichen Abstände in Sekunden zwischen zwei Durchläufen erfasst. Das ist das Bild "Zeit zwischen Durchläufen", hier auch davon die Rohdaten
16:31:25
16:31:48 23
16:32:05 17
16:32:24 19
16:32:39 15
16:32:56 17
16:33:10 14
16:33:26 16
16:33:40 14
16:33:55 15
16:34:09 14
16:34:23 14
16:34:37 14
16:34:51 14
16:35:05 14
16:35:19 14
16:35:33 14
16:35:47 14
16:36:01 14
16:36:16 15
16:36:30 14
16:36:46 16
16:37:01 15
16:37:17 16
16:37:34 17
16:37:50 16
16:38:07 17
16:38:25 18
16:38:42 17
16:38:59 17
16:39:17 18
16:39:36 19
16:39:54 18
16:40:12 18
16:40:32 20
16:40:52 20
16:41:11 19
16:41:31 20
16:41:52 21
16:42:13 21
16:42:33 20
16:42:55 22
16:43:18 23
16:43:40 22
16:44:03 23
16:44:28 25
16:44:51 23
16:45:15 24
16:45:40 25
16:46:06 26
16:46:32 26
16:46:59 27
16:47:26 27
16:47:54 28
16:48:22 28
16:48:51 29
16:49:21 30
16:49:52 31
16:50:24 32
16:50:57 33
16:51:31 34
16:52:06 35
16:52:41 35
16:53:17 36
16:53:54 37
16:54:33 39
16:55:14 41
16:55:55 41
16:56:36 41
16:57:21 45
16:58:06 45
16:58:52 46
16:59:39 47
17:00:31 52
17:01:23 52
17:02:16 53
17:03:08 52
17:04:01 53
17:04:54 53

Jetzt sieht man (was sich bei den Rohdaten nur andeutet), dass am Anfang die Zeit zwischen zwei Durchläufen in etwa gleich ist und dann immer größer wird.

Weder das erste Bild noch das zweite eignen sich für eine Verbrauchsansicht. Hier kommen nun grafana und event-aggregator ins Spiel. Wie beide funktionieren, ist mir nur zum Teil klar. Und damit dieser Post nicht zu lange wird, mache ich mit einem zweiten weiter.
FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

andies

In grafana nutze ich folgenden Code zur Darstellung,
SELECT
  UNIX_TIMESTAMP(TIMESTAMP) as time_sec,
  AVG(0.3*VALUE) as value,
  "Gasverbrauch" as metric
FROM history
WHERE READING="Gasverbrauch" AND DEVICE="Heizungskeller" AND $__timeFilter(TIMESTAMP)
GROUP BY UNIX_TIMESTAMP(TIMESTAMP) DIV 300

Das mit dem 0,3 habe ich durch ausprobieren gefunden, weil dann die Verbrauchsdaten passten. Ich nehme an, durch das "Group by" werden jeweils Daten, die 300 Sekunden beieinander liegen, erfasst. Die Daten, die dann erscheinen, sind die folgenden (man kann in grafana die Daten anzeigen lassen)

16:31:25 0,028
16:35:05 0,0285
16:40:12 0,028
16:45:15 0,0275
16:50:24 0,0267
16:55:14 0,0263
17:00:31 0,03

Das Bild sieht so aus wie im Anhang.

Was ich nicht verstehe (und ich muss zugeben, dass ich MySQL nur kopiert habe): Am Ende wird ja im Schnitt (bei gleich bleibenden Zeitintervallen) weniger verbraucht. Das sieht man aber in grafana nicht. Nun ist es so, dass zwischendrin (also zwischen den von mir erfassten Zeitpunkten) weitere Events stattfinden, die das hier meldende Gerät "Heizungskeller" auch erfassen, aber nichts mit Gasverbrauch zu tun haben. D.h. es gibt in der DbLog-Datenbank weitere Einträge der Form
16:37:50 Heizungskeller Gasverbrauch: 0.0999999999985448
16:37:57 Heizungskeller Gasverbrauch: 0 <== HIER
16:38:07 Heizungskeller Gasverbrauch: 0.0999999999985448

Es sind allerdings nur wenige Einträge (fünf oder sechs). Mich wundert, dass das Bild von grafana jedenfalls so aussieht, wie es aussieht. Für mich passt das nicht. Am Anfang müsste ein stärkerer Anstieg zu sehen sein, am Ende ein schwächeres abfallen.
FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

andies

#2
Und dann kommt noch event-aggregator ins Spiel. Damit hatte ich es auch nicht leicht (https://forum.fhem.de/index.php/topic,129800.msg1240718.html#msg1240718). Auch da habe ich die Daten erfasst, doch zuerst die Definition
Internals:
   CFGFN     
   NAME       Heizungskeller
   NR         248067
   TYPE       dummy
   eventCount 4715
   Helper:
     DBLOG:
       Gasverbrauch:
         DbLog:
           TIME       1666897651.4227
           VALUE      0
       Gasverbrauch_aggregiert:
         DbLog:
           TIME       1666897651.4227
           VALUE      0
       data:
         DbLog:
           TIME       1666379104.38363
           VALUE      Gasverbrauch_aggregiert:
       wasser:
         DbLog:
           TIME       1666897651.4227
           VALUE      1975
   READINGS:
     2022-10-22 10:09:35   Fehler          KeyError: Reading gas unlesbar {}
     2022-10-27 21:07:31   Gasverbrauch    0
     2022-10-27 21:07:31   Gasverbrauch_aggregiert 0
     2022-10-27 21:07:31   Zaehlerstand    6517.39
     2022-10-27 17:04:54   gas             651739
     2022-10-27 21:07:31   wasser          1975
Attributes:
   event-aggregator Gasverbrauch_aggregiert:300:none:integral:300
   userReadings Gasverbrauch difference {ReadingsVal($name,"gas",0)/10},
Zaehlerstand {ReadingsVal($name,"gas",0)/100;;},
Gasverbrauch_aggregiert {ReadingsVal($name, "Gasverbrauch",0);;}

und "gas" wird direkt mit python hochgezählt, wenn sich der Zähler einmal gedreht hat (silberne Sechs).

Das Bild, dass der Aggregator erzeugt, sieht mE viel plausibler aus. Da ist der Anstieg am Anfang genau so wie erwartet und am Ende auch, siehe Anhang. Auch da habe ich die Rohdaten, die sind allerdings um einen Faktor zehn falsch (lag an meiner Konvertierung, um sie lesbar zu machen):
16:31:48 0,10
16:32:05 0,20
16:32:18 0,30
16:32:24 0,30
16:32:39 0,40
16:32:56 0,50
16:33:10 0,60
16:33:26 0,70
16:33:40 0,80
16:33:55 0,90
16:34:09 1,00
16:34:23 1,10
16:34:37 1,20
16:34:51 1,30
16:35:05 1,40
16:35:19 1,50
16:35:33 1,60
16:35:47 1,70
16:36:01 1,80
16:36:16 1,90
16:36:30 2,00
16:36:46 2,00
16:37:01 2,10
16:37:17 2,10
16:37:34 2,10
16:37:50 2,10
16:37:57 2,10
16:38:07 2,00
16:38:25 2,10
16:38:42 2,10
16:38:59 2,00
16:39:17 2,00
16:39:36 2,00
16:39:54 2,00
16:40:12 1,90
16:40:32 1,90
16:40:52 1,90
16:41:11 1,80
16:41:31 1,80
16:41:52 1,70
16:42:13 1,70
16:42:33 1,70
16:42:55 1,70
16:43:18 1,60
16:43:30 1,60
16:43:40 1,50
16:44:03 1,60
16:44:28 1,50
16:44:51 1,50
16:45:15 1,50
16:45:40 1,40
16:46:06 1,40
16:46:32 1,40
16:46:59 1,30
16:47:26 1,30
16:47:54 1,30
16:48:22 1,30
16:48:51 1,20
16:48:59 1,20
16:49:21 1,20
16:49:52 1,20
16:50:24 1,10
16:50:57 1,10
16:51:31 1,10
16:52:06 1,10
16:52:41 1,00
16:53:17 1,00
16:53:54 1,00
16:54:24 0,90
16:54:33 0,80
16:55:14 0,90
16:55:55 0,90
16:56:36 0,90
16:57:21 0,80
16:58:06 0,80
16:58:52 0,80
16:59:39 0,80
16:59:48 0,70
17:00:31 0,70
17:01:23 0,70
17:02:16 0,70
17:03:08 0,70
17:04:01 0,60
17:04:54 0,60
17:05:11 0,60
17:10:27 0,60


Ich muss sagen, dass ich nur zum Teil verstehe, was ich hier mache:

  • Wieso sind die grafana-Daten so irreführend? Wieso ist der Durchschnitt konstant, obwohl der nicht konstant ist?
  • Aggregator sieht viel besser aus. So ganz passen die Daten am Ende aber auch nicht, wieso laufen die nicht auf 0,1 aus? 17:04 war doch Schluss mit Gas?
  • "interval" beim Event-aggregator scheint nicht zu funktionieren: es dürften doch die einzelnen Einträge nur alle fünf Minuten erfolgen? Es heißt doch, dass in dieser Zeitspanne (300) events unterdrückt werden?
Sind meine Definitionen richtig? Oder mache ich woanders was falsch?
FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

andies

Jetzt habe ich einen anderen event-aggregator verwendet, nämlich
Gasverbrauch_aggregiert::none:integral:300
Einziger Unterschied ist, dass jetzt interval=undef gesetzt wird. Laut commandref heißt das
Zitatassociated events are suppressed for a black-out period of at least interval seconds (downsampling)
Das heißt, eigentlich hätte im oberen Post nur alle 5 Minuten ein update erfolgen müssen (was aber nicht der Fall war), jetzt müsste ständig ein update erfolgen. Unten ist das Bild für das Aggregat, hier kommen die Rohdaten, die sehen aus wie gestern. Spoiler: klappt.
Rohdaten
05:50:58 0,1
05:51:25 0,1
05:51:56 0,1
05:52:24 0,1
05:52:48 0,1
05:53:11 0,1
05:53:32 0,1
05:53:52 0,1
05:54:11 0,1
05:54:29 0,1
05:54:30 0
05:54:47 0,1
05:55:04 0,1
05:55:22 0,1
05:55:41 0,1
05:56:01 0,1
05:56:22 0,1
05:56:44 0,1
05:57:07 0,1
05:57:30 0,1
05:57:54 0,1
05:58:19 0,1
05:58:42 0,1
05:59:08 0,1
05:59:35 0,1
06:00:00 0,1
06:00:01 0
06:00:28 0,1
06:00:57 0,1
06:01:25 0,1
06:01:53 0,1
06:02:25 0,1
06:02:55 0,1
06:03:26 0,1
06:04:01 0,1
06:04:33 0,1
06:05:08 0,1
06:05:28 0
06:05:45 0,1
06:06:21 0,1
06:06:58 0,1
06:07:39 0,1
06:08:19 0,1
06:09:00 0,1
06:09:45 0,1
06:10:30 0,1
06:10:52 0
06:11:15 0,1
06:12:04 0,1
06:12:56 0,1
06:13:48 0,1
06:14:40 0,1
06:15:32 0,1
06:16:14 0
06:16:24 0,1
06:17:16 0,1
06:21:32 0

event-aggregator
05:51:25 0,1
05:51:56 0,2
05:52:24 0,3
05:52:48 0,4
05:53:11 0,5
05:53:32 0,6
05:53:52 0,7
05:54:11 0,8
05:54:29 0,9
05:54:30 1
05:54:47 1
05:55:04 1,1
05:55:22 1,2
05:55:41 1,3
05:56:01 1,4
05:56:22 1,4
05:56:44 1,5
05:57:07 1,5
05:57:30 1,5
05:57:54 1,5
05:58:19 1,5
05:58:42 1,5
05:59:08 1,5
05:59:35 1,5
06:00:00 1,4
06:00:01 1,4
06:00:28 1,4
06:00:57 1,3
06:01:25 1,3
06:01:53 1,2
06:02:25 1,2
06:02:55 1,2
06:03:26 1,1
06:04:01 1,1
06:04:33 1,1
06:05:08 1,1
06:05:28 1
06:05:45 1
06:06:21 1
06:06:58 1
06:07:39 0,9
06:08:19 0,9
06:09:00 0,9
06:09:45 0,9
06:10:30 0,8
06:10:52 0,8
06:11:15 0,7
06:12:04 0,8
06:12:56 0,7
06:13:48 0,7
06:14:40 0,7
06:15:32 0,7
06:16:14 0,6
06:16:24 0,6
06:17:16 0,6
06:21:32 0,6
06:26:48 0,1
06:32:04 0
06:37:20 0
06:42:36 0
06:47:52 0

Ich muss mal den Code von "interval" suchen und verstehen, da scheint irgendwas nicht zu stimmen.
FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann

andies

#4
Ich glaube, ich habe es jetzt. Beim event-aggregator wird in der commandref der Übergabewert "interval" so beschrieben, dass er events unterdrückt:
ZitatIf set, updates for the listed readings are ignored and associated events are suppressed for a black-out period of at least interval seconds (downsampling). After the black-out period has expired, the reading is updated with a value that is calculated from the values and timestamps of the previously ignored updates within the black-out period as follows...
Das heißt, interval stoppe die Events, rechne aber intern weiter.

In der Programmierung passiert anscheinend etwas anderes. Der aggregator taucht in fhem.pl einmal auf, und zwar hier
        require "TimeSeries.pm";
        $ts = TimeSeries->new( { method => $method,
                  autoreset => $duration,   <======= HIER
                  holdTime => $holdTime } );

Dort wird interval als Variable "autoreset" gesetzt und übergeben. Die Verarbeitung erfolgt dann in TimeSeries.pm, und zwar hier:
  my $self= {
    method => $args->{method} || "none",
    autoreset => $args->{autoreset}, # if set, resets series every autoreset seconds

Erläutert wird das am Ende des Programmcodes, nämlich so
ZitatIt is also possible to define autoreset and holdtime at the same time. In this case the data buffer
  is enabled and will be cleared each time an autoreset occurs, independent of the value of holdtime.
Das sehe ich auch im Code,
# has autoreset period elapsed?
# used by fhem.pl for downsampling
#
sub elapsed($$) {
  my ($self, $t)= @_;
  return defined($self->{autoreset}) && defined($self->{_t0}) && ($t - $self->{_t0} >= $self->{autoreset});
}

Das ist etwas anderes als das, was oben in der commandref steht. ME erklärt das die Differenzen, anders gesagt die commandref beschreibt nicht korrekt, was interval macht.

Wie fordert man denn Änderungen dort ein?
FHEM 6.1 auf RaspPi3 (Raspbian:  6.1.21-v8+; Perl: v5.32.1)
SIGNALduino (433 MHz) und HM-UART (868 MHz), Sonoff, Blitzwolf, Somfy RTS, CAME-Gartentor, Volkszähler, Keyence-Sensor, Homematic-Sensoren und -thermostat, Ferraris-Zähler für Wasseruhr, Openlink-Nachbau Viessmann