openhab / openhab-addons

Add-ons for openHAB
https://www.openhab.org/
Eclipse Public License 2.0
1.88k stars 3.59k forks source link

[MQTT] Dimmer channel on/off properties not sending "ON" or "OFF" #7991

Closed digitlength closed 3 months ago

digitlength commented 4 years ago

Expected Behavior

Background is here: https://community.openhab.org/t/dimmer-values-0-255-into-mqtt-switch-channel-on-off/101191

I have a WLED device which does not explicitly report whether it is on or off - it just reports brightness. However, it can receive ON and OFF strings to turn on and off. I have setup the thing, item and sitemap switch as shown in this post

I expected that this setup would send the string "ON" over the commandTopic when the sitemap switch is switched on, and would subsequently receive a number between 0 and 255 on the stateTopic which would be magically transformed into either ON (anything greater than 0) or OFF (for 0).

Current Behavior

When switching the sitemap switch on, the number 255 (instead of "ON") is sent over the commandTopic. When the sitemap switch is off, the number 0 (instead of "OFF" is sent over the commandTopic.

Ultimately, I think I don't understand what the on and off options actually do on the dimmer channel. Could you provide some clarification over and above what is documented here: https://www.openhab.org/addons/bindings/mqtt.generic/#channel-type-dimmer

Steps to Reproduce (for Bugs)

Use the things, items and sitemap definitions provided in the Community post linked above.

Context

What I would like to do is use a sitemap switch to turn the lights on and off BUT NOT overwrite the currently set brightness value on the WLED device itself.

I actually have this working using a Javascript transform, but thought that the on and off options might enable me to get rid of the transform!

Your Environment

bodiroga commented 4 years ago

Hi @digitlength!

I'm not sure if we can consider it a bug, because it is how the binding was implemented, so the behaviour is the expected one. This is the sequence that is followed when an item linked to an MQTT channel receives a command:

1) The channel receives the command and calculates how the command should modify the state of the channel. In your example, as the channel is a dimmer (PercentageValue), the ON (or OFF) is converted to a numerical value (0-100 or 0-255). In fact, the binding stores an internal state cache, that gets updated when a command is received. 2) After updating the interval state, the binding asks the channel to convert that value to a string, in order to send it as an MQTT message. In your case, again, as the ON command has been converted to the 255 value, the "255" string is returned. 3) The returned string is published to the commandTopic of the channel.

Yeah, I don't understand why the binding works like that, it would be much easier to simply send the received command as an MQTT message. If the command syntax is not suitable for the device, then the user could apply an outgoing transformation, as it is able to do now. And @davidgraeff sadly is not involved in the binding development anymore, so changing is not going to be an easy task. @jochen314, do you understand why the binding behaves like that? Do you agree with me that this should be changed? I would like to hear your opinion before doing anything :wink:

Skinah commented 3 years ago

@digitlength There is now a merged WLED binding that you can use which completely bypasses the MQTT system as it uses HTTP to talk to the esp device.

digitlength commented 3 years ago

Thanks @Skinah, I'm aware of the WLED binding - great work!

This issue uses WLED as an example implementation, but it's more about the confusing behaviour with the on and off parameters, as @bodiroga has confirmed.

sovapatr commented 3 years ago

I took a stab at this as I was having the same issue trying to use zwavejs2mqtt. PercentageValue.java

So far it has been working well for me.

openhab-bot commented 3 years ago

This issue has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/mqtt-mapping-outgoing-command-to-value/89756/31

brlodi commented 3 years ago

I'm also running into this problem, similarly to @sovapatr, with ZwaveJS2MQTT.

To provide a concrete use-case, per the spec Zwave dimmers expose only a "level" option which is an integer in the range [0-99], with 0 representing 'off'. It can also additionally accept the special value 255, which is interpreted as "if you are currently off, turn on to your last brightness before you were turned off".

Currently accessing this functionality requires two Channels pointed at the same MQTT topic:

Type dimmer : brightness [ min=0, max=99, step=1, stateTopic="foo", commandTopic="bar" ]`
Type switch : power [
    stateTopic="foo",
    transformationPattern="{ transform mapping positive ints to ON}",
    commandTopic="bar"
  ]

with associated separate Items. To get it working in a seamless way ends up requiring 2 Channels, 3 Items (one for each channel and one proxy), and a Rule.

Ideally one should be able to do simply

Type dimmer : brightness [ min=0, max=99, step=1, on=255, stateTopic="foo", commandTopic="bar" ]`

and have one resulting Item in a straightforward way.

In my experience this isn't purely a Zwave-related thing, but is a very common pattern in MQTT-compatible devices.

jochen314 commented 3 years ago

I am sorry, but I also do not have any background on why the channels behave the way they do. My best guess it, that the focus during development was on the messages received from the device. So the device can sent another string to indicate 'ON' I would feel happy with separating the handling of messages from and to the device in the code. So receiving a message would update the state, Sending a message could update the state and decide, what message is actually transmitted to the device.

The biggest concern I would have with this is compability. We might need to deprecate the current types and create new ones with the nwe behavour.

Rossko57 commented 2 years ago

As a side comment, rollershutter type MQTT channels also "autotransform" commands UP/DOWN to fake position 0 100, whether you want that or not. Any fix taken for dimmer should be repeated for rollershutter.

In my view, this is a binding limitation. No matter what scripted transformation a user tries, they cannot distinguish an OFF command from a 0, or ON from 100, because the binding has done its trick first. It's not hard to see that this is needed sometimes, e.g. a dimmer device where "command turn ON" turns on at last brightness, and "command bright 100" does something different.

I think should be fixed, and the "breaking change" accepted/notified, to bring this binding more in line with standard openHAB behaviors.

It would be possible for an affected user to simulate "old" behaviour with a transformationPatternOut="JS:olddimroll.js"

// variable "input" contains command passed by OpenHAB binding
(function(i) {
    var newdata = i ;
    if (i == "OFF" || i == "UP") {
        newdata = 0 ;
    } else if (i == "ON" || i == "DOWN") {
        newdata = 100 ;
    return  newdata ;
})(input)
lsiepel commented 1 year ago

I guess this is still an issue? If so, is the change that is proposed by @sovapatr the right one? If so, could you update your branch to current main and make a PR? If you need any help, let me know and let's try to get this fixed.

sovapatr commented 1 year ago

I've moved to home assistant for my zwave devices and no longer have a build environment. I'm pretty sure I was still having issues with zwave dimmers even after my patch, but I can't remember exactly what it was now. Looking back over at my code it was probably that state was still being set to 100% when it received ON. It probably should have just not set state and waited for the device to send it's state after turning on. But that is just a guess as I can't test it currently.

lsiepel commented 1 year ago

Ok thanks for coming back to this issue. Is there a use case why one would not use the z-wave binding, but use this ZwaveJS2MQTT ? This issue still needs to be resolved. But just asking.

sovapatr commented 1 year ago

My use case was that I wanted to place my z-wave stick in a more central location using a raspberry pi than where my openhab server was. Zwavejs also supported 700 series sticks earlier, allows for much easier firmware updates, and had better support for the security options. It is also nice to have nearly all of my smart devices now accessible over mqtt.

On Fri, Dec 23, 2022, 9:34 AM lsiepel @.***> wrote:

Ok thanks for coming back to this issue. Is there a use case why one would not use the z-wave binding, but use this ZwaveJS2MQTT ? This issue still needs to be resolved. But just asking.

— Reply to this email directly, view it on GitHub https://github.com/openhab/openhab-addons/issues/7991#issuecomment-1364001194, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABFIFNANBRQDO7CRHEIFZJLWOWZ6LANCNFSM4OF3BCHQ . You are receiving this because you were mentioned.Message ID: @.***>