Need some help from our Javascript specialists. I’m converting my scripts from PY to JS and stepped upon strange issue. Basically I want to know how much time passed between now and the last time item was persisted. The code I had in PY which worked fine was translated to JS:
var lastTATime = items.getItem("itemName").persistence.lastUpdate();
var duration = time.Duration.between(time.ZonedDateTime.now(), lastTATime).seconds();
The second line crash with the strange error:
2025-02-02 22:00:46.205 [ERROR] [b.automation.script.file.mytestjs.js] - Failed to execute rule LivingRoomMotion01_test: RangeError: Maximum call stack size exceeded: RangeError: Maximum call stack size exceeded
at from (/node_modules/openhab.js:2)
at until (/node_modules/openhab.js:2)
at between (@openhab-globals.js:2)
at until (/node_modules/openhab.js:2)
at between (@openhab-globals.js:2)
at until (/node_modules/openhab.js:2)
at between (@openhab-globals.js:2)
at until (/node_modules/openhab.js:2)
at between (@openhab-globals.js:2)
Basically the error means that something stuck in a loop and exceeded the number of executions which doesn’t make sense in my case.
Similar code:
var test = time.Duration.between(time.ZonedDateTime.now(), time.ZonedDateTime.now().plusHours(20)).seconds()
works fine returning correct number of seconds, so something with the ZonedDateTime coming from persistent.
Would also appreciate suggestions on how to achieve the same the way but still want to understand why Joda time is not working with persistent.
To expand on @florian-h05’s statement, if your Item’s current state students from the most recent state stored in persistence, OH cannot know when the last update was so it returnsnull.
This could be what’s happening here and a reason why the lastTATime would benull.
No it is not null, this was check right away, I know about this.
The problem is that even this would generate the same error:
time.Duration.between(lastTATime, lastTATime)
Where it should return 0, somehow whatever returned from persistence is crashing “Duration”.
This however works fine:
var zdt = time.ZonedDateTime.now(time.ZoneId.of("Europe/Paris"));
var zdt_a = time.ZonedDateTime.now(time.ZoneId.of("America/Toronto"));
helper.log_debug("Paris: " + zdt);
helper.log_debug("Toronto: " + zdt_a);
helper.log_debug("Difference between Paris and Toronto: " + time.Duration.between(zdt, zdt_a).toHours().toString());
2025-02-03 14:47:19.891 [DEBUG] [nhab.automation.openhab-js.mytest_js] - Paris: 2025-02-03T20:47:19.889+01:00[Europe/Paris]
2025-02-03 14:47:19.891 [DEBUG] [nhab.automation.openhab-js.mytest_js] - Toronto: 2025-02-03T14:47:19.890-05:00[America/Toronto]
2025-02-03 14:47:19.895 [DEBUG] [nhab.automation.openhab-js.mytest_js] - Difference between Paris and Toronto: 0
I was thinking about Java to Joda conversion but not sure how to do one, toZDT just passing it through (yes, misspelled:)). Also error is not about type or type conversion but about calling function in the loop and eventually filling the stack.
I think this issue was there before that update happened, I was away and my OH was not updated I think since summer time, I’ve updated it yesterday to the latest and error is still the same.
Java ZDT and Joda ZDT are very similar but not identical. I could see Joda Duration becoming confused or otherwise failing in interesting ways if you pass it a Java ZDT. It wouldn’t necessarily just fail on it if they are similar enough.
But unless time.toZDT is also failing to recognize the Java Object and convert it, which I’m pretty sure worked at some point, my guess above isn’t correct and it is a Joda ZDT after all.
To see if time.toZDT is also broken, you can pass the toString to it instead of the Object. That for sure will guarantee you get a Joda zdt
So is this a bug in Joda implementation of Duration? It looks like an obvious bug but I don’t think it is in our OH code.
Anyway this would work for my implementation, it is just very strange and error is strange too.
Yes, this is a known thing but not in my case, it seems that Joda Duration got confused with ZonedDateTime from persistence for unknown to me reason, reparsing it from string works fine. Seems like a bug but I don’t know where.
Assuming that the Java Object is not being converted to a joda-ja ZDT by the add-on or time.toZDT() the bug is in OH, not joda-js. By parsing the String, you have ensured that a joda-js ZDT Object is passed to Duration.
I think start by filing an issue on openhab-js to fix time.toZDT() and to check the persistence methods to make sure they convert the Java to a joda-js.