triggeringItem and triggeringItemName don't get propagated to script run by GUI defined rule

  • Platform information:
    • Hardware: Intel/8GBRAM/1TB
    • OS: Windows 11 host, VirtualBox container, Ubuntu 22.04 guest, docker, openhab/openhab:4.2.0.M3
    • Java Runtime Environment: embedded in docker
    • openHAB version: 4.2.0.M3
  • Issue of the topic:

When using GUI to create new rule/script I run into an issue. Implicit variables triggeringItem and triggeringItemName don’t get propagated to DSL script invoked by the rule.
For debugging/replication just one log-line is sufficient:

logInfo("r_000", "Triggering item name:" + triggeringItemName + "; previous state: " + previousState + "; new state: " + newState )

Text based rule works flawlessly, reports all expected data.
Same rule created in GUI, same trigger item, same code (just in “script”) also created by GUI: only previousState and newState are logged correctly, but triggeringItem and also triggeringItemName show “null”.

Running “inline script” shows correct result (for both DSL script with the same line, as well as JSR):

console.log('Trigger: ' + event.itemName);

When the GUI based rule runs both inline script and DSL script, the inline works OK, DSL does not see the triggeringItem.

Hypothesis is that it could be caused by the change in helper libraries (as remembered I also had to do some previousState/historicState when I went to 4.2.xx some time ago based on release notes and log warning). When I have time I will try to install clean stable, but thought to report as I was able to replicate on both mine production instances (both on 4.2.0.M3)

Forgive me if it’s a feature and not a bug :slight_smile:

Rules DSL doesn’t have a helper library. Any interaction you do through Rules DSL uses the raw Java openHAB API. In fact, Rules DSL doesn’t support libraries at all and a helper library isn’t feasible.

I tested it out and it’s working for me on 4.2 M3.

Note, triggeringItem only exists when the rule is triggered by a “member of group” type trigger and triggeringItemName exists for regular Item changed, commanded, or updated triggered rules. Be sure to log out both so you can verify you are in fact not getting the variable or if you are just looking for the wrong one.

2024-06-14 08:45:15.475 [INFO ] [org.openhab.core.model.script.test  ] - triggeringItem null triggeringItemName TestSwitch newState ON previousState OFF

That was a change in OH core to support the fact that persistence can now store future values and return QuantityTypes.

Thanks a lot, Rich for the quick and detailed explanation and your time!

I’m not much into Java/libraries so my bad I thought that even DSL is using is somewhere deeper inside and confused it with the change of the core you are referring to. I’m smarter now.

Any hint what could I look into (or debug) as I’m really getting two different results from similar code and getting desperate. I’m sorry if it’s just some omission on my side…

This is log caused by flipping the only triggering item “testswitch2” ON/OFF:

2024-06-14 17:10:53.364 [INFO ] [org.openhab.core.model.script.r_000 ] - Inline script DSL. Triggering item name:testswitch2; triggeringItem:null; previous state: ON; new state: OFF
2024-06-14 17:10:53.595 [INFO ] [org.openhab.core.model.script.r_000 ] - DSL script (not inline). Triggering item name:null; triggeringItem:null; previous state: ON; new state: OFF
2024-06-14 17:10:59.964 [INFO ] [org.openhab.core.model.script.r_000 ] - Inline script DSL. Triggering item name:testswitch2; triggeringItem:null; previous state: OFF; new state: ON
2024-06-14 17:10:59.967 [INFO ] [org.openhab.core.model.script.r_000 ] - DSL script (not inline). Triggering item name:null; triggeringItem:null; previous state: OFF; new state: ON

This is the rule (one item only, no group, so triggeringItem should be null indeed):

(Sorry for screenshots… just in case I have tunnel vision and miss something obvious).

this is the inline script:

logInfo("r_000", "DSL script (not inline). Triggering item name:" + triggeringItemName + "; triggeringItem:" + triggeringItem + "; previous state: " + previousState + "; new state: " + newState )

this is the code for the external script (test9.script):

logInfo("r_000", "Inline script DSL. Triggering item name:" + triggeringItemName + "; triggeringItem:" + triggeringItem + "; previous state: " + previousState + "; new state: " + newState )

and

image

You should click on the code tab and post the YAML you find there. That shows the full definition of the rule in all it’s details. For example…

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: TestSwitch
    type: core.ItemStateChangeTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: logInfo('test', "triggeringItem " + triggeringItem + "
        triggeringItemName " + triggeringItemName + " newState " + newState + "
        previousState " + previousState)
    type: script.ScriptAction

I’m pretty sure that the run scenes, scripts & rules action is a trigger by itself, so when the code is executed, the trigger is indeed not the triggering item any longer.

That is true, I missed that detail about what is going on here.

If the log statement in the called rule is the one we are talking about, I would expect all the implicit variables to be null.

Thank you both! Learned few new good things today.

So it is a feature indeed :laughing:

I understand the only option (workaround) is either to use text-based rules or inline DSL script (which is the way I will take on the “GUI” driven instance.

Seems that the “run scenes” indeed nulls the trigerringItemName, but keeps previousState and newState. That was the confusing component.

I think that part would be considered a bug actually. I know that JS Scripting had to do some special work to make sure that that stuff didn’t hang around from one run of the rule to the next (e.g. if the rule was triggered by a Time trigger you don’t want event.itemState to have a value).

In ideal world there would be an option to decide weather to “propagate” the original trigger. There is already “Consider Contitions” checkbox. If not set perhaps the triggeringItemName could somehow point to the rule/script that was the immediate trigger.

Should I try to log it as bug/feature request? What is the proper way?

There already is that option really. Rules already support having arguments passed from calling rule to the called rule. You have to use a script to do that though, not just basic UI actions.

It’s just that Rules DSL does not support receiving arguments like that. And if the maintainers have not added support to Rules DSL for features that already exist, they are unlikely to add some new feature along the same lines.Rules DSL is really hard to change and there’s are not many maintainers with the knowledge and skill able to do it.

The fact of the matter is Rules DSL is way behind the other languages and shows no signs of catching up. And even if it were keeping up, Rules DSL is interior to Blockly for those who don’t already know programming in almost every conceivable way.

I do not recommend any OH user to do any new development in Rules DSL. User Blockly, JS Scripting, or jRuby instead.

All that is a long way to say you can open an issue but the issue should be to add support to Rules DSL to accept and make usable variables pass to the rule when called from another rule in the normal way, not to add a new flag to pass through a few implicit variables. Check whether there already is one open though. I wouldn’t hold my breath though.

Thanks a lot, I understand. I have started quite many years ago on my primary instance, hence file based, DSL and “old” sitemaps. The new I am building/playing with (different site) is more GUI based, but as I never properly learned “modern” languages (Basic → Turbo Pascal → … → basics of Python), I was kind of ok with DSL. I understand now I will probably need to do some JS Script learning. While Blockly seems nice I think some of the more complex rules could be tricky (and I’m still used to “old school” comments and logging [as I tend to make many mistakes]). Thanks once more!

Note that Blockly compiles to JS Scripting. It’s a great tool for learning. You can build up the blocks and then look at the JS Scripting code that gets generated.

For example:

which is a little bit of code to synchronize the state of members of a Group converts to this when you click on the “show generated code” tab.

var i_list = items.getItem('AllLights').members;
for (var i_index in i_list) {
  i = i_list[i_index];
  if (items.getItem(i).state != event.itemState?.toString()) {
    i.postUpdate(event.itemState?.toString());
  }
}

Comments and logging are of course also supported.

// This is a Blockly Comment
var i_list = items.getItem('AllLights').members;
for (var i_index in i_list) {
  i = i_list[i_index];
  if (items.getItem(i).state != event.itemState?.toString()) {
    i.postUpdate(event.itemState?.toString());
  }
}