Getting triggerName in execute

I have migrated all rules from DSL to Jython some time ago. At that time it seemed to be a reasonable decision.
Learned Python/Jython from zero. Meanwhile, I like Python.

As it looks right now I have to do another migration, now from Python/Jython to JS.

In this forum, it seems to be clear that Jython 2.7 is a dead-end, and waiting for a GraalVM implementation of Python may be like waiting for Godot.

Books are already ordered to brush up on my JS knowledge.

To make my day this evening and to get some optimism, I would need help with a probably simple problem.
Here a sample code snippet:

var trig = []

trig.push(triggers.GenericCronTrigger("0 0/1 * 1/1 * ? *", "CRON"))
trig.push(triggers.ChannelEventTrigger('homematic:HmIP-SMI55:3014F711A0001F5A4993FA84:0014D709AEF7C0:1#BUTTON', 'SHORT_PRESSED', "OPT1"))
trig.push(triggers.ChannelEventTrigger('homematic:HmIP-SMI55:3014F711A0001F5A4993FA84:0014D709AEF7C0:2#BUTTON', 'SHORT_PRESSED', "OPT2"))

rules.JSRule({
  name: "Test Rule",
  description: "Firste test for migration from Jython to JS",
  triggers: trig,
  execute: data => {
      console.info("triggered log: ", data)
  }
});

The question is how do I get the triggerName inside the execute which is set at the creation of the trigger?

Maybe, but it could be years before you would need to so don’t feel too much pressure to migrate or that you have to migrate everything all at once.

I’m not sure I understand the question. data (which is called event when doing UI rules) is an Object that encapsulates the implicit variables. This is the same Object and does the same thing as it did in Jython. In fact it’s a Java Object so I mean it is literally the same.

There is not and never has been a triggerName that is a part of this Object (as far as I’ve ever known). Do you mean the equivalent to triggeringItemName from Rules DSL? It’s the same as in Jython, data.itemName. However, data will be undefined when the rule is triggered by the cron trigger (or a system trigger or when the rule is triggered manually).

Note that the part between the execute: and => is going to define the name of the Object that has all the implicit variables.

Here a (cut-down-snippet) example in Jython:

triggers = []
triggers.append(ItemStateChangeTrigger("gHMLowBat", "CLOSED", "OPEN", "HMBAT").trigger)
triggers.append(ItemStateChangeTrigger("gIKLowBat", "CLOSED", "OPEN", "IKBAT").trigger)
triggers.append(CronTrigger("0 0 12 1/1 * ? *", "ALL").trigger)

@rule("Low Battery Rule", description="This Rule send an push message and an email if a battery powered device indicated low battery")
class lowBattRule(object):
    def __init__(self):
        self.triggers = triggers


    def checkHMBatteries(self):
......
    def checkIKBatteries(self):
......
    def checkIKBatteries(self):
......

    def execute(self, module, inputs):
        act = str(inputs["module"]).split("_")[0] if len(inputs) > 0 else "ALL"

        if act == "HMBAT":
            log.info("*** Low Battery Rule) *** checkHMBatteries")
            self.checkHMBatteries()
        elif act == "IKBAT":
            log.info("*** iLow Battery Rule) *** chevIKBatteries")
            self.checkIKBatteries()
        elif act == "ALL":
            log.info("*** iLow Battery Rule) *** ALL")
            self.checkHMBatteries()
            self.checkIKBatteries()

The “inputs” contains info about the trigger name

Sure, not all at once. Anyway, it’s a challenge and that is all that counts.

OK. So we know that both Jython and JS Scripting have an “execute” function.

You’ve defined the one in Jython to accept two arguments (not counting self).

Have you tried doing the same for the JS Scripting version?

Ultimately, when the rule is triggered, it’s OH itself which calls that execute function to run the rule. It should be the same now matter what language.

I have to do some reading though but as it looks, this is not possible without changing the core code.

Here in the rules.js the doExecute function:

    let doExecute = function (module, input) {
        try {
            return ruleConfig.execute(getTriggeredData(input));
        } catch (error) {
            log.error(`Failed to execute rule ${ruid}: ${error}: ${error.stack}`);
            throw error;
        }
    };

and the getTriggeredData does not extract the needed data.

Well, the fact that it did so in Jython was, based on how it’s supposed to work, but standard. So you are pregnant right that the JS Scripting library would have to change to support this. But be aware that doing so will potentially break compatibility with existing JS Scripting rules and error templates.

But, given your original rule in the OP, you can easily determine which trigger activated the rule.

If data.ItemName === undefined you know it was a Cron trigger. If it is defined, it will contain the beans if the item that triggered the rule which, in this case, corresponds to the trigger itself.

With the govern examples at least, this smells if an XY Problem.

True, I’ll create a pull request, and let’s see if it’s accepted. There should be no danger breaking anything if the “getTriggeredData” returns the “raw” input as well

const getTriggeredData = function (input) {
    let event = input.get('event');

    if (event && Java.typeName(event.class) === 'org.openhab.core.items.events.ItemCommandEvent') {
        return {
            eventType: "command",
            triggerType: "ItemCommandTrigger",
            receivedCommand: event.getItemCommand(),
            oldState: input.get("oldState") + "",
            newState: input.get("newState") + "",
            itemName: event.getItemName()
            _input: input  // raw input returned too
        }
    }

....
(just example, below there are other paths)

On the other side each trigger has a “name” parameter:

    ChannelEventTrigger: (channel, event, triggerName) => createTrigger("core.ChannelEventTrigger", triggerName, {
        "channelUID": channel,
        "event": event
    }),

why not exposing this info when the trigger fires.