Delay in rule

here is my current rule

rule “Motion Light ON Kitchen”

when
Item Kitchen_Movement changed from CLOSED to OPEN
then
if (Kitchen_Lux.state < 30){
sendCommand(WallSwitch_Kitchen, ON)
}
end

rule “Motion Light OFF Kitchen”

when
Item Kitchen_Movement changed from OPEN to CLOSED
then
kitchen_timer = createTimer(now.plusMinutes(5)) [|
if (Kitchen_Movement.state == CLOSED){
sendCommand(WallSwitch_Kitchen, OFF)
}
else
{
if (Kitchen_Movement.state == OPEN){
need to reset timer here
}
}
]

end

what I want to do it turn the light on if motion is detected and luminance is less than 30. that is working welll. the trouble is I want the rule to check if there has been movement in the last 5 minutes. if not then I want the light to turn off, if there was movement detected then i want the light to stay on.

I would implement it as follows. Typing this from my phone so it us likely to contain errors.

var Timer timer = null

rule "Kitchen light motion"
when
    Item Kitchen_Movement received command
then
    if(Kitchen_Movement.state == OPEN && (timer == null || timer.has terminated)) {
        WallSwitch_Kitchen.sendcommand(ON)
        timer = create timer(now.plus minutes(5), [|             WallSwitch_Kitchen.sendcommand(OFF) ]
    }
    else if(Kitchen_Movement.state == OPEN) {
        timer.reschedule(now. PlusMinutes(5))
    }
End

I use then a global retriggered counter and a global every minute rule:

var Integer counter_kitchen_light = 0

rule “Motion Light ON Kitchen”
when
Item Kitchen_Movement changed from CLOSED to OPEN
then
if (Kitchen_Lux.state < 30){
sendCommand(WallSwitch_Kitchen, ON)
counter_kitchen_light = 6
}
end

rule “every minute”
when
Time cron “0 * * * * ?”
then
if (counter_kitchen_light > 0) counter_kitchen_light = counter_kitchen_light - 1
if (counter_kitchen_light == 1) sendCommand(WallSwitch_Kitchen, OFF)
end

Holger

Thanks. Exactly what I needed.

I think this will turn off the light after 5 minutes regardless of the status of the motion sensor.

here is the cleaned up working example for reference.

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.openhab.model.script.actions.Timer
var Timer kitchen_timer = null
rule “Kitchen light motion”
when
Item Kitchen_Movement changed
then
if(Kitchen_Movement.state == OPEN && kitchen_timer == null) {
sendCommand(WallSwitch_Kitchen, ON)
kitchen_timer = createTimer(now.plusMinutes(2)) [|
sendCommand(WallSwitch_Kitchen,OFF)
kitchen_timer = null
]
}
else if (Kitchen_Movement.state == OPEN) {
kitchen_timer.reschedule(now.plusMinutes(2))
}

end

I think this will turn off the light after 5 minutes regardless of the status of the motion sensor.
Yes right, then decrement only if state = open

Holger

this is what I have now.

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.openhab.model.script.actions.Timer
var Timer kitchen_timer = null
rule “Kitchen light motion”
when
Item Kitchen_Movement changed
then
if(Kitchen_Movement.state == OPEN && kitchen_timer == null) {
if (Kitchen_Lux.state < 30){
sendCommand(WallSwitch_Kitchen, ON)
kitchen_timer = createTimer(now.plusMinutes(1)) [|
sendCommand(WallSwitch_Kitchen,OFF)
kitchen_timer = null
]
}
else {
kitchen_timer = createTimer(now.plusMinutes(1)) [|
kitchen_timer = null
]

   }
}
else if (Kitchen_Movement.state == OPEN) {
    kitchen_timer.reschedule(now.plusMinutes(1))
}

end

something like this??

var Integer counter_kitchen_light = 0

rule “Motion Light Kitchen”
when
Item Kitchen_Movement changed from CLOSED to OPEN
then
if (Kitchen_Lux.state < 30){
sendCommand(WallSwitch_Kitchen, ON)
counter_kitchen_light = 2
}
end

rule “every minute”
when
Time cron “0 * * * * ?”
then
if (Kitchen_Movement.state == CLOSED){
if (counter_kitchen_light > 0) counter_kitchen_light = counter_kitchen_light - 1
if (counter_kitchen_light == 1) sendCommand(WallSwitch_Kitchen, OFF)
}
if (Kitchen_Movement.state == OPEN && counter_kitchen_light < 2){
counter_kitchen_light = 2
}
end

I would say this should work:
If the Kitchen_movement changed the counter is set to 6 (in rule “Motion Light Kitchen”)
Every minute it decrement the counter if nobody detect.
Please check with value > 2

var Integer counter_kitchen_light = 6 // value >0 shut down light too when openHAB restart

rule “Motion Light Kitchen”
when
Item Kitchen_Movement changed from CLOSED to OPEN
then
if (Kitchen_Lux.state < 30){
sendCommand(WallSwitch_Kitchen, ON)
counter_kitchen_light = 6
}
end

rule “every minute”
when
Time cron “0 * * * * ?”
then
if (Kitchen_Movement.state == CLOSED){
if (counter_kitchen_light > 0) counter_kitchen_light = counter_kitchen_light - 1
if (counter_kitchen_light == 1) sendCommand(WallSwitch_Kitchen, OFF)
}
end

Holger

PS: i assume
closed: nobody is in kitchen
open: person is detect in kitchen

i have tried it with timer today, works fine for me:

var Timer kitchen_timer = null var Integer kitchen_timeout = 3
rule "Kitchen light motion"
when
Item Kitchen_Movement changed to OPEN  
then    
if (Kitchen_Lux.state < 30){    
    if (kitchen_timer != null) 
    {            
        kitchen_timer.reschedule(now.plusMinutes(kitchen_timeout))
        logInfo("Kitchen","Kitchen timer rescheduled for " + kitchen_timeout + " minutes")
    }
    else
    {            
        sendCommand(WallSwitch_Kitchen, ON)
        logInfo("Kitchen","Kitchen timer create with " + kitchen_timeout + " minutes")
        kitchen_timer = createTimer(now.plusMinutes(kitchen_timeout)) 
        [|        
            if (Kitchen_Movement.state ==  OPEN)   
            {
                kitchen_timer.reschedule(now.plusMinutes(kitchen_timeout))
                logInfo("Kitchen","Kitchen timer triggered, but rescheduled again for " + kitchen_timeout + " minutes")                    
            } 
            else 
            {            
                sendCommand(WallSwitch_Kitchen,OFF)
                kitchen_timer = null
            }
        ]
    }
}

end

Holger

1 Like

Does your kitchen light turn off after 3 minutes even if the state is OPEN?

No, it stays on.
open means: person is detected

I will try out this rule later today. I did not see anything in the rule that would reschedule the timer when the state remains open but the initial timer expires.

Apologize if i missed anything.

here it is:
Timer trigger and reschedule itself:

but isnt that triggered when the state changes to open.

how will that fire when the state remains open after the initial timer expires?

the initial timer trigger and reschedule itself, try it out please and look at the loginfos…

will do. thanks again for all your help.

if the timer once is started it runs outside the rule. if “expired” the timer look how the state is, if it is open it reschedule itself and again …

that makes a lot more sense. Sorry am not too familiar with programming rules yet.