Created
November 22, 2019 05:17
-
-
Save triphoppingman/76153ddf58072b10e229e9147b2bdf72 to your computer and use it in GitHub Desktop.
ESPHOME custom light that provides color temperature support to RGBW lights. This differs from the original (see link in the code) by mapping the RGBW from the
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" | |
// Constants | |
const float maxMired = 500; | |
const float minMired = 153; | |
const float scale1 = 1.25f; | |
const float red_offset = 0.4f; | |
const float green_offset = 0.8f; | |
/** | |
* Map a RGBW Light into a tunable color / RGB Light | |
* | |
* Bruce McDonald, Frank Evers (I think) | |
* | |
* derived from: | |
* https://gist.github.com/madjam002/31cc88640efa370630fed6914fa4eb7f | |
*/ | |
class ColorTempRGBWLight : public Component, public LightOutput { | |
public: | |
ColorTempRGBWLight( | |
FloatOutput *red, | |
FloatOutput *green, | |
FloatOutput *blue, | |
FloatOutput *white | |
) { | |
red_ = red; | |
green_ = green; | |
blue_ = blue; | |
white_ = white; | |
// Create initial state | |
colorTemp_ = -1.0f; | |
brightness_ = -1.0f; | |
rgbChanged_ = false; | |
// default scaling | |
cr = 1; | |
br = 0; | |
cg = 0.6; | |
bg = 0; | |
cb = -1.5; | |
bb = 0.5; | |
cw = -0.7; | |
bw = 1; | |
} | |
/** | |
* Constructor with scaling provided. | |
*/ | |
ColorTempRGBWLight( | |
FloatOutput *red, | |
FloatOutput *green, | |
FloatOutput *blue, | |
FloatOutput *white, | |
float _br, | |
float _cr, | |
float _bg, | |
float _cg, | |
float _bb, | |
float _cb, | |
float _bw, | |
float _cw | |
) { | |
red_ = red; | |
green_ = green; | |
blue_ = blue; | |
white_ = white; | |
// Create initial state | |
colorTemp_ = -1.0f; | |
brightness_ = -1.0f; | |
rgbChanged_ = false; | |
// Configured scaling | |
cr = _cr; | |
br = _br; | |
cg = _cg; | |
bg = _bg; | |
cb = _cb; | |
bb = _bb; | |
cw = _cw; | |
bw = _bw; | |
} | |
/** | |
* Get the traits for this light | |
*/ | |
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(minMired); // home assistant minimum 153 | |
traits.set_max_mireds(maxMired); // home assistant maximum 500 | |
return traits; | |
} | |
/** | |
* Write the state to this light | |
*/ | |
void write_state(LightState *state) override { | |
float colorTemp, brightness; | |
state->current_values_as_brightness(&brightness); | |
colorTemp = state->current_values.get_color_temperature(); | |
// If the color temp changed or the color temp is unchanged but the brightness is changed then process that. | |
if(colorTemp != colorTemp_ || (!rgbChanged_ && brightness != brightness_)) { | |
// Normalize the colorTemp | |
float xaxis = (colorTemp - minMired) / (maxMired - minMired); // Varies from 0 to 1 as it moves from MIN to MAX | |
// Place the rgb values on three lines | |
float red = std::min(std::max((cr * xaxis + br) * brightness,0.0f), 1.0f); | |
float green = std::min(std::max((cg * xaxis + bg) * brightness,0.0f), 1.0f); | |
float blue = std::min(std::max((cb * xaxis + bb) * brightness,0.0f), 1.0f); | |
float white = std::min(std::max((cw * xaxis + bw) * brightness,0.0f), 1.0f); | |
this->red_->set_level(red); | |
this->green_->set_level(green); | |
this->blue_->set_level(blue); | |
this->white_->set_level(white); | |
// ESP_LOGD("custom", | |
// "Outputs: Xaxis: %f, Red %f, Green %f Blue %f White %f", | |
// xaxis, xaxis * brightness, xaxis/2.5f * brightness, std::max(-xaxis * 2 + 2, 0.0f) * brightness, (-xaxis * 0.6 + 1) * brightness); | |
// Store this | |
colorTemp_ = colorTemp; | |
rgbChanged_ = false; | |
} else { | |
float red, green, blue, cwhite, wwhite; | |
state->current_values_as_rgbww(&red, &green, &blue, &cwhite, &wwhite); | |
this->red_->set_level(red); | |
this->green_->set_level(green); | |
this->blue_->set_level(blue); | |
this->white_->set_level(0); | |
// remember a color change | |
rgbChanged_ = true; | |
} | |
brightness_ = brightness; | |
} | |
protected: | |
FloatOutput *red_; | |
FloatOutput *green_; | |
FloatOutput *blue_; | |
FloatOutput *white_; | |
float colorTemp_; | |
float brightness_; | |
bool rgbChanged_; | |
// red intercept and scale | |
float br; | |
float cr; | |
// green intercept and scale | |
float bg; | |
float cg; | |
// blue intercept and scale | |
float bb; | |
float cb; | |
// white intercept and scale | |
float bw; | |
float cw; | |
}; |
Author
triphoppingman
commented
Nov 6, 2023
via email
Go for it.
…On Sun, Nov 5, 2023 at 6:04 PM Lee M ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
Is there any reason why this hasn't been submitted as a PR for ESPHome?
—
Reply to this email directly, view it on GitHub
<https://gist.github.com/triphoppingman/76153ddf58072b10e229e9147b2bdf72#gistcomment-4750580>
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA65QIPMF6IKQJV6UFLWRZTYDALPPBFKMF2HI4TJMJ2XIZLTSKBKK5TBNR2WLJDHNFZXJJDOMFWWLK3UNBZGKYLEL52HS4DFQKSXMYLMOVS2I5DSOVS2I3TBNVS3W5DIOJSWCZC7OBQXE5DJMNUXAYLOORPWCY3UNF3GS5DZVRZXKYTKMVRXIX3UPFYGLK2HNFZXIQ3PNVWWK3TUUZ2G64DJMNZZDAVEOR4XAZNEM5UXG5FFOZQWY5LFVA4TSNRQGYYDSNNHORZGSZ3HMVZKMY3SMVQXIZI>
.
You are receiving this email because you authored the thread.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment