Design Pattern: Motion Sensor Timer

@rlkoshak thank you very much for your DP (and JSR223) series - I’m learning new things every day.
I have one question to “Comprehensive example” - python part, I think @when part should be :

@when("Member of gMotionDetectors changed to ON")

instead of

@when("Item MotionDetector1 received update ON")

edit: I forgot comment // use an appropriate value

is throwing error, probably should start with #

Thanks! I’ve corrected both errors in the OP.

Hi,

I get an error on one of the rules, I copy pasted it, only replaced the item with mine and replaced the minute setting to 1, it looks like this:

var Timer occupancyTimer = null

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

When the sensor receives an ON update, the rule gets triggered but won’t be fired because there is an error: 2019-09-26 14:43:09.126 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'MotionDetector1 received ON': The name 'timeoutMinutes' cannot be resolved to an item or type; line 14, column 52, length 14

I tried some things but nothing solved it, any idea what I could do?

This means that the variable timeoutMinutes is not defined as a global variable in your rules file. If i read it correct yout timeout value should be one minute. Then just replace timeoutMinutes with a 1 or define the variable above your rules

val timeoutMinutes = 1

To use the variable or better constant replace your 1 minute with timeoutMinutes. If you now like to change the one minute to 2 minutes the just adjust the timeoutMinutes to 2

Thomas

Aaah now I understand, I added the val string and it is working now thanks a lot! :slight_smile: For another sensor, I want the same rule but it should only operate between a specific time range.

How can I merge a time cron dependence on the rule?

If statements inside the Rule. See Design Pattern: Time Of Day for examples on how to do time comparisons or, since this is something you will want to do in lots of Rules, a good way to centrally keep track of times of day.

Another good advice is maybe, that you should look into groups and how to handle them

Thanks, will play around with it when I have the time again, yesterday my first son was born so no PC time the last days :wink:

Will also look into that, for now the rule really works great and just how I wanted it :slight_smile:

Thank you for this, I have read through the thread with interest and havre replicated the “Timers Version” and it works, which as a newbie I am pleased with :slight_smile:
Could you explain the line:

if(occupancyTimer === null || occupanctTimer.hasTerminated()) {

as a beginner I struggle to find places to look up the syntax?
I assume “===” means does not equal?
What do the “||” characters mean?
and one final question, I thought occupanctTimer was a typo, but as it works, it is obviously not a typo, it is only referenced here and does not get reused, can you explain this in a little more detail please?

Sorry for all the questions, I’m finding OpenHab a steep learning curve :slight_smile:

Ian

It’s a “special equal” really, it means “is the same thing” in computer terms.
Consider
A = 2
B = 2
A has the same value as B, but is not the same thing as B. For a start, it’s called A. Equal but not identical. We can change A and that would not change B.
A === A is true, these are the same thing.
A === B is not true; same value but not same thing.
You generally only meet === (or the “not” opposite !==) in rules where null is involved. Things that are null really are null, not just having a value of null.

OR in logical evaluation.
AND is represented as && which isa bit more obvious.

It is a typo.
So the test could never be true there, but it would very rarely matter as in real life the timer is either timing or is null.

hasTerminated should never come about for this particular timer really - when it does terminate, it sets itself to null.

1 Like

Thanks for the explanations, that makes more sense now.
I’ve also got your “Expire Binding” version working, although didn’t realise that binding was being used as in the true sense of a HA binding and took me a while to get it working, as I didn’t have the binding installed :slight_smile:

1 Like

I like the idea of not using the OFF message of a motion detector, so you can define your own duration when the light is on. But this brought me to the following: Who likes to read on the toilet? :rofl:

What i would like to do is that after the timer expires, instead of turning off the light, dim the light to for ex. 50% to indicate the user that the light is about to go off. Then start a 2nd timer (don’t know if this is a good idea) to turn the light off after x seconds if the motion sensor does not detect any movement anymore. If movement is detected brighten up the light again and restart the timers.

Any idea how to implement this in the original timer example above?

Kind regards,
Eric

This is not problem. You need two timers.

  1. On motion, cancel and delete the second timer if it exists, turn the light up all the way, and set the first timer.
  2. If motion occurs again, reschedule the first timer.
  3. When motion hasn’t happened for long enough the fist timer goes off. This timer dimms the light to 50% and sets a second timer.
  4. When the second timer goes off it turns off the light.
2 Likes

I don’t understand this example unfortunately.

I have the following items and rules defined to turn on/off a Hue bulb using a Hue motion sensor.

Items:

Switch Motion_Badezimmer_Bewegungsmelder "Badezimmer Bewegungsmelder" <network> { channel="zigbee:philips_sml001:XXX:XXX:motion" }
Dimmer Lampe_Badezimmer_Decke "Badezimmer Lampe Decker" <lightbulb> { channel="zigbee:device:XXX:XXX:XXX_11_dimmer" }

Rules:

rule "Philips Hue Motion Sensor ON"
when
    Item Motion_Badezimmer_Bewegungsmelder changed from OFF to ON
then
    //execute your code here
    Lampe_Badezimmer_Decke.sendCommand(100)
end

rule "Philips Hue Motion Sensor OFF"
when
   Item Motion_Badezimmer_Bewegungsmelder changed from ON to OFF 
then
   Lampe_Badezimmer_Decke.sendCommand(0)
end

The Hue motion sensor changes back to OFF too quickly and therefore I want to delay this to turn off the lamp later. From the tutorial, I would have thought that modifying the motion detector item like so would work:

Switch Motion_Badezimmer_Bewegungsmelder "Badezimmer Bewegungsmelder" <network> { channel="zigbee:philips_sml001:XXX:XXX:motion", expire="5m,command=OFF" }

But it still turns off as soon as the Hue motion sensor sends the OFF state.

Because you didn’t remove the rule. So when the motion sensor turns offer it triggers your Rule to turn off the light. Remove the rule.

Could you explain this a bit more I am new to rules and openhab and I have the same problem as michaelmell. Thank you

Rules are event driven. An event occurs and Rules configured to trigger on that event. The Event that triggers the Rule is defined in the when clause.

michalemell has two Rules, one defined to trigger when Motion_Badezimmer_Bewegungsmelder changes from OFF to ON. This Rule sends essentially and ON command to Lampe_Badezimmer_Decke. The second rule triggers when Motion_Badezimmer_Bewegungsmelder changes from ON to OFF and sends essentially an OFF command to Lampe_Badezimmer_Decke.

So it doesn’t matter what is done with the Expire binding to control the light. The Rule will always trigger when the motion sensor goes to OFF and it will always turn off the light. If the light needs to be turned OFF by the Expire binding instead of by the Rule, the Rule must be removed.

Oh ok that makes sense, but I have a problem where even even when I use your simples design pattern

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

with this switch

Switch zwave_device_f57cd095_node16_alarm_motion "Motion Alarm" <motion> (motion_zwave) {channel="zwave:device:f57cd095:node16:alarm_motion", expire="2m,command=OFF"}

then it just never expires after 2 minutes and it seems to me that its identical to your example. I tried to make it with the expire on FibaroDimmer1_DimmerSwitch1 being 2min aswell but it doesnt make a difference.

How often does the motion sensor Item get updated? The Expire timer gets reset on every update. If the updates come faster than every two minutes it will never Expire.

Also, what evidence are you looking for that the Expire happened? You don’t have a Rule that does anything when the motion sensor goes to OFF. You don’t have a Rule that turns off the light when the motion sensor goes to OFF. If you are expecting the light to go off after 2 minutes of the last motion, you should put the Expire config on the Light.