[gelöst] 93_InfluxDBLogger.pm um Addlog-Funktion erweitern

Begonnen von meier81, 23 Januar 2021, 09:08:14

Vorheriges Thema - Nächstes Thema

meier81

Hallo und guten Morgen,

ich hätte eine Frage. Ich nutze seit ein paar Wochen das InfluxDBLogger-Modul parallel zu meinem DbLog-Modul. Da dies zuverlässig läuft würde prinzipiell gerne den DbLog einstampfen und mit InfluxDB weitermachen, zum einen kenne ich Influx von der Arbeit her und zum anderen lassen sich die Charts in Grafana wesentlich einfacher erstellen. Zudem ist es bei vielen Datensätzen um einiges schneller.

Für die endgültige Umstellung fehlt mir aber die Funktion "Addlog", damit kann ich um 23:59 bzw. um 0:00 Uhr die Readings über ein doif triggern und so den Plotabriss vermeiden.

Eventuell ist es möglich diese Funktion (gibt es ja z.B. im Modul 93_DbLog.pm) hier mit einzubauen, das wäre super. Ich denke die Funktion werden auch noch andere außer mir vermissen bzw. verwenden.

Gruß Markus

Edit:
Hab eben nochmal probiert und getestet, wie gesagt ich habe ja zur Zeit auch DBLog im Einsatz und hier den integrierten AddLog benutzt, das funktioniert ja einwandfrei.
Für InfluxDB habe ich jetzt mal zum testen das AddLog-Skript in der myUtils benutzt, da ich aber 86 Werte triggern möchte ist FHEM dann für ca. 12 Sekunden blockiert, solange dauert es bis 86mal das Skript abgearbeitet wurde. Diese Verhalten habe ich mit der AddLog-Funktion in DbLog nicht.
QNAP NAS mit Debian VM, darauf FHEM, debmatic, influxdb2 und Grafana || HB-RF-ETH || SIGNALduino 433MHz mit Maple mini || WS980 Wetterstation || Xiaomi Mi Robot mit valetudo-FW || Buderus web KM100 || div. Tasmota-Devices

volschin

Das Addlog in der myUtils funktioniert eben mit jeder Form von Logs - Text, DB, influxdb ...
Intel NUC+Ubuntu 22.04+Docker+FHEM6
HomeMatic: HM-MOD-RPI-PCB+HM-USB-CFG2+hmland+diverse, HUE: Hue-Bridge, RaspBee+deCONZ+diverse
Amzn Dash-Buttons, Siro Rollos
4xRPi, 4xCO20, OWL+USB, HarmonyHub, FRITZ!Box 7590, Echo Dots+Show8, Logi Circle 2, HomeBridge
TIG Stack (Telegraf, InfluxDB, Grafana)

meier81

#2
Zitat von: volschin am 25 Januar 2021, 00:26:40
Das Addlog in der myUtils funktioniert eben mit jeder Form von Logs - Text, DB, influxdb ...

Das ist ja soweit klar und auch richtig, AddLog des DbLog-Moduls macht allerding kein readingsSingleUpdate sondern schreibt die Werte einfach nochmal in die DB weg (hoffe ich habe den Code soweit richtig interpretiert).

Die Variante mit myUtils läuft ja über das readingsSingleUpdate, das heißt es wird ja auch jedes Mal ein Event erzeugt. Und da für 86 Werte das Skript 86mal durchlaufen wird dauert das halt ewig (12-13 Sekunden). Die Variante mit AddLog macht keinen wesentlichen Zeitunterschied bei der Abarbeitung.
QNAP NAS mit Debian VM, darauf FHEM, debmatic, influxdb2 und Grafana || HB-RF-ETH || SIGNALduino 433MHz mit Maple mini || WS980 Wetterstation || Xiaomi Mi Robot mit valetudo-FW || Buderus web KM100 || div. Tasmota-Devices

meier81

#3
Zitat von: timmib am 02 Februar 2021, 22:57:42

Hol mich mal grad ab. Du bist gedanklich bei dem Log Attribut a la DbLogInclude?

Hallo Tim,

es ist eher ein "set"-Befehl, kein Attribut. Ist vergleichbar wie in deinem Modul z.B. das set InfluxDB password xyz

Für mein DbLog-Modul habe ich z.B. folgende doif-Definition für den Plotabriss:
set DbLog addLog Fuehler.*:(temperature|humidity|dewpoint|absoluteHumidity)

Das heißt ich habe einen set-Befehl der addLog heißt und hinten dran ein Eingabefeld. Dort kann ich dann devices und readings reinschreiben von denen ich die dementsprechenden readings per set-Befehl in die Datenbank schreiben möchte. Das triggert die readings nicht sondern loggt die nur weg.

Wie gesagt ich hab das schonmal aus dem DbLog-Modul rausgefummelt, hier mal zur Übersicht der Code für die set-Definition (schon für dein Modul angepasst:

sub InfluxDBLogger_Set($$$@)
{
    my ( $hash, $name, $cmd, @args ) = @_;
    Log3 $name, 5, "InfluxDBLogger: [$name] set $cmd";

    if ( lc $cmd eq 'password' ) {
        my $pwd = $args[0];
        InfluxDBLogger_StoreSecret($hash, $name,"passwd", $pwd);
        return (undef,1);
    }
    elsif ( lc $cmd eq 'token' ) {
        my $token = $args[0];
        InfluxDBLogger_StoreSecret($hash, $name,"token", $token);
        return (undef,1);
    }
    elsif ( lc $cmd eq 'resetstatistics' ) {
        InfluxDBLogger_ResetStatistics($hash, $name);
        return (undef,1);
    }
    elsif ( lc $cmd eq 'addlog' ) {
        my $devrdspec = $args[0];
        InfluxDBLogger_addLog($hash, $name, $devrdspec);
        return (undef,1);
    }
    else {
        return "Unknown argument $cmd, choose one of resetStatistics:noArg password token addlog";
    }
}


Und der Code der eigentlichen Routine:

sub InfluxDBLogger_addLog($$$)
{
    my ( $hash, $name, $devrdspec )= @_;
    my ( $dev_name, $dev_reading, $read_val, $event );
    my @row_array;
    my $ts;

    return if(IsDisabled($name) || $init_done != 1);

    my $rdspec = (split ":",$devrdspec)[-1];
    my @dc = split(":",$devrdspec);
    pop @dc;
    my $devspec = join(':',@dc);

    my @exdvs = devspec2array($devspec);
    Log3 $name, 4, "InfluxDBLogger $name -> addLog known devices by devspec: @exdvs";
    foreach (@exdvs) {
        $dev_name = $_;
        if(!$defs{$dev_name}) {
            Log3 $name, 2, "InfluxDBLogger $name -> Device '$dev_name' used by addLog doesn't exist !";
            next;
        }

        my $r = $defs{$dev_name}{READINGS};
        my @exrds;
        my $found = 0;
        foreach my $rd (sort keys %{$r}) {   # jedes Reading des Devices auswerten
            $found = 1 if($rd =~ m/^$rdspec$/);   # Reading gefunden
            push @exrds,$rd if($rd =~ m/^$rdspec$/);
        }
        Log3 $name, 4, "InfluxDBLogger $name -> Readings extracted from Regex: @exrds";

        if(!$found) {
            Log3 $name, 2, "InfluxDBLogger $name -> addLog WARNING - Device: '$dev_name' -> Readingname '$rdspec' is no valid or regexp!";
        }

        no warnings 'uninitialized';
        foreach (@exrds) {
            $dev_reading = $_;
            $read_val = ReadingsVal($dev_name,$dev_reading,"");

            # dummy-Event zusammenstellen
            $event = $dev_reading.": ".$read_val;

            if(!defined $dev_reading) {$dev_reading = "";}
            if(!defined $read_val) {$read_val = "";}
            $event = "addLog";

            $ts = TimeNow();

            my $row = ($ts."|".$dev_name."|".$event."|".$dev_reading."|".$read_val);
            Log3 $hash->{NAME}, 3, "InfluxDBLogger $name -> addLog created - TS: $ts, Device: $dev_name, Event: $event, Reading: $dev_reading, Value: $read_val";

            push(@row_array, $row);
        }
        use warnings;
    }
    if(@row_array) {

}


Hab das mal so getestet, funktionieren tut es soweit, der Logeintrag wird erzeugt. Das ist aber natürlich alles noch nicht in dem Format wie du die Werte benötigst und demnach ist natürlich der untere Teil der Ausführung if(@row_array) auch noch nicht benutzt.

Gruß Markus

QNAP NAS mit Debian VM, darauf FHEM, debmatic, influxdb2 und Grafana || HB-RF-ETH || SIGNALduino 433MHz mit Maple mini || WS980 Wetterstation || Xiaomi Mi Robot mit valetudo-FW || Buderus web KM100 || div. Tasmota-Devices

timmib

Geht es darum einmalig bei Aufruf des Set die Werte zu speichern?

Wein ja, was ist interessehalber der Auslöser?

meier81

Zitat von: timmib am 03 Februar 2021, 18:44:49
Geht es darum einmalig bei Aufruf des Set die Werte zu speichern?

Wein ja, was ist interessehalber der Auslöser?

Genau, es geht eigentlich darum einmalig die readings der Devices die mit dem set-Befehl übergeben werden z.B. Fuehler.*:(temperature|humidity|dewpoint|absoluteHumidity) (das sind bei mir dann 9 Sensoren die alle mit Fuehler anfangen) in die Datenbank zu loggen.

Das wird z.B. verwendet wenn du einen Plotabriss vermeiden willst, meine Sensoren z.B. stehen alle auf event-on-change reading .* und deswegen werden nur Wertänderungen geloggt. Jetzt hast du z.B. abends um 21:00 Uhr eine Wertänderung und dann morgens wieder um 5:00 Uhr, dann hast du in Grafana bei einem täglichen Chart abends ab 21:00 Uhr keinen Strich mehr und für den nächsten Tag erst wieder einen ab 5:00 Uhr. Aus dieser Problematik heraus entstand diese addLog Geschichte, zumindest war dies einer der Gründe.

Hab auch schon gelesen es gibt Leute die Stündlich auf jeden Fall die readings wegschreiben möchten, scheint da viel Bedarf bzw. Anwendungen zu geben.

Bei mir nutzte ich diese Funktion wie gesagt per doif, hier mal meine Definition:

define di_Plotabriss DOIF ([23:59] or [00:00])\
   (set DbLog addLog Buderus:(DesiredSupplyTemp|OutdoorTemp|Power|PowerModulation|PumpModulation|ReturnTemp|SupplyTemp|WaterDesiredTemp|WaterTemp)\
   ,set DbLog addLog Fuehler.*:(temperature|humidity|dewpoint|absoluteHumidity)\
   ,set DbLog addLog (Waschmaschine|Trockner):ENERGY_Power\
   ,set DbLog addLog Wetterstation:(temperature|humidity|dewpoint|absoluteHumidity|brightness|rainRate|wind|pressureAbs)\
   ,set DbLog addLog Astro:SunAlt\
   ,set DbLog addLog Rolladen.*:pct\
   ,set DbLog addLog Strom_Haus:Power_.*__kW)
attr di_Plotabriss do always
attr di_Plotabriss icon helper_doif


Wie gesagt die Variante es in das Modul zu intergieren hätte den riesen Vorteil das das nicht über readingsSingleUpdate geschieht und somit nicht getriggert wird. Das blockiert FHEM je nachdem wieviel Werte getriggert werden doch schon einige Zeit.
QNAP NAS mit Debian VM, darauf FHEM, debmatic, influxdb2 und Grafana || HB-RF-ETH || SIGNALduino 433MHz mit Maple mini || WS980 Wetterstation || Xiaomi Mi Robot mit valetudo-FW || Buderus web KM100 || div. Tasmota-Devices

timmib

Okay, verstanden.
Muss ich mir angucken.

Ist der InfluxLogger dann der selbe, der auch bei Events greift?

meier81

Zitat von: timmib am 03 Februar 2021, 20:38:32
Ist der InfluxLogger dann der selbe, der auch bei Events greift?

Du meinst damit wahrscheinlich ob die Werte dann genauso geloggt werden sollen wie normale Werte? Würde sagen ja, wenn ich deinen Modulaufbau anschaue würde ich sagen das wäre dann quasi die Alternative bzw. Parallele vom sub InfluxDBLogger_Notify. Das notify greift für readings die sich geändert haben (automatischer Teil) und das set für händisches schreiben der Werte.
QNAP NAS mit Debian VM, darauf FHEM, debmatic, influxdb2 und Grafana || HB-RF-ETH || SIGNALduino 433MHz mit Maple mini || WS980 Wetterstation || Xiaomi Mi Robot mit valetudo-FW || Buderus web KM100 || div. Tasmota-Devices

timmib


timmib

Hallo Markus,

ich würde es ein wenig anders programmieren, als in deinen Codebeispielen.

Wie bereits geschrieben würden die existernden Devices einfach per set aufgerufen werden ohne Argumente.

set logger write

("write" damit es besser zum Wording in den Statistiken passt)

Da ja im Device ohnehin die devspec als auch die Readings Ein und Ausschlüsse drin sind ist ja alles da.

In der Sub wird dann einfach devspec2array() gemacht plus Auswertung aller Readings gegenüber der Attribute In und Exlclude.

Jut?



meier81

Hallo Tim,

okay dann hatte ich dich weiter oben falsch verstanden. Die Variante finde ich auch fast besser, da wie du geschrieben hast ja schon die includes und excludes angegeben sind genauso wie die devices. Vereinfacht sogar das doif dann, ist keine lange Aufzählung mehr sondern nur noch ein Befehl und gut.

Hoffe das lässt sich einigermaßen einfach umsetzen im Modul.

Ich spiel gerne den Betatester  ;)

Gruß Markus
QNAP NAS mit Debian VM, darauf FHEM, debmatic, influxdb2 und Grafana || HB-RF-ETH || SIGNALduino 433MHz mit Maple mini || WS980 Wetterstation || Xiaomi Mi Robot mit valetudo-FW || Buderus web KM100 || div. Tasmota-Devices

timmib


timmib

Hallo Markus,

Hier eine einfache Version.

Da sind jetzt noch eine Hand voll Debug Statements drin. Die würde ich dann in der Produktiven Version löschen.

In meiner Perl-Sandbox klappt es.
In meiner FHEM-Dev Umgebung mit einem Dummy klappt es auch.

Viele Grüße

Tim

meier81

Hallo Tim,

da ging ja schnell. Hab mal ins Modul geschaut, war ja anscheinend gut mit einzubauen.

Hab´s eben mal installiert und in Betrieb genommen, hab mal nachgerechnet es sind bei mir 86 Readings die dann geschrieben werden sollten und die werden auch geschrieben, sieht also super aus. Ich warte jetzt mal heute Nacht um Mitternacht ab, da sieht man es am besten an den Plots. Ich gebe dir morgen dann nochmal Bescheid, sieht aber so aus als kann das so produktiv gehen.

Vielen Dank schon mal dafür.

Gruß Markus
QNAP NAS mit Debian VM, darauf FHEM, debmatic, influxdb2 und Grafana || HB-RF-ETH || SIGNALduino 433MHz mit Maple mini || WS980 Wetterstation || Xiaomi Mi Robot mit valetudo-FW || Buderus web KM100 || div. Tasmota-Devices

meier81

Guten Morgen Tim,

nochmal ne kurze Rückmeldung, Modul funktioniert einwandfrei, hat heute Nacht zuverlässig die Werte um 23:59 und 0:00 Uhr geschrieben und die Plots sehen prima aus.  8)

Dann kannst du das Modul ja produktiv nehmen wenn du willst, ich werde heute im Laufe des Tages dann meine MySQL-Benutzung einstampfen.

Vielen Dank nochmals.

Gruß Markus

P.S.: Hast du zufällig spontan eine Idee wie ich meine MySQL-Daten nach InfluxDB bekomme, zur Not geht das halt nicht.
QNAP NAS mit Debian VM, darauf FHEM, debmatic, influxdb2 und Grafana || HB-RF-ETH || SIGNALduino 433MHz mit Maple mini || WS980 Wetterstation || Xiaomi Mi Robot mit valetudo-FW || Buderus web KM100 || div. Tasmota-Devices