esphome / feature-requests

ESPHome Feature Request Tracker
https://esphome.io/
418 stars 26 forks source link

New RGBWithW light type to circumvent weird white channel handling in HA #212

Closed envy closed 5 years ago

envy commented 5 years ago

Describe the problem you have/What new integration you would like I flashed ESPHome onto my H801 as shown an the cookbook and then run into https://github.com/home-assistant/architecture/issues/123. Having a separate slider for white brightness is really weird, especially if it means that I have to turn on the RGB LEDs to use the whites.

Please describe your use case for this integration and alternatives you've tried: My expectation would have been this behaviour: Same UI as a RBG light, so color picker and brightness slider. However, when selecting white as a color, the RGB LEDs switch off and the white LEDs switch on. That way, white is really white. Brightness should obviously still work for white but same brightness for white and color. I would've just created a custom light, but this does not seem possible (like a custom sensor).

Additional context I actually have a prototype working, however the transition from color->white and white->color is a bit hard. It advertises itself as a RGB light but if you select the color white (i.e. all color values are the same) the RGB LEDs are turned off and the white LEDs are turned on.

So I would like to spark a discussion if such a new "workaround" light type should be added or if one should wait until HA fixes that on their part. Obviously a better name than "RGBWithW" needs to be found.

envy commented 5 years ago

Instead of having a new light type, it would also be possible to add an optional white channel to the rgb light that is used to create white when it's configured. If not configured, the rgb LEDs are used.

OttoWinter commented 5 years ago

However, when selecting white as a color, the RGB LEDs switch off and the white LEDs switch on.

That sounds like a bodge-solution to me. Yes technically we could do that but it would be very limited. Plus it would be workaround for a problem in HA - I wouldn't want to introduce a new platform to work around an issue in HA.

Adding a white option to the RGB also doesn't sound like a good option - the platform is called RGB after (no w in there).

This should be fixed in HA, not ESPHome.

envy commented 5 years ago

However, when selecting white as a color, the RGB LEDs switch off and the white LEDs switch on.

That sounds like a bodge-solution to me. Yes technically we could do that but it would be very limited. Plus it would be workaround for a problem in HA - I wouldn't want to introduce a new platform to work around an issue in HA.

I what way would it be limited? I have that running in a fork and even effects work. The only bad thing is the transition from/to white is kind of hard.

But yes, I agree that it should be fixed in HA.

Adding a white option to the RGB also doesn't sound like a good option - the platform is called RGB after (no w in there).

This should be fixed in HA, not ESPHome.

What if a TemplateLight is introduced instead? ESPHome hast TemplateSensor/Switch, why not TemplateLight? I think I could build my desired functionality in a template with lambdas. This would also offer more flexibility for other people.

envy commented 5 years ago

Hi,

I was able to use the new CustomLight platform to create my desired behaviour.

My custom light looks like this:

#pragma once

#include "esphome.h"

class BetterRGBWLightOutput : public Component, public LightOutput {
    public:
    BetterRGBWLightOutput(FloatOutput *red, FloatOutput *green, FloatOutput *blue, FloatOutput *white)
    {
        red_ = red;
        green_ = green;
        blue_ = blue;
        white_ = white;
    }

    LightTraits get_traits() override {
        auto traits = LightTraits();
        traits.set_supports_brightness(true);
        traits.set_supports_rgb(true);
        return traits;
    }

    void write_state(LightState *state) override {
        float red, green, blue, white;
        state->current_values_as_rgb(&red, &green, &blue);
        if (red == green && red == blue)
        {
            this->red_->set_level(0);
            this->green_->set_level(0);
            this->blue_->set_level(0);
            this->white_->set_level(red);
        }
        else
        {
            this->red_->set_level(red);
            this->green_->set_level(green);
            this->blue_->set_level(blue);
            this->white_->set_level(0);
        }
    }

    protected:
    FloatOutput *red_;
    FloatOutput *green_;
    FloatOutput *blue_;
    FloatOutput *white_;
};

And configuration for my H801:

output:
  - platform: esp8266_pwm
    id: red
    pin: 13
    frequency: 1000 Hz
  - platform: esp8266_pwm
    id: green
    pin: 15
    frequency: 1000 Hz
  - platform: esp8266_pwm
    id: blue
    pin: 12
    frequency: 1000 Hz
  - platform: esp8266_pwm
    id: white
    pin: 14
    frequency: 1000 Hz

light:
  - platform: custom
    lambda: |-
      auto light_out = new BetterRGBWLightOutput(id(red), id(green), id(blue), id(white));
      App.register_component(light_out);
      return {light_out};
    lights:
      - name: "wznico_led_tv"