Any way to isolate events from UI vs Hardware

  • Platform information:
    • Hardware: Raspberry Pi 2
    • OS: Openhabian
    • Java Runtime Environment: which java platform is used and what version
    • openHAB 2.1:
  • Issue of the topic: isolate events from UI versus from hardware

I have a question regarding the running of a rule only when changes to the item via the UI as opposed to changes to the item from the hardware.

Let’s say I have the following situation:

Items file:
Dimmer mydimmer “My Dimmer”

sitemap file:
Slider item=mydimmer “My Dimmer Slider”

rules file:
rule "mydimmer Changed Rule only when mydimmer item is changed on the UI and no other way"
when “Item mydimmer is changed on UI only” //plain English of what I want to accomplish
then LightingProcessorSend.sendCommand( “DIMMERVALUE:” + String.valueOf(mydimmer.state))
end

Is there an easy way of doing this?
My problem is that I am executing the “sendCommand” function when either the lighting processor updates the item, or the UI updates the item, this is causing problems. If the lighting processor updates the dimmer value, there is no need to send the updated information back to the lighting processor. However, if the user updates the dimmer value via the UI, then it should send the updated value to the lighting processor.

Asked another way, is this the difference between?:
“when item mydimmer received update” - ???Is this only via the binding???
“when item mydimmer received command” - ???Is this only via the UI???
“when item mydimmer changed” - ???Is this via both depending on if the value of mydimmer changes???

Thanks,
Tim.

There is not an easy way, but there is a way. But first your questions:

Any time an Item is updated, even if it is with the same state, the Item will receive an update. Commands also cause updates. Pretty much any time anything (rules, UI, binding) touches an Item an update event is generated. When posting an update from a Rule, only the OH Item state activates. Updates are not forwarded to the binding and therefore are not sent to the device.

Any time an Item is commanded, even if it is with the same state, the Item will receive a command. Commands are typically generated from the UI, Rules, or the Binding. All interactions from the UIs are commands. A commands are forwarded on to the binding and on to the device.

Any time an Item changes state, whether it is from the system (e.g. restoreOnStartup), from an update, or from a command there is a changed event.

None of these make any distinction between the sources of the command or update or change.

So the challenge is there is not a way to tell where commands or updates or changes come from in a Rule. We can only know that they happened.

There are three ways I can think of to achieve this, all three of which are a little complex. Two of them are documented in Design Pattern: Manual Trigger Detection. The third I’ll describe below.

For your dimmer, you need to define two Items, your original Item and a Design Pattern: Proxy Item. Put the Proxy on your sitemap and when you send a command to the light in your Rules use the Proxy Item.

You will need two rules:

rule "My Dimmer changed"
when
    Item MyDimmer received command // you might need received update here, changed could work, depends on how your binding reports changes made at the device itself
then
    // This was a change caused by manual interaction at the dimmer itself

    MyDimmerProxy.postUpdate(MyDimmer.state) // update the Proxy
end

rule "MyDimmerProxy received a command"
when
    Item MyDimmerProxy received command
then
    // This was a command that came from the UI or a Rule

    MyDimmer.sendCommand(MyDimmerProxy.state) // update the device
end

Notice the careful use of postUpdate in the first rule. By using postUpdate and triggering the second rule with received command we avoid getting into an infinite loop. The second rule will not trigger from the postUpdate.

1 Like

Brilliant! Those answers should go directly into the docs :grinning:
Never seen it explained that easy understandable …

Thanks Rich. That helps a lot. It looks like the secret is to flip hardware communication from commands to updates using postUpdate in the rules and not using the particular item in the UI. Now only proxied UI activity (which is known to be a command) can be sent on to the binding. Nice

To summarize:

UI generates commands.
Bindings generate commands
Rules generate commands (if sendCommand() is used in code) or updates (if postUpdate() is used in code).

Commands generate updates
non-commanded updates generate updates, even if state doesn’t change

Commands (including sendCommand) will forward to binding and subsequently device
Updates (like postUpdate) will NOT forward to binding and not to device

only changes in state, be it via commands or updates, generate changed events.

I agree with sihui, that example and explanation should be put into the documentation.