Using getHourOfDay in an rule for switching on lights

Hi there,

i got three rules to switch on the lights in my corridor in the morning, evening and at night.
But the rules gets triggered even when the time isn´t right …
Only the night rule stops because the time isn´t right.

Night
The rule should stop when it´s greater 06:00 and smaller 23:00 cause then it´s not night.

    if(now.getHourOfDay() <6 && now.getHourOfDay() >23)
    {
        return (false)
    }

Evening
The rule should stop when it´s greater 23:00 and smaller 17:00 because then it´s not evening.

    if(now.getHourOfDay() <23 && now.getHourOfDay() >17)
    {
        return (false)
    }

Morning
And this rule should stop when it´s greater 10:00 and smaller 06:00 because then it´s not morning.

    if(now.getHourOfDay() <6 && now.getHourOfDay() >10)
    {
        return (false)
    }

Any ideas?

The openHAB Designer got some errors but i got the same errors in other working rules.

Multiple markers at this line
- Couldn't resolve reference to JvmIdentifiableElement 'getHourOfDay'.
- Couldn't resolve reference to JvmIdentifiableElement '>'.
- Couldn't resolve reference to JvmIdentifiableElement '<'.
- Couldn't resolve reference to JvmIdentifiableElement 'now'.
- Couldn't resolve reference to JvmIdentifiableElement '&&'.

Thanks
Michael

Okay i got it.
The time can´t be greater #1 and smaller #2, it has to be or.

    if(now.getHourOfDay() <6 || now.getHourOfDay() >23)
    {
        return (false)
    }
    if(now.getHourOfDay() <23 || now.getHourOfDay() >17)
    {
        return (false)
    }
    if(now.getHourOfDay() <6 || now.getHourOfDay() >10)
    {
        return (false)
    }

Cheers
Michael

In fact, for the first rule it should be

if(now.getHourOfDay() >5 && now.getHourOfDay() <23) //06:00:00 to 22:59:59

and the third rule should be

if(now.getHourOfDay() <6 || now.getHourOfDay() >9) //10:00:00 to 05:59:59
1 Like

Thanks @Udo_Hartmann.

I just came home and checked the openHAB log to see if the rule for evening was working fine.
But the rule got stopped by the first if that checks the time with now.getHourOfDay …

    if(CurrentTime <23 || CurrentTime >17)
    {
        logInfo("RuleFlurEvening", "Stopping, it´s not evening.")
        return (false)
    }

But this should only happen when the time is greater 23 or smaller 17 …
And now it´s 19:17 !

Also i´m getting errors when using now.getHourOfDay in the openHAB Designer!

Multiple markers at this line
- Couldn't resolve reference to JvmIdentifiableElement 'getHourOfDay'.
- Couldn't resolve reference to JvmIdentifiableElement 'now'.

Cheers
Michael

You have to think through your logic.
If the hour is 1 then it is less than 23, test passed.
If the hour is 16 then it is less than 23, test passed.
If the hour is 18 then it is less than 23, test passed.
If hour is 24 then it is not less than 23, hurrah. But it is more than 17 so test still passed.
This test as written will always pass.

This test you had earlier will only pass between 17:00 and 22:59, is that what you want?

Don’t forget you can use ‘else’ clauses with your tests.
if(CurrentTime >17 && CurrentTime < 23)
it is evening 1700-2259
else
it is night or day 2300-1659
endif

And you can use 'elseif’
if(CurrentTime >17 && CurrentTime < 23)
it is evening 1700-2259
elseif(CurrentTime >8 && CurrentTime < 17)
it is daytime 0800-1659
else
it is not day or evening so it must be night 2300-0759
endif

There is currently a known problem with ‘now’ and Designer as mentioned many times in this forum, it is annoying but does not affect live working.

Please change your logic!

if(CurrentTime <23 || CurrentTime >17)

Given, that CurrentTime is equal to now.getHourOfDay, this would mean "either less then 23 or more than 17, so this if clause is true from 18:00:00 to 22:59:59.
And once more: there is no hour > 23, the clock jumps from 23:59:59 to 00:00:00!

Hi there,

yeah i´ve made a mistake and changed the > and <.
CurrentTime is just an var for the now.getHourOfDay.

Is there any way to work with the full time ?
Or would it work with:

var CurrentHour = now.getHourOfDay
var CurrentMinute = now.getMinuteOfHour

if((CurrentHour == 23 && CurrentMinute >= 1) && CurrentHour <17)

Cheers
Michael

Okay now i changed the rules and i think it should work.

In the morning:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*

import org.joda.time.*

rule "Flurlicht morgens einschalten"

when

    Item itmFIBmotion2 changed from 0 to 1

then

    var Timer timerFlur = null
    var Integer timerFlurTimeout = 30
    var CurrentHour = now.getHourOfDay

    // Prüfung ob die aktuelle Uhrzeit nicht zwischen 6 und 9 Uhr liegt, dann abbrechen
    if(CurrentHour <6 || CurrentHour >9)
    {
        logInfo("RuleFlurMorning", "Die Regel wird abgebrochen, es ist nicht Morgen.")
        return (false)
    }

    // Timer wird erneut gestartet wenn er noch nicht abgelaufen ist
    if (timerFlur != null)
    {
        timerFlur.reschedule(now.plusMinutes(timerFlurTimeout))
        logInfo("RuleFlurMorning","Timer wird erneut gestartet, fuer " + timerFlurTimeout + " Minuten.")
    }
    else
    {
        // Licht einschalten wenn eine Bewegung festgestellt wurde, für Dauer = timerFlurTimemout
        sendCommand(hueFlur, "360,80,30")
        logInfo("RuleFlurMorning","Timer wurde fuer " + timerFlurTimeout + " Minuten gestartet.")
        timerFlur = createTimer(now.plusMinutes(timerFlurTimeout))
        [|
            // Prüfung ob nach Ablauf des Timers noch eine Bewegung festgestellt wurde, dann Timmer verlängern
            if (itmFIBmotion2.state == 1)
            {
                timerFlur.reschedule(now.plusMinutes(timerFlurTimeout))
                logInfo("RuleFlurMorning","Timer ist abgelaufen aber wird erneut fuer " + timerFlurTimeout + " Minuten gestartet.")
            }
            else
            {
                // Licht ausschalten wenn der Timer abgelaufen ist und keine Bewegung festgestellt wurde
                sendCommand(hueFlur, "0")
                timerFlur = null
                logInfo("RuleFlurMorning", "Das Licht wird wieder ausgeschaltet.")
            }
        ]
    }

end

In the evening:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*

import org.joda.time.*

rule "Flurlicht abends einschalten"

when

    Item itmFIBmotion2 changed from 0 to 1

then

    var Timer timerFlur = null
    var Integer timerFlurTimeout = 30
    var CurrentHour = now.getHourOfDay
    var CurrentMinute = now.getMinuteOfHour

    // Prüfung ob aktuelle Uhrzeit nicht zwischen 23 und 17 Uhr liegt, dann abbrechen
    if((CurrentHour == 23 && CurrentMinute >=1) || CurrentHour <17)
    {
        logInfo("RuleFlurEvening", "Das Licht wird nicht eingeschaltet, es ist nicht abends.")
        return (false)
    }
    
    // Prüfung ob es zu hell ist, dann abbrechen
    if(itmFIBlux2.state >1)
    {
        logInfo("RuleFlurEvening", "Das Licht wird nicht eingeschaltet, es ist hell genug.")
        return (false)
    }

    // Timer wird erneut gestartet wenn er noch nicht abgelaufen ist
    if (timerFlur != null)
    {
        timerFlur.reschedule(now.plusMinutes(timerFlurTimeout))
        logInfo("RuleFlurEvening","Das Licht wird erneut fuer " + timerFlurTimeout + " Minuten eingeschaltet.")
    }
    else
    {
        // Licht einschalten wenn eine Bewegung festgestellt wurde, für Dauer = timerFlurTimemout
        sendCommand(hueFlur, "360,80,50")
        logInfo("RuleFlurEvening","Das Licht wird fuer " + timerFlurTimeout + " Minuten eingeschaltet.")
        timerFlur = createTimer(now.plusMinutes(timerFlurTimeout))
        [|
            // Prüfung ob nach Ablauf des Timers noch eine Bewegung festgestellt wurde, dann Timmer verlängern
            if (itmFIBmotion2.state == 1)
            {
                timerFlur.reschedule(now.plusMinutes(timerFlurTimeout))
                logInfo("RuleFlurEvening","Das Licht wird fuer " + timerFlurTimeout + " Minuten eingeschaltet, es wurde erneut Bewegung festgestellt.")
            }
            else
            {
                // Licht ausschalten wenn der Timer abgelaufen ist und keine Bewegung festgestellt wurde
                sendCommand(hueFlur, "0")
                timerFlur = null
                logInfo("RuleFlurEvening", "Das Licht wird wieder ausgeschaltet.")
            }
        ]
    }

end

In the night:

import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*

import org.joda.time.*

rule "Flurlicht nachts einschalten"

when

    Item itmFIBmotion2 changed from 0 to 1

then

    var Timer timerFlur = null
    var Integer timerFlurTimeout = 5
    var CurrentHour = now.getHourOfDay
    var CurrentMinute = now.getMinuteOfHour

    // Prüfung ob die aktuelle Uhrzeit nicht zwischen 23 und 5 Uhr liegt, dann abbrechen
    if(CurrentHour <5 && (CurrentHour =23 && CurrentMinute >=1))
    {
        logInfo("RuleFlurNight", "Die Regel wird abgebrochen, es ist nicht Nacht.")
        return (false)
    }

    // Timer wird erneut gestartet wenn er noch nicht abgelaufen ist
    if (timerFlur != null)
    {
        timerFlur.reschedule(now.plusMinutes(timerFlurTimeout))
        logInfo("RuleFlurNight","Timer wird erneut gestartet, fuer " + timerFlurTimeout + " Minuten.")
    }
    else
    {
        // Licht einschalten wenn eine Bewegung festgestellt wurde, für Dauer = timerFlurTimemout
        sendCommand(hueFlur, "360,80,1")
        logInfo("RuleFlurNight","Timer wurde fuer " + timerFlurTimeout + " Minuten gestartet.")
        timerFlur = createTimer(now.plusMinutes(timerFlurTimeout))
        [|
            // Prüfung ob nach Ablauf des Timers noch eine Bewegung festgestellt wurde, dann Timmer verlängern
            if (itmFIBmotion2.state == 1)
            {
                timerFlur.reschedule(now.plusMinutes(timerFlurTimeout))
                logInfo("RuleFlurNight","Timer ist abgelaufen aber wird erneut fuer " + timerFlurTimeout + " Minuten gestartet.")
            }
            else 
            {
                // Licht ausschalten wenn der Timer abgelaufen ist und keine Bewegung festgestellt wurde
                sendCommand(hueFlur, "0")
                timerFlur = null
                logInfo("RuleFlurNight", "Das Licht wird wieder ausgeschaltet.")
            }
        ]
    }

end

Thanks for your help.
It´s not always that easy when you´re not working with programming all day …

Cheers
Michael

The first if clause would never fire :slight_smile:

if(CurrentHour <5 && (CurrentHour =23 && CurrentMinute >=1))

In this case, you can omit the brackets, and there is no chance that CurrentHour is less 5 and equal 23…

A more simple way would be to compare not hourOfDay and minuteOfDay, but minuteOfDay:

if (now.getMinuteOfDay < (60*5) || now.getMinuteOfDay > (60*23)+1)

Finally, I will show a more dirty trick :wink:

if (now.plusHours(4).getHourOfDay > 10)

So, what is this?

if now() is 19:59:59, now.plusHours(4) is 23:59:59, so now.plusHours(4).getHourOfDay is 23 --> true
if now() is 20:00:00, now.plusHours(4) is 00:00:00, so now.plusHours(4).getHourOfDay is 0 --> false
if now() is 06:59:59, now.plusHours(4) is 10:59:59, so now.plusHours(4).getHourOfDay is 10 --> false
if now() is 07:00:00, now.plusHours(4) is 11:00:00, so now.plusHours(4).getHourOfDay is 11 --> true

The if clause is true for the time between 07:00:00 and 19:59:59 (including)!

Is there a way to have gethourofday for a UTC time instead of the current local timezone?
I am getting the hour to distinguish between two different electricity tariffs and the supplier is using UTC as their reference. In contrast my local time changes between summer and winter.

Try now(UTC).getHourOfDay Maybe it’s now("UTC").getHourOfDay

Hey Udo! Thanks for pointing me the right way!

Without the quotes it threw "The name ‘UTC’ cannot be resolved to an item or type."
With the quotes i got a different one: “An error occurred during the script execution: Could not invoke method: org.joda.time.DateTime.now(org.joda.time.DateTimeZone) on instance: null”

However a brief web search got me to try

now(DateTimeZone.UTC) 

and it seems that works! Woohoo :slight_smile:

Aah! Then I misunderstood the manual… :wink: thanks for enlighten this blind spot :slight_smile: