ECMA Script 2021 rules - which trigger triggered a rule?

Hello,
I’m aware that event.itemName gets me access to an item which has triggered a rule through update or command.

Is there a way, to achieve something similar for cron-triggered rules?

In the following rule snippet:

configuration: {}
triggers:
  - id: "1"
    configuration:
      cronExpression: 0/10 * * * * ? *
    type: timer.GenericCronTrigger
  - id: "2"
    configuration:
      cronExpression: 5/10 * * * * ? *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - inputs: {}
    id: "3"
    configuration:
      type: application/javascript;version=ECMAScript-2021
      script: |-
        console.log("Id of trigger",triggers.id)
    type: script.ScriptAction

I’m wondering whether it’s possible to determine, which of the two cron expresions (or more generally, which triggers.id) has triggered the rule. (Of course triggers.id doesn’t work, otherwise, I wouldn’t have asked :wink: )

Since you’re using ECMA-2021 the event object is handled by the openhab-js library:

To my knowledge, but that might have changed since my last update, cron does not give you an event.itemName type of trigger.
But you can use the following in your code:

this.event === undefined in combination with this.event = undefined

The code will then trigger if the event is undefined (which for cron is the case) and reset after the code did run to undefined.

I use this methodology based on this previous discussion.

Above will only help though with one cron trigger, not be able to decide which of the two triggered.
You could do that though maybe with a if clause that looks into the timestamp?

If there is an easier way, I am all ears though :slight_smile:

The short answer is no. If you have two time based triggers, there is no way to distinguish which one triggered the rule. You also cannot tell the difference between a time based trigger and a manual trigger.

You can tell the difference between an Item/Channel/Thing trigger by testing for what variables are defined on event like @chrismast mentions.

That’s actually not the case in UI rules and it’s a source of consternation. I’m not sure what to do about that yet. But in the UI, you get the raw event, same as you’d get in the JSR223 type rules (Nashorn, Jython, etc.). I don’t like it when it works that differently.

I was (re)looking into this thread and was wondering whether there is now a way of identifying, which trigger, triggered the rule …

Use case is a (complex) schedule (realized as a series of cron triggers. Depending on the trigger (e.g. the time of the day), an item (say a HVAC mode should receive a different value).

configuration: {}
triggers:
  - id: "1"
    configuration:
      cronExpression: 0 0 7 ? * MON,TUE,WED,THU,FRI *
    type: timer.GenericCronTrigger
  - id: "2"
    configuration:
      cronExpression: 0 0 17 ? * MON,TUE,WED,THU,FRI *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - inputs: {}
    id: "3"
    configuration:
      itemName: Benchmark_es
      state: "25"
    type: core.ItemStateUpdateAction

How would I configure this rule so that the Benchmark_es is set to say - 20 at 7am - and - 18 at 5pm… Can we get access within the openhab-js environment to the trigger id? so we could do something like:

    id: "3"
    configuration:
      itemName: Benchmark_es
      state: "= (trigger.id == 1 ? '20' : trigger.id == 2 ? '18' : '25')"

No and this isn’t the openhab-js environment. These are simple UI rules and have nothing to do with openhab-js (which is the helper library for the GraalVM JS Scripting rules language and have no access to anything JavaScript.

In the actual openhab-js environment (i.e. a Script Action using JS Scripting) you can tell the difference between a cron tigger and an Item based trigger and even which Item triggered the rule. But you cannot tell the difference between cron triggers, or a cron trigger and a manual trigger.

You have two options:

  • Make two rules.
  • Use a Script Action where you can test to see what time of day it is and apply the correct value.

UI Rules are very simple by design and intent. Anything beyond the simple “when event occurs command/update Item” use cases will require the use of Script Actions.

I understood, and that’s how I understood the situation a year ago, when this thread was started.

Obviously, I can use several rules, which I’m currently doing, but they are horrible to maintain and modify.

I was just wondering whether inside a Script Action, I could not easily refer back to which of the several Cron’s have actually triggered the rules. IMHO, it defies the purpose of the interaction between trigger and (complex) Script Actions, if I have to use server resources and plenty of lines of code (to allow for slight trigger delays) to reproduce exactly the same condition, which has triggered the trigger in the first place … but ok.

In JS Scripting:

if(now.isAfter(time.toZDT('07:00') && now.isBefore('17:00')) {
  ...
}
else {
  ...
}

compared to

if(event.triggerId == 1) {
  ...
}
else if(event.triggerId == 2) {
  ...
}

Exact same number of lines of code.

You don’t need to reproduce the exact trigger conditions. This rule gets triggered exactly twice a day. If it triggers and it’s between 07:00 and 17:00 you know that it was the first trigger. Otherwise you know it was the second trigger. There could be hours between the cron time and the rule running and it will still do the right thing. If you want it to be really tight

if(now.isClose(time.toZDT('07:00'), time.Duration.ofSconds(1))) {
  ...
}
else if(now.isClose(time.toZDT('17:00'), time.Duration.ofSeconds(1))) {
  ...
}

You could go down to the nanoseconds if you wanted to and make it as tight as you want, but there is no need to.

I’m not arguing against adding this information to the event (it’s never going to be available in UI only rules, only Script Actions), but the lack of it really isn’t that big of a deal.