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.
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()
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 ?
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)