OH 3.2 JavaScript file-based rule can't access triggering event

I just installed OH 3.2 in a Debian 11 VM and installed the new JSScripting binding. I’ve created a file called testrule1.js in /etc/openhab/automation/js/ with the following contents:

'use strict';

// scriptExtension.importPreset("RuleSupport");

rules.JSRule({
  name: "Change house mode",
  description: "Change house mode",
  triggers: [triggers.ItemStateChangeTrigger('HouseMode')],
  execute: data => {
      var logger = log(this.ruleUID);
      var triggeringItemName = events.itemName;
      logger.info("House mode changed to {}!", triggeringItemName);
  }
});

The item HouseMode is a string and I’m changing it via the BasicUI between ‘DAY’ and ‘NIGHT’. I’d like to learn how to use the JS equivalent of triggeringItem since I’m planning to convert all my Jython rules to JS rules and some of those rules are triggered by group and need to know which item in the group triggered the rule.

The output in openhab.log for the above rule when item HouseMode is changed is:

2021-12-22 18:25:40.527 [DEBUG] [org.openhab.automation.script.rules ] - Extracted event payload [object Object]
2021-12-22 18:25:40.534 [ERROR] [org.openhab.automation.script.rules ] - Failed to execute rule Change-house-mode-38c11b40-e9c6-40d3-bb24-f5d0953b5e73: Refer
enceError: "events" is not defined: ReferenceError: "events" is not defined
        at execute (testrule1.js:11)
        at doExecute (webpack://openhab/./node_modules/openhab/rules/rules.js?:110)
2021-12-22 18:25:40.536 [ERROR] [e.automation.internal.RuleEngineImpl] - Failed to execute rule 'Change-house-mode-38c11b40-e9c6-40d3-bb24-f5d0953b5e73': Fai
l to execute action: 1

I’ve tried ‘event’ instead of ‘events’. I’ve also tried ‘input.event’ and the old ‘triggeringItem’ but always get an error.

I did a lot of searching and saw the following code in the documentation:

'use strict';

scriptExtension.importPreset("RuleSupport");
scriptExtension.importPreset("RuleSimple");

However, when I add that at the top of the file and save I see this in the log:

2021-12-22 18:28:31.199 [INFO ] [rulesupport.loader.ScriptFileWatcher] - Loading script '/etc/openhab/automation/js/testrule1.js'
2021-12-22 18:28:31.343 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:
org.graalvm.polyglot.PolyglotException: ReferenceError: "scriptExtension" is not defined
        at <js>.:program(testrule1.js:3) ~[?:?]
        at org.graalvm.polyglot.Context.eval(Context.java:379) ~[?:?]
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:458) ~[?:?]
        at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:400) ~[?:?]
        at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:249) ~[java.scripting:?]
        at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocable.eval(DelegatingScriptEngineWithInvocable.java:56) ~[?
:?]
        at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocable.eval(InvocationInterceptingScriptEngineWi
thInvocable.java:79) ~[?:?]
        at org.openhab.automation.jsscripting.internal.scriptengine.DelegatingScriptEngineWithInvocable.eval(DelegatingScriptEngineWithInvocable.java:56) ~[?
:?]
        at org.openhab.automation.jsscripting.internal.scriptengine.InvocationInterceptingScriptEngineWithInvocable.eval(InvocationInterceptingScriptEngineWi
thInvocable.java:79) ~[?:?]
        at org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.loadScript(ScriptEngineManagerImpl.java:177) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.ScriptFileWatcher.createAndLoad(ScriptFileWatcher.java:231) ~[?:?]
        at org.openhab.automation.jsscripting.internal.fs.watch.JSScriptFileWatcher.createAndLoad(JSScriptFileWatcher.java:57) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.ScriptFileWatcher.importFile(ScriptFileWatcher.java:211) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.ScriptFileWatcher.lambda$2(ScriptFileWatcher.java:203) ~[?:?]
        at java.util.Optional.ifPresent(Optional.java:183) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.ScriptFileWatcher.importFileWhenReady(ScriptFileWatcher.java:201) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.ScriptFileWatcher.processWatchEvent(ScriptFileWatcher.java:178) ~[?:?]
        at org.openhab.core.service.WatchQueueReader.lambda$3(WatchQueueReader.java:323) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:829) [?:?]
2021-12-22 18:28:31.345 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab/automation/js/testrule1.js': or
g.graalvm.polyglot.PolyglotException: ReferenceError: "scriptExtension" is not defined

Could someone post the entire contents of a simple JS rule file please? In all the threads I’ve seen in my searching only the parts of the rule that people are working on are quoted and I’ve not seen an entire rule file yet. At least, I don’t think I have! :slight_smile:

JS Sripting is not JSR223 so it works significantly differently.

I’ve not done JS Scripting rules in .js files but I believe that data is the equivalent of event that gets passed to a Script in a UI Rule. Based on that assumption, the equivalent to triggeringItemName from Rules DSL will be data.itemName. There is no equivalent to triggeringItem so if you need the item itself for some reason you can use items.getItem(data.itemName).

To send the command you’ll use items.getItem(data.itemName).sendCommand('foo');

The documentation you need to look at is JavaScript Scripting - Automation | openHAB because, as I said, JS Scripting is not JSR223 and does not follow those conventions.

If for some reason you want it to work the same way though, for example you have a Nashorn JS rule that you want to make minimal changes to, add

Object.assign(this, require('@runtime'));

To the top of your rule file.That will import all the JSR223 default presets. But the JSR223 presets and JS Scripting Helper Library that comes with the add-on are not compatible.

That’s because most of the stuff being posted are for Script Actions and Script Conditions in UI created rules.

Thank you for the valuable info! :slight_smile: Changing the rule to:

rules.JSRule({
  name: "Change house mode",
  description: "Change house mode",
  triggers: [triggers.ItemStateChangeTrigger('HouseMode')],
  execute: data => {
      var logger = log(this.ruleUID);
      var triggeringItemName = data.itemName;
      logger.info("House mode changed to {}!", triggeringItemName);
  }
});

Produced the following in the log when I change the value of item HouseMode:

2021-12-22 20:58:18.794 [DEBUG] [org.openhab.automation.script.rules ] - Extracted event payload [object Object]
2021-12-22 20:58:18.806 [INFO ] [.openhab.automation.script.<unknown>] - House mode changed to HouseMode!

That makes sense. I like to use Visual Studio Code when I’m writing rules since that’s what I’m used to using. I’ll look into using the UI too.