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 sämtlicher Devices vollständig bestimmt.
- reading11
- reading12
- …
- reading21
- reading22
- …
- 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:
- Scripte die von anderen Scripten bei Bedarf gestartet werden und eine Mengen von Aktionen auszuführen
- Scripte die permanent arbeiten, das System beobachten und auf Veränderungen reagieren
Letztere arbeiten nach folgendem Schema:
Warten auf die Änderung von mindestens einem relevanten Reading, bzw. bis zu einem definierten Zeitpunkt
→
Überprüfung, ob Aktion(en) ausgeführt werden soll(en)
→
Wenn ja, Ausführung der Aktion(en)
→
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 selbstverständlich auch mit den originär in FHEM eingebauten Methoden relativ einfach zu realisieren. Die Stärke dieses Konzeptes zeigt sich mit zunehmender Komplexität der Steuerungsaufgaben.