Javascript ECMA 11 -- item.tags not an Array?

In a js ECMA 11 based script in a rule, I have been trying to check, whether the tags of an item, contain a certain String value. For some reason, the item.tags.includes("SomeTag") returns

an ominous error message:
2022-12-03 15:42:30.687 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'motionON' failed: org.graalvm.polyglot.PolyglotException: TypeError: invokeMember (includes) on java.util.Collections$UnmodifiableSet@ee3872 failed due to: Unknown identifier: includes

when checking Array.isArray(p.tags) this returns indeed false when doing the following:

  var motionItem = items.getItem(event.itemName);
  console.log('Motion Item ',motionItem.name);
  var sensor = actions.Semantics.getEquipment(motionItem.rawItem);
  console.log('Equipment',sensor.name);
  sensor.members.forEach(p => {
    console.log(p.name, p.tags, typeof p.tags, Array.isArray(p.tags));
  })

as seen here:

2022-12-03 15:32:54.482 [INFO ] [penhab.automation.script.ui.motionON] - Motion Item OfficeDirk_Motion

2022-12-03 15:32:54.499 [INFO ] [penhab.automation.script.ui.motionON] - Equipment OfficeDirk_Sensor

2022-12-03 15:32:54.525 [INFO ] [penhab.automation.script.ui.motionON] - OfficeDirk_Motion [Point] object false

2022-12-03 15:32:54.541 [INFO ] [penhab.automation.script.ui.motionON] - OfficeDirk_Occupancy [Status, Occupancy] object false

2022-12-03 15:32:54.560 [INFO ] [penhab.automation.script.ui.motionON] - OfficeDirk_Luminance [Measurement, Light] object false

2022-12-03 15:32:54.571 [INFO ] [penhab.automation.script.ui.motionON] - OfficeDirk_LightAutomation [LightAutomation, Point] object false

2022-12-03 15:32:54.580 [INFO ] [penhab.automation.script.ui.motionON] - OfficeDirk_Automation [Automation, Point] object false

2022-12-03 15:32:54.589 [INFO ] [penhab.automation.script.ui.motionON] - OfficeDirk_Presence [Status, Presence] object false

However, I can iterate through p.tags.forEach({ do something })..... I’m really puzzled.

The giveaway here is that you you have to use motionItem.rawItem in the Semantics call. The Semantics in the helper library is a direct import of the OH semantics java class, which is why its methods require the rawItem (the java version of the item object). This also means that it returns the java object versions of values so, in your case, sensor and everything derived from it are java objects until you specifically convert them back into js.

In this case, the helper library provides what you need in the utils object: javaSetToJsArray.

So to use the js array inlcudes method you would need:

utils.javaSetToJsArray(item.tags).includes("SomeTag")

@JustinG - thanks for that – so insightful as always!

This:

is something that I found in a different thread and it worked for me, but I didn’t fully understand what it does; two questions here:

  1. I have read, that using with getEquipment with the rawItem was not how it is supposed to be and an issue had been filed. Is there any update on that?

  2. Is there a helper function similar to javaSetToJsArray which allows to transform the entire java object (my is sensor) into a regular openhab item?

many Thanks

  1. I know the ultimate goal for the JSScripting library handle all of the java → js conversions behind the scenes to avoid exactly this kind of confusion. It’s a herculean effort and I don’t know it’s current status, one of the library maintainers would have to comment on that.

  2. There’s no specific function that I’m aware of, but you can just use the name from the java type item in the usual getItems method which does return the js item object:

items.getItem(sensor.name)

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.