[OH3] Determine if rule was triggered by command or update

Hi,

I upgraded to OH3 and I’m moving all my rules from file based to the main UI.

For my in-wall dimmers I need to know if there was a command before an update. Flipping the (physical) switch triggers only an update. (the physical switch toggles between OFF and last state, I want to toggle between OFF and full brightness)

Currently I have two rules in one file with a shared variable (BedRoom2commandTime) :

rule "BedRoom2Light: state changed"
when
    Item BedRoom2Light_Dimmer changed
then
        if((now.toInstant().toEpochMilli() - BedRoom2commandTime) < 2000){
                return;
        }
        if(newState as Number > 0){
                BedRoom2Light_Dimmer.sendCommand(100)
        }else{
                BedRoom2Light_Dimmer.sendCommand(OFF)
        }
end


rule "BedRoom2Light: state command"
when
    Item BedRoom2Light_Dimmer received command
then
        BedRoom2commandTime = now.toInstant().toEpochMilli()
end

In main UI there is (afaik) no way to share variables between rules without using proxy items.
So I’m trying to figure out a way to determine if a rule was triggered by a command or an update. (so I can set a variable if it was a command) I have the following test rule:

triggers:
  - id: "1"
    configuration:
      itemName: BedRoom2Light_Dimmer
    type: core.ItemCommandTrigger
  - id: "2"
    configuration:
      itemName: BedRoom2Light_Dimmer
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
  - inputs: {}
    id: "3"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: |
        
        logInfo("TEST","==========BEGIN============")

        if(receivedCommand !== null){
          logInfo("TEST","COMMAND {}", receivedCommand)
        }

        if(newState !== null){
          logInfo("TEST","UPDATE {}", newState)
        }

        logInfo("TEST","==========END==============")
    type: script.ScriptAction

And it works only once; receivedCommand is not reset to null if the rule was triggered by an update:

Flip switch ON

2020-12-30 17:34:42.018 [INFO ] [org.openhab.core.model.script.TEST  ] - ==========BEGIN============
2020-12-30 17:34:42.021 [INFO ] [org.openhab.core.model.script.TEST  ] - UPDATE 50
2020-12-30 17:34:42.023 [INFO ] [org.openhab.core.model.script.TEST  ] - ==========END==============

Flip switch OFF

2020-12-30 17:34:47.837 [INFO ] [org.openhab.core.model.script.TEST  ] - ==========BEGIN============
2020-12-30 17:34:47.840 [INFO ] [org.openhab.core.model.script.TEST  ] - UPDATE 0
2020-12-30 17:34:47.842 [INFO ] [org.openhab.core.model.script.TEST  ] - ==========END==============

"command" from Openhab app (50%)

2020-12-30 17:35:11.354 [INFO ] [org.openhab.core.model.script.TEST  ] - ==========BEGIN============
2020-12-30 17:35:11.358 [INFO ] [org.openhab.core.model.script.TEST  ] - COMMAND 50
2020-12-30 17:35:11.362 [INFO ] [org.openhab.core.model.script.TEST  ] - UPDATE 0
2020-12-30 17:35:11.363 [INFO ] [org.openhab.core.model.script.TEST  ] - ==========END==============

Flip switch OFF

2020-12-30 17:35:23.329 [INFO ] [org.openhab.core.model.script.TEST  ] - ==========BEGIN============
2020-12-30 17:35:23.334 [INFO ] [org.openhab.core.model.script.TEST  ] - COMMAND 50
2020-12-30 17:35:23.337 [INFO ] [org.openhab.core.model.script.TEST  ] - UPDATE 0
2020-12-30 17:35:23.339 [INFO ] [org.openhab.core.model.script.TEST  ] - ==========END==============

Flip switch ON

2020-12-30 17:35:28.738 [INFO ] [org.openhab.core.model.script.TEST  ] - ==========BEGIN============
2020-12-30 17:35:28.741 [INFO ] [org.openhab.core.model.script.TEST  ] - COMMAND 50
2020-12-30 17:35:28.745 [INFO ] [org.openhab.core.model.script.TEST  ] - UPDATE 50
2020-12-30 17:35:28.747 [INFO ] [org.openhab.core.model.script.TEST  ] - ==========END==============

as you can see “receivedCommand” stays at 50 and is only reset to null if I reload the rule.

Is there any way to determine if the rule was triggered by an update or a command?

If you switch to JavaScript I think this could work. You should be able to test for event.itemCommand === undefined (going from memory so could be wrong on the event variable). if that’s true, it wasn’t a command.

But ultimately I think sorting that in an item might be more straight forward. You can even use the timestamp profile to set the timestamp I think.

Or you can keep the rules in. rules files.

Looks related -

Switched to Javascript and it works!

this.BedRoom2commandTime = (this.BedRoom2commandTime === undefined) ? (Date.now() - 3000) : this.BedRoom2commandTime

if(event.itemCommand !== undefined){
  this.BedRoom2commandTime = Date.now();
}

if(event.itemState !== undefined){
  if((Date.now() - this.BedRoom2commandTime) > 2000 ){
    if(event.itemState > 0){
      events.sendCommand("BedRoom2Light_Dimmer",100)   
    }else{
      events.sendCommand("BedRoom2Light_Dimmer",0)   
    }
  }
}

Thanks both!

The way I worked around this in Javascript is to get rid of the event object in my script:
delete context.event; // where context is the outer most “this”.
It ain’t pretty, but the upstream engine seems to tolerate it (for now).

me too :slight_smile: