Es ist verlockend, das Problem mit Thread::sleep zu lösen, es birgt aber eine reale Gefahr, gerade, wenn der Trigger und das zugehörige if-Statement so leicht mehrfach hintereinander getriggert werden kann; Es kann jegliches Ausführen von Rules verhindern.
Hintergrund dazu: openHAB nutzt für die Ausführung von Rules einen sogenannten Thread Pool, das heißt, es gibt einen Pool von Threads (sic!) die zum Ausführen von Rules vorgehalten werden. Dieser Pool umfasst 5 Threads, es können also maximal 5 Rules gleichzeitig ausgeführt werden. Werden mehr als 5 Rules zeitgleich getriggert, muss die letzte in der Reihe (es gibt im Rechner keine Gleichzeitigkeit...) eben so lange warten, bis ein Thread frei wird. Da die Rules asynchron laufen und das nirgendwo aktiv verhindert wird, kann dieselbe Rule auch 5 mal gleichzeitig starten (z.B. Helligkeit schwankt schnell zwischen 1 und 2 Lux).
Besser ist es also, wenn möglich auf Thread::sleep zu verzichten, allenfalls, um eine kurze Denkpause einzulegen (bis maximal 500mSec) ist Thread::sleep ok.
Die Pausen zwischen den einzelnen Läden sind vermutlich der Funktechnik geschuldet, aber ich verstehe, dass Du da nicht unbedingt investieren willst, wo die manuelle Steuerung ja gut funktioniert.
Für mich sähe der Code eher so aus:
Code: Alles auswählen
// Globale Variablen immer zu Beginn der Datei definieren!
var Timer tLum = null
var Number nLum = 0
rule "Luminanz"
when
Item dataLum changed
then
if(!(dataLum.state instanceof Number)) {
logWarn("luminanz","dataLum enthält keinen gültigen Wert!")
return;
}
if ((dataLum.state as Number) < 4 && now.getHourOfDay > 17 && now.getHourOfDay < 23 && tLum === null) {
nLum = 0
tLum = createTimer(now.plusSeconds(1), [|
var Number nTime = 1
nLum += 1
switch nLum {
case 1: {
Markise.sendCommand(DOWN)
nTime = 60
}
case 2: {
Roll_WZ_W_li.sendCommand(DOWN)
}
case 3: {
Roll_WZ_W_re.sendCommand(DOWN)
}
case 4: {
Markise.sendCommand(DOWN)
}
case 5: {
Roll_WZ_W_li.sendCommand(DOWN)
}
case 6: {
Roll_WZ_W_re.sendCommand(DOWN)
nTime = 600
}
default: {
nTime = 0
}
}
if(nTime > 0)
tLum.reschedule(now.plusSeconds(nTime))
else {
tLum = null
}
])
}
end
Ich habe hier bewusst auf schmutzige Tricks verzichtet

möchte aber Verbesserungspotential nicht vorenthalten:
Wenn man auf verschieden lange Pausen verzichtet, kann man mittels Gruppierung der Items die Rule extrem einkürzen.
Die Rule startet, wenn alle Bedingungen erfüllt sind, dazu gehört, dass der Timer gerade nicht läuft.
Wenn alles passt, wird der Zähler initialisiert und der Timer angelegt. Der Timer startet nach einer Sekunde (man könnte diese Zeit auch noch kürzer wählen, das ist jetzt einfach Bequemlichkeit). Zuerst wird der Zähler erhöht, anschließend wird abhängig vom Zählerstand jeweils ein anderer Befehl ausgeführt. Zu Beginn wird die Hilfsvariable nTime auf 1 gesetzt. Anschließend wird nur bei Bedarf eine andere Zeit eingetragen (bei der Markise z.B. 60). Zum Schluss wird der Timer zur erneuten Ausführung geplant.
Im vorletzten Schritt wird nTime auf 600 gesetzt, was dann 10 Minuten Pause bedeutet.
Wenn der Zähler über 6 steigt, wird nTime auf 0 gesetzt. Damit führt die letzte Bedingung nicht mehr zum Reschedule, sondern der Zeiger (und damit der Code) wird gelöscht. Anschließend kann der Timer wieder durch die Rule angelegt werden.
Die Rule selbst kann nun beliebig oft triggern, der Code wird exakt einmal ausgeführt, danach ist 10 Minuten Ruhe. Der Timer selbst läuft nur wenige Millisekunden pro Zyklus, danach steht der Thread sofort wieder zur Verfügung, auch, wenn der Timer neu geplant wurde.
openHAB5.0.3 stable in einem Debian-Container (trixie, OpenJDK 21 headless runtime - LXC, 4 Kerne, 3 GByte RAM)
Hostsystem Proxmox 9.1.2 - AMD Ryzen 5 3600 6 Kerne, 12 Threads - 64 GByte RAM - ZFS Pools: Raid Z1, 3 x 20 TB HDD -> 40 TByte und Raid Z0-Mirrored 4 x 1 TByte NVMe -> 2 TByte