Created
November 2, 2019 10:49
-
-
Save madjam002/31cc88640efa370630fed6914fa4eb7f to your computer and use it in GitHub Desktop.
ESPHome Custom RGBW Light with emulated warm/cool white
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "esphome.h" | |
class FrankeverCustomLight : public Component, public LightOutput { | |
public: | |
FrankeverCustomLight(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); | |
traits.set_supports_rgb_white_value(false); | |
traits.set_supports_color_temperature(true); | |
traits.set_min_mireds(153); // home assistant minimum 153 | |
traits.set_max_mireds(500); // home assistant maximum 500 | |
// medium is 326.5 | |
return traits; | |
} | |
void write_state(LightState *state) override { | |
float red, green, blue, cwhite, wwhite, colourTemp; | |
state->current_values_as_rgbww(&red, &green, &blue, &cwhite, &wwhite); | |
colourTemp = state->current_values.get_color_temperature(); | |
// TODO at the moment the lights boot up with cool temperature, can we default to warm? | |
float coolToWarmThreshold = (colourTemp - 153) / (500 - 153); | |
// slowly fade in white LED and fade out colour LEDs | |
float whitePart = std::min(red, std::min(green, blue)); | |
float redPart = red - whitePart; | |
float greenPart = green - whitePart; | |
float bluePart = blue - whitePart; | |
float whiteLightMultiplier = std::min(coolToWarmThreshold * 2.25f, 1.0f); // half way point is full white light, so turn 0.5 -> 1 | |
float colourLightMultiplier = std::max(-(coolToWarmThreshold * 2.25f - 1.0f), 0.0f); | |
float extraRedMultiplier = whitePart * std::max(0.0f, std::min((coolToWarmThreshold - 0.6f) * 2.0f, 1.0f)); // beyond half way is extra warm red | |
float newWhite = whitePart * whiteLightMultiplier; | |
float newRed = (colourLightMultiplier * (red - redPart)) + redPart; | |
float newGreen = (colourLightMultiplier * (green - greenPart)) + greenPart; | |
float newBlue = (colourLightMultiplier * (blue - bluePart)) + bluePart; | |
float newRedWithExtraRed = (extraRedMultiplier * (1 - newRed)) + newRed; | |
// ESP_LOGD("custom", | |
// "colourTemp %f, whitepart %f redpart %f greenpart %f bluepart %f whitemulti %f colourmulti %f extramulti %f newwhite %f newred %f newgreen %f newblue %f newnewred %f", | |
// colourTemp, whitePart, redPart, greenPart, bluePart, whiteLightMultiplier, colourLightMultiplier, extraRedMultiplier, newWhite, newRed, newGreen, newBlue, newRedWithExtraRed); | |
this->red_->set_level(newRedWithExtraRed); | |
this->green_->set_level(newGreen); | |
this->blue_->set_level(newBlue); | |
this->white_->set_level(newWhite); | |
} | |
protected: | |
FloatOutput *red_; | |
FloatOutput *green_; | |
FloatOutput *blue_; | |
FloatOutput *white_; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
esphome: | |
includes: | |
- frankeverCustomLight.h | |
output: | |
- platform: my9231 | |
id: output_red | |
channel: 3 | |
- platform: my9231 | |
id: output_green | |
channel: 2 | |
- platform: my9231 | |
id: output_blue | |
channel: 1 | |
- platform: my9231 | |
id: output_white | |
channel: 0 | |
light: | |
- platform: custom | |
lambda: |- | |
auto light_out = new FrankeverCustomLight(id(output_red), id(output_green), id(output_blue), id(output_white)); | |
App.register_component(light_out); | |
return {light_out}; | |
lights: | |
- name: "${friendly_name}" | |
default_transition_length: 0.1s | |
restore_mode: ALWAYS_OFF # because powercut could then cause all lights to turn on | |
effects: | |
- random: | |
- strobe: | |
- flicker: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Jamie:
I have made some changes to your code: https://gist.github.com/triphoppingman/76153ddf58072b10e229e9147b2bdf72
This maps the color temp to the RGBW values using a set of linear equations.