Es gibt ein paar Ungereimtheiten. Zunächst einmal
Diese Bedingung ist verkehrt. === bedeutet "ist identisch". Das ist etwas anderes als "ist gleich", welches so aussieht: ==
Der Vergleich
=== ist in der DSL nur im Zusammenhang mit dem Wert
null zulässig und sinnvoll, denn hier wird geprüft, ob der
Zeiger einer Variablen auf eine bestimmte Speicherstelle verweist, eben diejenige, welche
null repräsentiert. Wann immer eine Variable mit
null initialisiert wird, wird deren Zeiger auf diese eine Speicherzelle umgeschrieben. Wenn der Wert nicht mehr null sein soll, bekommt die Variable eine andere Speicherzelle zugewiesen, welche dann mit dem konkreten Wert gefüllt wird.
Warum diese Bedingung im Zusammenhang mit
.state überhaupt funktionieren könnte, ist mir nicht so ganz klar.
Allerdings: die Rule triggert bei einem Update ON, damit ist zwingend der Status ON. Da das abgefragte Item identisch mit dem Trigger ist, ist dieser Teil also sinnfrei.
Der Aufbau der Rule insgesamt erscheint mir reichlich umständlich. Eigentlich möchtest Du, dass die Rule nichts tut, fall die Helligkeit über 0.2 ist. Warum fragst Du das nicht zu Beginn ab?
An dieser Stelle könnte es noch ein weiteres Problem geben, welches speziell nach einem Update auftauchen kann, und zwar der ITemtyp. Handelt es sich um ein
Number Item, oder eventuell (neuerdings) um ein
Number:Illuminance Item? Bei letzterem gehört eine Einheit zum Wert, gewöhnlich
lx. Diese muss beim Vergleich mit angegeben werden, alternativ kann man die Einheit vom Status strippen, muss dann aber darauf achten, wie der Wert im Item gespeichert wird.
Eine weitere Frage wäre die nach dem normalen Verhalten des Bewegungsmelders. Was passiert, wenn der Melder keine Bewegung erkennt (für x Sekunden...) Setzt der Melder das Item selbst auf OFF zurück, oder sendet der Melder ausschließlich ON?
Egal wie, einfacher geht es so:
Code: Alles auswählen
var Timer tFlur = null
rule "Licht Flur bei Bewegung Einschalten"
when
Item EG_Flur_PM_erkannt received update ON
then
if((EG_Flur_PM_Helligkeit.state as Number).floatValue > 0.2) { // zu hell
logInfo("motion","Flur Bewegung erkannt, aber zu hell: Nichts zu tun")
return; // Abbruch der Rule
}
tFlur?.cancel // Falls Timer existiert, abbrechen
if(Flur_Licht.state != ON) // Falls Licht aus
Flur_Licht.sendCommand(ON) // Licht einschalten
else // sonst
logInfo("motion", "Flur Timer wird verlängert") // Meldung wegen Verlängerung
tFlur = createTimer(now.plusMinutes(1), [| // Timer erstellen
logInfo("motion", "Flur Timer abgelaufen und aus")
Flur_Licht.sendCommand(OFF) // Licht aus
])
end
Als erstes prüft die Rule, ob es zu hell ist. Ist das der Fall, wird die Rule abgebrochen.
Als nächstes wird ein existierender Timer abgebrochen. Existiert der Timer nicht, wird der cancel-Befehl nicht ausgeführt (das ist das ?)
Man könnte auch stattdessen
schreiben, das Fragezeichen ist halt (wesentlich) kürzer.
Nun prüft die Rule, ob das Licht eingeschaltet ist, und schaltet das Licht ein, falls nicht. War es bereits an, muss der Timer aktiv gewesen sein, also handelt es sich um eine Verlängerung.
Die Logmeldungen sind beim Entwickeln vielleicht gut, aber bei einer so simplen Rule doch eher unnötig (sorry...), entsprechend wäre die Rule "ohne" auch etwa schlanker:
Code: Alles auswählen
var Timer tFlur = null
rule "Licht Flur bei Bewegung Einschalten"
when
Item EG_Flur_PM_erkannt received update ON
then
if((EG_Flur_PM_Helligkeit.state as Number).floatValue > 0.2) return;
tFlur?.cancel
if(Flur_Licht.state != ON) Flur_Licht.sendCommand(ON)
tFlur = createTimer(now.plusMinutes(1), [|
Flur_Licht.sendCommand(OFF)
])
end
Abschließend noch zum log-Befehl:
Dieser erwartet zwei Strings als Parameter, der erste String gibt dabei den Logger Namen an, der zweite die Meldung. Der Loggername wird vererbt, d.h. es wird immer der String
org.openhab.core.model.script. vorangestellt, es ergibt sich also für die Rule oben der Loggername
org.openhab.core.model.script.motion
Der Witz bei der Sache: man kann über den Loggernamen zur Laufzeit bestimmen, ob solche Meldungen überhaupt ausgegeben werden (im Log-bereich unten rechts auf das Zahnrad und einen Eintrag für den Loggernamen erzeugen, danach kann man das Level setzen, ab dem geloggt wird).
Es gibt insgesamt vier Logbefehle, in aufsteigender Reihenfolge nach "Schwere" der Meldung logDebug(), logInfo(), logWarn() und logError(). Die Befehle funktionieren identisch und unterscheiden sich lediglich im generierten Loglevel, man kann also in einer (komplexen) Rule diverse Logmeldungen generieren, später aber einen Teil dieser Meldungen ausblenden um z.B. nur "schlimme" Fehler gemeldet zu bekommen
FILE ist als Teil-Name eines Loggers nicht gut

(zu unspezifisch)
openHAB5.1.2 stable in einem Debian-Container (trixie, OpenJDK 21 headless runtime - LXC, 4 Kerne, 3 GByte RAM)
Hostsystem Proxmox VE 9.1.5 - 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