Neues Modul InfluxDBLogger

Begonnen von timmib, 07 Oktober 2020, 23:31:09

Vorheriges Thema - Nächstes Thema

rob

Das readingsProxy hatte ich vorgeschlagen, um die benötigten Readings herauszuschälen und jew. ein übersichtliches Device zu bekommen (z.B. power1, power2). Influx dann triggern lassen auf z.B. power.*
Das Atrribut event-aggregator hatte ich ebenfalls dort gesehen, damit die orig. Devices unangetastet bleiben können und nur im Proxy nach Bedarf modifiziert wird.

Warum bei Dir der Proxy keine Events auslöst, weiß ich nicht.
In meinem Test kommen Events, wenn ich in den Dummys etwas eingebe:
2023-05-25 08:18:08.198 readingsProxy power1 410
2023-05-25 08:18:08.198 dummy powermeter power: 410
2023-05-25 08:22:51.407 readingsProxy power1 430
2023-05-25 08:22:51.407 dummy powermeter power: 430
2023-05-25 08:42:09.768 readingsProxy power1 420
2023-05-25 08:42:09.768 dummy powermeter power: 420
2023-05-25 08:42:19.555 readingsProxy power2 340
2023-05-25 08:42:19.555 dummy solar total_power: 340

Wenn ich Dich richtig verstanden hatte, dann sollen beim Triggern eines Readings einer Auswahl (Events) immer auch der Rest an Readings dieser Auswahl gelesen werden, auch wenn die gerade nicht aktualisiert wurden, sodass immer zur selben Zeit eine Influx-Erfassung erfolgen kann.

Diese Ansätze müssten das auch unterstützen:

- AT oder DOIF, was periodisch (z.B. alle Minute) die Readings holt oder auf eines der readings triggert (dev1:reading.*|dev2.reading.*; [dev1:reading] or [dev2:reading] usw.) und dann den Rest auch abholt
- mit setreading wieder ins jew. Device reintun/ oder woanders reinschreiben (z.B. dummy)
- inlux-Device auf die Devices triggern lassen wenn setreading, oder halt auf dummy

- analog müsste das mit userreadings im jew. Device auch klappen, wäre imho nur etwas unübersichtlicher
- influx auf die devices triggern lassen ggf. per whitelist eingrenzen

Wären also vier Ansätze letztlich mit gleichem Timestamp vom Influx-Device in die DB schreiben zu lassen. Details müssten natürlich noch ausgeknobelt werden.
Du hast dann allerdings nur eine Scheingenauigkeit, weil der nicht-triggernde Wert noch immer derselbe sein wird, wie beim letzten Event - außer Du machst Berechnungen á la Durchschnittswert o.ä. per event-aggregator & Co..

Ertrag und Eigenverbrauch etc. visualisiere ich auch mit Grafana. Ich synchronisiere die Timestamps jedoch nicht. Ich bin nicht sicher, ob Dir der Aufwand am Ende mehr bringt.

lewej

Hallo rob,

das ist interessant. Könntest du mir deine Definition vom ProxyReading zur Verfügung stellen. Wenn bei dir Events getriggert werden, dann müsste das ja theoretisch auch bei mir gehen.

Gruss und Danke

rob

Ich hatte die so aufgebaut:
define power1 readingsProxy powermeter:power
attr power1 event-aggregator state:120:none:v

define power2 readingsProxy solar:total_power
attr power2 event-aggregator state:120:none:v

define powermeter dummy
attr powermeter readingList power
attr powermeter setList power

define solar dummy
attr solar readingList total_power
attr solar setList total_power

setstate power1 420
setstate power1 2023-05-26 06:29:59 state 420

setstate power2 340
setstate power2 2023-05-26 06:29:59 state 340

setstate powermeter 2023-05-25 08:42:09 power 420

setstate solar 2023-05-25 08:42:19 total_power 340
Aber lass Dich nicht zu sehr auf dem Proxy festnageln. Wenn es nicht will, investierst Du im Zweifel dort unnötig Zeit, ohne beim eigentl. Thema weiter zu kommen.

Ich hab mal ganz auf die Schnelle einen Sammeldummy + Notify geschustert. Zum Verdeutlichen. Wenn Du anstelle meiner zwei Dummys oben Deine echten Devices nimmst, müsste das Notify in den Testdummy immer gleiche Timestamps schreiben. In meinem Aufbau der Fall. Welches der zwei Events gerade triggert ist wurscht. Denn das Notify reagiert auf beide --> löst 1 aus, werden 1+2 geschrieben; löst 2 aus, werden 1+2 geschrieben - das ist der eigentl. Kniff.
define dmy_test dummy
attr dmy_test readingList erzeugte_power bezogene_power
attr dmy_test setList erzeugte_power bezogene_power

define nfy_test notify solar:total_power:.*|powermeter:power:.*\
{\
my $solar_power = ReadingsNum('solar','total_power',0);;\
my $meter_power = ReadingsNum('powermeter','power',0);;\
\
fhem("setreading dmy_test bezogene_power $meter_power");;\
fhem("setreading dmy_test erzeugte_power $solar_power");;\
\
}

setstate dmy_test 2023-05-26 06:55:46 bezogene_power 310
setstate dmy_test 2023-05-26 06:55:46 erzeugte_power 100

setstate nfy_test 2023-05-26 06:55:46
setstate nfy_test 2023-05-26 06:55:39 state active
setstate nfy_test 2023-05-26 06:55:46 triggeredByDev powermeter
setstate nfy_test 2023-05-26 06:55:46 triggeredByEvent power: 310
Auf den Testdummy kannst dann testweise InfluxDB reagieren lassen:
defmod myTestInflux InfluxDBLogger http://<IP>:<PORT> myinfluxdb <yourdev1>,<yourdev2>.*,dmy_test
Bei dem Beispiel wäre event-aggregator im dmy_test gut aufgehoben.
Gibt ganz sicher noch viel ausgebufftere Varianten. Ich denke, das ist trotzdem ein solider Start ;)

lewej

Hallo rob,

Was soll ich sagen, einfach nur Super. Der notify macht das was ich will.
Alle Readings landen mit dem selben Zeitstempel in der influxx.

Ist zwar etwas umfangreich mit dem definieren aber man macht es eigentlich nur einmal.

Danke und Gruss

Zitat von: rob am 26 Mai 2023, 07:17:21Ich hatte die so aufgebaut:
define power1 readingsProxy powermeter:power
attr power1 event-aggregator state:120:none:v

define power2 readingsProxy solar:total_power
attr power2 event-aggregator state:120:none:v

define powermeter dummy
attr powermeter readingList power
attr powermeter setList power

define solar dummy
attr solar readingList total_power
attr solar setList total_power

setstate power1 420
setstate power1 2023-05-26 06:29:59 state 420

setstate power2 340
setstate power2 2023-05-26 06:29:59 state 340

setstate powermeter 2023-05-25 08:42:09 power 420

setstate solar 2023-05-25 08:42:19 total_power 340
Aber lass Dich nicht zu sehr auf dem Proxy festnageln. Wenn es nicht will, investierst Du im Zweifel dort unnötig Zeit, ohne beim eigentl. Thema weiter zu kommen.

Ich hab mal ganz auf die Schnelle einen Sammeldummy + Notify geschustert. Zum Verdeutlichen. Wenn Du anstelle meiner zwei Dummys oben Deine echten Devices nimmst, müsste das Notify in den Testdummy immer gleiche Timestamps schreiben. In meinem Aufbau der Fall. Welches der zwei Events gerade triggert ist wurscht. Denn das Notify reagiert auf beide --> löst 1 aus, werden 1+2 geschrieben; löst 2 aus, werden 1+2 geschrieben - das ist der eigentl. Kniff.
define dmy_test dummy
attr dmy_test readingList erzeugte_power bezogene_power
attr dmy_test setList erzeugte_power bezogene_power

define nfy_test notify solar:total_power:.*|powermeter:power:.*\
{\
my $solar_power = ReadingsNum('solar','total_power',0);;\
my $meter_power = ReadingsNum('powermeter','power',0);;\
\
fhem("setreading dmy_test bezogene_power $meter_power");;\
fhem("setreading dmy_test erzeugte_power $solar_power");;\
\
}

setstate dmy_test 2023-05-26 06:55:46 bezogene_power 310
setstate dmy_test 2023-05-26 06:55:46 erzeugte_power 100

setstate nfy_test 2023-05-26 06:55:46
setstate nfy_test 2023-05-26 06:55:39 state active
setstate nfy_test 2023-05-26 06:55:46 triggeredByDev powermeter
setstate nfy_test 2023-05-26 06:55:46 triggeredByEvent power: 310
Auf den Testdummy kannst dann testweise InfluxDB reagieren lassen:
defmod myTestInflux InfluxDBLogger http://<IP>:<PORT> myinfluxdb <yourdev1>,<yourdev2>.*,dmy_test
Bei dem Beispiel wäre event-aggregator im dmy_test gut aufgehoben.
Gibt ganz sicher noch viel ausgebufftere Varianten. Ich denke, das ist trotzdem ein solider Start ;)


mlau

#289
Hallo,

Ich habe ein Problem mit dem logging von den meisten meiner KNX readings.
Das Problem scheint zu sein, dass das KNX Modul, abhängig vom Datentyp der Gruppenaddresse, auch gleich eine Einheit an den Wert hängt.
Das führt dann dazu, dass die Allermeisten KNX readings als nicht-numerisch eingestuft werden.

in Zeile 361, die Regex scheint nur nach dem ":" zu trennen; die Einheit wird nicht abgeschnitten:

356    sub InfluxDBLogger_Map($$$$)
357    {
358        my ($hash, $dev_hash, $event, $map) = @_;
359        my $name = $hash->{NAME};
360        my $deviceName = $dev_hash->{NAME};
361        my @readingAndValue = split(":[ \t]*", $event, 2);
362        my $readingName = $readingAndValue[0];
363        my $readingValue = $readingAndValue[1];
[...]
375        $map->{$deviceName}->{$readingName}->{"numeric"} = $readingValue =~ /^[-+]?[0-9]*[\.\,]?[0-9]+([eE][-+]?[0-9]+)?$/;

der $event ist z.b. "getG1: 300,5 W", die readingValue daher "300,5 W", und lt regex in 375 daher nicht numeric, was
später dazu führt dass das reading in BuildData() als incompatible verworfen wird.
Mein perl-fu ist null, daher hoffe ich dass der Ersteller des Moduls hier vielleicht etwas machen kann..

Danke!
  M.

EDIT: habs nun so gefixt:

--- 93_InfluxDBLogger.pm.orig   2023-07-04 19:13:47.334744323 +0200
+++ 93_InfluxDBLogger.pm        2023-07-04 19:12:49.212603906 +0200
@@ -360,7 +360,8 @@ sub InfluxDBLogger_Map($$$$)
     my $deviceName = $dev_hash->{NAME};
     my @readingAndValue = split(":[ \t]*", $event, 2);
     my $readingName = $readingAndValue[0];
-    my $readingValue = $readingAndValue[1];
+    my @readingValueUnit = split(" ", $readingAndValue[1], 2);
+    my $readingValue = $readingValueUnit[0];
 
     my $conversions = AttrVal($name, "conversions", undef);
     if ( defined($conversions)) {

lewej

Hallo rob,

Leider hab ich mich zu früh gefreut. Die Werte sind meistens auf die Sekunde genau, jedoch unterschiedlich sind die Millisekunden die in die InfluxDB weggeschrieben werden. Das heisst dort kann man die Werte nicht zueinander bringen.

Mit flux und der pivot Tabellen Funktion bleibt die Auswertung leer.

Als ich darüber nachgedacht habe, was ja beim setreading passiert, war mir auch klar sie Millisekunden auseinander laufen werden.

Es werden ja nur Befehle nach einander abgesetzt.
Hast du noch eine Idee oder jemand anders, wie ich Werte mit selben Zeitstempeln wegschreiben kann?

Gruss


Zitat von: lewej am 27 Mai 2023, 10:19:45Hallo rob,

Was soll ich sagen, einfach nur Super. Der notify macht das was ich will.
Alle Readings landen mit dem selben Zeitstempel in der influxx.

Ist zwar etwas umfangreich mit dem definieren aber man macht es eigentlich nur einmal.

Danke und Gruss

Zitat von: rob am 26 Mai 2023, 07:17:21Ich hatte die so aufgebaut:
define power1 readingsProxy powermeter:power
attr power1 event-aggregator state:120:none:v

define power2 readingsProxy solar:total_power
attr power2 event-aggregator state:120:none:v

define powermeter dummy
attr powermeter readingList power
attr powermeter setList power

define solar dummy
attr solar readingList total_power
attr solar setList total_power

setstate power1 420
setstate power1 2023-05-26 06:29:59 state 420

setstate power2 340
setstate power2 2023-05-26 06:29:59 state 340

setstate powermeter 2023-05-25 08:42:09 power 420

setstate solar 2023-05-25 08:42:19 total_power 340
Aber lass Dich nicht zu sehr auf dem Proxy festnageln. Wenn es nicht will, investierst Du im Zweifel dort unnötig Zeit, ohne beim eigentl. Thema weiter zu kommen.

Ich hab mal ganz auf die Schnelle einen Sammeldummy + Notify geschustert. Zum Verdeutlichen. Wenn Du anstelle meiner zwei Dummys oben Deine echten Devices nimmst, müsste das Notify in den Testdummy immer gleiche Timestamps schreiben. In meinem Aufbau der Fall. Welches der zwei Events gerade triggert ist wurscht. Denn das Notify reagiert auf beide --> löst 1 aus, werden 1+2 geschrieben; löst 2 aus, werden 1+2 geschrieben - das ist der eigentl. Kniff.
define dmy_test dummy
attr dmy_test readingList erzeugte_power bezogene_power
attr dmy_test setList erzeugte_power bezogene_power

define nfy_test notify solar:total_power:.*|powermeter:power:.*\
{\
my $solar_power = ReadingsNum('solar','total_power',0);;\
my $meter_power = ReadingsNum('powermeter','power',0);;\
\
fhem("setreading dmy_test bezogene_power $meter_power");;\
fhem("setreading dmy_test erzeugte_power $solar_power");;\
\
}

setstate dmy_test 2023-05-26 06:55:46 bezogene_power 310
setstate dmy_test 2023-05-26 06:55:46 erzeugte_power 100

setstate nfy_test 2023-05-26 06:55:46
setstate nfy_test 2023-05-26 06:55:39 state active
setstate nfy_test 2023-05-26 06:55:46 triggeredByDev powermeter
setstate nfy_test 2023-05-26 06:55:46 triggeredByEvent power: 310
Auf den Testdummy kannst dann testweise InfluxDB reagieren lassen:
defmod myTestInflux InfluxDBLogger http://<IP>:<PORT> myinfluxdb <yourdev1>,<yourdev2>.*,dmy_test
Bei dem Beispiel wäre event-aggregator im dmy_test gut aufgehoben.
Gibt ganz sicher noch viel ausgebufftere Varianten. Ich denke, das ist trotzdem ein solider Start ;)


rob

So ganz verstehe ich nicht, wie/ wo Du auswertest/ visualisierst. Würden Dein Solar und Powermeter beide jede Sekunde senden und Du hättest immer ein Event und es ginge beides jede Sekunde in die InfluxDB, dann wären die Millisekunden auch immer mal unterschiedlich. Will sagen, wie sollte das auch anders sein? Selbst wenn Du exakt zeitgleich sendest, würde es auf den Nanosekunden doch wieder auseinanderlaufen  ;)

Ich habe auch Powermeter + Solar und visualisiere in FHEM und in Grafana. Strom wird jede Minute und Solar spätestens nach 5 Minuten aktualisiert. Trotzdem klappen die Visualisierungen nebst Berechnungen wunderbar. Warum? Weil man doch meist eh aggregiert z.B. via Differenz oder Durchschnittswert usw.

Millisekunden sollten m.E. hier keine Rollen spielen - wir arbeiten ja nicht am LHC (https://de.wikipedia.org/wiki/CERN#Large_Hadron_Collider) - die wären sonst auch noch zu grob  ;D . Aus meiner Sicht lässt sich das FHEM-seitig nur schwer lösen. Du könntest beim Visualisieren z.B. in Grafana entweder zuvor die Millisekunden abschneiden oder schlicht aggregieren. InfluxDB v2 bietet z.B. Funktionen dafür an (https://docs.influxdata.com/flux/v0/data-types/basic/time/#truncate-timestamps-to-a-specified-unit). Grafana macht das automatisch beim aggregieren und FHEM sind die millisec eh Wurscht.

Zitat von: lewej am 28 September 2023, 17:38:31...Mit flux und der pivot Tabellen Funktion bleibt die Auswertung leer...
Liest sich so, als würdest Du direkt im Influx-WebIf auswerten. Ich hab die V2 nicht und deshalb auch kein Webif. Ich behaupte mal keck, die Auswertungen dort sind eher für grobe Sichtungen/ Checks gedacht und zeigen dafür mehr die Rohwerte.
Zum Visualisieren imho weniger geeignet/ nicht so gedacht - das können Plots in FHEM oder eben Grafana besser.

Aber vielleicht hat noch jmd. Ideen oder Tricks im Köcher.

Viele Grüße
rob

lewej

Hier ist mal ein Beispiel:

from(bucket: "Strom")
    |> range(start: startTime, stop: fullHourTime)
    |> filter(fn: (r) => r._measurement == "pvdaten_proxy")
    |> filter(fn: (r) => r._field == "SMAHM_Einspeisung_Wirkleistung_Zaehler" or r._field == "SPOT_ETOTAL" or r._field == "priceIn")
    |> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value")
    |> filter(fn: (r) => r.SMAHM_Einspeisung_Wirkleistung_Zaehler > 0 and r.SPOT_ETOTAL > 0)
    |> difference(columns: ["SMAHM_Einspeisung_Wirkleistung_Zaehler", "SPOT_ETOTAL"])
    |> map( fn: (r) => ({r with _value: (r.SPOT_ETOTAL - r.SMAHM_Einspeisung_Wirkleistung_Zaehler) / 1000.0 * r.priceIn}))

Wenn die Werte nicht mit gleichen Zeitstempel versehen sind, wird die pivotabelle nicht richtig befühlt und somit funktioniert es dann nicht.