mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 08:55:22 +01:00
Add constant_brightness property to CWWW/RGBWW lights (#1007)
Fixes https://github.com/esphome/feature-requests/issues/460 Co-authored-by: Otto Winter <otto@otto-winter.com>
This commit is contained in:
parent
dea6675c21
commit
8613c02d5c
8 changed files with 41 additions and 16 deletions
|
@ -13,6 +13,7 @@ class CWWWLightOutput : public light::LightOutput {
|
||||||
void set_warm_white(output::FloatOutput *warm_white) { warm_white_ = warm_white; }
|
void set_warm_white(output::FloatOutput *warm_white) { warm_white_ = warm_white; }
|
||||||
void set_cold_white_temperature(float cold_white_temperature) { cold_white_temperature_ = cold_white_temperature; }
|
void set_cold_white_temperature(float cold_white_temperature) { cold_white_temperature_ = cold_white_temperature; }
|
||||||
void set_warm_white_temperature(float warm_white_temperature) { warm_white_temperature_ = warm_white_temperature; }
|
void set_warm_white_temperature(float warm_white_temperature) { warm_white_temperature_ = warm_white_temperature; }
|
||||||
|
void set_constant_brightness(bool constant_brightness) { constant_brightness_ = constant_brightness; }
|
||||||
light::LightTraits get_traits() override {
|
light::LightTraits get_traits() override {
|
||||||
auto traits = light::LightTraits();
|
auto traits = light::LightTraits();
|
||||||
traits.set_supports_brightness(true);
|
traits.set_supports_brightness(true);
|
||||||
|
@ -25,7 +26,7 @@ class CWWWLightOutput : public light::LightOutput {
|
||||||
}
|
}
|
||||||
void write_state(light::LightState *state) override {
|
void write_state(light::LightState *state) override {
|
||||||
float cwhite, wwhite;
|
float cwhite, wwhite;
|
||||||
state->current_values_as_cwww(&cwhite, &wwhite);
|
state->current_values_as_cwww(&cwhite, &wwhite, this->constant_brightness_);
|
||||||
this->cold_white_->set_level(cwhite);
|
this->cold_white_->set_level(cwhite);
|
||||||
this->warm_white_->set_level(wwhite);
|
this->warm_white_->set_level(wwhite);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +36,7 @@ class CWWWLightOutput : public light::LightOutput {
|
||||||
output::FloatOutput *warm_white_;
|
output::FloatOutput *warm_white_;
|
||||||
float cold_white_temperature_;
|
float cold_white_temperature_;
|
||||||
float warm_white_temperature_;
|
float warm_white_temperature_;
|
||||||
|
bool constant_brightness_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cwww
|
} // namespace cwww
|
||||||
|
|
|
@ -7,12 +7,15 @@ from esphome.const import CONF_OUTPUT_ID, CONF_COLD_WHITE, CONF_WARM_WHITE, \
|
||||||
cwww_ns = cg.esphome_ns.namespace('cwww')
|
cwww_ns = cg.esphome_ns.namespace('cwww')
|
||||||
CWWWLightOutput = cwww_ns.class_('CWWWLightOutput', light.LightOutput)
|
CWWWLightOutput = cwww_ns.class_('CWWWLightOutput', light.LightOutput)
|
||||||
|
|
||||||
|
CONF_CONSTANT_BRIGHTNESS = 'constant_brightness'
|
||||||
|
|
||||||
CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({
|
CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({
|
||||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(CWWWLightOutput),
|
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(CWWWLightOutput),
|
||||||
cv.Required(CONF_COLD_WHITE): cv.use_id(output.FloatOutput),
|
cv.Required(CONF_COLD_WHITE): cv.use_id(output.FloatOutput),
|
||||||
cv.Required(CONF_WARM_WHITE): cv.use_id(output.FloatOutput),
|
cv.Required(CONF_WARM_WHITE): cv.use_id(output.FloatOutput),
|
||||||
cv.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
cv.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||||
cv.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
cv.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||||
|
cv.Optional(CONF_CONSTANT_BRIGHTNESS, default=False): cv.boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,3 +29,4 @@ def to_code(config):
|
||||||
wwhite = yield cg.get_variable(config[CONF_WARM_WHITE])
|
wwhite = yield cg.get_variable(config[CONF_WARM_WHITE])
|
||||||
cg.add(var.set_warm_white(wwhite))
|
cg.add(var.set_warm_white(wwhite))
|
||||||
cg.add(var.set_warm_white_temperature(config[CONF_WARM_WHITE_COLOR_TEMPERATURE]))
|
cg.add(var.set_warm_white_temperature(config[CONF_WARM_WHITE_COLOR_TEMPERATURE]))
|
||||||
|
cg.add(var.set_constant_brightness(config[CONF_CONSTANT_BRIGHTNESS]))
|
||||||
|
|
|
@ -190,24 +190,33 @@ class LightColorValues {
|
||||||
|
|
||||||
/// Convert these light color values to an RGBWW representation with the given parameters.
|
/// Convert these light color values to an RGBWW representation with the given parameters.
|
||||||
void as_rgbww(float color_temperature_cw, float color_temperature_ww, float *red, float *green, float *blue,
|
void as_rgbww(float color_temperature_cw, float color_temperature_ww, float *red, float *green, float *blue,
|
||||||
float *cold_white, float *warm_white) const {
|
float *cold_white, float *warm_white, bool constant_brightness = false) const {
|
||||||
this->as_rgb(red, green, blue);
|
this->as_rgb(red, green, blue);
|
||||||
const float color_temp = clamp(this->color_temperature_, color_temperature_cw, color_temperature_ww);
|
const float color_temp = clamp(this->color_temperature_, color_temperature_cw, color_temperature_ww);
|
||||||
const float ww_fraction = (color_temp - color_temperature_cw) / (color_temperature_ww - color_temperature_cw);
|
const float ww_fraction = (color_temp - color_temperature_cw) / (color_temperature_ww - color_temperature_cw);
|
||||||
const float cw_fraction = 1.0f - ww_fraction;
|
const float cw_fraction = 1.0f - ww_fraction;
|
||||||
const float max_cw_ww = std::max(ww_fraction, cw_fraction);
|
*cold_white = this->state_ * this->brightness_ * this->white_ * cw_fraction;
|
||||||
*cold_white = this->state_ * this->brightness_ * this->white_ * (cw_fraction / max_cw_ww);
|
*warm_white = this->state_ * this->brightness_ * this->white_ * ww_fraction;
|
||||||
*warm_white = this->state_ * this->brightness_ * this->white_ * (ww_fraction / max_cw_ww);
|
if (!constant_brightness) {
|
||||||
|
const float max_cw_ww = std::max(ww_fraction, cw_fraction);
|
||||||
|
*cold_white /= max_cw_ww;
|
||||||
|
*warm_white /= max_cw_ww;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert these light color values to an CWWW representation with the given parameters.
|
/// Convert these light color values to an CWWW representation with the given parameters.
|
||||||
void as_cwww(float color_temperature_cw, float color_temperature_ww, float *cold_white, float *warm_white) const {
|
void as_cwww(float color_temperature_cw, float color_temperature_ww, float *cold_white, float *warm_white,
|
||||||
|
bool constant_brightness = false) const {
|
||||||
const float color_temp = clamp(this->color_temperature_, color_temperature_cw, color_temperature_ww);
|
const float color_temp = clamp(this->color_temperature_, color_temperature_cw, color_temperature_ww);
|
||||||
const float ww_fraction = (color_temp - color_temperature_cw) / (color_temperature_ww - color_temperature_cw);
|
const float ww_fraction = (color_temp - color_temperature_cw) / (color_temperature_ww - color_temperature_cw);
|
||||||
const float cw_fraction = 1.0f - ww_fraction;
|
const float cw_fraction = 1.0f - ww_fraction;
|
||||||
const float max_cw_ww = std::max(ww_fraction, cw_fraction);
|
*cold_white = this->state_ * this->brightness_ * cw_fraction;
|
||||||
*cold_white = this->state_ * this->brightness_ * (cw_fraction / max_cw_ww);
|
*warm_white = this->state_ * this->brightness_ * ww_fraction;
|
||||||
*warm_white = this->state_ * this->brightness_ * (ww_fraction / max_cw_ww);
|
if (!constant_brightness) {
|
||||||
|
const float max_cw_ww = std::max(ww_fraction, cw_fraction);
|
||||||
|
*cold_white /= max_cw_ww;
|
||||||
|
*warm_white /= max_cw_ww;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compare this LightColorValues to rhs, return true if and only if all attributes match.
|
/// Compare this LightColorValues to rhs, return true if and only if all attributes match.
|
||||||
|
|
|
@ -718,19 +718,21 @@ void LightState::current_values_as_rgbw(float *red, float *green, float *blue, f
|
||||||
*blue = gamma_correct(*blue, this->gamma_correct_);
|
*blue = gamma_correct(*blue, this->gamma_correct_);
|
||||||
*white = gamma_correct(*white, this->gamma_correct_);
|
*white = gamma_correct(*white, this->gamma_correct_);
|
||||||
}
|
}
|
||||||
void LightState::current_values_as_rgbww(float *red, float *green, float *blue, float *cold_white, float *warm_white) {
|
void LightState::current_values_as_rgbww(float *red, float *green, float *blue, float *cold_white, float *warm_white,
|
||||||
|
bool constant_brightness) {
|
||||||
auto traits = this->get_traits();
|
auto traits = this->get_traits();
|
||||||
this->current_values.as_rgbww(traits.get_min_mireds(), traits.get_max_mireds(), red, green, blue, cold_white,
|
this->current_values.as_rgbww(traits.get_min_mireds(), traits.get_max_mireds(), red, green, blue, cold_white,
|
||||||
warm_white);
|
warm_white, constant_brightness);
|
||||||
*red = gamma_correct(*red, this->gamma_correct_);
|
*red = gamma_correct(*red, this->gamma_correct_);
|
||||||
*green = gamma_correct(*green, this->gamma_correct_);
|
*green = gamma_correct(*green, this->gamma_correct_);
|
||||||
*blue = gamma_correct(*blue, this->gamma_correct_);
|
*blue = gamma_correct(*blue, this->gamma_correct_);
|
||||||
*cold_white = gamma_correct(*cold_white, this->gamma_correct_);
|
*cold_white = gamma_correct(*cold_white, this->gamma_correct_);
|
||||||
*warm_white = gamma_correct(*warm_white, this->gamma_correct_);
|
*warm_white = gamma_correct(*warm_white, this->gamma_correct_);
|
||||||
}
|
}
|
||||||
void LightState::current_values_as_cwww(float *cold_white, float *warm_white) {
|
void LightState::current_values_as_cwww(float *cold_white, float *warm_white, bool constant_brightness) {
|
||||||
auto traits = this->get_traits();
|
auto traits = this->get_traits();
|
||||||
this->current_values.as_cwww(traits.get_min_mireds(), traits.get_max_mireds(), cold_white, warm_white);
|
this->current_values.as_cwww(traits.get_min_mireds(), traits.get_max_mireds(), cold_white, warm_white,
|
||||||
|
constant_brightness);
|
||||||
*cold_white = gamma_correct(*cold_white, this->gamma_correct_);
|
*cold_white = gamma_correct(*cold_white, this->gamma_correct_);
|
||||||
*warm_white = gamma_correct(*warm_white, this->gamma_correct_);
|
*warm_white = gamma_correct(*warm_white, this->gamma_correct_);
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,9 +270,10 @@ class LightState : public Nameable, public Component {
|
||||||
|
|
||||||
void current_values_as_rgbw(float *red, float *green, float *blue, float *white);
|
void current_values_as_rgbw(float *red, float *green, float *blue, float *white);
|
||||||
|
|
||||||
void current_values_as_rgbww(float *red, float *green, float *blue, float *cold_white, float *warm_white);
|
void current_values_as_rgbww(float *red, float *green, float *blue, float *cold_white, float *warm_white,
|
||||||
|
bool constant_brightness = false);
|
||||||
|
|
||||||
void current_values_as_cwww(float *cold_white, float *warm_white);
|
void current_values_as_cwww(float *cold_white, float *warm_white, bool constant_brightness = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend LightOutput;
|
friend LightOutput;
|
||||||
|
|
|
@ -8,6 +8,8 @@ from esphome.const import CONF_BLUE, CONF_GREEN, CONF_RED, CONF_OUTPUT_ID, CONF_
|
||||||
rgbww_ns = cg.esphome_ns.namespace('rgbww')
|
rgbww_ns = cg.esphome_ns.namespace('rgbww')
|
||||||
RGBWWLightOutput = rgbww_ns.class_('RGBWWLightOutput', light.LightOutput)
|
RGBWWLightOutput = rgbww_ns.class_('RGBWWLightOutput', light.LightOutput)
|
||||||
|
|
||||||
|
CONF_CONSTANT_BRIGHTNESS = 'constant_brightness'
|
||||||
|
|
||||||
CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({
|
CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({
|
||||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(RGBWWLightOutput),
|
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(RGBWWLightOutput),
|
||||||
cv.Required(CONF_RED): cv.use_id(output.FloatOutput),
|
cv.Required(CONF_RED): cv.use_id(output.FloatOutput),
|
||||||
|
@ -17,6 +19,7 @@ CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({
|
||||||
cv.Required(CONF_WARM_WHITE): cv.use_id(output.FloatOutput),
|
cv.Required(CONF_WARM_WHITE): cv.use_id(output.FloatOutput),
|
||||||
cv.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
cv.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||||
cv.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
cv.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||||
|
cv.Optional(CONF_CONSTANT_BRIGHTNESS, default=False): cv.boolean,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,3 +41,4 @@ def to_code(config):
|
||||||
wwhite = yield cg.get_variable(config[CONF_WARM_WHITE])
|
wwhite = yield cg.get_variable(config[CONF_WARM_WHITE])
|
||||||
cg.add(var.set_warm_white(wwhite))
|
cg.add(var.set_warm_white(wwhite))
|
||||||
cg.add(var.set_warm_white_temperature(config[CONF_WARM_WHITE_COLOR_TEMPERATURE]))
|
cg.add(var.set_warm_white_temperature(config[CONF_WARM_WHITE_COLOR_TEMPERATURE]))
|
||||||
|
cg.add(var.set_constant_brightness(config[CONF_CONSTANT_BRIGHTNESS]))
|
||||||
|
|
|
@ -16,6 +16,7 @@ class RGBWWLightOutput : public light::LightOutput {
|
||||||
void set_warm_white(output::FloatOutput *warm_white) { warm_white_ = warm_white; }
|
void set_warm_white(output::FloatOutput *warm_white) { warm_white_ = warm_white; }
|
||||||
void set_cold_white_temperature(float cold_white_temperature) { cold_white_temperature_ = cold_white_temperature; }
|
void set_cold_white_temperature(float cold_white_temperature) { cold_white_temperature_ = cold_white_temperature; }
|
||||||
void set_warm_white_temperature(float warm_white_temperature) { warm_white_temperature_ = warm_white_temperature; }
|
void set_warm_white_temperature(float warm_white_temperature) { warm_white_temperature_ = warm_white_temperature; }
|
||||||
|
void set_constant_brightness(bool constant_brightness) { constant_brightness_ = constant_brightness; }
|
||||||
light::LightTraits get_traits() override {
|
light::LightTraits get_traits() override {
|
||||||
auto traits = light::LightTraits();
|
auto traits = light::LightTraits();
|
||||||
traits.set_supports_brightness(true);
|
traits.set_supports_brightness(true);
|
||||||
|
@ -28,7 +29,7 @@ class RGBWWLightOutput : public light::LightOutput {
|
||||||
}
|
}
|
||||||
void write_state(light::LightState *state) override {
|
void write_state(light::LightState *state) override {
|
||||||
float red, green, blue, cwhite, wwhite;
|
float red, green, blue, cwhite, wwhite;
|
||||||
state->current_values_as_rgbww(&red, &green, &blue, &cwhite, &wwhite);
|
state->current_values_as_rgbww(&red, &green, &blue, &cwhite, &wwhite, this->constant_brightness_);
|
||||||
this->red_->set_level(red);
|
this->red_->set_level(red);
|
||||||
this->green_->set_level(green);
|
this->green_->set_level(green);
|
||||||
this->blue_->set_level(blue);
|
this->blue_->set_level(blue);
|
||||||
|
@ -44,6 +45,7 @@ class RGBWWLightOutput : public light::LightOutput {
|
||||||
output::FloatOutput *warm_white_;
|
output::FloatOutput *warm_white_;
|
||||||
float cold_white_temperature_;
|
float cold_white_temperature_;
|
||||||
float warm_white_temperature_;
|
float warm_white_temperature_;
|
||||||
|
bool constant_brightness_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace rgbww
|
} // namespace rgbww
|
||||||
|
|
|
@ -1074,6 +1074,7 @@ light:
|
||||||
warm_white: pca_6
|
warm_white: pca_6
|
||||||
cold_white_color_temperature: 153 mireds
|
cold_white_color_temperature: 153 mireds
|
||||||
warm_white_color_temperature: 500 mireds
|
warm_white_color_temperature: 500 mireds
|
||||||
|
constant_brightness: true
|
||||||
- platform: fastled_clockless
|
- platform: fastled_clockless
|
||||||
id: addr1
|
id: addr1
|
||||||
chipset: WS2811
|
chipset: WS2811
|
||||||
|
|
Loading…
Reference in a new issue