Die einfachste Möglichkeit, ein Delay einzubauen:
Items:
Code: Alles auswählen
Group:Dimmer gTradfri "Alle Tradfri"
Dimmer dTradfri_01 "Tradfri Lampe 1 [%d %%]" (gTradfri)
Dimmer dTradfri_02 "Tradfri Lampe 2 [%d %%]" (gTradfri)
Dimmer dTradfri_03 "Tradfri Lampe 3 [%d %%]" (gTradfri)
Dimmer pTradfri "Proxy Tradfri"
Rule:
Code: Alles auswählen
rule "control Tradfri Group"
when
Item pTradfri changed
then
gTradfri.members.forEach[i|
i.sendCommand(pTradfri.state as Number)
Thread::sleep(100)
]
end
Du musst natürlich immer das Proxy Item verwenden, um die Gruppe zu steuern, keinesfalls die Gruppe. Man könnte auf die Idee kommen, dioe Gruppe selbst zu verwenden, aber die Gruppe sendet dann selbst die Befehle (ohne Delay) und die Rule zeitgleich auch noch mal (mit Delay), was dann zu noch mehr Durcheinander führt.
Die Zeit in Thread::sleep() kannst Du natürlich anpassen, da ist Platz für Experimente (wieviele Telegrammme/Sekunde verträgt Tradfri?)
Noch kurz ein Hinweis: Thread::sleep() sollte keinesfalls für Verzögerungen über 500 Millisekunden verwendet werden, auch wenn das natürlich möglich ist. Der Grund ist hier, dass openHAB 5 Threads für die Rule-Abarbeitung zur Verfügung hat. Eine laufende Rule blockiert also einen Thread, und die Bezeichnung sleep ist wörtlich zu nehmen, der Thread ist weiterhin blockiert und schläft halt. Wenn man also z.B. eine Rule hat, die mit Thread::sleep(120000) zwei Minuten wartet, bis sie mit der Arbeit fortfährt, und diese Rule vielleicht außerdem mehrfach aufgerufen werden kann, kann die Abarbeitung jeglicher anderer Rules verhindert werden, indem die Rule einfach fünf mal startet wird.
Die Alternative ist dann, einen Timer zu verwenden. Timer werden im Scheduler von openHAB verwaltet und benötigen keinen Thread, bis der Timer abläuft (dann natürlich schon, um den hinterlegten Code auszuführen).
Man könnte die Rule oben genauso auch mit einem Timer realisieren. Nicht empfohlen für kleine Zeitspannen (unter 500Millisekunden):
Code: Alles auswählen
var Timer tTradfri = null
rule "control Tradfri Group"
when
Item pTradfri changed
then
tTradfri?.cancel
tTradfri = createTimer(now.plusMillis(500), [ |
if(gTradfri.members.filter[i|i.state != pTradfri.state].size > 0) {
gTradfri.members.filter[i|i.state != pTradfri.state].head.sendCommand(pTradfri.state as Number)
tTradfri.reschedule(now.plusMillis(500))
} else
tTradfri = null
]
end
Dieses Konstrukt wird die Lampen solange ansteuern, bis alle Lampen auf dem korrekten Wert sind. Falls man die Tradfri Items mit autoupdate="false"konfiguriert, kann es zu einem Problem kommen, wenn eine der Lampen nicht mehr erreichbar ist, denn das betreffende Item wird dann seinen Status nicht mehr ändern. In der Folge bleibt die Rule an dieser Lampe hängen. Will man das vermeiden, muss man eine zusätzliche Variable als Zeiger nutzen, aber auch hier lauern Fallstricke
