Wie gesagt, das ist Quatsch. Die von Dir gepostete Rule macht folgendes:
Lampe und Shelly werden eingeschaltet. Anschließend wird ein eventuell laufender Timer (auf welchen auch immer der Zeiger tSzene_TV gerade zeigt) abgebrochen.
Danach wird ein Timer erzeugt und dem Zeiger zugewiesen. Inhalt:
Code: Alles auswählen
IR_Control.sendCommand("IRSEND,NEC,0x400501FE,32") // Logitech Z906 "Power" --> (ircodes.map)
tSzene_TV = createTimer(now.plusSeconds (5))[| // Abwarten bis Anlage an ist
IR_Control.sendCommand("IRSEND,NEC,0x400530CF,32") // Logitech Z906 "Input 3/ TV" --> (ircodes.map)
]
tSzene_TV = null
Unmittelbar daran anschließend(!)wird ein weiterer Timer erstellt, der dem selben Zeiger zugewiesen wird (womit es keinen gültigen Zeiger auf den ersten Timer mehr gibt). Inhalt des Timers:
Code: Alles auswählen
Szene_TV.sendCommand(OFF) // Wiederausschalten des Szenenswitchs
tSzene_TV = null // Timer = 0
Dieser Timer wird nach 5 Sekunden ausgeführt, das heißt, das Item Szene_TV bekommt den Befehl 0. Anschließend wird der Zeiger gelöscht.
Zehn Sekunden später läuft der Timer ab, auf welchen es keinen gültigen Zeiger gibt. Der Timer sendet den Befehl IRSEND,NEC,0x400501FE,32 an das Item IR_Control und definiert einen Timer, der nach 5 Sekunden abläuft. Inhalt:
Code: Alles auswählen
IR_Control.sendCommand("IRSEND,NEC,0x400530CF,32") // Logitech Z906 "Input 3/ TV" --> (ircodes.map)
Der Timer wird dem Zeiger zugewiesen, welcher unmittelbar darauf gelöscht wird.
Du möchtest eigentlich etwas komplett anderes haben:
Code: Alles auswählen
var Timer tSzene_TV = null
var Integer nSzene_TV = 0
rule "Szene TV"
when
Item Szene_TV changed from OFF to ON // Schalter zum aktivieren der Szene
then
tSzene_TV?.cancel // Falls Timer läuft stoppen
nSzene_TV=0
tSzene_TV = createTimer(now, [| // Ablaufsteuerung
nSzene_TV = nSzene_TV + 1
switch(nSzene_TV) {
case 1: { // Schritt 1 (ohne Verzögerung)
WZ_TVLampe.sendCommand(ON)
ShellyPlugS_7A35C0_Power.sendCommand(ON) // Fernseher
}
case 2: { // Schritt 2 (nach 5 Sekunden)
Szene_TV.postUpdate(OFF) // Wiederausschalten des Szenenswitchs
}
case 3: {} // Schritt 3 (nach 10 Sekunden, nix tun)
case 4: { // Schritt 4 (nach 15 Sekunden)
IR_Control.sendCommand("IRSEND,NEC,0x400501FE,32") // Logitech Z906 "Power" --> (ircodes.map)
}
case 5: { // Schritt 5 (nach 20 Sekunden)
IR_Control.sendCommand("IRSEND,NEC,0x400530CF,32") // Logitech Z906 "Input 3/ TV" --> (ircodes.map)
tSzene_TV = null // Zeiger auf Timer löschen
}
}
if(tSzene_TV !== null) // falls Zeiger nicht null
tSzene_TV.reschedule(now.plusSeconds(5)) // Timer erneut in 5 Sekunden ausführen
])
end
Es geht dabei um Kontrolle. In dem Moment, wo Du einen Zeiger (tSzene_TV) auf null setzt, verlierst Du die Kontrolle über den Timer (der Timer ist denoch vorhanden und wird ausgeführt).
Der Ablauf ist hier in 5-Sekunden-Schritten organisiert. die Anweisung "case 3" habe ich hier nur der Vollständigkeit halber aufgeführt, die Zeile kann entfallen. Der Timer wird einfach ausgeführt und tut nichts weiter, als sich selbst neu zu planen.
Man könnte auch den reschedule pro case einsetzen, dann könnte man auf den "Leerschritt" verzichten, hätte dafür aber drei mal die fast identische Zeile im Code. Das sähe dann so aus:
Code: Alles auswählen
var Timer tSzene_TV = null
var Integer nSzene_TV = 0
rule "Szene TV"
when
Item Szene_TV changed from OFF to ON // Schalter zum aktivieren der Szene
then
tSzene_TV?.cancel // Falls Timer läuft stoppen
nSzene_TV=0
tSzene_TV = createTimer(now, [| // Ablaufsteuerung
nSzene_TV = nSzene_TV + 1
switch(nSzene_TV) {
case 1: { // Schritt 1 (ohne Verzögerung)
WZ_TVLampe.sendCommand(ON)
ShellyPlugS_7A35C0_Power.sendCommand(ON) // Fernseher
tSzene_TV.reschedule(now.plusSeconds(5)) // Timer erneut in 5 Sekunden ausführen
}
case 2: { // Schritt 2 (nach 5 Sekunden)
Szene_TV.postUpdate(OFF) // Wiederausschalten des Szenenswitchs
tSzene_TV.reschedule(now.plusSeconds(10)) // Timer erneut in 10 Sekunden ausführen
}
case 3: { // Schritt 3 (nach 15 Sekunden)
IR_Control.sendCommand("IRSEND,NEC,0x400501FE,32") // Logitech Z906 "Power" --> (ircodes.map)
tSzene_TV.reschedule(now.plusSeconds(5)) // Timer erneut in 5 Sekunden ausführen
}
case 4: { // Schritt 5 (nach 20 Sekunden)
IR_Control.sendCommand("IRSEND,NEC,0x400530CF,32") // Logitech Z906 "Input 3/ TV" --> (ircodes.map)
tSzene_TV = null // Zeiger auf Timer löschen
}
}
])
end
Natürlich könnte man auch die unmittelbar auszuführenden Befehle vor dem Anlegen des Timers ausführen und den Timer 5 Sekunden in der Zukunft ausführen lassen. Die gezeigte Variante hat aber den Vorteil, dass der gesamte Ablauf im Timer liegt, man kann also klar erkennen, wie die Steuerung funktioniert.
openHAB4.3.5 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet