Design Pattern: Motion Sensor Timer

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 an occupancy Contact OPEN (or Switch ON) until the desired amount of time after the last motion is detected.

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 (see Generic Is Alive), to avoid flapping (e.g the switch constantly switching back and forth when something is on the edge of detection, see Presence Detection Rule), implementing the Latch Pattern, etc.

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, turn the occupancy Switch OFF.

Simple Example: Expire Binding Version

Items

Switch Occupancy1 { expire="5m,command=OFF" }
Switch MotionDetector1 { expire="5m,command=OFF" }

Rules

Python

from core.rules import rule
from core.triggers import when

@rule("Motion sensor triggered")
@when("Item MotionDetector1 received update ON")
def motion(event):
    events.sendCommand("Occupancy1", "ON")

Rules DSL

rule "Motion sensor triggered"
when
    Item MotionDetector1 received update ON
then
    Occupancy1.sendCommand(ON)
end

Theory of Operation

That is all there is to it. When the MotionDetector1 receives and ON update it sends an ON command to the occupancy switch. The Expire binding will set the occupancy Switch to OFF five minutes after the last ON command is received.

Simple Example: Timers Version

Items

Switch MotionDetector1

Rules

Python

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 MotionDetector1 received update ON")
def motion(event):
    global occupancyTimer
    if occupancyTimer is None or occupancyTimer.hasTerminated():
        occupancyTimer = ScriptExecution.createTimer(DateTime.now().plusMinutes(5), lambda: events.sendCommand("MotionDetector1", "OFF"))
    else:
        occupancyTimer.reschedule(DateTime.now().plusMinutes(5))

Rules DSL

var Timer occupancyTimer = null

rule "MotionDetector1 received ON"
when
    Item MotionDetector1 received update ON
then
    if(occupancyTimer === null || occupancyTimer.hasTerminated()) {
        occupancyTimer = createTimer(now.plusMinutes(5), [|
            MotionDetector1.sendCommand(OFF)
            occupancyTimer = null
        ])
    }
    else {
        occupancyTimer.reschedule(now.plusMinutes(timeoutMinutes ))
    }
end

Theory of Operation

When MotionDetector1 receives and ON update create a Timer to turn it OFF in 5 minutes. If there already is a timer, reschedule the Timer.

Comprehensive Example

This example shows one way one can manage and consolidate the above logic for multiple Motion Detectors. The following rule depends upon persistence having been set up on the MotionDetector Items and assumes that detectors will not trigger really really close together.

Items

Group gMotionDetectors
Switch MotionDetector1 (gMotionDetectors)
Switch MotionDetector2 (gMotionDetectors)

Rules

Python

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

timers = {}
timeoutMinutes = 5 # use an appropriate value

@rule("Motion sensor triggered")
@when("Member of gMotionDetectors received command ON")
def motion(event):

    if event.itemName not in timers or timers[event.itemName].hasTerminated():
        timers[event.itemName] = ScriptExecution.createTimer(DateTime.now().plusMinutes(timeoutMinutes), lambda: events.sendCommand(event.itemName, "OFF"))
    else:
        timers[event.itemName].reschedule(DateTime.now().plusMinutes(timeoutMinutes))

Rules DSL

import java.util.Map

val Map<String, Timer> timers = newHashMap

rule "A Motion Detector triggered"
when
    Member of gMotionDetectors received command ON
then

    val timeoutMinutes = 5 // use an appropriate value

    if(timers.get(triggeringItem.name) === null or timers.get(triggeringItem.name).hasTerminated()){
        timers.put(triggeringItem.name, createTimer(now.plusMinutes(timeOutMinutes), [|
            triggeringItem.sendCommand(OFF)
            timers.put(triggeringItem.name, null)
        ]))
    }
    else {
        timers.get(triggeringItem.name).reschedule(now.plusMinutes(timeOutMinutes))
    }
end

Theory of Operation

We store the Timers in a dict/Map using the name of the Motion Detector Item as the key. When one of the members of gMotionDetectors receive an ON command create a Timer for that detector to go off in 5 minutes. If one already exists reschedule it. Store the Timer in the Map.

Here is the version of the above code using the Expire binding:

Switch MotionDetector1 { expire="5m,command=OFF" }
Switch MotionDetector2 { expire="5m,command=OFF" }

Look ma, no code! The above does exactly the same thing as the complex example above with the Map and Timers.

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. Eventually these two will be merged.

Edit: Added Python examples. Minor cleanup of the Rules DSL code.

23 Likes
Design Pattern: Sensor Aggregation
Motion detection -> lights on - if it's dark and within time period, with timer - Help needed
Rule to trigger presence with motion detectors
Rule check for Motion Detection
OpenHAB 2.0 Rules: Create list of HSBTypes
Timer Rule Problem
[SOLVED] How do I use a user-set timer in a rule to send a command?
Rules with a wait for changing state back
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
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
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
Help with Recommendation
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!
Design Pattern: Associated Items
[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
[SOLVED] Rules start only after rewrite the rule file
Using a previousState for timer rule
Devolo zwave motion sensor mt02647 binary sensor always triggered
Motion detection getting me crazy
Change item state with rules, help
Keep off the actions spam
Presence detection via iPhone's mDNS Entry. How to integrate into OH2?
My openHab Setup
Problem with rule
Rules and special variable forms
PIR sensor, timer rule won't work as intended
Making Decisions Based on Time of Day
Switch set on time
PIR + LED ligth
Simple Motion Rule Question
Openhab2 rules not working for me
Functions in rules
Rule that send command off to item only if item is off since 10 min
Example of a Lambda Function for timing the turning on and off of Lights (or switches)
Openhab 2 rules not catching changes to strings
Help, I'm ready to give up
Start one binding with another binding
Set last tripped/alarm date, or last action date to an item - best practice?
Fibaro fgms-001 association groups
Problems with OneWire hang ups
Design Pattern: Expire Binding Based Timers
Trying to run openhab2 timer but i have multiple problems
Timer DSL rule reschedule if state
[Deprecated] Design Pattern: Debounce
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
Add delay to action
Simple GUI rule turning hue scene at night time after presence detected
Value greather than 65 for 30 minues
Bidirectional rule creates a loop
Alarm email if doors remains open for longer time
Design Pattern: Expire Binding Based Timers
Code review for rules; checking state after 30s
Two step lightcontrol with motion sensor
Automation of venetian blinds

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: