Distinguishing between different time-based triggers in a script within one rule

How can I distinguish in a Blockly / ECMAScript, which time-based condition triggered the script?

I know that with contextual info, I can get, e.g., an item name that triggered the script. But I cannot see any such equivalent to distinguish between non-item-based trigger events, in my case multiple time-based triggers.

My situation is as follows, I want to:

  • use a cron expression (e.g. once a minute) to trigger my script to update sun position to see whether a shutter being controlled by the script should be closed or open.
  • use a fixed time of the day in the evening to switch mode of the script to a SLEEP mode when the sun’s position is no longer calculated and the shutter is closed.
  • use a fixed time of the day in the morning to switch mode of the script to a WAKEUP mode when the sun’s position is no longer calculated and the shutter is opened.

But in my script, I can separate the time-based triggers from an item-based trigger (i.e. when I use the shutter control, to set the script in MANUAL mode, which overrides any of the autonomous functions), but how do I distinguish between these various time-based triggers so that the appropriate behavior is achieved?

I could think of some work arounds like:

  • Setting the SLEEP and WAKEUP times as constants within the script so that there is only the cron trigger and the SLEEP/WAKEUP are determined in the script itself. CON: I don’t like that the times would be buried inside a script instead of being easily settable.
  • Use three rules with the same script and use the rule_UID to see which one of the triggers it is. CON: It will create a lot of additional mess and reduce maintainability.

So a method of being able to distinguish different time-based triggers within one rule is still highly preferrable over those. Thank you very much in advance for your replies.

openHAB version: 3.3.0

For now, I think the only way is to check what time it is right now compared to what you know are the times the rule could be triggered.

For now when a rule is triggered manually, based on a system event, or based on a time event, there is no event object at all. So you can test to see if this.event === undefined and know that the rule wasn’t triggered by a Thing or Item event but beyond that you are on your own.

There was some talk about making sure there is always an event with what triggered the rule but it will be OH 4.0 at the earliest that it would become available, if at all. And even then, I think all you’d get is that it was a time based trigger, not which time based trigger it was.

The astro binding updates the sun position channel once per minute anyway. So just link the Azimuth or Elevation Channel to an Item and trigger the rule with changes to that.

Use a different rule that disables the first rule at the given time and another to enable it at the time it should start again. Though if your time is after the sun has gone down, Azimuth and Elevation will remain unchanged until the sun starts to rise again so you might get that for free.

see above

Check to see if now is a few milliseconds after one of the times the rule is triggered at and assume it was triggered based on that time event. You can distinguish between Item events and other triggering events by testing to see if event exists or not.

But, if you link an Item to the appropriate Astro Channel, you can just check to see which Item triggered the rule and you’ll know whether it’s based on a new sun position or some positive action you’ve taken. Simple as can be.

So set them in a DateTime Item

Ultimately that’s an XY problem. Even better is to trigger it based on Items. Then it’s no big deal to figure out the different ways it can be triggered, just check for event.itemName.

You can call a script (and pass some parameters) from a rule.

For each trigger you can have separated rules, all calling the same script with different parameters