Hi everybody,
I am facing an issue which seems to be simple to the more advanced.
My trigger is a motion sensor. It provides the state ON/OFF by motion. Then, by vTimeOfDay the light should be switched to a defined state. If no motion is detected for e.g. 3 min the light should be swittched of.
What is happening? Motion is detected, but the timer runs and switches OFF the light after 3 min.
Please help me!!!:
Thank you!
My rule:
import org.openhab.model.script.actions.Timer
var Timer = null
rule "Badlicht mit Bewegungsmelder"
when
Item HueBadBewegungsmelderPresence received update
then
if((HueBadBewegungsmelderPresence.state == ON) && (vTimeOfDay.state == "MORNING" || vTimeOfDay.state == "DAY" || vTimeOfDay.state == "AFTERNOON")){
Hue_Badschrank_Switch.sendCommand(ON)
gTradfriBadDimmer1.sendCommand(80)
}
else
if((HueBadBewegungsmelderPresence.state == ON) && (vTimeOfDay.state == "EVENING" || vTimeOfDay.state == "NIGHT")){
Hue_Badschrank_Switch.sendCommand(ON)
gTradfriBadDimmer1.sendCommand(50)
}
else
if((HueBadBewegungsmelderPresence.state == ON) && (vTimeOfDay.state == "BED")){
Tradfri_Bad2_Brightness.sendCommand(15)
}
else
if(HueBadBewegungsmelderPresence.state == OFF)
Timer = createTimer(now.plusMinutes(3)) [|
sendCommand(gTradfriBadDimmer1, OFF)
sendCommand(Hue_Badschrank_Switch, OFF)
Timer = null
]
end
What are is the Item & rules setting vTimeOfDay
?
It is from the Design Pattern: Time Of Day by @rlkoshak.
Beside that: The state request for the time of day works. So the preset light is used.
1 Like
The logic breaks in 2: your rule processes either HueBadBewegungsmelderPresence.state
is ON
or OFF
. But the logic is incomplete and the rule will indeed turn off gTradfriBadDimmer1
and Hue_Badschrank_Switch
whenever the motion sensor goes from âpresence/motion detectedâ to âno presence/motion detectedâ).
What is missing in your code, is:
- a way to cancel the
timer_BadzimmerLichte
timer when (a) HueBadBewegungsmelderPresence.state
is ON
and (b) it has been previously scheduled (Timer is not null
) due to a âno motion detectedâ signal (HueBadBewegungsmelderPresence.state
was OFF
previously).
- a way to switch off
Tradfri_Bad2_Brightness
when vTimeOfDay.state
is no longer set to "BED"
.
You may want to reassess the actual use case you intend to implement with your rule with a state table.
I rewrote your rule replacing the complex if ()
statements with a more elegant switch () { case }
approach, and moved the "BED"
case from your rule in another rule as itâs most likely unrelated to the motion sensor logic:
import org.openhab.model.script.actions.Timer
// This timer will take care of turning off the bathroom lights:
var Timer timer_BadzimmerLichte = null
rule "Badlicht mit Bewegungsmelder"
when
Item HueBadBewegungsmelderPresence changed
then
switch (HueBadBewegungsmelderPresence.state) {
case ON:
{
// Cancel timer_BadzimmerLichte if it was running, or we will end up in the dark
timer_BadzimmerLichte?.cancel()
// Process time of day
switch (vTimeOfDay.state) {
case "MORNING",
case "DAY",
case "AFTERNOON":
{
Hue_Badschrank_Switch.sendCommand(ON)
gTradfriBadDimmer1.sendCommand(80)
}
case "EVENING",
case "NIGHT":
{
Hue_Badschrank_Switch.sendCommand(ON)
gTradfriBadDimmer1.sendCommand(50)
}
}
}
case OFF:
{
timer_BadzimmerLichte = createTimer(now.plusMinutes(3), [ |
sendCommand(Hue_Badschrank_Switch, OFF)
sendCommand(gTradfriBadDimmer1, OFF)
timer_BadzimmerLichte = null
])
}
}
end
rule "Nachtlicht im Badzimmer"
when
Item vTimeOfDay changed
then
// Process time of day
switch (vTimeOfDay.state) {
case "BED":
{
Tradfri_Bad2_Brightness.sendCommand(15)
}
default:
{
// Turn off:
Tradfri_Bad2_Brightness.sendCommand(0)
}
}
end
Thank you for the enormous help! I did expect something, but not such a big solution. Very nice!
You are right, I missed the way to cancel the timer. The idea to put the âBEDâ time of day into a seperate rule is okay. But I would prefer to trigger it by the motion sensor as well. So I just created ontoher case for âBEDâ.
Here my final rule:
import org.openhab.model.script.actions.Timer
// This timer will take care of turning off the bathroom lights:
var Timer timer_BadzimmerLichte = null
rule "Badlicht mit Bewegungsmelder"
when
Item HueBadBewegungsmelderPresence changed
then
switch (HueBadBewegungsmelderPresence.state) {
case ON:
{
// Cancel timer_BadzimmerLichte if it was running, or we will end up in the dark
timer_BadzimmerLichte?.cancel()
// Process time of day
switch (vTimeOfDay.state) {
case "MORNING",
case "DAY",
case "AFTERNOON":
{
Hue_Badschrank_Switch.sendCommand(ON)
gTradfriBadDimmer1.sendCommand(80)
}
case "EVENING",
case "NIGHT":
{
Hue_Badschrank_Switch.sendCommand(ON)
gTradfriBadDimmer1.sendCommand(50)
}
case "BED":
{
Tradfri_Bad2_Brightness.sendCommand(15)
}
}
}
case OFF:
{
timer_BadzimmerLichte = createTimer(now.plusSeconds(30), [ |
sendCommand(Hue_Badschrank_Switch, OFF)
sendCommand(gTradfriBadDimmer1, OFF)
timer_BadzimmerLichte = null
])
}
}
end
Youâre welcome.
In re-reading my code I see that I wrote a mistake in the timer call-back: I forgot to rename Timer
to timer_BadzimmerLichte
. I updated this in my earlier post.
The problem with the one single rule is that:
- you only switch on
Tradfri_Bad2_Brightness
when the motion sensor is activated and vTimeOfDay equals "BED"
.
- you donât control when to switch off
Tradfri_Bad2_Brightness
.
The 2nd rule I wrote ("Nachtlicht im Badzimmer"
) takes care of this, I assumed the following (which may not be right):
-
Tradfri_Bad2_Brightness
is a night-mode auxiliary light that you set to a low value (15%) when vTimeOfDay
is set to "BED"
to avoid being blinded at night when entering the bathroom
-
Tradfri_Bad2_Brightness
is switched off when vTimeOfDay
is not set to "BED"
.
In case all you want to do is to define the lights to manipulate depending on the time of day, then the timer call-back method should also manage Tradfri_Bad2_Brightness
(through gTradfriBadDimmer2
, I guess).
You also may want to watch out for situations where vTimeOfDay
changes value while the timer is running. The call-back should probably switch off all lights. Thatâs fairly simple, add sendCommand(gTradfriBadDimmer2, OFF)
before timer_BadzimmerLichte = null
.
âTradfri_Bad2_Brightnessâ is a member of gTradfriBadDimmer1. So it should be switched of when the timer finishes, does it not? So three bulb in the bathroom which could be triggered seperately and in group.
Additionally there is a smart plug.
The Items are
Group gTradfriBadDimmer1
Dimmer Tradfri_Bad1_Brightness "...." (gTradfriBadDimmer1) {channel="---"}
Dimmer Tradfri_Bad2_Brightness "...." (gTradfriBadDimmer1) {channel="---"}
Dimmer Tradfri_Bad3_Brightness "...." (gTradfriBadDimmer1) {channel="---"}
Switch Hue_Badschrank_Switch "..." (...) {channel="---"}
I will check how it will run.
Thank you!
Indeed, that should do the job!