Core: MQTT: Brightness should not be applied when brightness commands are present

Created on 6 Apr 2018  路  14Comments  路  Source: home-assistant/core

Home Assistant release with the issue: 0.66.1 (+ dev branch as of writing this)

Last working Home Assistant release (if known): N/A

Operating environment (Hass.io/Docker/Windows/etc.): x86-x64 Docker

Component/platform: light.mqtt including light.mqtt_json and light.mqtt_template

Description of problem: The brighness should not be applied when brightness_* commands exist in config otherwise it'd apply brightness twice to the light.

For example:

  1. User set color to red [255,0,0] -> (MQTT: H801-200/rgb/set/[255,0,0])
  2. User set brightness to 50% -> (MQTT: H801-200/brightness/set/0.5)
  3. User click on red again -> HA apply brightness -> (H801-200/rgb/set/[128,0,0]) -> Device apply 50% brightness as well -> [64,0,0]

As you can see the correct value would be [128,0,0] but since Home Assistant & the device applied the 50% brightness it'll show [64,0,0] instead.

Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant):

light:
  - name: H801_200
    platform: mqtt
    state_topic: H801-200/relay/0
    command_topic: H801-200/relay/0/set
    availability_topic: H801-200/status
    brightness_state_topic: H801-200/brightness
    brightness_command_topic: H801-200/brightness/set
    rgb_state_topic: H801-200/rgb
    rgb_command_topic: H801-200/rgb/set

Traceback (if applicable):

https://github.com/home-assistant/home-assistant/blob/3394916a68122913c7b066b50d217cfe298914eb/homeassistant/components/light/mqtt.py#L427-L428

https://github.com/home-assistant/home-assistant/blob/3394916a68122913c7b066b50d217cfe298914eb/homeassistant/components/light/mqtt_json.py#L319-L320

https://github.com/home-assistant/home-assistant/blob/3394916a68122913c7b066b50d217cfe298914eb/homeassistant/components/light/mqtt_template.py#L309-L310

Additional information:

Is this a bug or should I fix this on device level? How do other devices handle it? Ref: https://github.com/xoseperez/espurna/issues/755

Most helpful comment

That's basically what I did when I added "on_command_type" as an input to allow for backward compatibility. So something like "rgb_with_brightness" ("rgb_old_method" isn't a good name - they should be descriptive of the behavior) and set it to true/false would be a good option. I can take a look at adding that next week some time.

All 14 comments

Here is some debug log:

// Turn ON
2018-04-07 10:53:52 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on H801-201/rgb: b'255,0,0'
2018-04-07 10:53:52 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on H801-201/brightness: b'255'
2018-04-07 10:53:52 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on H801-201/relay/0: b'1'

//Change Brightness:
2018-04-07 10:53:58 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on H801-201/rgb: b'255,0,0'
2018-04-07 10:53:58 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on H801-201/brightness: b'115'

//Click on same color again:
2018-04-07 10:54:05 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on H801-201/rgb: b'115,0,0'
2018-04-07 10:54:05 DEBUG (MainThread) [homeassistant.components.mqtt] Received message on H801-201/brightness: b'115'

This is pretty much expected due to Home Assistants API design and I think this should be handled on the controller side. Especially with the light.mqtt platform this is expected, and quite a few integrations seem to depend on this behavior. However, the light.mqtt_json actually shouldn't do this, it automatically packages all information from the turn_on call into a single JSON payload. So the brightness and RGB will not result in two MQTT messages. For your project, I would definitely recommend using the mqtt_json platform, it just makes handling edge cases with the order of receiving commands much easier. It's also how esphomelib does it.

I don't know - I tend to agree with @Skaronator. If HA sends a brightness topic, it shouldn't apply that setting to the other values. I think that if there is not brightness topic set, then yes, it should apply the setting to the RGB values (and emit a new RGB message when the brightness is changed) - or does HA turn off the brightness control if there is not brightness topic (I can't remember)?. I think the logic would work if brightness was always sent when any change is made. Perhaps something like this:

  • device has brightness topic:

    • initial: color=255,255,255 brightness=1.0
    • change RGB red -> send color=255,0,0; send brightness=1.0
    • change brightness to 50% -> send brightness=0.5
    • change RGB green -> send color=0,255,0; send brightness=0.5
  • device has no brightness topic:

    • initial: color=255,255,255 brightness=1.0
    • change RGB red -> send color=255,0,0
    • change brightness to 50% -> send color=128,0,0
    • change RGB green -> send color=0,128,0

Thoughts?

I did a quick test. Currently you can't change the brightness when you remove the brightness_command_topic.

image

It might be good moment to add a brightness slider even if the device doesn't have a brightness topic.

Brightness and color are two different things! The RGB color topic/mqtt_json section is strictly only for the color of the light not how bright that color should be. I guess this behavior can best be described by the internal color representation: internally Home Assistant uses the HS color space to represent colors. As you see in the color wheel in the front end, the color is only there to set the hue and saturation of a light, not how bright the light should be.

For example, all the messages you receive on the rgb topic will always have at least one color component be equal to 255. Only the brightness topic describes how bright the light should actually be.

@TD22057 The design of the MQTT platforms in Home Assistant is made in such a way that only the properties that have really changed are sent. Every controller that receives these messages is expected to hold the light state internally.

@Skaronator As I said, brightness and color are two different things. While it's highly unlikely that there are any lights that only support color and not brightness, I think we should keep these two separate for consistency.

I think the obvious solution if you're trying to create a controller/receiver for this integration is to store the brightness and RGB color separately and compute the actual outputted color by multiplying the two.

When brightness and color are two different things then it should it be sperated in HA as well. Currently HA apply the brightness to the RGB values...

 rgb = color_util.color_hsv_to_RGB( 
-     hs_color[0], hs_color[1], brightness / 255 * 100) 
+     hs_color[0], hs_color[1], 255) 

I think the obvious solution if you're trying to create a controller/receiver for this integration is to store the brightness and RGB color separately and compute the actual outputted color by multiplying the two.

Thats what I'm already doing but Home Assistant sends RGB values which include the brightness.

https://github.com/xoseperez/espurna/blob/b5b534877fa2a51f48fdec72092f7c8d6bf9be9d/code/espurna/light.ino#L119-L121

Oh, that's bad. Now I understand your point. The problem is that we can't really update these platforms very well because many implementations depend on the current behavior, so changing anything in there about brightness would break lots of devices (for which updates are sometimes very difficult). The current behavior is definitely weird.

I've created a PR adding HSV color support for the mqtt_json light platform here: #14029. It should fix the issue.

Would it be possible to change (fix) the default behaviour and add a option to switch back to the old way?

  - platform: mqtt
    name: H801_201
    state_topic: H801-201/relay/0
    command_topic: H801-201/relay/0/set
    payload_on: 1
    payload_off: 0
    availability_topic: H801-201/status
    payload_available: 1
    payload_not_available: 0
    brightness_state_topic: H801-201/brightness
    brightness_command_topic: H801-201/brightness/set
    rgb_state_topic: H801-201/rgb
    rgb_command_topic: H801-201/rgb/set
+   rgb_old_method: true

Depending on how it has been implemented (on device base) it should work fine with old and the fixed way.

That's basically what I did when I added "on_command_type" as an input to allow for backward compatibility. So something like "rgb_with_brightness" ("rgb_old_method" isn't a good name - they should be descriptive of the behavior) and set it to true/false would be a good option. I can take a look at adding that next week some time.

I just ran into the same problem described by @Skaronator. I would really appriciate if the brightness behaviour would be changed.

I also just hit this issue, and would very much appreciate a flag to correct the behaviour :)

Fixed by #15053

Cool thanks!

@Skaronator @TD22057 as it seems there has been a FIX for issue, with the latest version I still have this problem. Could you please tell me how to fix this? I use H801 controller with tasmota - change of colour looses brightness setting and make it 100% again.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aguilaair picture aguilaair  路  162Comments

soldag picture soldag  路  143Comments

Ciqsky picture Ciqsky  路  129Comments

Bergasha picture Bergasha  路  176Comments

rschaeuble picture rschaeuble  路  230Comments