OH 4.0.3: Rules (JS Scripting) throws error with "time.toZDT": unsupported type for conversion to time.ZonedDateTime

Just migrated from OH3 to OH4(.0.3) using openHABian.

Most things run smoothly, but I’m kinda lost here. In my JS Scripting rules&scripts I use multiple “DateTime”-items:

label: Spülmaschine letzter Start
type: DateTime
category: ""
groupNames:
  - PL12EMSLoads
groupType: None
function: null
tags:
  - Point

With OH3, the following code worked nicely:

    var LetzerStart = time.toZDT(items.getItem("EMS_SpMaLetzterStart"));

With OH4, the following error appears:

2023-10-01 10:29:23.838 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: Error: "EMS_WaMaLetzterStart (Type=DateTimeItem, State=2023-10-01T10:11:28.000+0200, Label=Waschmaschine letzter Start, Category=, Tags=[Point], Groups=[PL12EMSLoads])" is an unsupported type for conversion to time.ZonedDateTime
	at <js>.R(@openhab-globals.js:2) ~[?:?]
	at <js>.checkWW(<eval>:82) ~[?:?]
	at <js>.:program(<eval>:44) ~[?:?]
	at org.graalvm.polyglot.Context.eval(Context.java:399) ~[?:?]
	at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:458) ~[?:?]
	at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:426) ~[?:?]
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:262) ~[java.scripting:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:53) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:78) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocableAndAutocloseable.eval(DelegatingScriptEngineWithInvocableAndAutocloseable.java:53) ~[?:?]
	at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.eval(InvocationInterceptingScriptEngineWithInvocableAndAutoCloseable.java:78) ~[?:?]
	at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:71) ~[?:?]
	at java.util.Optional.ifPresent(Optional.java:178) ~[?:?]
	at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:68) ~[?:?]
	at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1188) ~[?:?]
	at org.openhab.core.automation.internal.RuleEngineImpl.runRule(RuleEngineImpl.java:997) ~[?:?]
	at org.openhab.core.automation.internal.TriggerHandlerCallbackImpl$TriggerData.run(TriggerHandlerCallbackImpl.java:87) ~[?:?]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[?:?]
	at java.lang.Thread.run(Thread.java:833) ~[?:?]
2023-10-01 10:29:23.843 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'EMS_checkWW' failed: org.graalvm.polyglot.PolyglotException: Error: "EMS_WaMaLetzterStart (Type=DateTimeItem, State=2023-10-01T10:11:28.000+0200, Label=Waschmaschine letzter Start, Category=, Tags=[Point], Groups=[PL12EMSLoads])" is an unsupported type for conversion to time.ZonedDateTime

I tried to:

    var LetzerStart = time.toZDT(items.getItem("EMS_SpMaLetzterStart").state);
    var LetzerStart = time.toZDT(items.getItem("EMS_SpMaLetzterStart").rawState);

but this also didn’t help. What has to change here?

I think it should be

var LetzerStart =  items.getItem("EMS_SpMaLetzterStart").rawState.getZonedDateTime();

or even better:
var LetzerStart = items.EMS_SpMaLetzterStart.rawState.getZonedDateTime();

1 Like

There is a known bug that has been fixed. time.toZDT() wasn’t properly recognizing when it was sent a DateTime Item. You can upgrade OH to 4.1 M1, upgrade openhab-js separately using npm, or change your rule to

var LetzerStart = time.toZDT(items.getItem("EMS_SpMaLetzterStart").state);

The whole point of time.toZDT() is to avoid that when working with ZonedDateTimes.

From the docs:

There will be times when this automatic conversion is not available (for example when working with date times within a rule). To ease having to deal with these cases a time.toZDT() function will accept almost any type that can be converted to a time.ZonedDateTime. The following rules are used during the conversion:

Argument Type Rule Examples
null or undefined time.ZonedDateTime.now() time.toZDT();
time.ZonedDateTime passed through unmodified
java.time.ZonedDateTime converted to the time.ZonedDateTime equivalent
JavaScript native Date converted to the equivalent time.ZonedDateTime using SYSTEM as the timezone
number, bingint, java.lang.Number, DecimalType rounded to the nearest integer and added to now as milliseconds time.toZDT(1000);
Quantity or QuantityType if the unit is time-compatible, added to now time.toZDT(item.getItem('MyTimeItem').rawState);, time.toZDT(Quantity('10 min'));
items.Item or org.openhab.core.types.Item if the state is supported (see the Type rules in this table, e.g. DecimalType), the state is converted time.toZDT(items.getItem('MyItem'));
String, java.lang.String, StringType parsed based on the following rules; if no timezone is specified, SYSTEM timezone is used
ISO8601 Date/Time (opens new window)String parsed, depending on the provided data: if no date is passed, today’s date; if no time is passed, midnight time time.toZDT('00:00');, time.toZDT('2022-12-24');, time.toZDT('2022-12-24T18:30');
RFC String (output from a Java ZonedDateTime.toString()) parsed time.toZDT('2019-10-12T07:20:50.52Z');
"kk:mm[:ss][ ]a" (12 hour time) today’s date with the time indicated, the space between the time and am/pm and seconds are optional time.toZDT('1:23:45 PM');
ISO 8601 Duration (opens new window)String added to now time.toZDT('PT1H4M6.789S');

When a type or string that cannot be handled is encountered, an error is thrown.

Note, I’m not certain that if you go down that path if the auto-conversion between java.time.ZonedDateTime and joda-js ZonedDateTime occurs so beware. You might end up with a ZDT that behaves slightly differently .

1 Like

strange. I did test that beforehand and it didn’t seem to work. Now it does. Thanks again, Rich!