GledholtHall / beta-3

H E update
2 stars 3 forks source link

/set being published when receiving updates from Indigo #16

Open autolog opened 2 years ago

autolog commented 2 years ago

I have successfuly discovered a LIFX lamp connected to Indigo. When I update the dim value in Indigo, this is sent to HE (just updating /dim with a payload of the dim valuee. The value is correctly updated in HE. Then the MQTT App sends a '.../dim/set' with a payload = 'the just sent dim value' back to Indigo.

I assumed that /set commands would only be sent for alterations being done on HE not from inputs from discovered devices?

cesarvoggithub commented 2 years ago

Yes, I can see the same issue in a z-wave dimmer discovered from Indigo. It appears to have the same root cause of issues #13 and #15, where HE is updating the $nodes topic under homie/<the-name-you-set-for-your-hubitat-elevation-device-in-the-MQTT-app/driver>. Besides mistakenly adding the foreign device into the list of native nodes, it also updates the /dim subtopic, and the /onoff subtopics. While the /dim subtopic gets the exact value set from Indigo, the onoff also updates, as viewed from MQTT Explorer, but it does not change from false to true when turning on, and from true to false when turning off, it always updates to "false".

GledholtHall commented 2 years ago

I have this fixed for pre25 However I still allow manually enabling republishing a device still which I am still thinking over

The non updating of on|off directly may be another issue but might be irrelevant anyway if I disable this.

cesarvoggithub commented 2 years ago

Jon and I are working on a brief description of how we think the interaction between your App/Driver and his Indigo Plugin could work. Will post back here when that is ready.

cesarvoggithub commented 2 years ago

Ok, Jon and I finished the description I talked about on my last comment. Here it is:

Kevin, allow me to present you how we envision this integration between your App/Driver and @autolog 's plugin in Indigo:

Your App/driver only publishes to the MQTT broker Hubitat Elevation native devices (at the homie/[name-of-hubitat-elevation-hub] topic.

At the same time, your App/Driver subscribes to all discovered devices, under the homie/[name-of-topic-for-configured-for-homie-discovery].

@autolog 's Plugin for Indigo does the opposite. It published to homie/[name-of-topic-for-configured-for-homie-discovery] all native Indigo devices the user selected for publishing in his plugin. At the same time, it subscribes to the homie/# (to pick up multiple Hubitat hubs) where your App/Driver publishes native HE devices e.g homie/[name-of-hubitat-elevation-hub]/...

If I understand this correctly, then we have two possible cases occurring when the user changes the value of a property from EITHER platform, while the other platform simply "picks up" with the changes:

The user is interacting with his devices from the HE Dashboard or Indigo User Interface:

a) the user turns something on/off/changes the brightness level manually or via automation of the used platform (HE or Indigo) - for example: the user turns something on from HE Dashboard or from the Indigo UI.

b) If the device is published by HE or Indigo, the value of the MQTT property will be refreshed by updating the topic directly (e.g. ../onoff = true) otherwise if the device is discovered by either HE or Indigo, the refresh will be requested via a /set topic (e.g. ../onoff/set = true) This will result in the corresponding property being refreshed under homie/[name-of-hubitat-elevation-hub] if device published by HE or homie/[name-of-topic-for-configured-for-homie-discovery] if published by Indigo.

c) the other platform will notice that something changed on a subscribed subtopic (via the /set for a device published by that platform) or directly for a device discovered by that platform.

d) these changes will be reflected in the Indigo and HE interface.

Of course there will be the need that both you and Jon differentiate between devices that are published by your MQTT App and devices that are discovered. a s explained above, for devices published by HE, the topic value e.g. onoff is changed to e.g true. For discovered devices (in HE), your would send a /set topic. Vice versa applies to Jon Plugin for Indigo.

Please feel free to ask in case anything needs clarifying and many thanks for your efforts bringing this much needed app/driver to Hubitat Elevation.

Cesar

GledholtHall commented 2 years ago

Good and useful stuff, I'll have another read over this shortly ..

it subscribes to the homie/# (to pick up multiple Hubitat hubs)

I block subscribing to anything within my own hub device topic but I can subscribe to other specific HE hubs and homie devices. I don't wildcard as a lot of traffic can originate - I for example have 7 HE hubs and 26 homie devices ! Initially I discover via wildcarded topics but I then remove these after discovery completes and re-instate specific device state subscribes to minimise received MQTT traffic. Indigo will be running on a higher power CPU so this may not be a concern to Jon.

I will be adding multi device discovery eventually once I can manage identifying from the name map which homie device a node is on. You can actually just change the homie device topic in homie discovery and re-run and they will get concatenated into the discovered dropdown lists but identical named nodes on different devices will overwrite each other.

if the device is discovered by either HE or Indigo, the refresh will be requested via a /set topic (e.g. ../onoff/set = true)

This does not refresh the current state - it asks the controller to change the state of the physical device to match the set command.

Of course there will be the need that both you and Jon differentiate between devices that are published by your MQTT App and devices that are discovered.

Well yes and no.. My app will never issue.../set commands to HE's own devices - only to MQTT linked remote devices. I only subscribe to.../set commands to my own devices. I do not subscribe to../set commands on MQTT linked remote devices. Likewise I do not subscribe to any state topics for HE's internal devices e.g ../onoff or .../dim

There is an issue that when a state changes on a 'discovered' device from MQTT then I need to propagate the new state to the remote device by using a .../set command but that is likely to generate another state update on MQTT which will then likely generate another event and another .../set command from HE. A possible loop and Jon may have this same issue.

One of HE's deficiencies is that you aren't informed and can't tell who originated a state change on a device when the event happens (user interface click, MQTT status update, rule machine or scheduler. Maker API, webhook, physical device interaction, my App or any other app) so I have to determine if the update came from MQTT and block a .../set being sent in that one specific case. Harder to implement than it seems. Indigo might be more helpful in this regard.

autolog commented 2 years ago

Good morning Kevin, I see you have been burning the midnight oil with the release of pre25!

I have installed the updated App and driver and then rebooted my C7.

I am still getting /set commands being returned for updates published by Indigo for devices discovered by HE. If this going to be problematic for you to resolve, I can probably add some logic to Indigo to drop any /set topics received that are reflecting back what I have published for an HE devicediscovered in HE.

GledholtHall commented 2 years ago

Will take another look… is this with all device types or just the LIFX ? The created device type in HE was ? Is just one attribute being updated from Indigo or several at once and if so which ones ?
Do several …/set commands to different attributes get sent ?

it shouldn’t happen - I need to fix it within my app.. status updates from an MQTT remote discovered device shouldn’t re-propogate as …/set command. How many topic updates get posted to MQTT with such a change (not any resultant change triggered by the …/set command I erroneously am sending)

I re-read you say it happens using only a single dim value update … so you get a …dim/set.. sent. No other attribute values are updated/published by your code ? let me try here….

autolog commented 2 years ago

It is happening for dimming devices and switch devices.

I have added logic into my Indigo plugin to suppress /sets that won't make a difference because value is already set. Here is a log (ignore the errors, just using it to get colouring):

Screenshot 2022-02-02 at 15 05 48
GledholtHall commented 2 years ago

Ahh so a homie/indigo-1/dev99417865/onoff/$name is sent immediately after the same device …/dim and the … /onoff status update ? I can see my logic is maybe flawed in that the messages are received asynchronously and so the ‘last/current’ status update ($name) might not be the one I am currently actioning (onoff or dim)

Plus.. HE enforces changing the device state to off when dim is set to 0 or on when dim is non 0. As dim arrives first I am therefore seeing an onoff update that apparently wasn’t originated from MQTT ... Sending the onoff first might circumvent the issue or actually you might be able to omit the onoff altogether if the level is sent.

Let me think on this…. ( it probably doesn’t go into a loop as such but sends just the one …/set command). Your fix whilst it works for Indigo probably just hides the issue and other controller implementations will still encounter it

autolog commented 2 years ago

I have just changed my plugin not to change the $name. I was treating it as a dynamic field but looking at the spec, I think it should be a fixed device name and so won't change on every state change.

GledholtHall commented 2 years ago

Does that fix this issue re .../set or is it still happening ? Does altering the order of the onoff and dim to dim first improve it at all ?

cesarvoggithub commented 2 years ago

Kevin, as far as I can tell, we seem to be well on the right track. The re-publishing by your App/Driver of devices it discovered from Indigo earlier is still happening, but - with all the work you put up on pre25 and all the work Jon put up on filtering out some spurious /set commands, it's now possible to foresee a brilliant future for this integration between HE and Indigo. Since you persevered in developing this solution for the homie schema, I can also see it being useful for folks running OpenHAB (pending the development of something like Jon's Plugin by one of OpenHAB's developers) to support their Home Automation goals. NICELY DONE, guys!

autolog commented 2 years ago

I'll check that out now. . .

LIFX sent "Study Lamp [W]" on with duration of 0.0 seconds Hubitat Bridge Debug >>> Published Discovery: Topic='homie/indigo-1/dev-99417865/dim', Payload='49' for Study Lamp [W] Hubitat Bridge Debug >>> Published Discovery: Topic='homie/indigo-1/dev-99417865/onoff', Payload='true' for Study Lamp [W] Hubitat Bridge Error >>> Received Discovery /Set: Topic='homie/indigo-1/dev-99417865/onoff/set', Payload='true' Hubitat Bridge Warning >>> Ignoring Received Discovery: Topic='homie/indigo-1/dev-99417865/onoff/set', Payload='true' for 'Study Lamp [W]' Hubitat Bridge Error >>> Received Discovery /Set: Topic='homie/indigo-1/dev-99417865/dim/set', Payload='49' Hubitat Bridge Warning >>> Ignoring Received Discovery: Topic='homie/indigo-1/dev-99417865/dim/set', Payload='49' for 'Study Lamp [W]'

I publish the dim first, followed by the on"off, but still getting the /set 's. $name no longer published.

GledholtHall commented 2 years ago

Since you persevered in developing this solution for the homie schema, I can also see it being useful for folks running OpenHAB (pending the development of something like Jon's Plugin by one of OpenHAB's developers)

OpenHAB already supports the homie protocol schema :-)

autolog commented 2 years ago

Good morning Kevin, I have installed pre-26 + rebooted my C7.

I was chasing down a problem yesterday on pre-25 which is still present in pre-26. I have another Zigbee socket (INNR) defined as a native device in HE. I publish it to Indigo. When I turn it on|off in Indigo, Indigo publishes this topic:

Published to 'home-2': Topic='homie/home-2/hall-outlet--xmas-/onoff/set', Payload='true'

I then get a response from HE:

Received from 'home-2': Topic='homie/home-2/hall-outlet--xmas-/onoff/set', Payload='true'

What my plugin is expecting (and used to happen) is a message in the format

Received from 'home-2': Topic='homie/home-2/hall-outlet--xmas-/onoff', Payload='true'

So rather than the topic onoff being updated to 'true', a /set command is now being issued and so my plugin is ignoring it. It is checking for a topic length of 4 elements.

I think I am correct in saying that as the device is owned by HE, a /set shouldn't be used as this should only be used when a third party (Indigo in this case) wants to alter the value?

autolog commented 2 years ago

Hi Kevin, Another update. It has just occured to me that the /set being detected when I send a /set command to HE is the one I just sent to HE as I subscribe to the same topics i.e. 'homie/#'. Just tested this by turning off my Hub and still receiving the /set from the broker.

This why I ignore /set commands received for devices published by HE.

In fact this particular error ii have been chasing turns out to be another another 'No matched device' error

GledholtHall commented 2 years ago

OK - so you are also getting that 'No matched device' error on this device. I can see your MQTT uploads on my broker now so I'll test against those devices as best I can

It's a very frustrating aspect of MQTT brokers that you can't tell which client updates a particular topic/payload. Also do ensure each client you connect to the broker uses a different and unique client ID as duplicate clients are not allowed - the earlier one will get kicked off. Bear in mind that other remote users using your app might be connected now too.

autolog commented 2 years ago

Testing on pre-27.

This report is for a LIFX lamp linked to Indigo and published by my plugin for discovery in HE.

It is dsicovered OK in HE and controllable by HE.

However, there is still the issue that when Indigo publishes and updated value for the device, either on|off or dim value, HE is sending back a /set for the same value. I now have processing in my plugin to ignore any /set topics if the value being set is equal to the value already presnt in Indigo. Example turn off log from my plugin:

LIFX sent "Study Lamp [W]" off with duration of 0.0 seconds Hubitat Bridge Debug >>> Published Discovery: Topic='homie/indigo-1/dev-99417865/dim', Payload='0' for Study Lamp [W] Hubitat Bridge Debug >>> Published Discovery: Topic='homie/indigo-1/dev-99417865/onoff', Payload='false' for Study Lamp [W] Hubitat Bridge Warning >>> Ignoring Received Discovery: Topic='homie/indigo-1/dev-99417865/dim/set', Payload='0' for 'Study Lamp [W]' Hubitat Bridge Warning >>> Ignoring Received Discovery: Topic='homie/indigo-1/dev-99417865/onoff/set', Payload='false' for 'Study Lamp [W]'

Example log from my plugin, setting dim value:

LIFX sent "Study Lamp [W]" set White Level to "100" and White Temperature to "9000K Blue Ice" with duration of 1.0 seconds Hubitat Bridge Debug >>> Published Discovery: Topic='homie/indigo-1/dev-99417865/dim', Payload='100' for Study Lamp [W] Hubitat Bridge Warning >>> Ignoring Received Discovery: Topic='homie/indigo-1/dev-99417865/dim/set', Payload='100' for 'Study Lamp [W]'

The LIFX log entry is sending a command to Indigo to alter the on|off|dim value as appropriate. Indigo actions this and I intercept the update and publish it to HE. HE then responds with the unwanted /set which I ignore.

Whilst the above is related to a LIFX lamp (but in can be any dimmable device), the same applies to relay | switch devices where the on|off command is reflected back vi a /set e.g.:

Action Group Virtual 1 ON Virtual Devices sent "Virtual 1" on Hubitat Bridge Debug >>> Published Discovery: Topic='homie/indigo-1/dev-1333137217/onoff', Payload='true' for Virtual 1 Hubitat Bridge Warning >>> Ignoring Received Discovery: Topic='homie/indigo-1/dev-1333137217/onoff/set', Payload='true' for 'Virtual 1'

Now that I have put in the ignore logic in my plugin, it isn't actually causing my plugin an issue any more AFAICS.