Neues Modul InfluxDBLogger

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

Vorheriges Thema - Nächstes Thema

timmib

Guten Tag,

da FHEM eine super Sache ist und die InfluxDB auch, gehören die beiden zusammen. Es gab schon ein externes erstes InfluxDBLog Modul von jemandem (siehe https://forum.fhem.de/index.php/topic,71551.msg1073087.html), aber es:

  • wurde nicht weiter gepflegt
  • blockierte den Main-Loop
  • war kaum konfigurierbar
  • intransparent was wirklich passierte
  • das Passwort wurde im Klartext gespeichert

Deswegen habe ich nun ein neues Modul geschrieben welches:

  • nicht den Main-Loop blockiert, da es die HTTPUtils verwendet
  • konfigurierbarer ist
  • transparent statistik-readings und logs produziert
  • das Passwort ordentlich gespeichert

Zum Thema "konfigurierbar":

  • Man kann die devspec und eine separate optionale regex für die readings definieren.
  • Bei einer devspec die auf alles matched disabled sich das Modul erstmal selber, weil es sonst die DB zumüllt.
  • Man kann über ein Attribut die Art der Security wählen (bisher basicAuth und keine, InfluxDB unterstützt aber auch Token
  • Das Passwort setzt man über set password, der user über ein Attribut
  • Man kann den Namen des Tags wählen wo der Devicename gespeichert wird. Um alte Datenschätze nicht zu stören ist der default wie beim alten Modul 'site_name'

Zum Thema "Statistik":

  • Es werden die Gesamtzahl die Erfolge und Mißerfolge gezählt
  • Es wird der letzte Fehler als Reading angezeigt
  • Es werden DNS, HTTP und Influx Fehler als Fehler erkannt
  • Man kann die Statisik über set resetStatistics zurücksetzen

Zum Thema "Sonstiges":

  • Es werden true,yes und on und deren Gegenspieler in 1 bzw. 0 übersetzt

Es auch mein erstes Modul aber besonders Mutige sind herzlich eingeladen das mal in einer Testumgebung zu testen. Ich selber habe es auch einer Testumgebung getestet und setze es nun auch produktiv ein.
Das Ziel ist es, das Ganze recht bald auch offiziel in SVN zu commiten.  8)

Es liegt englische und deutsche Dokumentation vor.

*** UPDATE  28.11.2020 ***
Das Schema ist jetzt frei konfigurierbar über die Attribute measurement,tags,fields.
Die HTTP Calls werden nun bei Bulk-Updates vereint.

*** UPDATE  30.11.2020 ***
tagset ist jetzt optional mit '-' (Danke an gvzdus)
Zeilen werden schon FHEM-seitig optimiert. (Danke nochmal an gvzdus)

*** UPDATE  09.12.2020 ***
Unterstützung für Influx2-Token Security und Perl-Ausdrücke in tags. Doku ergänzt.

*** UPDATE 10.12.2020 ***
Das Modul ist nun im FHEM SVN.

*** UPDATE 16.12.2020 ***
Es werden nun https://fhem.de/commandref.html#readingFnAttributes unterstützt. (Danke nochmal an gvzdus)
Damit lassen sich die Events des Loggers selber unterdrücken.

*** UPDATE 04.02.2022 ***
Es werden nun Zeichenketten als Wert und die originalen Zeitstempel unterstützt - siehe (https://forum.fhem.de/index.php/topic,114860.msg1205868.html#msg1205868 und Dank an msome)

Viele Grüße

Tim


timmib

Hier ein paar Worte zu der Design-Entscheidung die Geräte und Reading Filter in den Logger und nicht wie bei Dblog an die zu loggenden Devices zu packen:

Der Hintergrund hängt stark damit zusammen wie klassischen SQL Datenbanken aufgebaut sind und vor allem wie sie aufgesetzt werden. Und zwar recht aufwändig. Ohne das Schema zu definieren passiert recht wenig. Außerdem kennen klassiche SQL Datenbanken keine "Retention Policies" also zu Deutsch Vorhaltefristen.

Das ist bei InfluxDB beides anders. Hier wird eigentlich nur die leere Datenbank angelegt und die Messreihen und "Spalten" entstehen von alleine. Zum anderen sind "Retention Policies" Einwohner erster Güte. D.h. zur Defnition einer Datenbank gehört auch, wie lange die Daten dort drin zurückreichen.

Entsprechend ist es nicht unüblich verschiedenen Daten in verschiedenen Datenbanken zu schreiben. Da dies a) kein Aufwand ist und b) erlaubt die Daten unterschiedlich lang auzuheben.

Nun kommen wir endlich zu FHEM. Da man die Datenbank am Logger definiert, macht es Sinn auch dort den Kreis an Devices und Readings anzugeben welche geloggt werden sollen. Andersherum wie bei Dblog funktioniert das auch schlecht. Den die Auswahl der Datenbank und damit der Retention Policy über das Device was Loggen will wäre etwas Umständlich. Besonders, dann wenn aus dem selben Device Readings teilweise in die eine und in die andere Datenbank gehören.

Was denkt ihr?

plin

Zitat von: timmib am 07 Oktober 2020, 23:31:09
Zum Thema "Sonstiges":

  • Es werden true,yes und on und deren Gegenspieler in 1 bzw. 0 übersetzt

Wie kann ich die Liste erweitern (z.B. um open/closed)? Siehe auch https://forum.fhem.de/index.php/topic,71551.msg968874.html#msg968874
FHEM1 (Main) Raspi4 mit CUL, Homematic, SDUINO 433/OOK, zentrale Steuerung
FHEM2 (Keller) x86 mit CUL/hmland, IP-basierte Module
FHEM3 (Erdgeschoss) Raspi2 mit SDUINO 868/GFSK
FHEM4 (Hausanschlussraum), USV und OBIS-Modul
FHEM5 (Docker) mit FHEM2FHEM, InfluxDB

timmib

Habe ich übersehen. Wird eingebaut.

timmib

Es gibt Neuigkeiten:


  • Das Attribut readingRegEx heißt jetzt readingInclude und es gibt nun auch readingExclude. Bitte entsprechend vorsichtig migrieren!
  • Es gibt nun ein Attribut conversion. Das ist Kommagetrennte Liste von Ersetzungen e.g. open=1,closed=0,tilted=2 oder true|on|yes=1,false|off|no=0
  • Es wird nun nichts mehr automatisch konvertiert!
  • Nicht numerische Readings werden jetzt garnicht erst zur Datenbank geschickt. Aber lokal gezählt als "dropped" und die letzte Meldung angezeigt.
  • Deutsch und englische Doku habe ich entsprechend angepasst

Viele Erfolg beim Testen

kadettilac89

#5
Zitat von: timmib am 12 Oktober 2020, 21:17:50
Also bei mir funktioniert das wunderbar - dachte ich bis grade,

Wenn ich z.B. Harry als devspec am Ende vom define angebe habe ich automatisch ein NOTIFYDEV mit dem Wert Harry und bekommen auch nur noch Ereignisse von Harry gemeldet.

Ich sehe grad beim meinem a,b,c Beispiel setzt der das NOTIFYDEV nicht. Laut https://wiki.fhem.de/wiki/DevelopmentModuleAPI#notifyRegexpChanged  Womöglich ist das bei a,b,c der Fall - Schade.

Und nu? Soll ich jetzt selber filtern oder selber $event_regexp setzen.

BTW. Ich habe das andere Thema verschoben und ein paar neue Sache eingebaut. Inklusive konfigurierbarer Konvertierung.

Ich schreibe mal hier weiter. Hier kann ich editieren.

Es ist die Frage was gewollt ist. Devspec kann auch folgendes ... <readingname>=<Wert oder regex>. Das ist der große Vorteil von devspec. Das kann notifydev nicht. Das macht "nur" regex auf Devicename.

Ich finde es verwirrend wenn Regex auf Devicename und dann später Regex auf Reading. Regex-Syntax ist nicht so ohne. Da hast du dann laufend Supportprobleme mit Leuten die mit Regex nicht umgehen können. Nicht jeder ist Entwickler ....

Wie gesagt, devspec wäre eine feine Sache da mächtig und schon gut dokumentiert. Jetzt müsstest du bei Init einmalig ein Array füllen und puffern. devspec2array füllt ein Array mit allen Devices auf die devspec zutrift.

Das Array ist statisch bis sich die Definition ändert. Beim Aufruf von Notify ... in der Sub die das Filtern auf die Events macht .... kannst dann als ersten Schritt ein grep -w oder eine andere Perl Funktion rufen die prüft ob das event-device im Array vorkommt. An der Stelle, an der ich quck'n'dirty auch devspec2array eingebaut habe ... siehe Kommentar im anderen Thread.

Ich habe mich noch nie mit den Dev-Richtlinien in Fhem beschäftigt. Es müsste aber funktionieren ein array als element in der list (hash->{xxxx})  zu setzen und dann später zu prüfen, $hash ist überall verfügbar.

Speicher des Arrays sollte nicht viel sein. Wenn ich mal UTF-8 nehme mit max 4 bytes pro Char, Dev-Namen mit 30 Zeichen und 200 Devices auf das devspec filtert wären das worst case 24 KB Ram wenn ich jetzt nicht falsch gerechnet habe. Also akzeptabel.

Ich denke das Array wäre schnell eingebaut mit weniger Aufwand als selber was auszuwerten. Im Idealfall 2 Zeilen Code.

Ich meine so in etwa. Ich habe kein Fhem hier an dem ich testen kann. Die Syntax wie man auf Array in der Liste zugreift weiß ich jetzt nicht, ggf. fehlt irgendwo ein @ oder % zum referenzieren ...


sub InfluxDBLogger_Initialize($) {
    my ($hash) = @_;
    $hash->{DefFn}    = "InfluxDBLogger_Define";
    $hash->{NotifyFn} = "InfluxDBLogger_Notify";
    $hash->{SetFn} = "InfluxDBLogger_Set";
    $hash->{RenameFn} = "InfluxDBLogger_Rename";
    $hash->{AttrList} = "disable:1,0 security:basic_auth,none username readingInclude readingExclude conversions deviceTagName";
    $hash ->{DevSpecArray} = devspec2array($hash->{REGEX}); <<<<---- Array füllen
    Log3 undef, 2, "InfluxDBLogger: Initialized new";
}



in **notify

my $devName = $dev_hash->{NAME}; # Device that created the events
my $events = deviceEvents($dev_hash, 1);

return "" if not grep { $_ eq $devName } $own_hash->{devSpecArray};     #<< -------   check if device in array

    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








timmib

Wäre schön, wenn ich nur 200 Devices hätte  ::)

Dein Plan hat nur einen Haken. Alle Definition die anschließend erstellt werden würden nicht erkannt werden. Beim Neustart ist das ganze womöglich noch schlimmer.

Demnach https://wiki.fhem.de/wiki/DevelopmentModuleIntro kann ich das $hash->{NOTIFYDEV} auch einfach selber setzen und FHEM macht das.

Ich probier das mal kurz in der Entwicklungs VM.


timmib

#7
Klappt wunderbar. Habe die neue Version an die Themeneröffnung angehangen. Musste nur eine Zeile ändern und eine löschen.

kadettilac89

#8
du hast jetzt in der Definition auf {NOTIFYDEV} gewechselt. Bei mir schein das devspec dann zu  funktionieren.

was meinst du mit a,b,c Beispiel, wie sieht da die Definition und das Event aus, oder was willst du filtern? .. .dein Kommentar im anderen Thread.

Zitat von: timmib am 12 Oktober 2020, 21:17:50
Ich sehe grad beim meinem a,b,c Beispiel setzt der das NOTIFYDEV nicht. Laut

timmib

#9
Ich meinte mit a,b,c sowas wie hier wie in meinem konkreten produktiven Beispiel. Dort reduziere ich in der Definition auf die drei Klima-Geräte.

defmod influxer_klima InfluxDBLogger http://hostname:8086 klima klimaKindControl,klimaBueroControl,klimaSchlafzimmerControl
attr influxer_klima readingInclude pwr_hour_last:.*


Daraus hat der vorher nicht von alleine mittles notifyRegexpChanged eine NOTIFYDEV gemacht. In der Doku steht ja auch
ZitatEs kann durchaus vorkommen, dass kein Eintrag in NOTIFYDEV gesetzt wird, da nicht zweifelsfrei zwischen Definitionsnamen und Event unterschieden werden kann.
Wobei ich nicht gedacht hätte, das er a,b,c nicht als devspec erkennen würde.

Egal, jetzt geht es.

kadettilac89

Zitat von: timmib am 13 Oktober 2020, 09:05:33
Ich meinte mit a,b,c sowas wie hier wie in meinem konkreten produktiven Beispiel. Dort reduziere ich in der Definition auf die drei Klima-Geräte.

defmod influxer_klima InfluxDBLogger http://hostname:8086 klima klimaKindControl,klimaBueroControl,klimaSchlafzimmerControl
attr influxer_klima readingInclude pwr_hour_last:.*


Daraus hat der vorher nicht von alleine mittles notifyRegexpChanged eine NOTIFYDEV gemacht. In der Doku steht ja auch  Wobei ich nicht gedacht hätte, das er a,b,c nicht als devspec erkennen würde.

Egal, jetzt geht es.

Du meinst "klima klimaKindControl,klimaBueroControl,klimaSchlafzimmerControl" ist dein devspec? Wenn du das zerlegst hast du in "$hash->{NOTIFYDEV} = $a[4];" nur den String "kind" ... das Leerzeichen setzt "klimaKindControl,klimaBueroControl,klimaSchlafzimmerControl" in element $a[5]. Das wird aber nicht verwendet.

Ggf. eine Prüfung ob mehr als 4 Parameter im Def. angegeben wurden.

Siehe Doku devspec "die Spezifikation kann keine Leerzeichen enthalten."

Du kann die sevspec testen indem du "list <devspec>" in die Eingabezeile gibst. Dann siehst du was gefunden wird. In deinem Fall wahrscheinlich sogar einen Fehler.

timmib

#11
Nene, das ist schon richtig so.

Zwischen der URL und der devspec kommt ja der Datenbankname. Da ist kein Leerzeichen in der devspec.

Siehe Hilfe:
Usage: define devname InfluxDBLogger [http|https]://IP_or_Hostname:port dbname devspec

mh76

Erstmal vorneweg ein Danke das jemand weiter an der Anbindung von Influxdb an FHEM arbeitet.

Ich habe das Modul gerade installiert und es läuft soweit stabil und tut was es soll,
das alte Modul InfluxDBLog habe ich etwa seit einem halben Jahr am laufen.

Was mich bei beiden Modulen stört, das als Tag nur "site_name" bzw. "device", mit ein paar Änderungen im Code, gesetzt wird.

Da ich Influxdb aus der Monitoring, Visualisierung und Reporting Sicht kenne, weiß ich wie wichtig die vergabe von Tags ist,
da jeder eine andere Sciht auf Daten via Grafana oder oder hat und haben will.

Momentan lasse ich mir die Daten meiner ESP (ESPEasy) direkt via UDP in eine andere Influxdb schreiben, dort sieht meine Übergabe in etwa so aus:

%valname%,site=G13,floor=OG2,room=Office,sensor=%tskname%,device=%sysname% value=%value%

so kann ich mir dann im Grafana meine Dashboards bzw. Graphen bauen und diese werden dann auf Basis der Tags dynamisch erweitert. Kommt einer neuer ESP dazu landet er im SYSINFO Dashboard und wird den Graphen für VCC, RSSI und Load automatisch hinzugefügt. Ebenso ein neuer Temperatursensor im Gebäude 13 und OG2 usw.

Ich hoffe das Tags bzw. an den Devices vorhandene Räume, Gruppen, Aliase etc auch mal übergeben werden können an Influxdb.



plin

Wie wär's mit einem globalen Attribut in dem dann für jedes Device die Tags festgelegt werden können. Am besten auch über Variable wie room=$room etc.
FHEM1 (Main) Raspi4 mit CUL, Homematic, SDUINO 433/OOK, zentrale Steuerung
FHEM2 (Keller) x86 mit CUL/hmland, IP-basierte Module
FHEM3 (Erdgeschoss) Raspi2 mit SDUINO 868/GFSK
FHEM4 (Hausanschlussraum), USV und OBIS-Modul
FHEM5 (Docker) mit FHEM2FHEM, InfluxDB

timmib

#14
Hallo,

man muss nichts am Code ändern um das device tag zu ändern. Es gibt ein Attribut "deviceTagName".

Dir schwebt aber zusätzliches ein Attribut am Logger vor wie:
additionalTags welches dann mit room=%room%,hans=%franz%

..gesetzt wird.

Das in %% sollten dann readings,attribute oder internals sein.
Dies könnte man auch zusätzlich als global defnieren.

Richtig verstanden?