Code: Alles auswählen
if(BewegungsmelderInnenIllumination.state.toString < 10)
Seit wann kann ein String kleiner (oder größer) als ein Zahlenwert sein?
Eine hoffentlich funktionierende Variante sollte so aussehen:
Code: Alles auswählen
rule "Bewegung erkannt"
when
Item BewegungsmelderInnenBewegung changed
then
if(BewegungsmelderInnenBewegung.state == ON)
if((BewegungsmelderInnenIllumination.state as Number) < 10)
TP_L1_Switch.sendCommand(ON)
else
if(TP_L1_Switch.state == ON)
TP_L1_Switch.sendCommand(OFF)
end
Das Ausschalten erfolgt immer, wenn keine Bewegung erkannt wird. Das Einschalten erfolgt, sobald Bewegung erkannt wird und der numerische Wert der Helligkeit kleiner 10 ist.
Allerdings könnte es sein, dass Du nicht glücklich mit der Lösung bist, denn wenn kurzzeitig keine Bewegung erkannt wird, schaltet das Licht unmittelbar ab. Deshalb sieht man normalerweise einen Timeout vor, also z.B.: "Schalte bei Bewegungserkennung das Licht ein, falls die Helligkeit untere 10 ist. Schalte das Licht aus, falls eine Minute keine Bewegung erkannt wurde oder die Helligkeit zwischenzeitlich über 20 gestiegen ist." Das sähe dann so aus:
Code: Alles auswählen
var Timer tMotion = null
rule "Bewegung erkannt"
when
Item BewegungsmelderInnenBewegung changed or // Bewegung Anfang oder Ende bzw.
Item BewegungsmelderInnenIllumination changed // Helligkeit geändert
then
val Number nBright = BewegungsmelderInnenIllumination.state as Number
if(BewegungsmelderInnenBewegung.state == ON && nBright < 10) { // Bewegung und zu dunkel
if(TP_L1_Switch.state != ON) // Licht noch aus
TP_L1_Switch.sendCommand(ON) // Licht an!
if(tMotion === null) // Timer noch nicht initialisiert
tMotion = createTimer(now.plusMinutes(10),[| // Falls 10 Minuten keine Meldung vom Bewegungsmelder kommt
if(TP_L1_Switch.state != OFF) // Falls Licht an
TP_L1_Switch.sendCommand(OFF) // Licht aus!
tMotion === null // Timer deinitialisieren
])
else // Timer läuft schon
tMotion.reschedule(now.plusMinutes(10)) // Timerablauf neu setzen
} else if(BewegungsmelderInnenBewegung.state == ON && nBright > 20) // Bewegung aber zu hell
tMotion.reschedule(now.plusSeconds(1)) // Timerablauf neu setzen
else if(BewegungsmelderInnenBewegung.state == OFF) // Keine Bewegung
tMotion.reschedule(now.plusMinutes(1)) // Timerablauf neu setzen
end
Die Theorie dazu: Die Rule löst jedesmal aus, wenn es eine Helligkeitsänderung oder eine Zustandsänderung der Bewegung gibt.
Wenn Bewegung erkannt wurde und die Helligkeit unterschritten ist, schaltet das Licht ein, falls noch nicht geschehen. Anschließend wird geprüft, ob der Timer schon existiert. Falls nicht, wird er mit 10 Minuten Timeout angelegt. Falls also der Bewegungsmelder 10 Minuten nichts von sich gibt, schaltet das Licht aus.
Falls der Timer schon existiert, wird er einfach nach hinten geschoben, denn der Melder hat ja Bewegung erkannt.
Falls zwar Bewegung erkannt wurde, die Helligkeit aber inzwischen gestiegen ist, wird das Licht nach einer Sekunde abgeschaltet (die zeit ist so kurz gewählt, weil ich nicht weiß, wie häufig der Helligkeitssensor Änderungen sendet).
Falls Keine Bewegung erkannt wurde, wird der Timeout auf eine Minute herabgesetzt.
Das Hauptproblem bei solchen Logiken ist, alle Eventualitäten zu erfassen und passend zu reagieren, also: Was soll passieren, falls
- der Bewegungsmelder keine Telegramme mehr sendet?
- die Helligkeit sinkt, aber bereits Bewegung detektiert wurde?
- Bewegung detektiert wurde, aber die Helligkeit gestiegen ist?
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet