JS Scripting call another script with parameters

Hi!
I am working on a script for updating a Sonoff NSPanel display. Because the display will collect data form many various sources I don’t want to write a trigger for every value update. Instead I want to update the display on a “page change” event and periodically (every 30s or something). But the code that I need to execute is slightly different based on the trigger. So I wanted to do this with a rule that would pass some parameters to a “shared” script and that script would then do the refreshing.

So for example on a “page change event” I have this rule set up:

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: Zgoraj_Kuhinja_Nspanel_Event
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript;version=ECMAScript-2021
      script: 'osgi.getService("org.openhab.core.automation.RuleManager").runNow("e6235ca7c3",
        true, {"trigger_type": "event"});'
    type: script.ScriptAction

So the call executes my “refresh script” just fine. But I am not sure how to access the parameters that I passed in to the rule manager. Is it possible to access the “trigger_type” inside my script that gets called?

Consider if this is the best approach. Why can’t you just have the one rule with both triggers? When the rule is triggered based on cron the event Object will be undefined. So if all you are doing here is trying to tell the difference between the two triggers, it’s not necessary.

if(event === undefined) {
    // cron or manually triggered
}
else {
    // Item or Channel event triggered
}

It is almost always better to use a module rather than calling another rule to share code between rules. Not only can you pass arguments but you can get a return value as well. Modules are easier to share with other users and among your other rules also. I talk a little bit about creating modules at Some JS Scripting UI Rules Examples, though you can probably just put the .js file in a folder under node_modules.

There are some use cases where having a rule call a rule is a good choice but I’m not certain this is one of them. But for completeness, assuming that the called rule is also ECMAScript 2021 there will just be a trigger_type variable available in the called rule.

Hmm. Something fishy is going on here… So I changed my rule to this:

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: Zgoraj_Kuhinja_Nspanel_Event
    type: core.ItemStateUpdateTrigger
  - id: "3"
    description: 0/30 0 0 ? * * *
    configuration:
      cronExpression: 0/30 * * * * ? *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript;version=ECMAScript-2021
      script: >-
        if(event === undefined) {
          // cron or manually triggered
          console.log("CRON OR MAUAL");
        } else {
          // Item or Channel event triggered
          console.log("ITEM CHANGED");
        }

    type: script.ScriptAction

Well the item changed event works correctly. I get the “ITEM CHANGED” text in the log. However for the cron I get this:

2022-01-24 17:47:31.317 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'a644a7b4b6' failed: org.graalvm.polyglot.PolyglotException: ReferenceError: "event" is not defined

Also… I tried getting the trigger_type in my other script and that one seemed to be undefined as well.

Is there some kind of a reference available somewhere that states which variables are available in the scripts?

That’s right, that’s Nashorn. In JS Scripting use

if(typeof event === 'undefined') {
    // cron or manually triggered

I’d have to see the code that made the call and the code that is called. I just tested it again and it works as described.

var RuleManager = osgi.getService("org.openhab.core.automation.RuleManager");
var map = { 'test_data': 'Passed data to called rule' };
RuleManager.runNow('tocall2', true, map);

Note there is an open PR to add runRule to the rules namespace in openhab-js.

And tocall2

console.log(test_data);

Which results in the following in the logs:

2022-01-24 10:14:05.777 [INFO ] [org.openhab.automation.script       ] - Passed data to called rule

Awesome. Both of these options work nicely.
For the second one I never even imagined that I could just access those properties as is.

That might change in the future so be careful.