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.
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.
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"))