StyraHem / ShellyForHASS

Shelly smart home platform for Home Assistant
MIT License
620 stars 111 forks source link

[BUG] Color brightness doesn't do anything (RGBW2) #559

Open david-kalbermatten opened 3 years ago

david-kalbermatten commented 3 years ago

Environment

Describe the bug

Currently, the UI shows a color brightness slider that doesn't do anything. I don't know what the official best practice is for RGBW lights and how they should behave... (maybe color/white mixing?)

Steps to Reproduce

Open the UI for a Shelly RGBW2

Expected behavior

Honestly, I don't know how it should behave since I wasn't able to find any documentation on best practices for these kinds of lights but I think that the current implementation isn't how it should be since you can't control the brightness of the lights in Google Home when only using white.

Screenshots

image image

Additional context

I have asked about implementing the white/color brightness controls in a different way before in #355. But back then @hakana argued that he can't cover all use-cases (fair enough).

Change in Home Assistant Core 2021.05 https://www.home-assistant.io/blog/2021/05/05/release-20215/#color-modes

rrkarman commented 2 years ago

I am experiencing what I believe to be a related issue in Shelly for HASS. I can not set the color channels (brightness) to 0% (off) the lowest it will go is 1%. This always includes a color tint in my white channel especially at low levels. I can set color on the RGBW2 to 0% in the WebUI or through the Cloud but Shelly for HASS always resets it to 1%. Can you please allow a 0% brightness level for the colors? -- Also may be related but I can not set the "Color Brightness" slider (below the color wheel) to 0% either. It always bounces back to 100%.

Shelly for HASS 0.2.2 Home Assistant: core-2021.11.1

hakana commented 2 years ago

I have been looking on this but not found a good solution. I would like to disable the main brightness and only show the Color and white brightness. But I can't make it work like that, I guess there is a bug in HA.

The main brightness can only be 1-100% so no way to get 0% from it.

Also the color brightness is not sent to the component so I can't use it nether.

If someone knows how to solve this or can try to find anyone knowing this in some HA forums it will help me a lot!

david-kalbermatten commented 2 years ago

The issue I see is the lack of an overall brightness control in the API of the Shelly RGBW2, you'd have to emulate that in code which in turn could cause issues when the lights are controlled externally...

Ideally, you'd want a brightness slider and then individual mixing sliders for white and color. However, the Shelly API doesn't seem to have such an option and only exposes the two absolute values for color and white.

I worked around this in a template where I simplify the capabilities of the light by removing the option of controlling the white channel separately, instead treating "rgb white" as a white channel.

image This is not an ideal solution but it allows me to control the white brightness of my Shelly RGBW2 through Google Assistant which I couldn't do before because "white" was just the rgb white and the white channel wasn't controllable through Google Assistant.

hakana commented 2 years ago

@david-kalbermatten So you mean when you select the white color it switches over to use the white channel only?

Can you share the template and maybe I understand better.

david-kalbermatten commented 2 years ago

@david-kalbermatten So you mean when you select the white color it switches over to use the white channel only?

Can you share the template and maybe I understand better.

Yes, but it's by no means pretty...

PS: I did a similar thing for the Shelly Bulbs to automatically switch them between color mode and white mode

# smart_white.py

entity_id = data.get('entity_id')

def fetch_color():
    if data.get('hs_color') is None or data.get('hs_color') == "":
        return hass.states.get(entity_id).attributes.get('hs_color')
    else:
        return data.get('hs_color')

def fetch_brightness():
    if data.get('brightness') is None or data.get('brightness') == "":
        return hass.states.get(entity_id).attributes.get('brightness')
    else:
        return data.get('brightness')

hs_color = fetch_color()
brightness = fetch_brightness()
white_value = hass.states.get(entity_id).attributes.get('white_value')

is_off = hass.states.is_state(entity_id, "off")
is_color = data.get('hs_color') is not None and data.get('hs_color') != ""
is_brightness = data.get('brightness') is not None and data.get('brightness') != ""
is_restore = is_color and is_brightness

# construct state
state_to_be = {"entity_id": entity_id}

if is_off and not is_restore:
    start_time = time.time()
    hass.services.call('light', 'turn_on', state_to_be, False)
    while is_off:
        hs_color = fetch_color()
        brightness = fetch_brightness()
        white_value = hass.states.get(entity_id).attributes.get('white_value')
        is_off = hass.states.is_state(entity_id, "off")
        if time.time() - start_time > 5: # Abort condition
            break

if is_off and is_restore:
    white_value = 0

if hs_color[1] <= 40: # Case: White
    state_to_be['hs_color'] = [hs_color[0], 0]
    state_to_be['brightness'] = 5
    if white_value > 0 and not is_brightness:
        state_to_be['white_value'] = white_value
    else:
        state_to_be['white_value'] = brightness
else: # Case: Color
    state_to_be['hs_color'] = hs_color
    state_to_be['white_value'] = 0
    if white_value > 0 and not is_brightness: # Case: Switch from White
        state_to_be['brightness'] = white_value
    elif is_brightness or is_restore:
        state_to_be['brightness'] = brightness

# Send Light On Command with Attributes
hass.services.call('light', 'turn_on', state_to_be, True)
# services.yaml

smart_white:
  description: Turns On an RGBW Light with smartly handled white_value
  fields:
    entity_id:
      description: The light that will be controlled
      example: light.bedroom
    brightness:
      description: The brightness of the light
      example: 255
    hs_color:
      description: The hs_color value that is used
      example: [255, 55]
    debug_mode:
      description: Turn on or off whether or not to show warnings to debug the script
      example: False
# lights.yaml

- platform: template
  lights:
    main_light:
      unique_id: main_light_smart
      friendly_name: "Main Light"
      icon_template: mdi:led-strip
      value_template: "{{ is_state('light.shelly_shrgbw2_xxxxxx', 'on') }}"
      level_template: >
        {% if state_attr('light.shelly_shrgbw2_xxxxxx', 'white_value') | int > 0 and is_state('light.shelly_shrgbw2_xxxxxx', 'on') %}
          {{state_attr('light.shelly_shrgbw2_xxxxxx', 'white_value')}}
        {% elif state_attr('light.shelly_shrgbw2_xxxxxx', 'white_value') | int == 0 and is_state('light.shelly_shrgbw2_xxxxxx', 'on') %}
          {{state_attr('light.shelly_shrgbw2_xxxxxx', 'brightness')}}
        {% else %}
          0
        {% endif %}
      color_template: >
        {% if is_state('light.shelly_shrgbw2_xxxxxx', 'on') %}
          {{ state_attr('light.shelly_shrgbw2_xxxxxx', 'hs_color') }}
        {% else %}
          (0,0)
        {% endif %}
      turn_on:
        service: python_script.smart_white
        data:
          entity_id: light.shelly_shrgbw2_xxxxxx
          brightness: "{{ brightness }}"
          hs_color: "{{ hs }}"
      turn_off:
        service: light.turn_off
        entity_id: light.shelly_shrgbw2_xxxxxx
      set_level:
        service: python_script.smart_white
        data:
          entity_id: light.shelly_shrgbw2_xxxxxx
          brightness: "{{ brightness }}"
          hs_color: "{{ hs }}"
      set_color:
        service: python_script.smart_white
        data:
          entity_id: light.shelly_shrgbw2_xxxxxx
          brightness: "{{ brightness }}"
          hs_color: "{{ hs }}"