[SOLVED] ECMA rule: How to check values in getTags()

  • Platform information:
    • Hardware: RaspberriPi3
    • OS: openHabian
    • openHAB version: 3.0.0

Hi,
I have recently started playing around with openHAB and rules using javascript and I am having so much fun but I seem to be hitting wall after wall.

Currently, I am trying to check the tags of the item that triggered the rule. The main problem I have is that I can see all the values when I log the itemTags, but I am unable to get a meaningful result when trying to see if it contains a certain value. Based on the suggestions the editor shows, it seems I would want to use either itemTags.includes(“Light”) or itemTags.indexOf(“Light”) >= 0 but neither seem to be working.

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

var item = itemRegistry.getItem("EnchufeEstanteria_Switch");
var itemTags = item.getTags();

logger.info(itemTags);
logger.info(itemTags.length);
logger.info(itemTags[1]);
logger.info(itemTags.includes("Light"));
logger.info(itemTags.indexOf("Light"));

In the log, I see an error when trying to use includes, and the same when trying to use findIndex

2021-02-17 22:48:06.133 [INFO ] [penhab.rule.enviar_alerta.fc3074bd8d] - [Switch, Light]
2021-02-17 22:48:06.148 [INFO ] [penhab.rule.enviar_alerta.fc3074bd8d] - 2
2021-02-17 22:48:06.164 [INFO ] [penhab.rule.enviar_alerta.fc3074bd8d] - undefined
2021-02-17 22:48:06.175 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'fc3074bd8d' failed: TypeError: itemTags.includes is not a function in <eval> at line number 9

I am familiar with C# but not with Javascript, so I keep thinking this is OK and the log keeps saying its not. This seems such a silly problem that it is driving me a bit crazy! I have tried checking the forum, but I cannot see any use of item.getTags() I can use for reference.

Thanks!

Unfortunately you are likely to run into many of these; the problem is with Java objects which look quite a lot like a JS object, but are not.

When I’m looking at what I need to call on an object, I try to figure out what the (Java) object is. In this case the item definition shows that the object you have is a (Java) Set<String>, so you probably want the contains method, rather than ‘includes’ (assuming that the Java Set has not been converted to a real JS Set).

As you’ve discovered, printing things out can be pretty unhelpful here, mostly because of the rough edges in the Java/JS object conversions. I’m afraid that I don’t have any better approach than looking up the Java definitions. For all the JS code I write, I’ve wrapped all the openhab objects in JS versions so that I don’t have to worry about it any longer. You’re welcome to take inspiration from my code, although beware that it’s ES2020 rather than ES5.

1 Like

How did you get ES2020 working with OH3? Babel?

Hi jpg0,

Thanks for the feedback! I was trying to find out where the definitons/API documentation was so I could figure out based on the return type what I needed, but I could not find it. So having that link will help quite a lot in the future!

When I tried to get the type of the object itself, it did point to it being a Set. I did think of using the contains (C# bleeding over) but the whole suggestions thing that pops up when trying to type made me think that includes was the equivalent here. It seems I will need to be querying for types every time I start using a feature/method I am unfamiliar with. I will take a look at that JS wrapping as it sounds quite interesting, although I am just starting openHAB and doing some scripting in it, so I am unfamiliar with where everything would go.

Btw, just for reference if anyone ends up having also some issue with types, the best way to get the type printed out is using the object.prototype as typeof might just say object. And from there, well, checking the corresponding API documentation is the way to go.

logger.info(typeof(itemTags));
logger.info(Object.prototype.toString.call(itemTags));
logger.info(itemTags.contains("Light")) //Code would need a null check
logger.info(item.hasTag("Light"))

Which prints

2021-02-18 09:25:29.395 [INFO ] [openhab.rule.enviar_alerta.fc3074bd8d] - object
2021-02-18 09:25:29.540 [INFO ] [openhab.rule.enviar_alerta.fc3074bd8d] - [object java.util.Collections$UnmodifiableSet]
2021-02-18 09:25:29.550 [INFO ] [openhab.rule.enviar_alerta.fc3074bd8d] - true
2021-02-18 09:25:29.564 [INFO ] [openhab.rule.enviar_alerta.fc3074bd8d] - true

The API Explorer under Developer Tools is supposed to be used for documentation & testing.

1 Like