Design Pattern: Motion Sensor Timer

Edit: Updates for OH 4

Please see Design Pattern: What is a Design Pattern and How Do I Use Them for details on how to use DPs.

Problem Statement

Many motion detectors only report ON when they detect motion but do not send a corresponding OFF after no motion has been detected after a period of time. In addition, often one wants to control a device like a light for a certain period after the last motion is seen, not after the motion sensor goes to OFF. Therefore one needs to keep a Contact OPEN (or Switch ON) until the desired amount of time after the last motion is detected.

This also applies in any cases where you want to do something when a state is first reached, and then doing something else a certain time after.

This approach works any time one wants something to happen a certain amount of time after the last time that an Item received a command or update. It can be easily adapted to report when a device stops reporting, to avoid flapping (e.g the switch constantly switching back and forth when something is on the edge of detection.

Concept

When the motion detector sends an ON command, create a timer. If subsequent ON commands are received reschedule the timer. When the timer expires call a rule containing the code to execute when there hasn’t been motion events for long enough.

For the examples blow we will assume:

  • MotionSensor is a Switch Item linked to the motion sensor, we assume it does not change to OFF on it’s own
  • Light is a Switch Item linked to the light controlled by the motion sensor

We will turn the light on upon first motion and will turn it off five minutes after the last motion.

Expire Timer

If you have a case where Light is only controlled by the MotionSensor you can use the Expiration Timer metadata on the Light Item. Set it to send command OFF after five minutes. By default it will reschedule itself every time it’s commanded ON.

Now all you need is something to command Light to ON when motion is reported. A simple rule that triggers when MotionSensor receives an ON update and which commands the Light to ON is sufficient.

Five minutes after the last command to Light is received, expire will command the light OFF.

Rule Template

Threshold Alert and Open Reminder [4.0.0.0;5.9.9.9] provides a rule that supports any time you have to “do X when Y hasn’t changed or remains above/below a threshold for a certain amount of time.” I has additional features like do not disturb periods and hysteresis but those are not needed here.

A motion sensor timer is one of these use cases.

First create a rule commands the Light ON when it’s run (we’ll use light-on as the ruleUID) and another rule that commands the Light OFF when it’s run (we’ll use light-off as the ruleUID). Also update MotionSensor to OFF in this second rule. These rules can be written as simple UI rules or using any script language desired.

  1. In MainUI navigate to Add-on Store → Automation and under “Rule Templates” find and add “Threshold Alert and Open Reminder”.
  2. Navigate to Rules → + to create a new rule. Fill in a meaningful ID, name, and description and select “Threshold Alert” as the template to base the rule on.
  3. This will show a form of parameters to fill out.

Fill in the following for the properties. Any property not listed leave at the default.

Property Value
Triggering Group Choose anything here. We’re going to change it later.
Threshold State “ON”
Reschedule Toggled on
Alert Delay “PT5M”
Alert Rule light-off
Initial Alert Rule light-on

Now we need to open the rule that was created and change the trigger. Change the trigger type to “an item’s state is updated” and choose MotionDetector as the Item.

With these settings and changes, the light will be commanded on immediately when MotionSensor changes to ON and after five minutes the light will be commanded off and MotionSensor reset to OFF.

This approach is best when your requirements for the motion sensor may be more complicated (e.g. you want it to not turn on the light during the day) or you are doing something based on a threshold (e.g. turning on a heater based on the current temperature).

Blockly

Trigger the rule when MotionSensor receives an update.

If you have lots of motion sensor and light pairs, consider using Timer Manager from openHAB Rules Tools [4.1.0.0;5.9.9.9].

JS Scripting

Trigger the rule when MotionSensor receives an update.

items.Light.sendCommand('ON');
var timer = cache.private.get('timer');
if(timer === null || timer.hasTerminated()) {
  cache.private.put('timer', actions.ScriptExecution.createTimer(time.toZDT('PT5M'), () => {
    items.Light.sendCommand('OFF');
    items.MotionSensor.postUpdate('OFF');
  }
}
else {
  timer.reschedule(time.toZDT('PT5M');
}

Rules DSL

Trigger the rule when MotionSensor receives an update.

Light.sendCommand(ON)
val timer = privateCache.get('timer')
if(timer === null || timer.hasTerminated()) {
    privateCache.put('privateCache', createTimer(now.plusMinutes(5), [ |
        Light.sendCommand(OFF)
        MotionSensor.postUpdate(OFF)
    ])
}

Jython

from core.rules import rule
from core.triggers import when
from core.actions import ScriptExecution
from org.joda.time import DateTime

occupancyTimer = None

@rule("Motion sensor triggered")
@when("Item MotionSensor received update ON")
def motion(event):
    global occupancyTimer
    events.sendCommand("Light", "ON");
    if occupancyTimer is None or occupancyTimer.hasTerminated():
        occupancyTimer = ScriptExecution.createTimer(DateTime.now().plusMinutes(5), lambda: events.sendCommand("MotionSensor", "OFF"))
    else:
        occupancyTimer.reschedule(DateTime.now().plusMinutes(5))

Related Design Patterns

Design Pattern How It’s Used
Design Pattern: Sensor Aggregation The complex example of Sensor Aggregation uses this DP to implement an ant-flapping timer.
Design Pattern: Debounce A similar DP that involves changes instead of updates.
23 Likes
Motion detection getting me crazy
Change item state with rules, help
Keep off the actions spam
OR Switch Group misbehaving and/or rule issues
My openHab Setup
Problem with rule
Rules and special variable forms
PIR sensor, timer rule won't work as intended
Rule for motion detector
Simple Switch "dummy/mirrored" unexplained behaviour
[OH4] Hue Motion Sensor - Reschedule Timer - Can't seem to figure it out
Timer with alert for open window
Timer Rule Problem
Making Decisions Based on Time of Day
Can a rule be triggered by activating it?
Sensor configuration, unstable status
Help with a simple Rule to wait 5 seconds
Delayed command for controlling presence modes
Expire Motion Sensor -> Run other script/switch off other items
Switch set on time
Trigger when an item is in state for certain time
PIR + LED ligth
Light on Motion Rule - Need to understand
One Thing - Two Items, One of which with Expire
How can I trigger a rule only when the item has the new state for a certain time?
Rule is triggering two times in a row
Design Pattern: Expire Binding Based Timers
How to calculate the difference in time
Simple Motion Rule Question
Why is everything in JSON format in my OpenHAB installation
Functions in rules
Trying to run openhab2 timer but i have multiple problems
Timer DSL rule reschedule if state
Rule that send command off to item only if item is off since 10 min
OpenHAB 3.1 expire command does not always work
Item status duration condition trigger?
Has anyone Managed to add a SONOFF RF Bridge and PIR sensor to their OH3 setup? and if so how? please
Openhab 2 rules not catching changes to strings
Start one binding with another binding
Add delay to action
Simple GUI rule turning hue scene at night time after presence detected
Value greather than 65 for 30 minues
Set last tripped/alarm date, or last action date to an item - best practice?
OpenHAB 2.0 Rules: Create list of HSBTypes
Bidirectional rule creates a loop
Rule check for Motion Detection
Motion detection -> lights on - if it's dark and within time period, with timer - Help needed
Alarm email if doors remains open for longer time
Presence detection via iPhone's mDNS Entry. How to integrate into OH2?
Design Pattern: Expire Binding Based Timers
Fibaro fgms-001 association groups
Design Pattern: Associated Items
Code review for rules; checking state after 30s
Two step lightcontrol with motion sensor
Automation of venetian blinds
Problems with OneWire hang ups
Rule to trigger presence with motion detectors
Need an idea for better "trigger only if unchanged for X minutes" script
Proposal: ActivityManager for Consistent Handling of Motion/Triggers and Their Timers
HUE Motion Sensor + Timer + Time + Lux + Fade in one Rule
Terminate a Running Rule Thread
Rules with "now.getHourOfDay" working inconsistently
Rule: dimm lights after Xmin of no motion with expire binding
Expire Binding
Rule issue and question
createTimer in temperature control
Delay between sensor and actor since OH2.5
Proposal: ActivityManager for Consistent Handling of Motion/Triggers and Their Timers
[Solved] Postponed rule execution? Do rules get put on stack?
Bathroom ventilation stops too early
How to deal with device command state that doesn't change back when in use (motion sensor)?
Advice on multiple timers / light switches
Event Scheduling
Execute function in a time slot
Reset timer in rule when switch is pressed again
Rules: Initialization of var DateTime fails; => How to solve?
Race conditions: best practices in rules?
How to make a scene with Z-Wave
[SOLVED] Total disaster when trying on my own, with the great help of this community I got it running. Thanks
Expire don´t work at mqtt Switch
[SOLVED] Getting error when using timestamp for managing lights on and off with motion sensor
Sonoff 433 Bridge Configuration
Extended Motion Sensor Rule: any Suggestions?
Extended Motion Sensor Rule: any Suggestions?
Expire binding does not expire when using longer intervals
[SOLVED] How do I use a user-set timer in a rule to send a command?
Motion sensor items
Automation #2: Bathroom Smart light
[SOLVED] How to use timer state as trigger in rule
[SOLVED] How do I debounce or antiflap notifications for many devices in a group?
Need help with Rule Xiaomi Motion Sensor
[SOLVED] How do I resolve my timer rule error?
[SOLVED] Detect absent of motion from multiple sensors in period of time
createTimer error in rules script
Turn light off when no one is in the room (no motion)
[SOLVED] Variable timer on sitemap
[Help Needed] Hue online / offline rule
Pause rule after execution
[SOLVED] Options for motion sensor with fixed timeout value
Rule: Shutdown if state is?
Online motion sensor not showing up in log
How to send a command every x sec. during the next x minutes?
PIR Sensor trigger if event occured more than x times in timespan
[SOLVED] Need rule for HUE Motion Sensor switching lights
openHAB and local control
Expire binding not working for group switches
Should I check the state of a switch before sending a command?
[SOLVED] Help with a light timer rule
[SOLVED] Motion sensor timer on 2 way lighting
[SOLVED] Cannot Calculate the Milliseconds time difference between two vars
[SOLVED] Best approach delay a flickering contact, proxy and/or timer or?
OH 2.x Timer Things
Rules with a wait for changing state back
Zwave 2.4 and update a thing parameter
Timer with feed back to close lights working with sensor
Delay Alarm
[SOLVED] Question about how createTimer works
Help with Recommendation
Rule not triggering on change to UNDEF via expiration
Xiaomi Motion sensor with Milights use in rules
Remembering which lights were turned off
[SOLVED] Rule not working properly - Lights out after Timer
[SOLVED] Simple Switch OFF rule
[SOLVED] MQTT populating temperature values - no it is not!
[SOLVED] Trying to avoid "debounce" in a rule
[SOLVED] Help with Motion sensor goes too off too quick / canceling a timer
Please test the new Expire Binding
Openhab2 rules not working for me
Example of a Lambda Function for timing the turning on and off of Lights (or switches)
Help, I'm ready to give up
Help with Recommendation
While loop within a dsl rule causes 100% cpu load
[SOLVED] Rules start only after rewrite the rule file
Looking for a "latch" behavior for a motion sensor contact-type item
Detect Open Window (aqara) - Reduce Temperature by Wiser
Using a previousState for timer rule
OpenHAB core rules - making rule fail if item state changes after rule starts running
Devolo zwave motion sensor mt02647 binary sensor always triggered

Question -
Can we use instead

when
   Item gMotionDetectors received update ON

for a more generic rule?
(note, I believe when triggering from a Group we should look for ‘update’ rather than ‘command’
Furthermore, we should bear in mind a group may receive multiple updates for a single “real event”. But in this example, I think repeated execution will have no harmful effect.)

I haven’t tested with it that way yet. My first inclination was to write the rule that way. However, I don’t know what state comes as the update. My suspicion is that the Group’s state comes as the update. So, if for example, you have Group:AND(ON, OFF), which is perfectly reasonable, the updates will be all OFF unless all the switches are ON. And if you leave the Group with default or use OR all the updates will be ON as long as at least one Switch is ON.

Consequently there will be no way to distinguish between ON and OFF updates for a given Switch.

I’m pretty sure it could be made to work but I chose to implement it this slightly less generic way to be less error prone for inexperienced users who may try to use it.

If you get it to work triggering on the Group updates (you will have to trigger on all updates, not just ON) post it here. I will do the same if I ever get to it.

I primarily wrote this as an answer to a question so didn’t spend a whole lot of time on it.

FYI

plusMinutes(timeOutMinutes)

Should be

plusMinutes(timeoutMinutes)

Weirdly I also found the import line is required for it to work in Openhab2 else timers.get throws an exception.

import java.util.Map

Corrected the typo.

That is correct, OH 2 automatically imports all the core openHAB and ESH stuff but not other utilities like java.util.*, etc. The import is there in the second example above.

Ah ok, makes sense.

Forgot to mention you’re also missing some closing brackets I think

timers.put(sw.name, createTimer(now.plusMinutes(timeoutMinutes), [|
                        sw.sendCommand(OFF)
                        timers.put(sw.name, null)
                ]))

Indeed. That error has been corrected as well.

I’m trying the whole day to get a motion sensor timer code running with my fibaro fgms 001 motion sensor and milight bulbs, but I guess I need some help…

This is what I have so far:

.items

	//EZ_Auge
	Number EZ_Lux "Motion Sensor [%.2f Lux]"    <sun>                     (ZwaveEye1) { channel="zwave:device:5b97d7f6:node4:sensor_luminance" }
	Number EZ_Battery "Motion Sensor [%d %%]"      <battery>    (ZwaveEye1)        { channel="zwave:device:5b97d7f6:node4:battery-level" }
	Number EZ_Temp "Motion Sensor [%.1f C]"     <temperature>    (ZwaveEye1)    { channel="zwave:device:5b97d7f6:node4:sensor_temperature" }
	Switch EZ_Motion "Motion Sensor Motion [%s]"           (ZwaveEye1)     { channel="zwave:device:5b97d7f6:node4:sensor_binary" }
	Contact EZ_MotionC "Motion Sensor MotionC [%s]"           (ZwaveEye1)     { channel="zwave:device:5b97d7f6:node4:sensor_binary" }
	Switch EZ_Alarm "Motion Sensor Alarm [%s]"             <fire>   (ZwaveEye1)      { channel="zwave:device:5b97d7f6:node4:alarm_general" }
	Switch EZ_Burglar "Motion Sensor Alarm b [%s]"             <fire>   (ZwaveEye1)      { channel="zwave:device:5b97d7f6:node4:alarm_burglar" }
	Number EZ_Seismic "Motion Sensor Seismic [%f]"                (ZwaveEye1)      { channel="zwave:device:5b97d7f6:node4:sensor_seismicintensity" }

.rules

	//EZ Auge
    var Number counter = 0
    var Number lastCheck = 0

    rule "EZ Auge - Licht An"
    when   
            Item EZ_Motion changed from ON to OFF
    then   
            counter = counter + 1
            //if(EZ_Lux.state < 40) {
            sendCommand(Scene_EZ, 3)
            }
    end

    rule "EZ Auge - Licht Aus"
    when   
            Time cron "0 * * * * ?"
    then   
            if(lastCheck == counter) {
                    counter = 0
                    lastCheck = -1;
                    sendCommand(Scene_EZ, 1)
                    sendCommand(EZ_Motion, OFF)
            } else {
                    lastCheck = counter
            }
    end

	// Scenes EZ
	rule "Scene EZ"
	when
	Item Scene_EZ received command 
	then
	/*Aus*/ if (receivedCommand==1) { 
	/*Aus*/ sendCommand(Scene_ColorSelect_EZ_Deckenlampe, new HSBType(new DecimalType(0),new PercentType(0),new PercentType(0)))
	/*Aus*/ Thread::sleep(500) sendCommand(Scene_ColorSelect_EZ_Buecherregal, new HSBType(new DecimalType(0),new PercentType(0),new PercentType(0)))
	/*Aus*/ Thread::sleep(500) sendCommand(Scene_ColorSelect_EZ_Sideboard, new HSBType(new DecimalType(0),new PercentType(0),new PercentType(0)))
	}
	/*Normal*/ if (receivedCommand==2) { 
	/*Weiss*/ sendCommand(Scene_ColorSelect_EZ_Deckenlampe, new HSBType(new DecimalType(0),new PercentType(0),new PercentType(70)))
	/*Aus*/ Thread::sleep(500) sendCommand(Scene_ColorSelect_EZ_Buecherregal, new HSBType(new DecimalType(0),new PercentType(0),new PercentType(0)))
	/*Aus*/ Thread::sleep(500) sendCommand(Scene_ColorSelect_EZ_Sideboard, new HSBType(new DecimalType(0),new PercentType(0),new PercentType(0)))
	}
	/*Hell*/ if (receivedCommand==3) { 
	/*Weiss*/ sendCommand(Scene_ColorSelect_EZ_Deckenlampe, new HSBType(new DecimalType(0),new PercentType(0),new PercentType(100)))
	/*Weiss*/ Thread::sleep(500) sendCommand(Scene_ColorSelect_EZ_Buecherregal, new HSBType(new DecimalType(0),new PercentType(0),new PercentType(100)))
	/*Weiss*/ Thread::sleep(500) sendCommand(Scene_ColorSelect_EZ_Sideboard, new HSBType(new DecimalType(0),new PercentType(0),new PercentType(100)))
	}
	/*Stimmung*/ if (receivedCommand==4) { 
	/*Lila*/ sendCommand(Scene_ColorSelect_EZ_Deckenlampe, new HSBType(new DecimalType(300),new PercentType(100),new PercentType(100)))
	/*GrĂźn*/ Thread::sleep(500) sendCommand(Scene_ColorSelect_EZ_Buecherregal, new HSBType(new DecimalType(130),new PercentType(100),new PercentType(100)))
	/*TĂźrkis*/ Thread::sleep(500) sendCommand(Scene_ColorSelect_EZ_Sideboard, new HSBType(new DecimalType(190),new PercentType(100),new PercentType(100)))
	}
	/*GrĂźn*/ if (receivedCommand==5) { 
	/*GrĂźn*/ sendCommand(Scene_ColorSelect_EZ_Deckenlampe, new HSBType(new DecimalType(130),new PercentType(100),new PercentType(100)))
	/*GrĂźn*/ Thread::sleep(500) sendCommand(Scene_ColorSelect_EZ_Buecherregal, new HSBType(new DecimalType(130),new PercentType(100),new PercentType(100)))
	/*GrĂźn*/ Thread::sleep(500) sendCommand(Scene_ColorSelect_EZ_Sideboard, new HSBType(new DecimalType(130),new PercentType(100),new PercentType(100)))
	}
	end

The scene rules are working manually with some buttons.

This is probably better posted as a new topic as your implementation has almost nothing to do with the Design Pattern described above.

“EZ Auge - Licht An” has a syntax error. With the if statement commented out the } is incorrect and an error like this could prevent the rest of the rules in this file from being loaded.

Avoid using C style comments (i.e. /*) . I’ve seen some reports of people having problems when using this type of comments. That probably isn’t the case here since you said they work.

The following is what your code does as written. I’m writing this out because based on this code I have no idea what you are trying to do.

  • When EZ_Motion turns OFF one up a counter and send 3 to Scene_EZ.

  • Every second, if lastcheck == counter reset counter and lastCheck, send 1 to Scene_EZ and turn off EZ_Motion (which triggers the EZ Auge - Licht An rule.

  • When Scene_EZ receives a command 3 it sets the color of a few lights with half second sleeps between (it is a lot easier to read if you put each line on its own line).

  • When Scene_EZ receives a command 1 it turns off these lights.

Given that the flow would go something like the following.

  1. EZ Auge - Licht Aus triggers. lastCheck == counter (both start off at 0) so lastcheck is set to -1, Scene_EZ is sent 1, and EZ_Motion is set to OFF.

  2. Scene_EZ 1 runs turning off the lamps.

  3. If EZ_Motion is OFF nothing else happens. If EZ_Motion is ON counter becomes 1 and Scene_EZ 3 runs turning on the lamps.

  4. If EZ_Motion was OFF, when EZ Auge - LichtIf runs again lastCheck != counter so lastCheck gets set to 0. EZ_Motion was ON, one second later EZ Auge - Licht Aus runs again. this time lastCheck != counter so lastCheck gets set to 1 (the current value of counter).

  5. EZ_Motion turns ON and OFF again based on motion. At that point counter is set to 1 or 2 and the lamps are turned on again. Then step 1 runs again.

Honestly this code is unclear and overly complicated and exceptionally difficult to follow, even if it did work. Assuming what you are trying to do is keep a light on for a certain period of time after the last time a motion sensor went off, is there some reason you don’t want to use a Timer like the example at the top of this thread?

Sorry for that, what I trying to do is combining your timer code with the wiki-example I already posted and which can be found here: How to turn on light when motion detected and is dark?

OK thanks, I will avoid this.

I try a, I think very basic thing at home automation: “indoor lights-on at motion detection when it’s dark and lights-off after a given time” so I don’t have to switch on and off lights anymore and won’t forget lights on.

It is a very basic thing but this approach with counters is not a very easy way to do it.

Using the example at the top of the thread…

var Timer ezMotionTimer = null

rule "EZ Auge - Licht Aus"
when
    Item EZ_Motion received command
then
    Scene_EZ.sendCommand(3)

    if(ezMotionTimer != null) {
        ezMotionTimer.reschedule
    }
    else {
        ezMotionTimer = createTimer(now.plusMinutes(5), [|
            Scene_EZ.sendCommand(1)
            ezMotionTimer = null
        }
    }
end

The above will turn on the Lights (i.e. sendCommand 3 to EZ_Scene). Five minutes after the last time the EZ_Motion receives a command the Timer will go off and turn off the lights.

I’ve a few other minor comments about your rule. These are not problems but could help you avoid problems in the future.

It is better to use the sendCommand and postUpdate method on the Item rather than the actions. So you would rewrite:

sendCommand(Scene_ColorSelect_EZ_Deckenlamp, new HSBType(new DecimalType(0),new PercentType(0),new PercentType(70)))

as

Scene_ColorSelect_EZ_Deckenlamp.sendCommand(new HSBType(new DecimalType(0),new PercentType(0),new PercentType(70)))

ColorItems can receive ONOFFType and PercentType commands. So where you set the bulb to HSBType(0,0,0) you can just sendCommand(OFF).

1 Like

Thanks for the hints, I changed my code as you recommend.

But the timer code is still not working.

This is working → items and sensor are OK

	rule "WZ Auge - Licht"
	when
    Item WZ_Burglar received update
	then
    Scene_WZ.sendCommand(2)
    end

But this does nothing

	var Timer ezMotionTimer = null

	rule "WZ Auge - Licht Timer"
	when
    Item WZ_Burglar received update
	then
    Scene_WZ.sendCommand(3)

    if(ezMotionTimer != null) {
        ezMotionTimer.reschedule
    }
    else {
    	ezMotionTimer = createTimer(now.plusMinutes(1))
    	Scene_WZ.sendCommand(1)
    	ezMotionTimer = null
    	}
    }
	end	
    else {
    	ezMotionTimer = createTimer(now.plusMinutes(1))
    	Scene_WZ.sendCommand(1)
    	ezMotionTimer = null
    	}
    }

Needs to be

    else {
    	ezMotionTimer = createTimer(now.plusMinutes(1)) [ |
    	    Scene_WZ.sendCommand(1)
    	    ezMotionTimer = null
    	]
    }

Thanks very much, but still no reaction

    var Timer ezMotionTimer = null

	rule "Licht Timer"
	when
    Item EZ_Auge_Burglar changed from OFF to ON
	then
    Scene_EZ.sendCommand(3)

    if(ezMotionTimer != null) {
        ezMotionTimer.reschedule
    }
    else {
    	ezMotionTimer = createTimer(now.plusMinutes(1)) [ |
    	    Scene_EZ.sendCommand(1)
    	    ezMotionTimer = null
    	]
    }
	end 

May I have to import some bibs or place the var at the top of the .rules or need some addons or extra services or so?

ezMotionTimer needs to be declared above any rule in that file.

Add logging statements so you know whether the rule is triggering.

That was the problem, now it works great.
Thank you very much :slight_smile:

In this topic I’ll go forward with some more terms: Motion detection → lights on - if it’s dark and within time period, with timer - Help needed

I don´t want to make the variables as global variables.

Can i make this inside the rule as well?

If i put val and var to the top of my rules-file, it works. But if i put it inside the rule, nothing happens…

working:

var Timer md1Timer = null
val int timeoutMinutes = 5

// KG Garage Licht aus nach 5 Minuten

rule "KG Garage Licht auto off"
when
    Item Licht_KG_Garage_1 changed
then
	if (Licht_KG_Garage_1.state == ON) {
			md1Timer = createTimer(now.plusMinutes(timeoutMinutes), [|
				Licht_KG_Garage_1.sendCommand(OFF)
				md1Timer = null
			]
	}
    else {
			md1Timer = null
    }
end

not working:

// KG Garage Licht aus nach 5 Minuten

rule "KG Garage Licht auto off"
when
    Item Licht_KG_Garage_1 changed
then
        var Timer md1Timer = null
        val int timeoutMinutes = 5
	if (Licht_KG_Garage_1.state == ON) {
			md1Timer = createTimer(now.plusMinutes(timeoutMinutes), [|
				Licht_KG_Garage_1.sendCommand(OFF)
				md1Timer = null
			]
	}
    else {
			md1Timer = null
    }
end

By doing this you are defining local vs. global variables. Local in this case means (as in all programming languages) the scope and the existence of this variable is limited to one execution of the code block, being your rule. The Timer variable will be deleted when reaching end and recreated when executing the rule again.

Yes, i know this. I want to have this variable “var Timer md1Timer = null” only inside my rule. The rule will not reach “end” while the timer is running.

And when the timer is “null”, i don´t need it anymore.

But this doesn´t work with “var timer…” inside the rule. No error-message in the log-file. I made some logging and the rule will not get triggered, if i put var inside it.

Do you know the reasen, why it doenst´t work?

I don’t think you understand how Timers work. They do not block the rest of the execution of your Rule. Once created the timer runs in the background while the rest of your Rule continues to execute. So in the above your rule immediately exits once the Timer is created instead of waiting around for the timeout.

This is why you must store the timer variable as a global.

See the following: