Herzlich willkommen im openHAB Forum!
Die unselige Geschichte mit den Szenen...
Eine Szene ist aus openHAB-Sicht ein Schnappschuss der Zustände einer festgelegten Anzahl von Kanälen.
Was Du haben willst, ist eine Ablauf Automation.
openHAB konnte ursprünglich "nur" Automation, und keine Szenen oder Zeitsteuerung, weil Automation all das uneingeschränkt kann, warum also sollte man überhaupt eine Trennung vornehmen... Aber weil andere Systeme "Szenen" beherrschen, musste openHAB auch welche bekommen.
In meinen Augen sind das Alibi-Szenen. "openHAB kann das jetzt auch!"
Spoiler: openHAB konnte das schon immer
besser, nur halt unter dem Namen "Rule" und nicht "Szene".
Was Du für die Automation brauchst, ist eine Rule (oder meinetwegen zwei, eine für auf und eine für zu).
Wenn Du mit JavaScript firm bist, kannst Du die Rule so programmieren, Du kannst auch Blockly verwenden, wenn Du mehr der optische Typ bist

Oder Du verwendest eine der anderen Sprachen, welche von openHAB unterstützt werden.
Direkt mit an Bord ist aber nur die Rules DSL.
Thread.sleep() ist im Übrigen nicht die gute Lösung, richtig macht man das mit Timern.
Schlecht:
Code: Alles auswählen
rule "Rollläden schließen"
when
Item RL_Alle received command ON
then
RL_Studio_Level.sendCommand(DOWN)
Thread.sleep(3000)
RL_Schlafzimmer_Level.sendCommand(DOWN)
Thread.sleep(2000)
RL_Christopher_Level.sendCommand(DOWN)
end
Besser:
Code: Alles auswählen
// Globale Variablen zu Beginn der Datei definieren!
var Timer tRoll = null
var Integer iRoll = 0
rule "Rollläden schließen"
when
Item RL_Alle_Befehl received command ON
then
if(tRoll !== null)
return;
iRoll = 0
tRoll = createTimer(now, [|
iRoll += 1
switch(iRoll) {
case 1: {
RL_Studio_Level.sendCommand(DOWN)
tRoll.reschedule(now.plusSeconds(3))
} case 2: {
RL_Schlafzimmer_Level.sendCommand(DOWN)
tRoll.reschedule(now.plusSeconds("))
} case 3: {
RL_Christopher_Level.sendCommand(DOWN)
tRoll = null
}
}
])
end
Noch besser: Du definierst eine Gruppe für die zu steuernden Items (bei 9 Stück lohnt das definitiv) und änderst die Namen der Items leicht ab, um eine Reihenfolge vorgeben zu können. Nennen wir die Gruppe
gRL und geben den Items Namen der Form
RL_n_bla -
n ist eine Ziffer, die angibt, in welcher Reihenfolge die Items abgearbeitet werden, bla ist beliebiger Text, der den Regeln für Itemnamen folgt.
Gehen wird weiter davon aus, dass alle Items mit dem gleichen zeitlichen Abstand gefahren werden sollen (z.B. weil der verwendete Bus sonst überlastet wird), sieht die passende Rule so aus:
Code: Alles auswählen
// Globale Variablen zu Beginn der Datei definieren!
var Timer tRoll = null
var Integer iRoll = 0
rule "Rollläden schließen"
when
Item RL_Alle received command ON
then
if(tRoll !== null)
return;
nRoll = 0
tRoll = createTimer(now, [|
iRoll += 1
gRL.members.filter[r|r.name.split("_").get(1) = iRoll.toString].head.sendCommand(DOWN)
if(iRoll < gRL.members.size)
tRoll.reschedule(now.plusSeconds(3))
else
tRoll = null
])
end
Wohlgemerkt: diese Rule kümmert sich um beliebig viele Rollläden, egal ob nun einer oder 1000, solange die Itemnamen korrekt gewählt werden (also es gibt nur eindeutige n, wobei n mit 1 startet und keine Zahl ausgelassen wird; keine führenden Nullen oder andere Besonderheiten)
Alle drei Sekunden wird ein Rollladen geschlossen, bis alle Member der Gruppe gRL angesteuert wurden.
Die gleiche Rule per UI:
Code: Alles auswählen
configuration: {}
triggers:
- id: "1"
configuration:
itemName: RL_Alle_Befehl
type: core.ItemCommandTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
type: application/vnd.openhab.dsl.rule
script: >-
if(sharedCache.get("tRoll"))
return;
sharedCache.put("iRoll",0)
sharedCache.put("tRoll", createTimer(now, [|
sharedCache.put("iRoll", sharedCache.get("iRoll") + 1)
gRL.members.filter[r|r.name.split("_").get(1) = sharedCache.get("iRoll").toString].head.sendCommand(DOWN)
if(sharedCache.get("iRoll") < gRL.members.size)
sharedCache.get("tRoll").reschedule(now.plusSeconds(3))
else
sharedCache.put("tRoll", null)
])
)
type: script.ScriptAction
Die Rule ist per UI etwas aufwändiger, weil es keine globalen Variablen gibt und man stattdessen den shared Cache verwenden muss.
Ich habe die Rule auch nicht getestet

und es ist wahrscheinlich, dass ich irgendwo einen Tippfehler drin habe... es soll hier eher darum gehen, zu zeigen, wie so etwas grundsätzlich aussieht.
Natürlich kannst Du auch die
Thread.sleep() Version über die UI verwenden, wie gesagt, schlechter Stil, aber was soll's:
Code: Alles auswählen
configuration: {}
triggers:
- id: "1"
configuration:
itemName: RL_Alle_Befehl
type: core.ItemCommandTrigger
conditions: []
actions:
- inputs: {}
id: "2"
configuration:
type: application/vnd.openhab.dsl.rule
script: >-
RL_Studio_Level.sendCommand(DOWN)
Thread.sleep(3000)
RL_Schlafzimmer_Level.sendCommand(DOWN)
Thread.sleep(2000)
RL_Christopher_Level.sendCommand(DOWN)
Thread.sleep(3000)
RL_Zimmer4_Level.sendCommand(DOWN)
Thread.sleep(3000)
RL_Zimmer5_Level.sendCommand(DOWN)
Thread.sleep(3000)
RL_Zimmer6_Level.sendCommand(DOWN)
Thread.sleep(3000)
RL_Zimmer7_Level.sendCommand(DOWN)
Thread.sleep(3000)
RL_Zimmer8_Level.sendCommand(DOWN)
Thread.sleep(3000)
RL_Zimmer9_Level.sendCommand(DOWN)
type: script.ScriptAction