Naja, das sollte eigentlich kein Problem sein. Du brauchst nur die passenden Items, je nachdem, wie es technisch gelöst ist je ein Item für Leinwand und Beamerlift, ein weiteres Item für die Szene, je nach Beamer noch ein paar weitere Items für die Beamersteuerung. Diese Items müssen natürlich mit den passenden Geräten verbunden werden, je nach eingesetzter Technik über ein OH2 Binding (dann mit Thing und Channel) oder über ein OH1 Binding (dann direkt mit dem Binding).
Das Item zur Steuerung (das nimmt den Befehl "Kino" entgegen) braucht kein Binding, dafür aber natürlich Kontakt zu Alexa und ein Widget in der Sitemap, damit man es bedienen kann. Dazu kommt dann noch eine Rule, die nacheinander die passenden Befehle aufruft, wenn der Befehl "Schalte Kino ein" kommt. Da hier verschiedene Geräte mit erheblicher zeitlicher Verzögerung eingeschaltet werden sollen, sollte ein Timer zum Einsatz kommen.
Nehmen wir mal folgende Items als gegeben an:
Code: Alles auswählen
Switch scKino "Kino" [ "switchable" ] //Szenensteuerung
Rollershutter rLeinwand "Leinwand [%d %%]" <cinemascreen> {channel="..."} //Leinwandlift
Rollershutter rBeamerlift "Beamerlift [%d %%]" <beamer> {channel="..."} //Beamerlift
Switch sBeamerPower "Beamer Power [%s]" <beamer> {channel="..."} //Beamer Power
// ...
Nehmen wir weiter an, die Leinwand braucht 15 Sekunden, um herunter zu fahren, der Beamer braucht 20 Sekunden zum runterfahren und 30 Sekunden zum Einschalten. Der Beamer soll erst eingeschaltet werden, wenn der Lift schon vollständig ausgefahren ist. Dann sähe ein passende Rule ungefähr so aus:
Code: Alles auswählen
var Timer tKino = null // Timervariable für die Szenensteuerung
var Number iKino = 0 // Ablaufzähler für die Szenensteuerung
rule "Kino einschalten"
when
Item scKino changed to ON
then
if (tKino !== null) return; // die Szenensteuerung ist bereits in Betrieb, Abbruch!
tKino = createTimer(now, [ | // setze Timer und führe ihn unmittelbar aus
iKino = iKino + 1
switch iKino {
case 1: { // 1. Schritt, schalte Beamer ein
rBeamerlift.sendCommand(DOWN)
tKino.reschedule(now.plusSeconds(20)) // nächster Schritt in 20 Sekunden (Beamer ist unten angekommen)
}
case 2: { // 2. Schritt, Beamer an
sBeamerPower.sendCommand(ON)
tKino.reschedule(now.plusSeconds(15)) // Warmup 30 Sekunden, dann soll die Leinwand bereits unten sein
}
case 3: { // 3. Schritt, Leinwand runter
rLeinwand.sendCommand(DOWN)
tKino.reschedule(now.plusSeconds(15)) // Szenensteuerung wird beendet, sobald die Leinwand unten ist
}
default: { // 4. Schritt, Szene für nächsten Aufruf reinitialisieren
iKino = 0
tKino = null
}
}
])
end
Das Ganze ist eine rein zeitgesteuerte Ablaufsteuerung. Wenn der Beamer sehr schnell betriebsbereit ist (z.B. LED-Beamer), kann es sein, dass man Schritt zwei und drei tauschen muss, damit die Leinwand rechtzeitig unten ist. Vielleicht kann der Beamer auch schon eingeschaltet werden, während der Lift noch arbeitet, weil der Beamer nicht empfindlich gegen Erschütterungen ist.
Durch die switch-Anweisung ist der Rule-Aufbau denkbar einfach.
Die Rule selbst läuft nur wenige Millisekunden, die zum Prüfen auf einen vorhandenen Timer und das Initialisieren des Timers benötigt werden.
Der Timer ist ebenfalls simpel, jedesmal, wenn der Timer-Code ausgeführt wird, wird der Zähler iKino um eins erhöht. Anschließend wird mit der switch-Anweisung der Stand des Zählers geprüft. Der 1. Timer startet unmittelbar, der 1. Schritt wird ausgeführt. Am Ende dieses Schritts wird der Timer erneut geplant. Da der Timer bereits im Speicher ist, muss er nicht erneut initialisiert werden, das macht einen Teil der Einfachheit dieses Lösungsansatzes aus
Der Letzte Schritt in der Ablaufsteuerung ist default, dieser Schritt wird bei jedem nicht gelisteten Wert ausgeführt. Damit ist also sichergestellt, dass die Ablaufsteuerung auf jeden Fall wieder korrekt initialisiert ist.