Usage of new ECMA2021 Automation Scripting (GraalVM)

@jpg0 I got it now to run, things I did:

  1. Installed ohj-support Add-on from https://github.com/jpg0/oh-config/files/5745369/org.openhab.automation.ohj-support-3.0.0-SNAPSHOT.jar.zip
  2. A fresh git clone of GitHub - jpg0/ohj: Openhab Javascript Library into “/etc/openhab/automation/lib/javascript/community”
  3. Changed the mentioned function “lookupService” to the fixed one Testing the GraalJS package with OH3 · Issue #2 · jpg0/oh-config · GitHub

After a restart it worked.

What I am wondering is that I do have to use always relative paths for loading the ohj package via require:

const { item, sendIt } = require("../../../lib/javascript/community/ohj/fluent/fluent");
const ohj = require("./../../../lib/javascript/community/ohj");
const LOG = ohj.log("second");
const fluent = ohj.fluent;

with (fluent) {
    when(cron("0/30 * * * * ?")).then(sendOff().toItem("RemoteopenHABServerPROD_ItemSFStudioLichtDecke"));
}

When I am going through your personal git repo you always use “…require(‘ohj’);”.

Why is that not working on my setup?

Also I am wondering if there is something like the “event.itemState” property like it is available in the definition of “classic” oh scripters ECMA5 rules (when using JSRule with ohj)?

Thank you very much for your help!

Why is that not working on my setup?

Hmm, looking at the current implementation, you need to put ohj in personal, not community. The problem is that node cannot use multiple library paths, so I hardcoded it to this. TBH I believe that the right option is to not use ‘lib’ at all and instead to follow the node standard of a relative ‘./node_modules’ folder (hence within the jsr233 folder), but this deviates from openHAB current, and requires some more work.

Also I am wondering if there is something like the “event.itemState” property like it is available in the definition of “classic” oh scripters ECMA5 rules (when using JSRule with ohj)?

Looking at the code, for the fluent API, there is something that is defined for rules that trigger on commands send to items; you can see some of my code here: oh-config/automation/jsr223/javascript/personal/fluoro_lights.js at master · jpg0/oh-config · GitHub

The fluent API was very much to satisfy what I have needed for bulk rules, and even then for more complex rules I’ve switched to the JSRule style rule declaration, so I expect there to be missing features. Saying that, I’m happy to accept PRs if you want to add any features.

1 Like

Thank you very much, now I know how to import services like itemRegistry and events.

But how can I import:

  • types, as I would like to do the HSBType.fromRGB(r, g, b) conversion
  • openHAB core actions, like Exec.executeCommandLine(), HTTP actions and NotificationAction
  • Java classes from openHAB, e.g. org.openhab.core.model.script.actions.Exec — I can import normal Java classes like java.time.Duration, but importing openHAB classes causes errors like:
org.graalvm.polyglot.PolyglotException: TypeError: Access to host class org.openhab.core.model.script.actions.Exec is not allowed or does not exist.
1 Like

@florian-h05

Works in my ECMA2021 scripts

const screx = Java.type("org.openhab.core.model.script.actions.ScriptExecution");
const ohj = require('./../../../lib/javascript/community/node_modules/ohj');
const actions = ohj.actions;
...
actions.Exec.executeCommandLine("/path/to/script.sh");
1 Like

I am facing exactly the same error
i tried with a quite simple rule

//'use strict';

//const LoggerFactory = Java.type('org.slf4j.LoggerFactory');
var logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.openhab.rule." + ctx.ruleUID);

logger.info("Hello world!");
logger.info(JSON.stringify(ctx));

//var Exec = Java.type("org.openhab.core.model.script.actions.Exec");
//const JavaThingBuilder = Java.type('org.openhab.core.thing.binding.builder.ThingBuilder');
var ZonedDateTime = Java.type("java.time.ZonedDateTime");  
var ScriptExecution = Java.type("org.openhab.core.model.script.actions.ScriptExecution");
//  timer = createTimer(now.plusMinutes(3), function() { logger.info("Hello from Timer") })
timer = ScriptExecution.createTimer(ZonedDateTime.now().plusSeconds(10), function() { logger.info("Hello from Timer") });

but as soon as it comes to the Java.type("org.openhab... line i get a error, other types can be imported, also i observed that my ctx.ruleUID is undefinded

23:54:11.323 [INFO ] [openhab.event.RuleUpdatedEvent       ] - Rule '334a42598c' has been updated.
23:54:12.367 [DEBUG] [ript.internal.ScriptEngineManagerImpl] - Added ScriptEngine for language 'application/javascript' with identifier: 402f3e2d-dcb4-4392-987b-893844574a3e
23:54:12.427 [WARN ] [g.internal.OpenhabGraalJSScriptEngine] - Failed to retrieve script script dependency listener from engine bindings. Script dependency tracking will be disabled.
23:54:12.453 [INFO ] [org.openhab.rule.undefined           ] - Hello world!
23:54:12.465 [INFO ] [org.openhab.rule.undefined           ] - {}
23:54:12.487 [ERROR] [ab.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: TypeError: Access to host class org.openhab.core.model.script.actions.ScriptExecution is not allowed or does not exist.
        at <js>.:program(<eval>:13) ~[?:?]
        at org.graalvm.polyglot.Context.eval(Context.java:345) ~[?:?]
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:379) ~[?:?]
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:356) ~[?:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) ~[java.scripting:?]
        at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocable.eval(DelegatingScriptEngineWithInvocable.java:51) ~[?:?]

in the meanwhile i read so many post here, but nothing really helped me.
i reinstaled the jsscript automation i restarted/rebooted but nothing helped
(runinning an openhabian on a RPI)

5 Likes

for what it’s worth, I have the same issue.

There are reports (@opus at openHAB 3.1 Release discussion - #8 by opus) that reboot should help but it did not help on my side.

2 Likes

Did you followed the steps from my post?

I haven’t…

Is that needed even if I don’t use ohj? I am simply trying to use new ecmascript as an “action” in UI rules…

Sorry about hijacking this thread, but how did you manage to run it at all?

I’m running 3.2.0.M1-debian in Docker and getting this:

2021-08-02 21:57:49.315 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/openhab/conf/automation/jsr223/javascript/personal/testRule.js': /openhab/conf/automation/jsr223/javascript/personal/testRule.js:1:0 Expected an operand but found const
const ohj = require("ohj");
^ in /openhab/conf/automation/jsr223/javascript/personal/testRule.js at line number 1 at column number 0

It looks like there is no ES6+ support. What do I need to do to install/activate GraalJS?

A minor update here. After unzipping the ohj-support you also need to take it out of the folder. I got caught with the folder name being the same as the JAR so thought that was it. After taking the actual JAR out of the folder to the root of the add ons directory we are in business. (lockdown has fried my brain).

An additional tip I worked out is that the logger has a hard coded prefix of script.js so for the messages to show in the openhab log you need to update the openhab console with
log:set debug script.js

Happy to write a beginners guide based on my setup from today collecting all the above information

For the record, I filed several issues on jsscripting. The import issue (PolyglotException: TypeError: Access to host class) discussed in this issue here: https://github.com/openhab/openhab-addons/issues/11222

Other issues:

2 Likes

Imports are working now!

With the release of the 3.2.0.M4 Milestone Build the import of classes from org.openhab.core works, as this Issue #11222 was closed by PR #11400.

Please note

The folder openhab-conf/automation/lib/javascript/personal must exist, without that folder the Add-On throws errors.

I have created this Issue #11616 to either mention that in the docs or to create that folder on openHAB start-up/Add-On installation.

Small guide for GraalVM

I have completed a few tests and created a small guide which is hosted at florian-h05/openhab-addons.

Table Of Contents of the Guide

1 Like

Excellent summary! Would be great if you could consider improving the jsscripting addon docs with those.

In the guide you state

Please note that toString() is supported, but toBigDecimal()is not working anymore.

What does this mean exactly? What is the error and is there already a github issue filed?

Thank you, of course I can add those to the jsscripting addon docs.

I thought that the conversion toBigDecimal() is not working anymore (I used to use it when getting item states to make sure they are number and not string), but I checked it again and it is working.

So it does not mean something, I wrote it because I thought it does not work but I just had a typo on my tests.

I have updated my guide to fix my misconception, next I will work on adding it to the addon docs.

1 Like

I have created a PR on GitHub for the docs.

2 Likes

Before going to too much effort on the docs front, be sure to review what’s going on at GraalVM JavaScript replaces Nashorn, breaking Blockly and existing Nashorn rules · Issue #2433 · openhab/openhab-core · GitHub. Work is going on to address several related issues in that one issue:

  • installation of the helper libraries with the add-on which will; potentially change the docs significantly
  • working in the UI without requiring too many imports
  • migration of Nashorn script to GraalVM JS scripts.
3 Likes

Thank you for that hint, my docs were already finished yesterday.

I read that discussion and it clearly seems that the docs have to be rewritten during these issues are addressed and resolved.
I think my docs are a good first version to just show a few basics that are working currently on the 3.2.0.M4 Milestone Release.

1 Like

Hi guys,

I know, it’s little out of this topic, but let me ask. I’m using the DSL rules (1.5 years) from the beginning, but I don’t really like it. I have decided that the next project I will build into my system will be on JS basis. I thought it will be 1hours to get familiar with the new API calls(I already have JS experience), then I can start developing the code.

Unfortunately, I’m spending the 3rd or 4th night to find out what to do, to get the JS stuff even running. I’m fully confused about everything. I’m running on OH 3.1. Do I need to install the “JSScripting” automation add-on? Which JS engine and library to use? I have started with this guide (Installation — openHAB Helper Libraries documentation), but the helloWorld.js example is not working. Then came here to this topic, where you are discussing a new engine with a new (unofficial) library.

It seems to me, that DSL is the “official” scripting and all the others are only hackings, to get it there, but except of some hackers or pioneers nobody is (able) using it. Based on what I see, the JS is something which would get more focus in the later versions, but it needs some time …
Am I right? Or can someone point me to the right direction?

Thanks!

There are two JavaScript Engines. The default one that comes with openHAB is called Nashorn and it implements ECMAScript 5.1.

The add-on is a completely different JavaScript which implements ECMAScript 2021 (I think, at least something way more recent).

The two are pretty different in usage. The two have completely different helper libraries. In general, the two are not compatible with each other. If you have the add-on installed, scripts written for Nashorn will not work.

A few posts up there is a thread where work is going on to rectify that and make GraalVM JS easier to use. But if you don’t want to wait, see @florian-h05’s documentation. If you want to use Nashorn use the link you posted already.

Thanks for the quick reaction Rich. The posts, you created a year ago (OH 3 Examples: Writing and using JavaScript Libraries in MainUI created Rules) is then for Nashorn?