arachnetech / homebridge-mqttthing

A plugin for Homebridge allowing the integration of many different accessory types using MQTT.
Apache License 2.0
467 stars 104 forks source link

dimmable light - turn on without setting brightness #452

Open bahamas10 opened 3 years ago

bahamas10 commented 3 years ago

Hello!

Background

I have a question about a dimmable zwave light i have accessible through mqtt. My config looks like this:

    {
      "accessory": "mqttthing",
      "type": "lightbulb",
      "name": "Patio Rope Lights",
      "url": "mqtts://mqtt:8883",
      "username": "zwavejs2mqtt",
      "password": "foo",
      "logMqtt": true,
      "topics": {
        "getOnline": "zwavejs2mqtt/Outside/Patio_Rope_Lights/status",
        "setOn": "zwavejs2mqtt/Outside/Patio_Rope_Lights/38/0/targetValue/set",
        "getOn": {
          "topic": "zwavejs2mqtt/Outside/Patio_Rope_Lights/38/0/currentValue",
          "apply": "return message != 0"
        },
        "setBrightness": "zwavejs2mqtt/Outside/Patio_Rope_Lights/38/0/targetValue/set",
        "getBrightness": "zwavejs2mqtt/Outside/Patio_Rope_Lights/38/0/currentValue"
      }
    }

This is a GE dimmer switch that supports on/off and set/get brightness (values are 0-100, where 0 means the lights are off).

There are 2 mqtt topics that are of note here:

  1. .../targetValue/set
  2. .../currentValue

the targetValue/set topic is somewhat overloaded, and can be sent the following values:

  1. true - turn the dimmer on, brightness will be the last value set when turned off
  2. false - turn the dimmer off
  3. 0-100 - set the brightness manually, 0 will turn the dimmer off, 1-100 will turn it on (if it is off)

the currentValue topic will only contain an integer 0-100. 0 signifies off, >0 signifies on.

Because of this, I have setOn and setBrightness using the same topic, since setOn will send a boolean value (which is supported), and setBrightness will send an int 0-100 (which is also supported).

getOn and getBrightness also use the same topic, but the getOn topic has a small apply function to handle 0 as off, and not 0 as on.


My Issue

The issue I have seems very specific. Almost everything I want with this light works as expected, except for one small detail.

When turning on the light (from the off-state) in home kit I noticed 2 messages are published via mqtt:

zwavejs2mqtt/Outside/Patio_Rope_Lights/38/0/targetValue/set 100
zwavejs2mqtt/Outside/Patio_Rope_Lights/38/0/targetValue/set true

I want the boolean value to be sent, but i don't want the brightness to be manually set to 100 when turning it on from nothing - is this possible?

I can't really trace if the issue i'm having is in homekit, homebridge, homebridge-mqttthing, or my config. Any pointers on this would be appreciated... all I need is the initial brightness value to not be sent when the light is toggled on from the homekit UI.

economycomfort commented 3 years ago

@bahamas10 did you ever sort this out? I have a similar issue with my GE dimmer switch.

jaredoconnor commented 2 years ago

Hello, from the future. I think I found a solution, but it feels like a hack.

My dimmers are from Zooz, but I believe all Z-Wave dimmers use the "multilevel switch" device class, where 0-99 set the dimmer level, 0 turns the switch off and 255 turns the switch on (with the last known dimmer level). Below is what happens when setting the dimmer level, with MQTTThing controlling the dimmer and switch via the same topic.

zwave/Office/Office_Dimmer/38/0/targetValue/set 41
zwave/Office/Office_Dimmer/38/0/targetValue/set 255
zwave/Office/Office_Dimmer/38/0/currentValue 41
zwave/Office/Office_Dimmer/38/0/targetValue 41
zwave/Office/Office_Dimmer/38/0/targetValue 255
zwave/Office/Office_Dimmer/38/0/targetValue 87
zwave/Office/Office_Dimmer/38/0/currentValue 87

The dimmer was set to ~40% (41), but MQTTThing also sent the "on" (255) value. Sending the "on" value has the side effect of immediately setting the dimmer level back to the last known value (87). Putting the controls on separate topics allows optimizePublishing to be used, which stops MQTTThing from continually sending the switch state. Thus, we can avoid the problem of having the switch value override the dimmer value.

{
    "type": "lightbulb-Dimmable",
    "name": "Office Dimmer",
    "topics": {
        "getOn": {
            "topic": "zwave/Office/Office_Dimmer/38/0/targetValue",
            "apply": "return message > 0 ? 255 : 0"
        },
        "setOn": {
            "topic": "zwave/Office/Office_Dimmer/38/0/targetValue/set",
            "apply": "return message"
        },
        "getBrightness": {
            "topic": "zwave/Office/Office_Dimmer/38/0/currentValue",
            "apply": "return Math.round(message / 0.99)"
        },
        "setBrightness": {
            "topic": "zwave/Office/Office_Dimmer/38/0/currentValue/set",
            "apply": "return Math.round(message * 0.99)"
        }
    },
    "onValue": 255,
    "offValue": 0,
    "optimizePublishing": true,
    "accessory": "mqttthing"
}

Below is what happens, with the above configuration. Note that mapping targetValue to 0 or 255 (message > 0 ? 255 : 0) is necessary, because that allows physical switch control to function properly.

zwave/Office/Office_Dimmer/38/0/currentValue/set 42
zwave/Office/Office_Dimmer/38/0/currentValue 42
zwave/Office/Office_Dimmer/38/0/targetValue 42
zwave/Office/Office_Dimmer/38/0/targetValue 42
zwave/Office/Office_Dimmer/38/0/duration {"value":0,"unit":"seconds"}
zwave/Office/Office_Dimmer/38/0/currentValue 42

When turning the switch on, HomeKit will initially show the dimmer level as 0%. After a second or two, it will update to the actual value. I don't understand what is causing the delay, because the currentValue update occurs almost immediately.

zwave/Office/Office_Dimmer/38/0/targetValue/set 0
zwave/Office/Office_Dimmer/38/0/currentValue 0
zwave/Office/Office_Dimmer/38/0/targetValue 0
zwave/Office/Office_Dimmer/38/0/targetValue 0
zwave/Office/Office_Dimmer/38/0/duration {"value":0,"unit":"seconds"}
zwave/Office/Office_Dimmer/38/0/currentValue 0
zwave/Office/Office_Dimmer/38/0/targetValue/set 255
zwave/Office/Office_Dimmer/38/0/targetValue 255
zwave/Office/Office_Dimmer/38/0/targetValue 73
zwave/Office/Office_Dimmer/38/0/duration {"value":0,"unit":"seconds"}
zwave/Office/Office_Dimmer/38/0/currentValue 73

I think the correct solution here is for MQTTThing to have an option to not send the switch value, every time. Alternatively, sending the switch value before the dimmer value should also fix it.

alfredopisano commented 1 year ago

Any other progress/options on this issue? i tried home assistant but i don't like the extra layer of data. i need to stick with home bridge because it has implementations /plugins that Home Assistant doesn't.