Neues Modul InfluxDBLogger

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

Vorheriges Thema - Nächstes Thema

timmib

Wenn die Zeile 117 so aussieht geht es:

$value =~ s/@ab[0]/eval(@ab[1])/ei;

Das Problem war, dass der das sonst schon ersetzt aber mit $1, weil $1 nicht richtig ausgewertet wird. Hilft Dir evtl als Workaround. Ich muss mal in Gänze gucken ob das so ideal ist.

kadettilac89

Zitat von: Hogi am 21 November 2020, 15:58:17
Leider ein. Ich habe nun verschiedene Ausdrücke mit online Regex Testern ausprobiert und die Variante mit dem Grouping erscheint mir auch logisch richtig und wird auch von den Regex Testern als richtig angesehen. Aber mit

attr logger conversions ([0-9]+)%=$1

meldet dropped_writes_last_message immer noch "FHT_3e14 actuator: 0%", d.h. das Prozentzeichen wird immer noch übergeben.
Unabhängig von der Convert-Routine. Wenn im Reading das % ohne Leerzeichen drin ist scheint das ein Problem im Modul zu sein. Du kannst hierzu auch einen Thread zum entsprechenden Modul öffnen. Es sollte nicht nötig sein, die Einheit vom Reading zu entfernen.

Hogi

Mit dem Workaround in Zeile 117 funktioniert es für mich nun perfekt. Habe in der InfluxDB noch aufgeräumt und alle unnötigen Series gedropt, so dass auch dort nur noch die Measurements vorhanden sind, die vom Modul übertragen werden. Alles nun tip top. Vielen Dank, Tim. Was'n geiler Tag  ;D

timmib

ZitatAlles nun tip top. Vielen Dank, Tim. Was'n geiler Tag
@Hogi Freut mich.

ZitatEs sollte nicht nötig sein, die Einheit vom Reading zu entfernen.

@kadettilac89
Wieso? Versteheh ich nicht. InfluxDB logged Skalare Werte. Was soll die Datenbank mit %, °C, km usw. anfangen? Welche Aufgabe siehst Du da am Modul?

kadettilac89



Zitat von: timmib am 21 November 2020, 20:33:47
@kadettilac89
Wieso? Versteheh ich nicht. InfluxDB logged Skalare Werte. Was soll die Datenbank mit %, °C, km usw. anfangen? Welche Aufgabe siehst Du da am Modul?

Zitat von: Hogi am 20 November 2020, 19:42:21
2) Ich übertrage ein paar FHT80 Readings meiner Thermostate. Eines davon ist die Ventilöffnung, die in den Readings z.B mit "10%" angegeben sind. Über attr <name> conversion 0%=0, 1%=1, ... konvertiere ich die Strings in die numerischen Werte. Bei 0% bis 100% wird das aber Mühsam. Es gibt doch bestimmt einen kürzeren Weg aus einem Reading das "%" zu entfernen.

Das Konvertieren eines Readings mit Wert 100% sollte überhaupt nicht nötig sein. Es gibt oder gab ein paar Module in denen die Readings nicht korrekt aufgebaut sind und das Leerzeichen zwischen <value> und <unit> fehlt. Das hat zur Folge das im Filelog, DB-Log oder hier in deinem Modul ein String statt einem reinem Zahlenwert verarbeitet wird.

Darum meine Empfehlung den Modulauto vom FHT80-Modul zu fragen ob das ein Fehler ist. Oder wie andere damit umgehen.

In HM-Thermostaten wird das vergleichbare Reading (valvePosition) mit z. B. mit  10 % ausgegeben. Da ist dann kein Zusatzaufwand nötig.

Alternativ ein UserREading mit ReadingsNum o. ä.. Wäre einfacher als regex auf % und so ...

timmib


gvzdus

Hi Tim,

ich habe mir 1-2 Tagen endlich den Ruck gegeben, auch mal mit Grafana & Co. auf Schönheit zu achten, und auf die Schnelle was bei Amazon als Datensenke für meinen FHEM-Raspi aufgesetzt. Was soll ich sagen: Mit dem Beispiel auf Seite 1 gelang es sofort, vielen Dank!
Spaßeshalber füttere ich gerade die Werte meines Stromzählers (6 Werte / Sekunde) hoch - klappt.
Mit HTTPS zieht es allerdings etwas viel CPU.

Egal. Auf jeden Fall hat es auf Anhieb und gut geklappt - Danke!!

timmib

Influx macht halt einfach Spaß. Ich kann nur jedem auch den Kapacitor ans Herz legen. Der kann auch per MQTT zurück nach FHEM "telefonieren".

gvzdus

Moin, also, natürlich ist Dein Modul das beste der Welt :-)

Was wäre denn d.E. die "Best practise", um massenhaft Events zu schaufeln?
Mein Usecase ist aktuell, die Daten auf einen AWS EC2-Server mit Ubuntu mit InfluxDB + Grafana zu schaufeln. Das umfasst aktuell alles rund um die MAX-Thermostate und Strom (Stromzähler und Solarproduktion).

Im Moment gönne ich mir spaßeshalber, die Stromzählerwerte komplett - also sekündlich und mit allen 3 Phasen - "hochzupusten".
Dass das per HTTPS für eine RPi 3 nicht die beste Idee ist, habe ich schon festgestellt und auf HTTP umgestellt.

Variante 1) Ich stelle auf was Anderes um
Variante 2) Ich pfusche an Deinem Modul herum und überlege mal, ob man da so was wie Aggregieren und Bulkupload hinbekommt. (Z.B. 5 Sekunden sammeln, dann pusten).

Was meinst Du?

Ansonsten, um vielleicht dem einen oder anderen Zeit zu sparen:

Meine Vorgehensweise für Datenquellen:
1) Device-Spezifikation anpassen und gucken, ob die Live-Daten in InfluxDB ankommen.
2) Alt-Daten vom File-Logger hinterherblasen.

Mikro-Perlscript "influxconv":
#!/usr/bin/perl

use Time::Local;

while (<>) {
  next unless (/^(\d{4})-(\d\d)-(\d\d)_(\d\d):(\d\d):(\d\d) (\S+) (\S+): ([0-9.]+)\s*$/);
  my $time = timelocal($6, $5, $4, $3, $2-1, $1);
  print "$8,site_name=$7 value=$9 $time"."000000000\n";
}


... und dann mit beispielsweise:

egrep '(temperature|desiredTemperature|valveposition)' eg_wohnz_wt1-2020.log  | influxconv | curl -XPOST -i http://<meine-url>/write?db=fhem --data-binary @-

hochpusten. Klappt selbst für geschwätzigere Geräte wie die Wandthermostate in einem Rutsch.

timmib

Hi,

das geht runter wie Öl.

Also in Antwort #16 war ja schonmal die Idee:
ZitatMan könnte natürlich zusätzlich zu dem additionalTags Attribut, auch ein additionalFields Attribut machen, nur müssten diese dann zeitgleich oder besser vor dem auslösenden Reading aktualisiert worden sein.
Sonst passt der Zeitpunkt nicht. Müsste man mal testen. Oft werden Readings ja im Bulk aktualisiert. https://wiki.fhem.de/wiki/DevelopmentModuleAPI#readingsEndUpdate
In den Fällen würde das dann passen.

Damit wäre ein Bulk möglich. Muss man wie geschrieben halt aufpassen, sonst kommt Murks bei raus, in dem Sinne, dass alte Werte geschrieben werden würden.

Soll ich das mal einbauen?

gvzdus

#40
Naja, InfluxDB arbeitet ja auf Nanosekundenbasis. Grundsätzlich hat ggf. der Zielserver die genauere Uhrzeit als der FHEM-Raspi. Aber in meinem Fall macht das keinen Unterschied. Daher würde ich zu jedem Event die Uhrzeit im Buffer mitspeichern und diese mit übergeben.

Ich muss jetzt sagen: Beim schnellen Lesen verstehe ich den Source nicht ganz. Ich sehe, dass Du die Events als Array und nicht zwingend einzeln bekommst, und mein gebrochenes Perl, die Größe des Arrays auszugeben, führt hierzu:

Eingefügt habe ich (kaputt):
<code>
    return "" if($devName eq "global" && grep(m/^INITIALIZED|REREADCFG$/, @{$events}));
    return "" if($own_hash->{TYPE} eq $dev_hash->{TYPE}); # avoid endless loops from logger to logger
    Log3 $name, 4, "InfluxDBLogger: [$name] notified about " . ((@#{$events})+1) . " events";
    foreach my $event (@{$events}) {
</code>
(Ich wollte die Arraygröße verstehen).

Das führt zu folgendem Logging:
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] notified about 1 events
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] notified from device MT175 about total_consumption: 357889.7
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] Sending data total_consumption,site_name=MT175 value=357889.7 to http://<myurl>/write?db=fhem
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] notified from device MT175 about total_consumption_Ch1: 357889.7
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] Sending data total_consumption_Ch1,site_name=MT175 value=357889.7 to http://<myurl>/write?db=fhem
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] notified from device MT175 about power: 304
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] Sending data power,site_name=MT175 value=304 to http://<myurl>/write?db=fhem
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] notified from device MT175 about 1.0.36.7.0.255: 312
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] Sending data 1.0.36.7.0.255,site_name=MT175 value=312 to http://<myurl>/write?db=fhem
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] notified from device MT175 about 1.0.56.7.0.255: -62
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] Sending data 1.0.56.7.0.255,site_name=MT175 value=-62 to http://<myurl>/write?db=fhem
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] notified from device MT175 about 1.0.76.7.0.255: 52
2020.11.26 09:25:34 4: InfluxDBLogger: [influxfhem] Sending data 1.0.76.7.0.255,site_name=MT175 value=52 to http://<myurl>/write?db=fhem


Also offenbar schon ein Array (auch wenn mein "((@#{$events})+1)") offenbar falsch ist), aber Du machst einzelne Writes daraus. Das wäre also schon einmal der erste Aggregationslayer.

Der zweite Aggregationslayer wäre dann ein Buffern für z.B: 1 Sekunde oder maximal z.B. 30 Messwerte, whatever first.

timmib

Hi,

der Witz ist das pro aktualisiertem Reading in FHEM ein Event kommt. Wenn man nun das "additionalFields" einbaut, würde dies AKTIV beim auslösenden Device die Readingsnachlesen um dann alle zusammen (das aus dem Event und die nachgelesenen) an Influx zu schicken. Das setzt wie gesagt aber vorraus, das diese nachgelesenen Werte genau so aktuell sind wie das was den Event auslöst. Sonst werden alte Daten verschickt.

Viele Grüße

Tim

gvzdus

Nee, wir reden aneinander vorbei.

Was ich möchte: Weniger HTTP-Operationen. Im Falle meines Stromzählers erhälst Du *einen* Notify-Aufruf mit mehreren Events. Die würde ich lieber in einem Rutsch hochgeblasen sehen, also das Ergebnis von InfluxDBLogger_BuildData erst zu einem String zusammenzuführen, und dann außerhalb der
foreach my $event (@{$events}) {
-Schleife - wenn der String nicht leer ist - als eine Operation hochzuladen.
Im Moment erhalte ich vom Stromzähler etwa 1 Notify pro Sekunde, und Du machst daraus 4-6 Writes, weil das @{$events} 4-6 Werte enthält.

Was Du erwähnst: Zusätzlich noch Readings auszulesen.

Was mh73 (?) m.E. wollte: Einzelreadings, die aus komplexen Key/Values bestehen, zu splitten.

timmib

#43
Aber das sind doch weniger HTTP Operationen wenn man mehrere Readings in ein Write packt.

Man kann natürlich auch den Kram aus einem Notify sammeln, aber das wird wohl wenig bringen weil selten zufällig geloggete Geräte gleichzeitig auslösen und inhaltlich es es auch ungünstig die Werte von einem Gerät zu splitten auf mehrer Measurements.

https://docs.influxdata.com/influxdb/v1.8/guides/write_data/#writing-multiple-points

gvzdus

Schau Dir doch bitte noch einmal mein obiges Posting an:
Ich habe eine Zeile in Dein Modul eingebaut, die die Anzahl der Events loggen sollte, das aber nicht getan hat ("1" statt richtigem Wert). Das ist aber egal, weil man im darunterstehenden Aufruf erkennt, dass im events-Array mehrere "Zeilen" waren. Der Grund ist, dass das OBIS-Modul sauber aufgebaut ist und mit "BulkUpdate" mehrere geänderte Readings zu einem Block zusammenfasst.

Daher bekommst "Du" auch ein Array von x events. Du machst daraus aber unnötigerweise x HTTP-Aufrufe.