Converting DSL rule to GraalJS script

This is my first attempt to convert one of my DSL rules to the new JS engine.
Rules DSL:

gLampen.members.filter(g | (g.getStateAs(OnOffType)) == ON).forEach[g | g.sendCommand(OFF)]

JS:

var OnOffType = Java.type("org.openhab.core.library.types.OnOffType");
items.getItem("gLampen").members.filter(i => i.getStateAs(OnOffType) == ON).forEach(function(i) {i.sendCommand("OFF");});

I already tried various approaches:

  • OnOffType.class instead of OnOffType
  • i.state.as instead of getStateAs

No matter what I try I always get the following errors:

[WARN ] [.internal.OpenhabGraalJSScriptEngine] - Failed to retrieve script script dependency listener from engine bindings. Script dependency tracking will be disabled.

and either
"OnOffType" is not defined
or
i.state.as is not a function.

I can’t help you with the JS script side (which I know was your ask…). But if you want to use the JRuby library instead, what I think that code is trying to do is turn off any members of gLampen that are currently ON is that correct?

The JRuby with helper library would be:
gLampen.ensure.off

That warning is something you can ignore for now. I get it too and it has something to do with the loading of the helper library as far as I can tell. All it’s telling us is that it’s not going to be able to monitor the library and load a new version should a new version appear. This is unlikely to happen for most users so it can be ignored.

Here it’s going to be important to pay special attention to the docs for the add-on. The library does a very good job of converting everything to native JavaScript Objects and types instead of exposing the Java classes that openHAB uses.

So looking at the docs we see that .members returns a JavaScript Array, not a java.util.Collections. The members of that Array are a JavaScript Item which has a somewhat different set of methods than you might be used to. See JavaScript Scripting - Automation | openHAB.

Unfortunately you will find that getStateAs() isn’t defined. This is indeed a significant omission so I’d request that you file an issue on the openhab-js repo: GitHub - openhab/openhab-js: openHAB Javascript Library.

It really should be there.

In the mean time, I think we can still get at the Java Item Object. Looking at the code it looks like the following should work:

items.getItem("gLampen").members
                        .filter(i => i.rawItem.getStateAs(OnOffType) == OnOffType.ON)
                        .forEach( i => i.sendCommand("OFF"));

However, is there a technical reason you wouldn’t want to send OFF commands to lights that are already OFF? If that doesn’t cause problems it might be as simple as

items.getItem("gLampen").sendCommand("OFF");
1 Like

Firt of all let me say that I honestly appreciate your help and that without your help I would not have developed such an enthusiasm about openHAB. If I can buy you a beer, please let me know…

done

Wow.Kudos to you. Would have never accomplished this on my own.
But be sure that the time you spent is a good invest as I am 100% willing to learn and pass on as much as I can to others.

Yes.

  • My device is “reacting” on OFF commands although being in an OFF state
  • If in the future there are 30 devices being controlled, the script takes too much time
  • From a development perspective I think it is better style

Just to mention out of completeness: there is also an interesting new command available:

.sendCommandIfDifferent()

I figured that out by looking at the code for the library. I’ve taken a note to add a comment to the docs that when you need to do something that the library doesn’t support we have access to the raw Java Item Object.

Must be a super duper slow machine. But note that it’s not the script that is processing it, it’s core openHAB. It’s all done on the event bus. Your script will return almost instantly.

I thought there was but couldn’t remember if it was this library or the old Nashorn one.

Anyway, as a reference document, the current docs for the add-on are really quite complete and you can even click through to get to the raw source code. It should be everyone’s first place to look.