Design Pattern: Motion Sensor Timer

Expire has been merged into the core. So you configure it the same as it always has but you don’t have to install a separate binding to use it.

If that’s all you need then I recommend configuring the Expire Item metadata on the switch.

Any examples of rules that you see will still work in OH 2.5 with minor changes (usually to do with changing the date time classes or executeCommandLine). So pretty much everything in the original post will work as is. To use the Python code you’ll need to install the Python add-on and the Helper Libraries for OH 3.

thanks. That seemed so easy, I tried it right away :-). So I added this Expiration Timer to the Hue Motion Sensor metadata:

value: 0h2m0s,command=OFF
config: {}

However, this doesn’t change anything, thus I am guessing I got something wrong.

That looks OK. How did you test it? As configured, when the Item changes or updates to any state other than OFF, two minutes later Expire will send an OFF command to the Item. If you didn’t change or update the Item after setting the metadata nothing will happen. There has to be an event to start the timer.

You might want to think about what effect you are expecting. Sending an OFF command to the sensor is not likely to do much?
If you want lights to turn off after a period, it is the light that needs the expire.

thanks much. How stupid of mine - typical beginner mistake I guess :-). Thinking about it, it’s so obvious :slight_smile:

Hello,
I am trying to switch a Tasmota electrical plug with Xiaomi Aqara motion detector.

RuleDSL:

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

PIR:

Electric plug:

If I wave in front of sensor, I got Item 'PIRVchod_MotionStatus' changed from OFF to ON

after one minute the binding is expired, I got this:

2021-02-09 20:09:21.184 [ERROR] [al.handler.XiaomiSensorMotionHandler] - Channel mihome:sensor_motion_aq2:286c0785f092:158d00016dacaf:motion does not exist

==> /var/log/openhab/events.log <==

2021-02-09 20:09:21.172 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'PIRVchod_MotionStatus' received command OFF

2021-02-09 20:09:21.181 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'PIRVchod_MotionStatus' predicted to become OFF

2021-02-09 20:09:21.187 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'PIRVchod_MotionStatus' changed from ON to OFF

The rule is simply not working - the plug is not switched on, but I cant even see, if the rule was activated.

Where is the mistake?
Thanks,
Michal

Given the events.log above, the rule didn’t trigger because it didn’t update to ON. You’ve written the rule to only run when that happens.

Add logging to the rule to see if it was activated. Or bring up the developer sidebar and start the event stream. You’ll see an event when the rule triggers

It is changed I hope:
debug:
Item 'PIRVchod_MotionStatus' changed from OFF to ON
am I right, or should I use a different command to triger?

I will try to find how to add logging,
M

It’s a sensor, don’t command it. You want the expire action to be state=OFF I think.

1 Like

OK. All I can know is what you’ve posted and you didn’t post that log statement before.

Add some logging to the rule to verify the rule is triggering. When it changes it will also be receiving an update.

rossko57 has a point, you don’t want to command a sensor so adjust your expire config, but I don’t think that would prevent the rule from running.

OK, updated the expiration timer.

this is what I have from Developers Event Monitor:

* openhab/items/PIRVchod_LastActivityDateTime/statechanged
ItemStateChangedEvent
{"type":"DateTime","value":"2021-02-09T21:59:50.203864+0100","oldType":"DateTime","oldValue":"2021-02-09T21:57:48.369426+0100"}

* openhab/items/PIRVchod_MotionStatus/statechanged
ItemStateChangedEvent
{"type":"OnOff","value":"ON","oldType":"OnOff","oldValue":"OFF"}

* openhab/items/PIRVchod_LastActivityDateTime/state
ItemStateEvent
{"type":"DateTime","value":"2021-02-09T21:59:50.203864+0100"}

* openhab/items/PIRVchod_MotionStatus/state
ItemStateEvent
{"type":"OnOff","value":"ON"}

openhab/items/PIRVchod_Illumination/state
ItemStateEvent
{"type":"Decimal","value":"2"}

after binding is expired:

openhab/items/PIRVchod_MotionStatus/state
ItemStateEvent
{"type":"OnOff","value":"OFF"}

I have added some logging to my command like this:

rule "Motion sensor triggered"
when
    Item PIRVchod_MotionStatus received update ON
then
    logInfo("rule running", "Rule Motion running")
    BWSHP63_state.sendCommand(ON)
end

Looks like there is no more error on Binding expiration, but I cant see that the Rule has been catched.
Hmmm…

OK, the think that second to last ItemStateEvent is the motion sensor updating to ON.

When you change the .rules file do you see a log statement in openhab.log indicating that the rule was loaded?

This is what I see when I re-save the rule:
2021-02-09 22:15:31.141 [INFO ] [openhab.event.RuleUpdatedEvent ] - Rule 'ec851ce8ac' has been updated.

I am using standard IP:9001 web interface displaying of
tail -f /var/log/openhab/openhab.log /var/log/openhab/events.log

If you are not using .rules files and instead are defining the rule in the UI, you are using the completely wrong syntax. You create the Rule and configure the trigger separately. For the then choose Script Action and choose Rules DSL as the language and put

    logInfo("rule running", "Rule Motion running")
    BWSHP63_state.sendCommand(ON)

as the code.

Or put the code as you’ve written it into a .rules file located in /etc/openhab/rules.

1 Like

:smiley: now I got it how does it works.
The rule is running now.
Sorted out also my other issue.

Now I am going to try to update it with presence detection…

Dumb question… what is the current best practice to implement a Motion Sensor Timer in OH3?

It depends on the rest of your requirements but I’d recommend using the Open Door Reminder rule template on the marketplace (link in the OP). Why write code if you don’t have to?

Beyond that, any of the approaches discussed above should work, just not necessarily the code examples. You might need to translate to more modern ways of doing things. But the approach remains to set a timer, reschedule it on subsequent events, do something when the timer expires.

Went the route you suggested. I think I assumed that approach was deprecated since this post has [Deprecated] in the title, but that’s probably just a bad assumption on my part.

I followed the steps above, all seemed ok, but the rule didn’t seem to be working. Check my logs and saw this

2023-03-27 21:06:30.931 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘garageLightsOffAfterTime’ failed: org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: ‘openhab_rules_tools’
2023-03-27 21:06:30.940 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: Cannot load CommonJS module: ‘openhab_rules_tools’
at com.oracle.truffle.polyglot.PolyglotMapAndFunction.apply(PolyglotMapAndFunction.java:46) ~[?:?]
at org.openhab.automation.jsscripting.internal.OpenhabGraalJSScriptEngine.lambda$7(OpenhabGraalJSScriptEngine.java:216) ~[?:?]
at java.util.Optional.orElseGet(Optional.java:369) ~[?:?]
at org.openhab.automation.jsscripting.internal.OpenhabGraalJSScriptEngine.lambda$5(OpenhabGraalJSScriptEngine.java:216) ~[?:?]
at .:program(:1) ~[?:?]
at org.graalvm.polyglot.Context.eval(Context.java:399) ~[?:?]
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:458) ~[?:?]
at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:426) ~[?:?]
at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) ~[java.scripting:?]
at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:53) ~[?:?]
at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:74) ~[?:?]
at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:53) ~[?:?]
at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:74) ~[?:?]
at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:71) ~[?:?]
at java.util.Optional.ifPresent(Optional.java:183) [?:?]
at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:68) [bundleFile:?]
at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1180) [bundleFile:?]
at org.openhab.core.automation.internal.RuleEngineImpl.runRule(RuleEngineImpl.java:989) [bundleFile:?]
at org.openhab.core.automation.internal.TriggerHandlerCallbackImpl$TriggerData.run(TriggerHandlerCallbackImpl.java:89) [bundleFile:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
at java.lang.Thread.run(Thread.java:829) [?:?]

Saw a few threads on the error but nothing recent. I’m running OH 3.4.2

I am lazy and just use the expire in OH3.

I have a rule that turns on an item that has the expire set to the time I want when motion is detected.

I have the motion detector device timeout set to 10 seconds so every time there is movement it sends an ON to the item with the expire and this resets the item timeout.

You can use real item switches or virtual item switches.

Yes I know I am using the expire for uses it wasn’t intended but it works well. I have been using it this way for over a year or so.

Pay attention to the prequisites. Did you install the openhab_rukes_tools library? If you are on openHABian there ya an option to do so in openhabian-config.