CW/WW and Colour Temperature slider support in custom Light Output

Hi all,

I’ve got a bunch of LOHAS-branded LED lamps that I’ve reflashed to ESPHome, trying to replicate their original behaviour with homeassistant.

I successfully identified the GPIO PWM channels by experimenting with Tasmota. It’s a 5 PWM device (R, G, B, ColdWhite, WarmWhite).

A standard setup with ESPHome gives me this behaviour in HASS:

  • ‘Brightness’, ‘Color Temperature’ and ‘White Value’ sliders, and a colour picker
  • Brightness only controls the RGB brightness
  • White Value only controls the White brightness
  • To see colours, I need to set White Value to 0, Brightness to non-0 and pick a colour
  • To see White, I need to set Brightness to 0, White Value to non-0 and adjust Colour Temperature as needed.

This isn’t great - and confuses the hell out of HomeKit and Alexa.

I found a github issue that almost addresses this problem. I used the code that user envy provides here: https://github.com/esphome/feature-requests/issues/212#issuecomment-498036079

Initially, I altered it slightly, using my cold_white channel in place of white in the code. This works how I want, but has no colour temperature support.

So - I’m trying to add colour temperature support to this code, and hoping I can get some help and advice.

Here’s my naive attempt:
https://paste.ubuntu.com/p/JKX93NFF4K/

Unfortunately, the colour temperature slider is non-functional (I think this is because I’m not setting min/max temperature values in the yaml - but I can’t find the right syntax in the yaml file to provide those to a custom output). Also, the Brightness slider has no effect on the white light - looks like cold_white and warm_white are always at max in the calls to set_level.

Any advice greatly appreciated!

Here you go

          // initialize ledarray (cwww)
          auto traits = id(biome_ledarray).get_traits();
          traits.set_min_mireds(id(g_led)[COLD]);
          traits.set_max_mireds(id(g_led)[WARM]);

The mired value of a light source is equal to ‘1,000,000 / X’ where x equals the colour temperature in Kelvin.

Thanks! I’d almost come to the same answer (I didn’t know how to reference the configured values so hard coded it).

So now colour temp works great. The last problem is that the brightness slider still only works when showing RGB rather than white. Is there a method other than set_level I should be calling to set the brightness of the CW/WW channels?

Thanks!

Here is sample code I use to change brightness, etc on my CWWW led array. It works fine for transitioning from one light scene to another. Not sure what you mean about white not changing. White should change with color temperature changes which I do through set_color_temperature. If the color temperature is not changing then I don’t know that white would change with brightness.

 // light update
        auto sun = id(biome_ledarray).make_call();
        sun.set_state(true);
        sun.set_brightness(brightness);
        if (color_temp) sun.set_color_temperature(color_temp);
        sun.set_transition_length(transition);
        sun.perform();

Thanks! I’ll have a play with set_brightness and see what happens.

By default, this lamp presents a ‘brightness’ slider which affects RGB only. It has an additional slider, ‘white value’, which adjusts the brightness of the white LEDs – the white temperature is a separate, third slider.

The aim of my custom output is to merge the ‘white value’ and ‘brightness’ sliders. There’s a bit of logic to decide if the light is white – basically, check if R, G and B set to the same value. If they are, then the code sets the R G B levels to zero and instead sets the CW and WW levels. If not, it sets CW/WW to zero and sets the R G B levels.

It’s very nearly there now. I can set the colour temperature fine - but I only have maximum-brightness at my set temperature.

I’m wondering if I might have to check the brightness level being set on one of the RGB channels and then use that to scale the values for CW/WW before setting them.

So I’m not a color scientist but perhaps you need to convert your current settings to another color space (perhaps Hue, Saturation and Brightness) modify the values per your controls and then convert back to determine how to set the RGBW values. Just a thought.

@displaced I have a Lohas color bulb as well that I would like to do the same thing with. I’m guessing you are using the my9231 setup in your esphome yaml? Would you mind sharing what channels the red, green, blue, ww, and cw are?

Hi @loralg - the bulbs I’m looking at now aren’t the my9231-based devices. I do have some of those that I need to get working at some point, but I’ll get to those eventually!

The LOHAS WiFi Smart Light Bulb E27, 8W A60 RGB Colour+Tunable White 2700K-6000K LED Bulb is what I’m working on at the moment.

These use regular esp8266_pwm outputs, with the following GPIO assignments:

GPIO5 - Red
GPIO4 - Green
GPIO13 - Blue
GPIO14 - Cold White
GPIO12 - Warm White

I’ve not had a chance yet to play with getting the white brightness working - will try again this evening.

For the my9321-based bulbs, I had a bit of success with the bigcolor1 yaml file and copychan3 code at digiblur’s github. However, if I remember rightly, it had the same weird controls as I’ve discussed here. So I think for those we’ll need to combine the channel-copying code and the custom output code in this thread to get them working well. And figure out the white brightness too, of course!

Good luck!!

1 Like

Ok! Looks like I’ve got there :slight_smile:

I call state->current_values_as_brightness(&brightness); to get the brightness (0.0 to 1.0) that has been set.

Then, when setting the CW and WW levels, I do this->cold_white_->set_level(cold_white * brightness);

I now have the bulbs behaving as I want: CW/WW set according to the desired temperature and brightness when the colour is ‘white’. When a colour is set, the CW/WW LEDs are turned off and the RGB LEDs are set to the desired levels according to the chosen colour and brightness.

I’m just seeing if I can get the min/max mireds values from the config instead of hardcoding them.

1 Like

Pretty new to this, but I have the same issue you had. Same bulbs as well. Could you elaborate a bit on the solution you found? When you say you call “state->current_values_as_brightness(&brightness);”, which file would that be in? Appreciate any advice!

1 Like

Can you please share the final code. Thanks!

Ok! Sorry for the delay everyone – here’s the final code:

The ESPHome YAML is at:
https://paste.ubuntu.com/p/qVK2DFcByn/

The better_rgbww_output.h file is at:
https://paste.ubuntu.com/p/KWBTMqn9mg/

Hope this helps! I’m in the middle of sanitising my configs and using secrets throughout so that I can eventually get the whole lot up into github.

Hope this helps some people!

Chris

[EDIT]: Just noticed a couple of oddities in the .h file - mainly a symptom of hacking-at-it-until-it-worked.

I’ve got two calls to traits.set_supports_color_temperature(true); – you can safely remove one.

Also, I’ve still got hardcoded min/max minred values. This should be altered to pull values from the YAML config, but I didn’t get around to that – any fixes welcome!

6 Likes

Thanks for this! The default behavior, while workable, was far from ideal – especially when using Google Home to change colors, etc. This works just the way I hoped it would!

Ah - glad it’s working for you too!

I don’t think it’s exactly the same as the stock configuration. I feel like the colour output is dimmer than it should be. I reckon the stock firmware probably mixes a bit of CW/WW in with the RGB to achieve a brighter appearance. But this is good enough for me.

Hi,
there are two PR in esphome, can you please compare it with your code?


Can you also create PR, please?
Maybe light behaviour/computation can be selected by some new configuration option, if it makes sense?

Thanks

Libor

1 Like

Just like to say thank you, this is great. I’ve now almost got the expected behaviour from my RGBWW lights.

It works fine when the RGB colour wheel is set to white, however, there are two points to note:

  1. The transition from “RGB white” to the white only LED’s it a bit harsh - the transition to “RGB white” happens smoothly then the white only LED’s come on with no transition - big jump in colour temp/brightness.
  2. I found it didn’t work when using google home to change from a non-white colour to white. This is due to the parameters being sent from google home only includes the colour temperature - no RGB values - so the colour wheel stays on whatever colour it was previously. This was easily fixed by getting Node Red to listen to the command from google assistant and if it contains a temp value then set RGB to 255,255,255.

Finding this thread is exactly what I needed!
I picked up some Lohan ZH-ZN037E bulbs (Tuya) that have CW and WW LED’s and found the built in integrations for these bulbs just don’t handle the two W LEDs well at all. I had put one bulb on ESPhome (the other is still on Tasmota while I test) and found the correct pinouts thanks to @displaced’s info earlier. Puzzling through how to get the .h and custom light into my hass setup was also a learning experience. But I’ve confirmed, now scenes can correctly set the CW/WW levels, which the stock rgbw component just wouldn’t do.

Victory!! Thanks so much for your work.

ps - the transition being not-smooth doesn’t even bother me. figuring out how to non-hardcode the mireds, is beyond my abilities at this time.

my project: three of these bulbs in my yard light. most of the time they’ll just be dim white or bright white (dusk and sunset). but on holidays or special occasions, i’ve a list of scenes ready to go :slight_smile:

edit: the color wheel/sliders are very visually janky, shifting formatting in the dialog “back and forth” many times a second, don’t know what that is all about? shows poorly on chrome and didn’t do that at all before I set this config in.

This works very well. I just used the better_rgbww_output.h with some Feit Electric OM60/RGBW/CA/AG/3 that I picked up at Lowe’s. Here is the relevant part of the esphome configuration:

substitutions:
  device_name: feit_01
  friendly_name: "Feit 01 Light"

esphome:
  name: ${device_name}
  platform: ESP8266
  board: esp01_1m
  includes:
    - better_rgbww_output.h

sm16716:
  data_pin: GPIO04
  clock_pin: GPIO05
  num_channels: 3
  num_chips: 1

output:
  - platform: sm16716
    id: output_red
    channel: 2
    power_supply: rgb_power
  - platform: sm16716
    id: output_green
    channel: 1
    power_supply: rgb_power
  - platform: sm16716
    id: output_blue
    channel: 0
    power_supply: rgb_power
  - platform: esp8266_pwm
    id: output_cold_white
    pin: GPIO12
  - platform: esp8266_pwm
    id: output_warm_white
    pin: GPIO14


light:
  - platform: custom
    lambda: |-
      auto light_out = new BetterRGBWLightOutput(id(output_red), id(output_green), id(output_blue), id(output_cold_white), id(output_warm_white));
      App.register_component(light_out);
      return {light_out};
    lights:
      - name: ${friendly_name}

power_supply:
  - id: rgb_power
    pin: GPIO13

Thanks for the great work!

Great!! I’m not a programmer, not an IT guy, only an happy enthusiast who discovered all these geek things at the end of 2019. Wasn’t sure how to use your solution, but I think I got it.

I use a RGBWW bulb Aigital LE13 from Amazon. If someone has the same bulb, GPIO are : red (GPIO15), green (GPIO5),blue (GPIO12), cold_white (GPIO14) warm_white (GPIO4). I used your ESPHOME Yaml to add some of yours and the better_rgbww_output.h went to the folder /config/esphome/better_rgbww_output.h

It seems to work awesome and look like that in HA :

Since the last update, white no longer works. Any ideas?

UPDATE POST : I returned to version 1.14.5 of ESPhome. Seems to correct the problem, but the the light twinkle a little. Any solution?