Samstag, 8. Januar 2022

Diagramm für die Luftfeuchteregelung mit FHEM

Um ein Diagramm mit Messwerten anzeigen zu können, muss man zuerst ein SVG-Device erstellen. Die Daten für die Grafik holt sich das SVG-Device aus der Log-Datei für das Gerät, das die Daten liefert. Am einfachsten ruft man dazu die Detailansicht für die Log-Datei auf und klickt auf Create SVG instance. Der Vorgang ist in der FHEM-Referenz beschrieben. Man landet dann sofort im Plot-Editor, in dem man die Grafik dann an seine Wünsche anpassen kann.

In meinem Diagramm für die Regelung der Luftfeuchtigkeit werden zwei Graphen angezeigt, der Verlauf der Luftfeuchtigkeit und des Schaltzustands des Luftentfeuchters.

Plot-Editor-Anzeige für meine Luftfeuchtigkeitsregelung

Unter Plot title gibt man die Überschrift des Diagramms ein, hier "Luftfeuchtigkeit Küche". Man kann die anzuzeigenden Werte einer linken oder rechten Y-Achse zuordnen. Die auf Plot title folgenden Eingabezeilen sind daher in left und right aufgeteilt. Zunächst gehe ich auf die Darstellung der Luftfeuchtigkeit ein, die der linken Y-Achse zugeordnet ist.

In das Feld Y-Axis label wird die Beschriftung der Y-Achse eingegeben - hier "%", weil die Luftfreuchtigkeit in Prozent gemessen wird. Mit Range as [min:max] kann man den Minimal- und Maximalwert angegen, der angezeigt werden soll. Wenn man das Feld leer lässt, passt SVG den Bereich automatisch an den minimalen und maximalen Wert aus der Log-Datei für den dargestellten Zeitraum an. Mit log kann die Skala auf logarithmische Darstellung umgeschaltet werden. Mit Tics as ("Txt" val, ...) kann man Zahlenwerte als Text darstellen. Dazu komme ich noch später.

In den auf Tics as ("Txt" val, ...) folgenden Zeilen werden die Graphen definiert. Diagram label benennt den Graphen (die Kurve), hier "Luftfeuchtigkeit". In Source wird festgelegt, aus welcher Log-Datei die Informationen gewonnen werden, hier "FileLog_Ku_Thermometer". Wenn man das Drop-Down-Menü anklickt, bekommt man eine Liste der verfügbaren Log-Dateien.

Aus dem Drop-Down-Feld Column wählt man aus, aus welcher Spalte der Log-Datei der Wert genommen werden soll. Dazu hilft ein Blick in die Log-Datei oder man sieht sich die unter Example lines for input aufgelisteten Beispielzeilen aus der Log-Datei an. Der Zahlenwert für die Luftfeuchtigkeit steht in der 4. Spalte der Log-Datei, also ist hier der Wert "4" einzustellen. Aus dem Drop-Down-Menü Regexp wählt man aus, welches Reading verwendet werden soll. Der Sensor stellt ja nicht nur die Luftfeuchtigkeitswerte zur Verfügung, sondern auch noch andere Werte, wie die Temperatur oder den Taupunkt. Für meinen Anwendungsfall habe ich hier "Ku_Thermometer.humidity:" eingestellt. Der Punkt ersetzt ein Leerzeichen, weil es sich um einen regulären Ausdruck handelt. Der Punkt steht für ein beliebiges Zeichen in einem regulären Ausdruck, also auch für ein Leerzeichen.  

Y-Axis legt fest, ob der Graph der linken oder rechten Y-Achse zugeordnet werden soll. Plot-Type, Style und Width sind zum großen Teil selbsterklärend. Ein bisschen experimentieren mit den Werten kann nicht schaden. Ich verwende Stufenlinien, weil ich nur die tatsächlich gemessenen Werte darstellen will und keine Interpolationen. Alle Eingaben und Änderungen werden erst wirksam, wenn man Write g.plot file gedrückt hat.

Für den Schaltzustand des Luftentfeuchters muss man ein wenig mehr Aufwand treiben. Es soll kein Messwert angezeigt werden, der Graph soll nur "ein" oder "aus" anzeigen. Den Graph für den Schaltzustand habe ich der rechten Y-Achse zugeordnet. Der Graph kann nur Zahlenwerte interpretieren. Deshalb ordne ich "aus" den Wert 0 zu und "ein" den Wert 2. Das geschieht in der Zeile Tics as ("Txt" val, ...) im der rechten Achse zugeordneten Eingabefeld mit dem Eintrag "("ein" 2, "aus" 0)". Damit der Einzustand nicht am oberen Rand des Diagramms klebt, habe ich den Wertebereich für den Schaltzustand auf 0 bis 3 begrenzt. Das erledigt in der Zeile Range as [min:max] der Eintrag "[0:3]".

Der Graph erhält die Bezeichnung "Entfeuchter" im Eingabefeld Diagram label. Als Source wird jetzt die Log-Datei für den Steckdosenschalter eingetragen: FileLog_Ku_Luftentfeuchter. Den Eintrag in Column muss ich nicht anpassen, weil ich keinen Zahlenwert auswerten will, sondern den Status des Schalters und der ist entweder "on" oder "off" (siehe folgendes Bild).

Beispiele für die Readings aus der Log-Datei des Steckdosenschalters (Example lines for input)

Als Regexp verwende ich Ku_Luftentfeuchter.*. Der Punkt steht für ein beliebiges Zeichen, der Stern "*" bewirkt, dass das vorherstehende Zeichen beliebig oft wiederholt wird. Mit diesem regulären Ausdruck werden also alle Readings ausgewählt, die mit "Ku_Luftentfeuchter" beginnen, somit also alle Readings des Device's Ku_Luftentfeuchter. Warum nicht das Reading Ku_Luftentfeuchter.on? Es reicht nicht, den On-Zustand festzustellen, sondern es muss auch der Off-Zustand für die Auswertung erfasst werden. Es lässt sich aber nur ein regulärer Ausdruck aus Regexp auswählen.

Damit der Status im Diagramm angezeigt werden kann, muss er in einen Zahlenwert umgewandelt werden. Das geschieht im Eingabefeld Function. Der Ausdruck, der dort steht, wird evaluiert und ersetzt den Wert, der in der mit Column festgelegten Spalte steht. Der Ausdruck ist in der Programmiersprache Perl zu schreiben. Hier ist beispielsweise eine Einführung in Perl zu finden.

Der komplette Ausdruck in Function lautet:

$fld[2]=~"on"?2:$fld[2]=~"off"?0:""

SVG speichert das Reading für den jeweils aktuell auszuwertenden Punkt des Diagramms im Array @fld. Jede Spalte des Readings (durch Leerzeichen getrennte Einträge) ist in einem Element des Array's abgelegt. Die Werte "on" und "off" stehen in der 3. Spalte. Weil die Zählung der Array-Elemente bei 0 beginnt, findet sich "on" und "off" in $fld[2]. Der Operator "=~" bewirkt, dass der Speicherinhalt von $fld[2] mit der Zeichenkette "on" verglichen wird. Wenn "on" in $fld[2] enthalten ist, ergibt "$fld[2]=~"on"" den Wert true, andernfalls false.

Das Fragezeichen (?) ist ein ternärer Operator. Er ersetzt eine einfache if-Abfrage. Wenn der Ausdruck vor dem Fragezeichen true ist, dann wird der Befehl nach dem Fragezeichen ausgeführt, wenn er false ist, wird der Befehl nach dem Doppelpunkt ausgeführt. Wenn in den Readings an der 3. Position nur "on" oder "off" stände, dann könnte der Function-Ausdruck lauten:

$fld[2]=~"on"?2:0

Der Ausdruck bedeutet: Wenn "on" in $fld[2] enthalten ist, ist der Wert in Function 2, sonst 0. Leider kommen an 3. Position des Readings aber nicht nur "on" und "off" vor, sondern beispielsweise auch "power", "voltage" oder "energy" (siehe Bild oben). Damit beispielsweise nicht "power" als "off" interpretiert wird, ist für den Fall, dass der Vergleich auf "on" negativ ausfällt, eine weitere ternäre Operation nachgeschaltet, die prüft, ob "off" in $fld[2] enthalten ist. Wenn ja, wird der Wert von Function 0, sonst wird er eine leere Zeichenkette (""). Die beiden hintereinander geschalteten ternären Operatoren bewirken also, dass für den Grafen der Wert 2 verwendet wird, wenn das Reading an 3. Position "on" enthält, wenn "off" im Reading steht, wird 0 eingesetzt und sonst eine leere Zeichenkette.




Keine Kommentare:

Kommentar veröffentlichen