File-based JS rule cannot import because missing reference to "rules"

  • Platform information:
    • OS: OpenHABian 3.4.2 release
    • Java Runtime Environment:Zulu11.62+17-CA (build 11.0.18+10-LTS)

I’m trying to replace my existing UI-based javascript (ECMAScript-2021) rules into file-based rules, in order to make the project easier to maintain and update. I created a sample rule file called tst.js, and uploaded it to /etc/openhab/automation/js, as per the documentation for file-based javascript rules (JavaScript Scripting - Automation | openHAB).

Sample file:


rules.JSRule({
  id: "r_TEST_1",
  name: "FILE TEST 1",
  description: "This is a test.",
  triggers: [triggers.ItemStateUpdateTrigger('tst_item')],
  execute: (event) => {
    var tst = "hello world";
  }
});

The rule does not show up in the list of rules on the web GUI, and when I check the openhab.log file from /var/log/openhab, I see the following error saying that “rules is not defined”:

[ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab/automation/js/tst.js': org.graalvm.polyglot.PolyglotException: ReferenceError: "rules" is not defined

I looked at the documentation linked above, and do not see anything about needing to include any additional include directives or java imports. I have the javascript add-on installed, and all my javascript ECMAScript rules made in the web GUI are working.

I also tried putting the file in /etc/openhab/automation/jsr223 (I’m not clear on the difference between js and jsr223). If I do that, I get the following error saying that it expects a comma instead of the function injection:

[ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab/automation/jsr223/tst.js': /etc/openhab/automation/jsr223/tst.js:7:19 Expected comma but found =>
  execute: (event) => {
                   ^ in /etc/openhab/automation/jsr223/tst.js at line number 7 at column number 19
2023-10-23 14:39:28.346 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error during evaluation of script 'file:/etc/openhab/automation/jsr223/tst.js': /etc/openhab/automation/jsr223/tst.js:7:19 Expected comma but found =>

What am I missing here? Does this file belong in automation/js or in automation/jsr223? Thanks in advance for any help.

Oh, and a tangential question: If I wanted to include multiple trigger conditions, how would I delimit them? Are they separated by commas, or by an “or” keyword, or something else? I’m guessing from the rule builder documentation that I would use “or” to delimit multiple triggers, but I’m not sure. Thanks again.

Remove the second line with key 'id: “r_Test_1” '.

Triggers are an array. So you can use multiple triggers and separating with commas. You must place the file in automation/js.

Remove the second line with key 'id: “r_Test_1” '.

Well, that did indeed work. Thanks for the quick reply! I played around a bit after testing your suggestion and found that the id does work if it is included after the execute field. I didn’t realize the order of the fields would matter. I don’t use javascript very often outside of OpenHAB, and I thought the rule definition looked more like a json object (in which the order wouldn’t matter). But looking further down the documentation, I see

Rule are completed by calling .build(name, description, tags, id) , all parameters are optional and reasonable defaults will be used if omitted.

So I guess these are function arguments (in which the order does matter)?

You can see the actual code here. It is indeed a JSON Object and order shouldn’t matter. I cannot explain why it didn’t work before or why changing the order fixed it.

Note that there are two different ways to create rules in files for JS Scripting: JSRule or the rule builder. That section of the docs covers the rule builder. A rule created using the builder would look something like:

rules.when().item('tst_item').receivedUpdate().then( event => (event) {
  var tst = "hello world";
}).build("File Test 1", "This is a test", [], "r_TEST_1");

Another thing that I’m not seeing in the documentation is how to implement the equivalent of the “but only if” triggers that are available when creating rules through the GUI. Is this possible with the file-based javascript rules? I don’t think it’s a huge deal. I can always check any extra conditions in the actual script code. But if I can do a “but only if” condition on the rule, I would prefer to do that, so as to avoid any extra overhead associated with having to actually execute the rule.

There really is no universal equivalent. Rule Conditions are primarily a UI Rule concept. See Rules | openHAB

However, the JS Scripting rule builder has limited support for rule conditions. JavaScript Scripting - Automation | openHAB

JSRule has no support for rule conditions. You have to do that part in the execute section.