How to trigger event on state change (instead of state update)

In the MQTT binding (see https://github.com/openhab/openhab/wiki/MQTT-Binding), an output message can be triggered from:

  • a state update with this item: Switch mySwitch {mqtt=">[mybroker:/myhouse/office/light:state:ON:1]"}

  • a received command with this item: Switch mySwitch {mqtt=">[mybroker:/myhouse/office/light:command:ON:1]"}

I’d like to trigger a message only on a state change. Is there a way to
implement that in the item (instead of doing it in a rule)? I am asking here instead of a MQTT sub forum because I think this behaviour is shared with other bindings.

Thanks for any help!

No; you will have to use a rule to publish to an MQTT broker on change only. The binding does not listen for changes, only updates.

Try something like:

rule PublishOnChangeOnly
when
  Item MyMQTTItem changed
then
  publish(yourBrokerName, yourTopic, MyMQTTItem.state.toString)
end

See MQTT publish action.

Hello Watou and thank you for your quick reply!

Too bad about this limitation… But the solution you are suggesting (available as of openHAB 1.8) is an easy workaround. I’ll use it until the MQTT binding is updated.

Thank you very much for the info.

1 Like

Hello Watou, I am trying to apply your solution but the rule doesn’t execute. The error is:

2016-02-02 22:27:37.989 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'debug-OFF': The name 'publish(<XStringLiteralImpl>,<XStringLiteralImpl>,<XStringLiteralImpl>)' cannot be resolved to an item or type.

I am using OH 1.8 with MQTT binding 1.8. I tried restarting OH but it didn’t help. Any clue?

You will also have to install the MQTT action as well as the binding. If you installed via apt-get, it’s

sudo apt-get install openhab-addon-action-mqtt

Ooohh! I didn’t know that. Thank you very much. I confirm it works perfect now!

1 Like

postUpdate(MyMQTTItem) triggers the rule if the trigger changed is used. How can I avoid that? I’d like a “received command AND changed” trigger (so that I could use postUpdate for updates without triggering the rule) but it doesn’t exist…

My main goal here is to be able to update an MQTT item without triggering the associated rule. I imagined this solution:
rule PublishOnChangeOnly when Item MyMQTTItem received command then if (MyMQTTItem.previousState.state != MyMQTTItem.state){ publish(yourBrokerName, yourTopic, MyMQTTItem.state.toString) } end

but I got buggy results (the MQTT message is not always published, even if the IF condition is TRUE!). Thanks for any help.

Maybe you only want to send commands from openHAB? You could have autoupdate="false" in your item binding, like

Switch myMQTTSwitch { mqtt=">[broker:topic:command:ON:1],>[broker:topic:command:OFF:0]", autoupdate="false" }

so the act of flipping the switch won’t also update the state of the item?

Hello watou and thanks for your answer. The problem with your solution is I’d lose the “change” trigger. What I am looking for is a change trigger that wouldn’t be triggered by updates (even if the new updated status changed).

That’s not possible, but it may be that thinking about the overall objective differently could yield a simple answer. What is the overall objective? What is publishing and what is subscribing?

I’m also interested in this solution.

my scenario is that i am developing a light switch using an arduino.

the switch will have the ability to to trigger a relay via both a push button on the physical unit, and i want it to also be able to trigger based on an MQTT event…

My theory is

  • listener for MQTT on lightswitch/command channel
  • publish changes on lightswitch/state channel

So in openhab i want the switch to publish an action to the command channel if the slider is moved, but if someone clicks on the physical button onthe unit (and thus triggers an update in the state channel), i want the state of the switch to change also,.

thoughts on the best way to achieve this?

A single openHAB Dimmer item bound to MQTT ought to work:

Dimmer ArduinoLightSwitch "light [%d %%]" { mqtt="<[broker:/lightswitch/state:state:default],>[broker:/lightswitch/command:command:*:default]" }

Your sitemap could show both a switch and a slider:

Switch item=ArduinoLightSwitch
Slider item=ArduinoLightSwitch

Your Arduino would publish “0” for off, “100” for on, or any number in between. Your Arduino would subscribe and expect those same values, but also “ON” and “OFF”. This wiki information should help.

Or you could use a MAP(arduino.map) instead of default in the item’s outbound (publish) section, so the “ON” is published as “100” and “OFF” is published as “0”. transform/arduino.map:

ON=100
OFF=0

There are probably other approaches as well; which one you choose would be driven by how your Arduino wants to publish and subscribe.

1 Like

Thank you for your quick and detailed reply!

Worked a treat!
Thanks for your help

1 Like