Mittwoch, 30. Oktober 2019

File Log - und gut?

Ich suche schon lange einen Anfang um vom FileLog auf eine Datenbank umzusteigen. Es soll ja Vorteile bringen ...
Das sind einfach ein paar Notizen, eine Anleitung wird das so erstmal nicht werden.

Ein paar Gedankenstriche

  • Ich hätte Bedenken eine SQL Datenbank auf einer SD Card zu betreiben.
  • SQLite ist eine Datei basierte, lokale Datenbank, es ist kein Datenbankserver.
  • MySql ist ein Datenbankserver, der Zugriff kann auch Remote erfolgen, man könnte die Server-Instanzen auf mehrere Maschinen aufteilen.
  • Einzelne Textdateien können beim Stromausfall unbrauchbar werden, bei einem Datenbankserver kann die gesamte Datenbank unbrauchbar werden.
  • Backup muss anders gemacht werden, einfach alle Dateien eines laufenden DB Servers sichern ist nicht sinnvoll.
  • Die Erzeugung von SVG-Plots ist aus meiner Sicht derzeit schwieriger als aus FileLogs und hat Stolpersteine.

Um in das Thema einzusteigen, habe ich MariaDB installiert, ein DBLog und ein FileLogConvert Device in FHEM angelegt und erstmal geschaut wie es sich mit einem importierten Jahreslog von 2018 mit der Temperatur und Luftfeuchte meines Aussensensors so arbeiten lässt.
Ich konnte die Temperatur plotten, die Luftfeuchte funktionierte nicht. Obwohl ich dachte, ich hätte die Erklärungen im Wiki für den Umstieg verstanden. Hatte ich - aber meine Daten waren Murks.

Plot erzeugen

Was habe ich beim Erzeugen eines Plot bisher verstanden und für mich als Handlungsgrundlage festgelegt habe:
Das Anlegen eines Plots geht quasi los wie immer:
Am DbLog Device gibt es oben einen Link: Create SVG Plot from DbLog
Im Menüpunkt "Diagram label, Source" wählt man als Quelle sein DbLog Device.
Dahinter kommt die Wertzuweisung in der Form (für den Fall das man nicht nur ein Reading mit einem Wert pro Zeile geloggt hat).
<Device>:<Reading>:::$val=~s/<regex>/$1/eg
$val ist die interne Variable die letztendlich den Wert für diese Plotzeile enthält (z.B. die Temperatur)
Auf $val wird ein regex angewendet (=~) welches mit suchen (<regex>) und ersetzen ($1) den Inhalt von $val verändert. Trifft das regex nicht zu, bleibt $val unverändert!
$1 (oder auch $2 usw) enthält dabei den "Groupmatch", also normal einen Teilstring.

Match

Dezimalzahlen mit Punkt kann man so als Gruppe erkennen: ([-\d.]+) -> erkennt eine Zeichengruppe aus "- . und Ziffer" zwischen 1 und unendlich mal. (* erkennt zwischen 0 und unendlich mal, Punkt ist hier wirklich der Punkt und nicht ein beliebiges Zeichen)
Ein "T: " am Beginn eines Wertes kann man so erkennen: ^T:\s -> Anfang der Zeichenkette, ein T, ein : und ein Whitespace.
Einen Trenner zwischendrin kann man so erkennen: .H:\s -> Ein Zeichen, ein H ein : und ein Whitespace
Mein geloggtes state Reading sieht so aus: T: 20.7 H: 69 und mit dem regex   ^T:\s([-\d.]+).H:\s([-\d.]+) habe ich den Zahlenwert hinter T in $1 und den Zahlenwert für H in $2.
Nach diesem Schema ließen sich jetzt beliebige Kolonnen analysieren. Anstatt in jeder Zeile die Klammern zu versetzen und immer eine Ersetzung mit $1 zu machen, finde ich es übersichtlicher jede Zeile mit gleichen (allen) Klammern auszustatten und von Zeile zu Zeile $1 auf $n zu wechseln.

Resultat

Zeile in der Datenbank
select * from history where (TIMESTAMP like "2019-08-19 10:25:21");

+---------------------+--------------+-------+----------------------+---------+---------------+------+
| TIMESTAMP           | DEVICE       | TYPE  | EVENT                | READING | VALUE         | UNIT |
+---------------------+--------------+-------+----------------------+---------+---------------+------+
| 2019-08-19 10:25:21 | SensorAussen | DUMMY | state: T: 20.7 H: 69 | state   | T: 20.7 H: 69 |      |
| 2019-08-19 10:25:21 | SensorAussen | DUMMY | tempMax: 30.3        | tempMax | 30.3          |      |
| 2019-08-19 10:25:21 | SensorAussen | DUMMY | tempMin: 18.6        | tempMin | 18.6          |      |
+---------------------+--------------+-------+----------------------+---------+---------------+------+

Zeilen im SVG Plot
SensorAussen:state:::$val=~s/^T:\s([-\d.]+).*H:\s([-\d.]+)/$1/eg
SensorAussen:state:::$val=~s/^T:\s([-\d.]+).*H:\s([-\d.]+)/$2/eg

Für die Zeilen wo nur ein Wert in Value steht sieht die Sache viel einfacher aus:
SensorAussen:tempMax::

Fragen

Was der Wert an dritter Stelle (::0:) bewirkt den man laut Wiki hinschreiben kann? - ist mir nicht klar.
Auch ist nicht klar, warum bei der Angabe von $val= noch ein vierter Trenner ":" sein muss.
Device:Reading:?:?:$val= ...
Der Umgang mit Platzhalter <SPEC1> (attr plotfunction) oder mit attr plotReplace ist mir auch noch nicht klar. Es würde SVG gplot Dateien universell nutzbar machen.

Achtung

Wenn die current Tabelle gefüllt ist, steht der Fenster Device:Reading nicht zum Schreiben zur Verfügung. Man kann dann nur "Pärchen" aus der Klappliste auswählen. Wenn man dann speichert wird jede Zeile die man vorher mit :$val= eingetragen hat gelöscht!
Will man den Inhalt der current löschen geht das mit einem SQL Statement:
delete from current;

Fazit

Es ist aufwendig und der Nutzen scheint mir derzeit gering. Ich muss mich noch weiter damit beschäftigen

2 Kommentare:

  1. Christoph Morrison30. Oktober 2019 um 11:39

    Meine Erfahrung ist - kürzlich auf DBLog / MariaDB umgestiegen - dass ich meine Plots weiter über FHEM erzeuge und dafür eben einzelne Werte in zusätzliche Text-Logfiles ablege und mich nicht weiter um die Erzeugung von Plots aus der DB kümmere, sondern dort nur Auswertungen mache.

    Best of both worlds.

    AntwortenLöschen
  2. Christoph Morrison30. Oktober 2019 um 11:40

    Eine alternative wäre z.B. Grafana.

    AntwortenLöschen