logoFHEM CONTROL 2.0

Philosophie hinter λscript

Eine FHEM-Installation besteht aus einer Menge von Devices (device1, device2, …). Jedes Device besitzt einen eindeutigen Namen. Der Zustand eines Devices ist zu jedem Zeitpunkt durch einen Satz von Variablen vollständig definiert. Diese Variablen sind in FHEM die "Readings". Der augenblickliche Zustand des gesamten Systems ist also durch die Angabe aller Readings aller Devices vollständig bestimmt.

device1
  • reading11
  • reading12
device2
  • reading21
  • reading22
device3
  • reading31
  • reading32
...
Zustand eines FHEM-Systems

Dieser Zustand ist nicht konstant sondern verändert sich ständig. Zum einen, weil die Readings Messwerte nicht konstanter physikalischer Größen darstellen. Zum anderen, weil Devices selbst Aktionen ausführen, die ihren eigenen Zustand oder den anderer Devices verändern. Das Auslösen solcher Aktionen ist in FHEM durch Kommandos der Gestalt "set device …" möglich.

Ein FHEM-System steuern heißt: Das System beobachten und beim Erreichen eines bestimmten Zustandes (oder zu einem bestimmten Zeitpunkt) ein oder mehrere Aktionen "set device …" auslösen.

Dem entsprechend gibt es zwei Typen von Scripten:

Letztere arbeiten nach folgendem Schema:

1.
Warten auf die Änderung von mindestens einem relevanten Reading, bzw. bis zu einem definierten Zeitpunkt

2.
Überprüfung, ob Aktion(en) ausgeführt werden soll(en)

3.
Wenn ja, Ausführung der Aktion(en)

4.
Zurück zu 1.
Grunsätzliches Schema für die Steuerung vom FHEM

Ein λscript besteht aus einer Folge von Kommandos. Die vier oben genannten Schritte können mit den folgenden Kommandos realisiert werden:

1. wait

Ein Script kann in einen Wartemodus wechseln. Der wird zu einem definierten Zeitpunkt, nach dem Ablauf einer Zeitspanne, oder nachdem sich der Zustand von Devices bzw. Variablen geändert hat beendet.

Um zu warten bis sich eines von mehreren beobachteten Readings ändert oder ein Zeitpunkt erreicht wurde, werden die Readings in folgender Weise hinter dem Schlüsselwort wait notiert:

wait [device1 reading1] [device2 reading2] … time1 time2 …;

timen steht für eine Zeitpunkt oder eine Zeitdauer. Die Reihenfolge und die Anzahl der Parameter sind beliebig. Ist ein Reading das Reading mit dem Namen state, dann reicht es, den Devicenamen in eckige Klammern zu setzen. Beispiel:

wait [WZ.Lampe] 17:00'today;

Dieses Kommando wartet darauf, dass sich der das Reading state von WZ.Lampe ändert. Der Wartezustand wird spätestens "heute 17:00 Uhr" beendet.

2. Überprüfung/Berechnung

Readings von FHEM-Devices können ausgelesen und mit ihnen arithmetische Berechnungen und Vergleiche durchgeführt werden. Zeichenketten können verglichen, zusammengesetzt oder durch Mustervergleiche (REGEX) überprüft werden. Es können Variable definiert und Werte in ihnen zwischengespeichert werden. Das Anlegen von Arrays und die Programmierung von Schleifen und Wiederholungen ist möglich. Die Möglichkeit eigene Klassen zu definieren, erlaubt es, Devices zu gruppieren und mit speziell definierten Kommandos anzusprechen. λscript hat den Umfang einer komplexen Programmiersprache. Im folgenden Beispiel wird eine Variable do definiert, die true ist, wenn die Lampe eigeschaltet und die Soll-Temperatur kleiner als 22 ist:

do := [WZ.Lampe] = "on" & [WZ.Thermostat desired-temp]'toNumber < 22;
3. Ausführung einer Aktion

Hat die eben definierte Variable b den Wert true soll am Thermostat WZ.Thermostat die Solltemperatur auf 22°C gestellt werden. Dazu wird in einem if-Konstukt das hierfür übliche FHEM-Kommando notiert:

if do {
   set WZ.Thermostat desired-temp 22;
};

Die letzten beiden Kommandos können natürlich ohne die Verwendung von do komprimiert geschrieben werden:

if ([WZ.Lampe] = "on" & [WZ.Thermostat desired-temp]'toNumber < 22) {
   set WZ.Thermostat desired-temp 22;
};
4. Ausführung als Endlosschleife

Um Scripte wiederholt laufen zu lassen, können Kommandos mit dem Schlüsselwort repeat verwendet werden. Dazu werden die Kommandos, die wiederholt werden sollen, in geschweiften Klammern nach repeat geschrieben. Das komplette Script sieht dann so aus:

repeat {
   wait [WZ.Lampe] 17:00'today;
   if ([WZ.Lampe] = "on" & [WZ.Thermostat desired-temp]'toNumber < 22) {
      set WZ.Thermostat desired-temp 22;
   };
};

Dieses Script stellt die Wohnzimmertemperatur jeden Tag um 17 Uhr oder beim Einschalten des Lichts auf 22°C ein. Diese Funktionalität ist auch mit den oben genannten in FHEM eingebauten Methoden relativ einfach zu realisieren. Die Stärke dieses Konzeptes zeigt sich mit zunehmender Komplexität der Steuerungsaufgaben.