I’m in the slow process of migrating my rules from file based to UI, mostly when I’ve got something to add to an existing rule.
I’ve got a file based JS rule which is triggered by a ChannelEventTrigger (being a “short press” on a Shelly BLU Button). In it, I can access the channel ID by String(event.channelUID). But that doesn’t seem to work in the UI. The documentation also doesn’t mention it.
If I run console.log(event.channelUID), the output is undefined.
If I run console.log(event), the output is shelly:shellyblubutton:38398f8bd741:status#button triggered SHORT_PRESSED.
If I run console.log(typeof event), the output is object.
This means that the properties are going to more closely map to the Rules DSL Implicit variables. Textual Rules | openHAB
rules/rules.js - openHAB JS is the source code in openhab-js that converts the Java event Object to a JS event Object. This doesn’t get run for UI rules (there’s no way we’ve found yet to intercept the event and replace it like can be done for file based rules). But you can see the code that extracts the data from the Java Object there so you’ll know what to reference in your UI rules..
So you can see that the JS event Object’s channelUID comes from event.getChannel().toString() and the actual event comes from event.getEvent(). But you should be able to just use event.channel and event.event. I know for sure event.event works at least.
There is a utility to dump all the members of an Object in openhab-js: utils.dumpObject()
For this reason I have written a small code. Add this to see all key/value pairs, and, if the key is the name of a function, the result of this function:
Object.keys(this.event).forEach(k => {
if (k != "equals") {
var v = this.event[k];
console.log("event." + k + (typeof v === "function" ? "() = " + v() : " = " + v));
}
});
Keep in mind that you are looking at a Java Object from JS. event.event is private in the Java class so the only way to access it is through event.getEvent() in Java. JS doesn’t recognize the concept of “private” as Java implements it so in JS you can get the event.event property without going through the getter function.
These sorts of differences between Java and JS is why openhab-js goes to such lengths to present everything to you as a JS Object instead of a Java Object. There are differences between these, often subtle differences, which can trip you up. Unfortunately, in managed rules the event Object is just about the only part that isn’t converted/wrapped as JS.
Which way is best? Both are acceptable. event.event of more JS like and event.getEvent() is more Java like but in this context they are both the same in terms of “goodness”.
event.event is already a String, there is no need to convert it to a String.
Accessing event using this is how you would do it in Nashorn JS. In GraalVM JS there is no need to use this. It only serves to make your code longer without adding anything.
I always use event.event. It’s shorter, clear(ish) and it’s already a String so there’s no need to convert it or call toString().
True, if you need to test if event exists, you need to use this. But it’s unnecessary everywhere else.
Testing against the event type is a powerful way to make flexible rules. For example, in my rule templates I use that so that when the rule is triggered manually it runs internal tests to ensure everything is configured correctly. For my MQTT EventBus rule template, I was able to combine the subscribe and publish functions into one rule by seeing how the rule was triggered (if triggered by a Channel event I know it’s a received message, when triggered by an Item I know it’s a message to publish).
But there are cases where event won’t exist (though it’s not super consistent, an issue was recently opened on that) so if you are using the event Object, and your rule has multiple ways to be triggered it’s important to test that it exists before trying to use it.
Most of the time, it’s an error case if the rule is triggered in a way that the event Object doesn’t exist so it’s OK to let it just thorw that exception.
According to the code, it only dumps the members and functions for JS Objects.
If it’s a Java Object it only tells you the name of the class. You can look that class up in the JavaDocs though and see all that it can do or look at the source code itself. Overview (openHAB Core 5.1.0-SNAPSHOT API)