Update of Switches

Hi Guys, I have a question about how switches are updated in openhab.

Case No.1 a switch which simply triggers a Rule

Switch Power_Plug_Socket_1 

I will have to use

Power_Plug_Socket_1.postUpdate(ON)

somewhere in my rule in order to visualise it in my Sitemap
But even without that it would turn on.

Switch Test1 "Just a test"
2018-07-19 22:43:02.776 [ome.event.ItemCommandEvent] - Item 'Test1' received command OFF
2018-07-19 22:43:02.788 [vent.ItemStateChangedEvent] - Test1 changed from ON to OFF

Why?

Case No. 2 is a zwave Switch:

Switch wz_switch2_switch1   "Gartenlicht" <light>                   (WZ_switch2, Garten)            {channel="zwave:device:zwave_usb:node7:switch_binary1"}

I guess in this case the binding is responsible (thus the zwave USB Dongle gets the update)

I have noticed though, that sometimes even if a zwave device is not connected, it still shows turned on (therefore I have no feedback if the light/pump/whatever actually received the command and was turned on.

No. 3:
How does that work with MQTT Switches?

Switch Relay1 "MQTT 1" { mqtt=">[MQTT:mqtt/irrigation/relay1/switch:command:ON:1], >[MQTT:mqtt/irrigation/relay1/switch:command:OFF:0], <[MQTT:mqtt/irrigation/relay1/state:state:default]"} 

In my case the Switch was not configured properly, so it returned the state ā€œNULLā€ but still the switch was turned on in my sitemap - so even if the mqtt subscriber was offline, I would still get the (wrong) feedback

also see my logfile here:

018-07-19 22:38:44.653 [ome.event.ItemCommandEvent] - Item 'Relay1' received command OFF
2018-07-19 22:38:44.670 [WARN ] [b.core.events.EventPublisherDelegate] - given new state is NULL, couldn't post update for 'Relay1'
2018-07-19 22:38:44.672 [vent.ItemStateChangedEvent] - Relay1 changed from ON to OFF

How do I prevent this from happening? Or am I just confused?

No. To visualise it in your sitemap just add a label to it and add it to the sitemap.
You donā€™t need to do a postUpdate to visualise it.

Why what? This is normal.
The item received a command ON and if it is OFF will be updated to ON. Nothing strange here.

Case 2: I donā€™t do zwave so I canā€™t help you here.

Case 3: MQTT
Again this is normal if your item wasnā€™t initialized. It would have been null at the start of openHAB.
You can initialise your items at start-up with persistence

I see a couple areas of confusion here.

  1. postUpdate only changes the state of the Item. sendCommand changes the state of the Item and goes it to the device through the binding. Usually, when a device sends a new value, the binding will send a command to the Item.

  2. OH Items represent the last known state. There isnā€™t some magical constant connection to the devices that the Items represent. So if your zwave device loses power, there is nothing to tell OH that the device is OFF. Technically, in this case the device is neither ON not OFF, itā€™s state is unknown. But regardless, until something tells OH by that the device is in a new state, it will remain in the same state forever. The appropriate way to handle situations like this depends greatly on you specific needs and environment so it is up to you to determine the correct way to detect and record when a device unexpectedly goes offline and how to represent that in your Item.

Another point:

By default openHAB does an automatic postUpdate() if doing a sendCommand(), so, if changing a Switch through UI, this will do a sendCommand() and thus also a postUpdate().
If you donā€™t want this behavior, you have to define the Item with autoupdate="false"

Switch Power_Plug_Socket_1 {autoupdate="false"}
Switch wz_switch2_switch1 "Gartenlicht" <light> (WZ_switch2, Garten) {channel="zwave:device:zwave_usb:node7:switch_binary1", autoupdate="false"}
Switch Relay1 "MQTT 1" { mqtt=">[MQTT:mqtt/irrigation/relay1/switch:command:ON:1], >[MQTT:mqtt/irrigation/relay1/switch:command:OFF:0], <[MQTT:mqtt/irrigation/relay1/state:state:default]", autoupdate="false"}

I did it to all items just to show how this configuration is used :slight_smile:

However, when using a Switch Widget and switching the Widget to ON, the UI will take a while until the Widget is pulled back to OFF (in case of no postUpdate(ON))

2 Likes

Guys, thank you for your very helpful answers.
I am well aware that no magic is involved in OH. Itā€™s all about the right approach.
The question really came up because of things/items with a back channel.
So taking my MQTT switch as an example:
I want to see in OH right away if the switch actually triggered, when I turned it on. I have seen that sometimes the WIfi connection is lost and therefore actuation did not take place for instance. Yet in openhab the device was indicated as being on. So I thought that I could make good use of the back channel that MQTT provides.

I guess that would be the correct approach then?

Yes that look fine, unless obviously the mqtt relay is offlineā€¦

But even in this case I would see that something is wrong with the mqttrelay, because the switch would not turn on (thus the dynamic icon change to on) - which is what I ultimately want. Correct?

Yes

Alright. It is much more clear in theory now, I will try it later tonight. Hopefully itā€™ll work as desired.

Please come back and post the solution if you get it working. :slight_smile: Good luck!

Hi all.
Thank you for your hints. I got it to work, even though the result does not fully satisfy me. But that is really due to my lack of skills when it comes to programming.

So first I will share my working solution:

Switch Relay1 "Rasen Haus" <irrigation>  (gIrrigation, gRasen, gGarten) { mqtt=">[MQTT:mqtt/irrigation/relay1/switch:command:ON:1], >[MQTT:mqtt/irrigation/relay1/switch:command:OFF:0],   <[MQTT:mqtt/irrigation/relay1/state:state:default]", autoupdate="false"} 

The switch only updates in OH, when the MQTT state:ON is received by openhab (which works really well in the app, my chrome browser does not refresh the sitemap automatically, but Iā€™ve read that this is a whole other story)

I added this to the end of my Arduino sketch:

 client.publish("mqtt/irrigation/relay1/state", "OFF");
//did this for all relays

That way the switch turns off, whenever the ESPrestarts. A couple of improvements are desired on my side:

  1. Iā€™ve seen the following syntax for outbound MQTT MEssages:
Switch mqttsw1 "Switch 1" (all) {mqtt=">[mosquitto:/testsw/1:command:*:default]"}

That would make my items much shorter, however it sends ON and OFF messages, and I am not sure how to make Arduino understand ON OFF Strings

void callback(char* topic, byte* payload, unsigned int length) {
if(payload[0] == '1'){
       digitalWrite(switchRelay1, LOW);
       client.publish("mqtt/irrigation/relay1/state", "ON");
       }

So Arduino would only accept 1 or 0 but publish ON. Very confusing for me.

  1. I should probably use a Last Will message to set my switches to 0 instead of doing that on start-up. If for some reason my arduino shuts down, the switches would still be indicated as on. But I guess I would have to use ESPEasy for that as making up my own sketch seems far two complicated to me.

  2. I was trying to use a group switch for the state that is published on startup. So the sketch looked like this:

  delay(5000);
        client.publish("mqtt/irrigation/relayall/state", "OFF");

And then in my items configuration i implemented:

Group:Switch:OR(ON, OFF) 	gIrrigation 		"Alle Relays" {mqtt=  "<[MQTT:mqtt/irrigation/relayAll/state:state:default]"}

Well let me tell you - that didnā€™t work at all. So the intention here was to switch all members of gIrrigation of, if the mqtt message comes in.

But really, I am happy, that I found a working config, the rest is just bonus.

1 Like

I donā€™t think you should bind Groups to real data/devices.
Groups update themselves based on state of members.
Yo can send a command to a group, which will automagically distribute it to member Items

I donā€™t know I would say that. I can see one or two use cases. For example. If I had a light switch and I wanted to turn on multiple lights with that one switch. I could link the channel/binding config to all the lights, or I could link it to a Group containing all the Items. Any time I flip the switch the Group will receive the command and forward the command to the members.

The problem is how to manage going the other direction. It gets complicated when trying to go the other way. But I think you could just treat the Group as if it were a Switch everywhere and the Group essentially becomes a proxy for all of its members.

I think that could work in a few circumstances. But you would want to make sure you never change the members individually.

mm, itā€™s all a bit headache provoking :slight_smile:

Groupā€™s not going to work as planned here with binding to data input, though. An incomiing ā€˜updateā€™ will not generate a ā€˜commandā€™ for forwarding to group members. The incoming update state will get trashed sometime, as/when group members do get updated.

I suggest the way to go here is to have an explicit Item for the incoming MQTT, and a rule that responds to Item update by commanding Group.

Correct, that will work explicitely with a postUpdate or sendCommand and cascage to group members but NOT with a binding I am afraid.

If the Group truly is a proxy for itā€™s members, we donā€™t care about the updates. There shouldnā€™t be any updates anyway since all controlling and interaction with those lights should be through the Group anyway so if there were updates, it would be an error case anyway.

Iā€™m thinking about something like one light fixture with three Hue bulbs in it and a ā€œsmartā€ wall switch to control them. All three lights should always operate as one and never individually so if I link the smart wall switch to the Group, all the forwarding of the commands are handled for me without extra Items or Rules.

Though like I said above, it is not generally applicable. But in at least this one use case it seems like a pretty good idea.

I cannot see how to link e.g wall switch directly to a Group via binding, such that it will cause commands necessary to trigger other binding(s) to act on Group members.
A bound input causes an update to an Item (or group). Only a UI or rule can issue a command to an Item (or group). Bindings only act on commands to control external devices.

To invoke a command in response to an update, youā€™d need to use a rule.

There is scope to bind an input (e.g. wall switch) to a Group as @soesas tried, but youā€™d still need to trigger a rule off group update to invoke a command.
Problem : there is risk of getting in an endless loop when those commands are passed by bindings to group member devices, and the target devices cause an update to member Items, causing updates to Group ā€¦
Easily avoided by having a separate Item bound to the input (wall switch), and a rule ā€˜listeningā€™ to that (which can of course issue one command to a Group and so affect many devices).

This is not correct. Some bindings may only report the Switch changing state as an update, but all of the bindings I use and am familiar with send command, including zwave, zigbee, and mqtt (Tasmota).

It is not the case that bindings only issue updates. And I would be surprised and question the logic of a binding that did not issue a command for events from a switch.

Come back all I said! On checking, some bindings can be configured to issue command in response to external events. Taa-daa!

@rlkoshak is right and I was wrong.

@soesas original idea to bind a ā€˜master control switchā€™ for a Group SHOULD work then. The problem was that itā€™s MQTT binding parameters need altering to invoke a suitable command.

(As an aside, Iā€™ve never noted or used this ā€˜featureā€™ with any binding. Apart from the oddball ā€˜expireā€™, unrelated to external events. Iā€™ve found it easy to work with rules while keeping a mental picture of command=outbound update=inbound, all while I was assuming that was OH philosophy.)

1 Like

I am glad you challenged those. Sometimes I think I know things and am wrong. In the future please do speak up again.