Rules with "now.getHourOfDay" working inconsistently

I have created rules that suppose to work only between curtain times with “now.getHourOfDay” only these rules don’t work very consistently, some rules seems to work all the time while other work only sometimes.
here is the rule that seems not to work:
it supposed to turn on a light if a motion sensor is triggered but only between the hours on18:00 and 20:00 on weekdays. if I remove the section with “now.getHourOfDay” this works perfectly (just not in the hours I want it to)

rule "Kitchen light on weekdays if triggered"
when
    Item mqtt_topic_2faa32a4_occupancy received update
then
    if (mqtt_topic_2faa32a4_occupancy.state == 'true' && isInDayset("workday") && kitchenlighttimer === null) {
        if (now.getHourOfDay > 18 && now.getHourOfDay < 20){
        miio_generic_0DF3A513_power.sendCommand(ON)
        miio_generic_0E0BE239_power.sendCommand(ON)
        kitchenlighttimer = createTimer(now.plusMinutes(10), [| 
            miio_generic_0DF3A513_power.sendCommand(OFF)
            if (mqtt_topic_298ef5dd_occupancy.state == 'false' && network_pingdevice_10_0_0_168_online.state == OFF){
                miio_generic_0E0BE239_power.sendCommand(OFF)
                logWarn("events", "livingroom lights off")
            }
            kitchenlighttimer = null
            ])
        }
        }
end

On the other hand here is a rule that seems to work flawlessly:

rule "Living room Sensor triggered when not home"
when
    Item mqtt_topic_298ef5dd_occupancy received update
then
    if (mqtt_topic_298ef5dd_occupancy.state == 'true' && isInDayset("workday") && network_pingdevice_10_0_0_122_online.state == OFF) {
        if (now.getHourOfDay > 10 && now.getHourOfDay < 18){
            val mailActions = getActions("mail","mail:smtp:81520fb9")
            mailActions.sendHtmlMail("sXXX@gmail.com", "Intruder Alert", "Living room sensor was triggered and you are not home")
            mailActions.sendHtmlMail("sXXX@XXX.com", "Intruder Alert", "Living room sensor was triggered and you are not home")
            sendNotification("sXXX@gmail.com", "Living room sensor was triggered and you are not home")
        }
        }
end

Any help on how I can make this work will be appreciated.

What hour of the day do you expect this to be true? You are likely looking for something with the “or” (||) operator (rather than the “and” (&&))…

if (now.getHourOfDay < 6 || now.getHourOfDay > 20){

To expand on that, this is true between 19:00 and 19:59 only

Does it make a difference if kitchenlighttimer is not declared as a global?

This at the top of the rule to make sure it’s null before the rule starts?
var Timer kitchenlighttimer = null

@shaulliv what do you see in the logs when the rule fires?

It’s intentional, every time the rule runs I want the time to reset itself.

I’m not sure I understand the logic of that.
What does “now.getHourOfDay” calculate?
As far as I understand It supposed to be true between 18:00 and 20:00.

I expect this to be true between 18:00 and 20:00.

Then you will need to use >= and <= to include the values…

    if (now.getHourOfDay >= 18 && now.getHourOfDay =< 20){

Previously, the only valid hour of the day was 19. This way, you have 18, 19 and 20.

But it doesn’t.
Every time the rule runs, you turn on the light, then start a new timer to turn it off. That does not stop, cancel or destroy any existing timer. That variable is just a handle, a pointer, a reference to an independent timer.
Must be like a disco with all those flashing lights.
See “Rules DSL” example


It looks to see if there is an existing running timer before making a new one.

I have the following at the end of the rule, so it should (this part works fine):

kitchenlighttimer = null

Ok, just for fun add var Timer kitchenlighttimer = null to the top of the rule and make the suggested >= <= changes Scott mentioned and see what happens.

BTW, how do you know that part works fine?

I just tested it and this works. I was under the impression that “now.getHourOfDay” assumes 00 minutes (I think it allows to add decimal numbers of minutes).
Anyway, Thank you.

Please click the square box on the post that provided the solution to mark the topic as solved.

Thanks

It does what it says, no more no less. From 13:59 say, it gets the number 13

1 Like

I have var Timer kitchenlighttimer = null at the top of the rules file.
I know it works fine because I tried it in simplified form (without the “now.getHourOfDay”) and everything worked 100% the light went of after 10 minutes.

By the way you said at the top of the rule? is it possible that I can’t put var Timer kitchenlighttimer = null as the very first line, when I tried it gave me a bunch of errors, I had to put an unnecessary import in-front of it?

org.joda.time.DateTime() inherits getHourOfDay from the ReadableDateTime interface and it returns an int representing the hour of the day.

Add a line to your rule like so … you’ll be amazed

kitchenlighttimer = createTimer(now.plusMinutes(10), [| 
            logInfo("diag", "timer expired")
            miio_generic_0DF3A513_power.sendCommand(OFF)

By the by, this is true from 18:00 until 20:59, not quite what you wanted.

1 Like

Yes, Once I read up the function from 5iver’s reply I got that.

To be even more precise :wink: now.getHourOfDay will be 18 from 18:00:00.000 to 18:59:59.999 (hours, minutes, seconds, milliseconds)

1 Like