Design Pattern: Motion Sensor Timer

Does someone also have an idea to implement a dynamic expire interval?

Follow the first example in the OP only instead of using timeoutMinutes use a dynamically calculated number.

You cannot use a dynamic timeout with the Expire binding.

1 Like

So I am trying to get a motion sensor rule running what activates a siren (just a switch) when the detector has changed from OFF to ON, 3 times in a minute. This should avoid not necessary activations.
Can you help me here?
Please keep it simple because when I am reading your examples I am quite often lost - maybe your coding is too good for me :slight_smile:

The rule I am running (without this logic) so far is:

var Timer shutoffTimer = null

rule “SonoffMotion changed from OFF to ON 3 times in a minute”

when
	Item Sonoff1 changed from OFF to ON or  //Question: how to say 3 activations in a minute?
	Item Sonoff3 changed from OFF to ON		//Question: how to say 3 activations in a minute?
then
	if (shutoffTimer === null && Alarm.state == ON && lastRun.isBefore(now.minusMinutes(5))) {
		sendMail("xxx@gmail.com", "Sonoff1", "Sonoff1 motion")
		Sonoff2.sendCommand(ON)
		lastRun = now
		logInfo("RuleInfo", "Siren START")
		shutoffTimer = createTimer(now.plusSeconds(240)) [|
		Sonoff2.sendCommand(OFF)
		logInfo("RuleInfo", "Siren STOP")
		shutoffTimer = null
		]
	}

end

Unfortunately there is no simple solution for this. You need to have a counter, a timer, and a way to have the count gradually reduce over time. If you want simple you need to change your requirements.

I’m on my phone so can’t really code up something as complicated as this. But what ever it is will be complicated.

You need to create a collection to store timers. Every time the motion sensor goes to on look to see if there are two timers in the collection. If so then you know that the sensors have gone off three times in five minutes. If not create a new timer and add it to the list.

The body of the timer is to remove the timer from the list.

But the timer is already there. Why an additional or different timer?
I thought when one detector was triggering the alarm nothing should stop that timer and the siren now running for 240 seconds.
After the if timer is done the story can start again from any other motion detector. For the moment I just added two md here.

It just needs to count somehow 3 detections within a minute, and I have no idea how to reach it, can this be a variable?

It sounds so simple but how do you:

  • deal with the events that took place 61+ seconds ago? How do those time out? You can’t just keep a running count because the events have to time out over time

  • trigger the alarm immediately after the three events occur rather than having to wait up to a minute after the three events occur before triggering the alarm?

You need a timer for each ON event, not a Timer for when to turn off the siren.

Now that I’m at a computer, here is the code. It is as simple as it can be made.

import java.util.List

var List<Timer> timers = createArrayList
var Timer shutoffTimer = null
var lastRun = now

rule "SonoffMotion changed from OFF to ON 3 times in a minute"
when
    Item Sonoff1 changed from OFF to ON or
    Item Sonoff3 changed from OFF to ON
then
    // ignore the event if we are playing the siren already or the Alarm is OFF or it has been less 
    // then five minutes since the last time the siren was played
    if(shutoffTimer !== null || Alarm.state == OFF || lastRun.isAfter(now.minusMinutes(5))) return;

    // if timers.size < 2 we have not yet had three ON events in a minute
    if(timers.size < 2) {
        val t = createTimer(now.plusMinutes(1), [ | timers.remove(t) ])
        timers.add(t)
    }

    // if timers.size == 2 then this event is the thrid ON event in a minute
    if(timers.size == 2) {
        sendMail("xxx@gmail.com", "Sonoff1", "Sonoff1 motion")
        Sonoff2.sendCommand(ON)
        lastRun = now
        logInfo("RuleInfo", "Siren START")
        shutoffTimer = createTimer(now.plusSeconds(240)) [|
            Sonoff2.sendCommand(OFF)
            logInfo("RuleInfo", "Siren STOP")
            shutoffTimer = null
        ]
    }
end

It is the exact same concept but slightly “cleaner” to use Design Pattern: Expire Binding Based Timers.

Group:Number:SUM MotionEventTimers
Switch MotionEvent1Timer (MotionEventTimers) { expire="1m,command=OFF" }
Switch MotionEvent2Timer (MotionEventTimers) { expire="1m,command=OFF" }

// Add the expire to the Siren
Switch Sonoff2 ... { mqtt=... , expire="4m,command=OFF" }
var lastRun = now

rule "SonoffMotion changed from OFF to ON 3 times in a minute"
when
    Item Sonoff1 changed from OFF to ON or
    Item Sonoff3 changed from OFF to ON
then
    // ignore the event if we are playing the siren already or the Alarm is OFF or it has been less 
    // then five minutes since the last time the siren was played
    if(shutoffTimer !== null || Alarm.state == OFF || lastRun.isAfter(now.minusMinutes(5))) return;

    // if there are less than 2 ON timers, find the one that is OFF and set it to ON
    if(MotionEventTimers.state < 2) {
        MotionEventTimers.members.filter[ t | t.state == OFF ].head.sendCommand(ON)
    }

    // if timers.size == 2 then this event is the thrid ON event in a minute
    if(MotionEventTimers.state == 2) {
        sendMail("xxx@gmail.com", "Sonoff1", "Sonoff1 motion")
        Sonoff2.sendCommand(ON)
        lastRun = now
        logInfo("RuleInfo", "Siren START")
    }

    // The Expire binding will automatically turn off the siren
end

One could try to use persitence for this but because both ON and OFF events gets stored in the database I don’t think it will work. Persistence also doesn’t record NULL so we can’t know if the event was changing from OFF to ON.

I’m also using the expire binding on my Aeotec MultiSensor 6, but I have the issue where it correctly turns on the light, and then the logs seem to show the sensor doesn’t detect motion after it ‘trips’, so the light always turns off after 5 minutes.

Any suggestions on eliminating the light turning off when I’m still in the kitchen?

tail

2018-05-15 14:14:28.580 [vent.ItemStateChangedEvent] - KitchenSensorArmedTripped changed from 0 to 1
2018-05-15 14:14:28.584 [vent.ItemStateChangedEvent] - KitchenArmedTripped changed from 0 to 1
2018-05-15 14:14:28.621 [INFO ] [marthome.model.script.Kitchen Motion] - KitchenArmedTripped.state=1
2018-05-15 14:14:28.629 [ome.event.ItemCommandEvent] - Item 'KitchenLight' received command ON
2018-05-15 14:14:28.648 [vent.ItemStateChangedEvent] - KitchenLight changed from OFF to ON
2018-05-15 14:14:28.653 [vent.ItemStateChangedEvent] - KitchenSensorLastTrip changed from 2018-05-15T13:25:46.000-0400 to 2018-05-15T14:14:28.000-0400
2018-05-15 14:14:28.657 [ome.event.ItemCommandEvent] - Item 'Kitchen_TIMER_5m_OFF' received command ON
2018-05-15 14:14:28.690 [vent.ItemStateChangedEvent] - KitchenTripped changed from 2018-05-15T13:25:46.000-0400 to 2018-05-15T14:14:28.000-0400
2018-05-15 14:14:28.693 [vent.ItemStateChangedEvent] - KitchenSensorTripped changed from CLOSED to OPEN
2018-05-15 14:14:28.699 [vent.ItemStateChangedEvent] - Kitchen_TIMER_5m_OFF changed from OFF to ON
2018-05-15 14:14:28.734 [vent.ItemStateChangedEvent] - KitchenDeviceStatus changed from NONE to PENDING
2018-05-15 14:14:28.929 [vent.ItemStateChangedEvent] - KitchenStatus changed from OFF to ON
2018-05-15 14:14:28.959 [vent.ItemStateChangedEvent] - KitchenDeviceStatus changed from PENDING to SUCCESS
2018-05-15 14:15:00.147 [vent.ItemStateChangedEvent] - KitchenDeviceStatus changed from SUCCESS to NONE
2018-05-15 14:19:28.698 [ome.event.ItemCommandEvent] - Item 'Kitchen_TIMER_5m_OFF' received command OFF
2018-05-15 14:19:28.711 [vent.ItemStateChangedEvent] - Kitchen_TIMER_5m_OFF changed from ON to OFF
2018-05-15 14:19:28.729 [INFO ] [marthome.model.script.Kitchen Motion] - Kitchen timer off
2018-05-15 14:19:28.743 [INFO ] [marthome.model.script.Kitchen Motion] - KitchenArmedTripped.state=1
2018-05-15 14:19:28.753 [ome.event.ItemCommandEvent] - Item 'Kitchen_TIMER_10s_OFF' received command ON
2018-05-15 14:19:28.764 [vent.ItemStateChangedEvent] - Kitchen_TIMER_10s_OFF changed from OFF to ON
2018-05-15 14:19:39.720 [ome.event.ItemCommandEvent] - Item 'Kitchen_TIMER_10s_OFF' received command OFF
2018-05-15 14:19:39.745 [vent.ItemStateChangedEvent] - Kitchen_TIMER_10s_OFF changed from ON to OFF
2018-05-15 14:19:39.755 [INFO ] [marthome.model.script.Kitchen Motion] - No Motion Detected.  Turning off kitchen
2018-05-15 14:19:39.764 [ome.event.ItemCommandEvent] - Item 'KitchenLight' received command OFF
2018-05-15 14:19:39.778 [vent.ItemStateChangedEvent] - KitchenLight changed from ON to OFF
2018-05-15 14:19:39.801 [vent.ItemStateChangedEvent] - KitchenTarget changed from 1 to 0
2018-05-15 14:19:39.835 [vent.ItemStateChangedEvent] - KitchenDeviceStatus changed from NONE to PENDING
2018-05-15 14:19:40.002 [vent.ItemStateChangedEvent] - KitchenStatus changed from ON to OFF
2018-05-15 14:19:40.033 [vent.ItemStateChangedEvent] - KitchenDeviceStatus changed from PENDING to SUCCESS
2018-05-15 14:19:53.380 [vent.ItemStateChangedEvent] - KitchenLastPollSuccess changed from 2018-05-15T14:12:43.000-0400 to 2018-05-15T14:19:53.000-0400
2018-05-15 14:20:11.112 [vent.ItemStateChangedEvent] - KitchenDeviceStatus changed from SUCCESS to NONE

Rules:

rule "Kitchen motion sensor fires"
    when
        Item KitchenArmedTripped changed to 1 

    then 
        logInfo("Kitchen Motion", "KitchenArmedTripped.state=" + KitchenArmedTripped.state)
        sendCommand(KitchenLight, ON)
        Kitchen_TIMER_5m_OFF.sendCommand(ON)
end

rule "Kitchen_TIMER_5m_OFF changed to  OFF"
    when
        Item Kitchen_TIMER_5m_OFF changed to OFF
    then
		logInfo("Kitchen Motion", "Kitchen timer off")
		logInfo("Kitchen Motion", "KitchenArmedTripped.state=" + KitchenArmedTripped.state)
	    Kitchen_TIMER_10s_OFF.sendCommand(ON)
end


rule "Kitchen_TIMER_10s_OFF changed to OFF"
    when
        Item Kitchen_TIMER_10s_OFF changed to OFF
    then
		if (KitchenArmedTripped.state == 0) {
			logInfo("Kitchen Motion", "Kitchen Motion still detected, reset timer.")
			Kitchen_TIMER_10s_OFF.sendCommand(ON)
		} else {
	           logInfo("Kitchen Motion", "No Motion Detected.  Turning off kitchen")
	           sendCommand(KitchenLight, OFF)
		}
end

Timer items:

Switch Kitchen_TIMER_5m_OFF 							(Virtuals)	{ expire="5m,command=OFF" }
Switch Kitchen_TIMER_10s_OFF 							(Virtuals)	{ expire="10s,command=OFF" }

Motion sensor items:

	/* Device - Kitchen Motion Sensor */

	DateTime KitchenTripped		"Last Tripped [%1$ta, %1$tm/%1$te %1$tR]" <calendar> 	(Kitchen) {mios="unit:house,device:208/service/SecuritySensor1/LastTrip"}
	Switch   KitchenArmed 		"Kitchen Motion Sensor Armed" 			  <shield-1>	(Kitchen) {mios="unit:house,device:208/service/SecuritySensor1/Armed"}
	String   KitchenArmedTripped "Kitchen Sensor Armed/Tripped [%s]" 					(Kitchen) {mios="unit:house,device:208/service/SecuritySensor1/ArmedTripped"}
	Switch   KitchenMotion 		"Motion Detected" 				  		  				(Kitchen) {mios="unit:house,device:208/service/SecuritySensor1/Tripped"}
	DateTime MotionTimeOn 		"Kitchen ON[%s]" 										(Kitchen)
	DateTime MotionTimeOff 		"Kitchen OFF[%s]" 										(Kitchen)
	Number   KitchenLux			"Kitchen Lux [%.4f]" 									(Kitchen) {mios="unit:house,device:210/service/LightSensor1/CurrentLevel"}
	Number   KitchenHumid		"Kitchen Humid [%.4f]" 					<humidity>		(Kitchen) {mios="unit:house,device:211/service/HumiditySensor1/CurrentLevel"}
	Number   KitchenTemp		"Kitchen Temp [%.1f F]" 				<temperature>	(Kitchen) {mios="unit:house,device:209/service/TemperatureSensor1/CurrentTemperature"}

If you keep moving during the five minutes, does KitchenArmedTripped actually change state or does it just keep getting updated to 1 over and over? If it doesn’t actually change then your Rule never fires again so the Expire timer doesn’t get reset.

Correct, the KitchenArmedTripped doesn’t fire again when it detects motion. The issue is that ‘nothing’ is updated until after it changes to a 0 and then detects motion again.

How do I get the ‘wait’ time between the sensor setting the KitchenArmedTripped to a 1 and then being reset to a 0. I think if it goes back to a 0, it may be ‘looking’ for motion again. Right now, it triggers and then stops looking for about 11 minutes (which is probably some kind of delay since the last trigger).

You will have to look in the manual for the sensor. Your rule will never work until you get updates faster than your Expire timer.

Rich, thank you so much,
but please give me some time to understand.
It looks at first view already really promising even I see some of the commands first time (no surprise:-)

I think I will go without this additional binding because it doesn’t increase my poor understanding.

Maybe a few questions already now
What is this import Java.util.List stands for and does this require always internet access?
What is this var List … stands for and what is this ArreyList I don’t see it used further?
Not so important but what happens when I would have a power loss during the timer runs, can I influence this?
There is not one timer for each device Target one for all, what gets restarted, right?

Please let me come back when I am able to apply that rule and see if it is working as required.

Thanks a lot

It tells the rules engine you want to use the List class. You can’t create and use a List without that import. It does not user the internet.

It stores the Timers for the first two ON events.

You see timers used again, several times. var List timers crates a variable of type List named timers.

Not without making the rule at least twice more complex. If you lose power the minute starts over.

You didn’t say anything about the events on one device. You said three events per minute from any device.

Hi Rich and others which may help here

Now I am trying to implement the rule you provided me, but there is something not correct I asume, can you check please and help me to resolve it?
Thanks in advance!

This is the rule I have created now:

import java.util.List
var List timers = createArrayList
var Timer shutoffTimer = null
var lastRun = now

rule “Sonbas Motion changed from OFF to ON 3 times in a minute”
when
Item Sonbas10b changed from OFF to ON or
Item Sonoff3 changed from OFF to ON
then
if(shutoffTimer !== null || Alarm.state == OFF || lastRun.isAfter(now.minusMinutes(2))) return;
if(timers.size < 2) {
val t = createTimer(now.plusMinutes(1), [ | timers.remove(t) ])
timers.add(t)
}

if(timers.size == 2) {
sendMail("xxx@gmail.com", “Sonbas10b”, “Sonbas10b motion”)
TH03.sendCommand(ON)
lastRun = now
logInfo(“RuleInfo”, “Siren START”)
shutoffTimer = createTimer(now.plusSeconds(30)) [|
TH03.sendCommand(OFF)
logInfo(“RuleInfo”, “Siren STOP”)
shutoffTimer = null
]
}
end

and this is stated in openhab.log:

2018-06-26 22:39:36.825 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model ‘MQTT.rules’
2018-06-26 22:39:51.397 [WARN ] [me.internal.engine.RuleContextHelper] - Variable ‘timers’ on rule file ‘MQTT.rules’ cannot be initialized with value ‘createArrayList’: The name ‘createArrayList’ cannot be resolved to an item or type; line 3, column 26, length 15
2018-06-26 22:39:51.587 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Sonbas Motion changed from OFF to ON 3 times in a minute’: The name ‘Alarm’ cannot be resolved to an item or type; line 12, column 32, length 5
2018-06-26 22:39:56.065 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Sonbas Motion changed from OFF to ON 3 times in a minute’: The name ‘Alarm’ cannot be resolved to an item or type; line 12, column 32, length 5
2018-06-26 22:40:00.583 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Sonbas Motion changed from OFF to ON 3 times in a minute’: The name ‘Alarm’ cannot be resolved to an item or type; line 12, column 32, length 5

newArrayList

I recommend using Maps though so you can associated the Timer with the Item that caused its creation.

Also, in the future How to use code fences.

You mean newArrayList instead createArrayList, that´s all?
Just one other thing. This command:
val t = createTimer(now.plusMinutes(1), [ | timers.remove(t) ])
timers.add(t)
how does this work, e.g. what means “timers.remove(t)”
Do I need to enter for “t” a value or does it just count it to “val t”

Ok now with code fences:-)

You mean newArrayList instead createArrayList ?

So I changed to newArrayList, but there is another error upcoming for the following line 12, column 32 this is the Alarmˋcommand
if(shutoffTimer !== null || Alarm.state == OFF || lastRun.isAfter(now.minusMinutes(2))) return;ˋ

What do I need to change here, any idea?
Thank you

2018-06-27 11:32:51.612 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Sonbas Motion changed from OFF to ON 3 times in a minute’: The name ‘Alarm’ cannot be resolved to an item or type; line 12, column 32, length 5
2018-06-27 11:32:57.599 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Sonbas Motion changed from OFF to ON 3 times in a minute’: The name ‘Alarm’ cannot be resolved to an item or type; line 12, column 32, length 5
2018-06-27 11:33:04.961 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Sonbas Motion changed from OFF to ON 3 times in a minute’: The name ‘Alarm’ cannot be resolved to an item or type; line 12, column 32, length 5
2018-06-27 11:33:12.747 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Sonbas Motion changed from OFF to ON 3 times in a minute’: The name ‘Alarm’ cannot be resolved to an item or type; line 12, column 32, length 5ˋ

Hi Rich, ok solved by my own -ˋAlarm.Stateˋ belongs to an item.

So the rule works, the only remaining thing is that I can see now in openhab.log tons of stupid comments - what can I do against that?
even that the rule works it raises so much issues?

And one of the comments refers to
val t = createTimer(now.plusMinutes(1), [ | timers.remove(t) ])
timers.add(t)ˋ

The ˋtˋ at position 65 is not recognized, do I need to adjust?

Thanks a lot

2018-06-27 13:21:31.828 [ERROR] [org.quartz.core.JobRunShell ] - Job DEFAULT.2018-06-27T13:21:31.823+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
.remove()
} ] threw an unhandled Exception:
java.lang.reflect.UndeclaredThrowableException: null
at com.sun.proxy.$Proxy145.apply(Unknown Source) [?:?]
at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:49) [137:org.eclipse.smarthome.model.script:0.10.0.oh230]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]
Caused by: org.eclipse.smarthome.model.script.engine.ScriptExecutionException: The name ‘t’ cannot be resolved to an item or type; line 14, column 65, length 1
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:133) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1115) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1045) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:991) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:143) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:763) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:219) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) ~[?:?]
… 4 more
2018-06-27 13:21:31.923 [ERROR] [org.quartz.core.ErrorLogger ] - Job (DEFAULT.2018-06-27T13:21:31.823+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {
.remove()
} ] threw an exception.
org.quartz.SchedulerException: Job threw an unhandled exception.
at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [107:org.eclipse.smarthome.core.scheduler:0.10.0.oh230]
Caused by: java.lang.reflect.UndeclaredThrowableException
at com.sun.proxy.$Proxy145.apply(Unknown Source) ~[?:?]
at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:49) ~[?:?]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[?:?]
… 1 more
Caused by: org.eclipse.smarthome.model.script.engine.ScriptExecutionException: The name ‘t’ cannot be resolved to an item or type; line 14, column 65, length 1
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:133) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluateArgumentExpressions(XbaseInterpreter.java:1115) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1045) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:991) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:143) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:763) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:219) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]
at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:219) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.ClosureInvocationHandler.doInvoke(ClosureInvocationHandler.java:46) ~[?:?]
at org.eclipse.xtext.xbase.interpreter.impl.AbstractClosureInvocationHandler.invoke(AbstractClosureInvocationHandler.java:29) ~[?:?]
at com.sun.proxy.$Proxy145.apply(Unknown Source) ~[?:?]
at org.eclipse.smarthome.model.script.internal.actions.TimerExecutionJob.execute(TimerExecutionJob.java:49) ~[?:?]
at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[?:?]
… 1 more

Sorry to bother you with so many questions but now I am playing a bit around with that rule and notice, that it isn’t working correct.
The delay for the next timer activation is working, but counting the single PIR movements doesn´t.
It means when alarm was triggered after the 3rd PIR signal, it takes two minutes until next activation can be triggered, that´s OK,
but now only one PIR movement re-activates the alarm, and the rule should always wait for 3 PIR movements.

You’ve applied code fences in the area they are needed the least.

Use code fences for ALL code and logs posted.

ReadingcodewithoutcodefencesislikereadingEnglishwithoutspacesbetweenwords.

As to your problem, you cannot refer to a call on the same line that it is declared on. You can declare it first then assign on the next line, or take my suggestion and use a Map instead of a List.