rkoshak / openhab-rules-tools

Library functions, classes, and examples to reuse in the development of new Rules.
Other
62 stars 23 forks source link

[helper] createTimer 'when' cannot be parsed properly #103

Closed rliegmann closed 1 year ago

rliegmann commented 1 year ago

Hi rkoshak, thanks for the great library :-) I use the loopingTimers for my window/heating control. After updating to openhab 4.0.0.M1, my rules no longer worked correctly. I always got the following error: 2023-03-30 17:24:18.062 [WARN ] [ore.internal.scheduler.SchedulerImpl] - Scheduled job 'Test Looper' failed and stopped org.graalvm.polyglot.PolyglotException: Error: "2023-03-30T17:24:19.037+02:00[SYSTEM]" is an unsupported type for conversion to time.ZonedDateTime It looks like the following line of code is causing the problem: https://github.com/rkoshak/openhab-rules-tools/blob/7372139897bafcde3b43b1ab54ac3254f3c97890/helpers.js#L16

Here toZDT() doesn't seem to be able to parse the when correctly. I was able to solve this by appending toString() . const timeout = time.toZDT(when.toString());

My question now is, is this a bug or am I doing something wrong? Can you help me there or verify the whole thing?

Thanks LG Ralf

rkoshak commented 1 year ago

Sorry for the delay, I've been on vacation for a week.

What specifically are you passing as the when? I mean what type is it?

time.toZDT() is actually a part of openhab-js, not this library (anymore, I moved it to openhab-js shortly after 3.0 was released). But I've seen some other reports of similar errors with my rule templates too.

I've not been able to reproduce it myself yet.

I think the best first step is to make sure you are using the version of openhab-js that comes with the add-on, and make sure you have the latest openhab_rules_tools installed (latest is 2.0.2).

If the error persists, install the latest openhab-js library (I think 4.0.1). If the error continues to persist, we will have to move this over to the openhab-js repo to figure out what's going on. From the error, it kind of looks like what ever type you are passing it as the when is not recognized and therefore it doesn't get converted. The toString() works because toZDT recognizes a DateTime String and knows how to parse it.

rliegmann commented 1 year ago

Hi, no problem. I hope you had a nice holiday. :-) I think I've found my mistake myself now, or is it not a mistake after all or what is really happening. In short, I only made the following js imports in my script/rules:

var {loopingTimer, timeUtils} = require('openhab_rules_tools');
var { openhab } = require('openhab');

If I add the time object from the openhab lib to the imports, everything works again.

var {loopingTimer, timeUtils} = require('openhab_rules_tools');
var { openhab, time } = require('openhab');

As it stands, the first block with the imports doesn't load the correct time object. Unfortunately, the time object appears the same in both variants. I wrote a small test script for this: The openhab time library expects a variable of the type: time.ZonedDateTime for toZDT().

Not working Script:

var {loopingTimer, timeUtils} = require('openhab_rules_tools');
var { openhab } = require('openhab');

var logger = log('rules_tools.'+ruleUID);

var i = 0;

function loopFunction  () {
  logger.error("TICK " + i);
  if (i <= 5) {
    i++;
    var response = time.toZDT("PT1s");
    logger.error(response instanceof time.ZonedDateTime);  
    return response;
  }
  else
    return null
}

var looper = new loopingTimer.LoopingTimer();
looper.loop(loopFunction, "00:00:01", "Test Looper");

Result Log:

2023-04-03 22:45:35.435 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - TICK 0
2023-04-03 22:45:35.441 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - true
2023-04-03 22:45:35.445 [WARN ] [ore.internal.scheduler.SchedulerImpl] - Scheduled job 'Test Looper' failed and stopped
org.graalvm.polyglot.PolyglotException: Error: "2023-04-03T22:45:36.436+02:00[SYSTEM]" is an unsupported type for conversion to time.ZonedDateTime
    at <js>.toZDT(/openhab/conf/automation/js/node_modules/openhab/time.js:281) ~[?:?]
    at <js>.createTimer(/openhab/conf/automation/js/node_modules/openhab_rules_tools/helpers.js:16) ~[?:?]
    at <js>.expired(/openhab/conf/automation/js/node_modules/openhab_rules_tools/loopingTimer.js:44) ~[?:?]
    at <js>.:=>(/openhab/conf/automation/js/node_modules/openhab_rules_tools/loopingTimer.js:29) ~[?:?]
    at com.oracle.truffle.polyglot.PolyglotFunctionProxyHandler.invoke(PolyglotFunctionProxyHandler.java:154) ~[bundleFile:?]
    at jdk.proxy1.$Proxy962.run(Unknown Source) ~[?:?]
    at org.openhab.automation.jsscripting.internal.threading.ThreadsafeTimers.lambda$0(ThreadsafeTimers.java:85) ~[bundleFile:?]
    at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$12(SchedulerImpl.java:191) ~[?:?]
    at org.openhab.core.internal.scheduler.SchedulerImpl.lambda$1(SchedulerImpl.java:88) ~[?:?]
    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) ~[?:?]

working Script:

var {loopingTimer, timeUtils} = require('openhab_rules_tools');
var { openhab, time } = require('openhab');

var logger = log('rules_tools.'+ruleUID);

var i = 0;

function loopFunction  () {
  logger.error("TICK " + i);
  if (i <= 5) {
    i++;
    var response = time.toZDT("PT1s");
    logger.error(response instanceof time.ZonedDateTime);  
    return response;
  }
  else
    return null
}

var looper = new loopingTimer.LoopingTimer();
looper.loop(loopFunction, "00:00:01", "Test Looper");

Result Log:

2023-04-03 22:47:55.268 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - TICK 0
2023-04-03 22:47:55.277 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - true
2023-04-03 22:47:56.269 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - TICK 1
2023-04-03 22:47:56.274 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - true
2023-04-03 22:47:57.271 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - TICK 2
2023-04-03 22:47:57.276 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - true
2023-04-03 22:47:58.273 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - TICK 3
2023-04-03 22:47:58.277 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - true
2023-04-03 22:47:59.273 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - TICK 4
2023-04-03 22:47:59.278 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - true
2023-04-03 22:48:00.274 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - TICK 5
2023-04-03 22:48:00.279 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - true
2023-04-03 22:48:01.275 [ERROR] [on.openhab-js.rules_tools.9db2a08676] - TICK 6

What is interesting here is that in both variants the returned time object is always of the type time.ZonedDateTime. As soon as the openhab time lib is imported, everything works. What can be the reason, or is that even correct? Do you possibly have an explanation for this? Thank you in advance.

LG Ralf

rkoshak commented 1 year ago

If I add the time object from the openhab lib to the imports, everything works again.

Do you have Settings -> JS Scripting -> Use Built in Variables? If so you don't need to import anything from openhab. time, items, and all the rest are directly injected into your scripts. But if you do import openhab you need to import everything that you use from it.

I have a low priority todo to make sure the openhab_rules_tools library works either way. But I've only ever tested it with "Use Built in Variables".

rliegmann commented 1 year ago

Yes, Use Built in Variables are active. (in German) Bildschirm­foto 2023-04-04 um 22 55 05

I rather believe that this is a general problem from openhab.

rkoshak commented 1 year ago

I was finally able to reproduce this problem.

The problem is apparently a bug in openhab-js that was fixed in version 4.2.0. Unfortunately even in the latest snapshots the version of openhab-js is 4.1.0.

I've updated the version check at the top of the rule template so instead of complaining it can't parse, it will tell you your library version is too old.

For now:

  1. choose "Do Not Use Included Library"
  2. reinstall the rule template and reinstantiate your rule using the new template (note, the config parameters you used when instantiating a rule from a template can be see at the top in the "Code" tab of the instantiated rule). Or if you just want to be quick about it, edit the script action of the instantiated rule and change the 4.1.0 in the call to verify version numbers to 4.2.0.
  3. install the latest released version either through openhabian-config (if you are running on that) or by running sudo npm install openhab from the $OH_CONF/automation/js folder.

It should work after that.

rliegmann commented 1 year ago

Perfect, thanks for the detailed explanation and support. With the update to openhab-js 4.2.0 everything works again. Thank you again rkoshak

LG Ralf

rkoshak commented 1 year ago

Glad it's working! I'll close this issue. Please come back if anything else breaks or feature requests.