OH3 .getHour "is not in a valid format"

  • Platform information:
    • Hardware: Raspberry Pi 3B
    • OS: OpenHABianPi
    • Java Runtime Environment: Default
    • openHAB version: 3.2.0

I am finally attempting to transition from OpenHAB 2.5 to 3.x. I am working through all of the breaking changes in the rules, but I have run into one that I cannot figure out. And based on other prost here It seems that I am “fixing” it correctly.

In 2.5 I had used: “now.getHourOfDay” frequently. I have read that this is replaced by “now.getHour” int several posts. But when I us this, I get an error in the log.

Script execution of rule with UID 'NameIsIrrelevant' failed: 2022-04-09T16:35:40.447957-05:00[US/Central] is not in a valid format.

I tried both:
now.getHour
and
now.getHour()

Both give the same error.

I also tried changing the time zone, but I still get the same error.

I also tried a clean start by installing a fresh version of OpenHABianPi from a fresh download to a new SD card, and I still have the same error.

Any idea what to try next?

Not very knowledgeable in this area, but have this line working in a DSL rule OH3.3M3. It could be different with other rule engines.
var Number hourofday = now.getHour()

Bob

Can you post your actual code? There seems to be something else happening. The error message indicates some sort of parsing is happening somewhere.

getHour() doesn’t do this

ECMAScript-2021:

var now = time.ZonedDateTime.now()
var HourOfDay = now.hour()

Have you seen this thread:

I am currently implementing the Blocklies for dates and this is what is generated in ECMAScript which works well for me:

var logger = Java.type(‘org.slf4j.LoggerFactory’).getLogger(‘org.openhab.rule.’ + ctx.ruleUID);
var zdt = Java.type(“java.time.ZonedDateTime”);
logger.info(zdt.now().getHour())

Do you get the error because of your getHour call fails or do you get the error messasge because of script code that uses the result of getHour and it builds a string that is not valid ?

You’re planting lines of DSL into javascript, It doesn’t work like that.

Unfortunately, time is something that has a lot of different possibilities depending on which language and library you’re using. So to get the best answer you’re going to have to give more info. How are you making this rule, is it a rules file or or via the MainUI? If it’s a UI based rule, which of the scripting languages have you selected? What is the entire rule code?

From the info you’ve given, the best guess is that you are just updating your old dsl rules files for 3.X. In that case, now.getHour() should work so we need to see if something else is going on somewhere else in the rule.

I believe michaeljoos sample is correct for ECMAScript-2021. The JSscripting helper library provides a time namespace that gives access to the js-joda library.

Thank you for all of the replies. It turns out “getHour” was actually working and there was another error further down the rule that triggered the same error message, so I thought I was not fixing it. Adding a bunch of log lines helped.

But I am now stuck on another issue, and based on the link posted by Matthias I think I have this correct but I am still getting errors. It’s the IF at the bottom. AutoOffAt_DownstairsBath is a DateTime type of Item.

I was able to get postUpdate to function as shown, but I am not sure I am putting the correct format in there. It reports back in this format: AutoOffAt_DownstairsBath.state: 2022-04-10T15:45:51.417902-0500

But then in the IF statement does not like that “state” format. With this error:

2022-04-10 16:16:45.034 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'DownstairsBathroom-1' failed: An error occurred during the script execution: Could not invoke method: java.time.chrono.ChronoZonedDateTime.isAfter(java.time.chrono.ChronoZonedDateTime) on instance: 2022-04-10T16:20:45.029519-05:00[US/Central] in DownstairsBathroom
rule "Downstairs Bathroom"
when 
    Member of Motion_DownstairsBathroom received update
then
    if(triggeringItem.state == ON)
    {
        if(Dimmer_DownstairsBath.state == 0 || Dimmer_DownstairsBath.state === NULL)
        {
            if(DimmerMemory_DownstairsBath.state > 0)
            { 
                Dimmer_DownstairsBath.sendCommand(DimmerMemory_DownstairsBath.state as Number)
            }
            else if (Mode.state == "Night" && Guests.state == OFF)
            {
                Dimmer_DownstairsBath.sendCommand(20)
            }
            else
            {
                var ThisHour = now.getHour()
                switch (ThisHour)
                {
                    case ThisHour < 5:
                    {
                        Dimmer_DownstairsBath.sendCommand(80)
                    }
                    case ThisHour < 12:
                    {
                        Dimmer_DownstairsBath.sendCommand(100)
                    }
                    case ThisHour < 22:
                    {
                        Dimmer_DownstairsBath.sendCommand(100)
                    }
                    default:
                    {
                        Dimmer_DownstairsBath.sendCommand(80)
                    }
                }
            }
        }

        if(AutoOffAt_DownstairsBath.state === NULL || now.plusMinutes(4).isAfter((AutoOffAt_DownstairsBath.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli))
        { 
            AutoOffAt_DownstairsBath.postUpdate(DateTimeType.valueOf(now.plusMinutes(3).toLocalDateTime().toString()))
        }
    }
end

I think the error message is telling you isAfter() would like just a zonedDateTime, please? No millis stuff.
now.plusMinutes(4).isAfter((AutoOffAt_DownstairsBath.state as DateTimeType).zonedDateTime)