mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00: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:
		| @@ -13,6 +13,7 @@ class CWWWLightOutput : public light::LightOutput { | ||||
|   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_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 { | ||||
|     auto traits = light::LightTraits(); | ||||
|     traits.set_supports_brightness(true); | ||||
| @@ -25,7 +26,7 @@ class CWWWLightOutput : public light::LightOutput { | ||||
|   } | ||||
|   void write_state(light::LightState *state) override { | ||||
|     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->warm_white_->set_level(wwhite); | ||||
|   } | ||||
| @@ -35,6 +36,7 @@ class CWWWLightOutput : public light::LightOutput { | ||||
|   output::FloatOutput *warm_white_; | ||||
|   float cold_white_temperature_; | ||||
|   float warm_white_temperature_; | ||||
|   bool constant_brightness_; | ||||
| }; | ||||
|  | ||||
| }  // 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') | ||||
| CWWWLightOutput = cwww_ns.class_('CWWWLightOutput', light.LightOutput) | ||||
|  | ||||
| CONF_CONSTANT_BRIGHTNESS = 'constant_brightness' | ||||
|  | ||||
| CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({ | ||||
|     cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(CWWWLightOutput), | ||||
|     cv.Required(CONF_COLD_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_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]) | ||||
|     cg.add(var.set_warm_white(wwhite)) | ||||
|     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. | ||||
|   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); | ||||
|     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 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 / max_cw_ww); | ||||
|     *warm_white = this->state_ * this->brightness_ * this->white_ * (ww_fraction / max_cw_ww); | ||||
|     *cold_white = this->state_ * this->brightness_ * this->white_ * cw_fraction; | ||||
|     *warm_white = this->state_ * this->brightness_ * this->white_ * ww_fraction; | ||||
|     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. | ||||
|   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 ww_fraction = (color_temp - color_temperature_cw) / (color_temperature_ww - color_temperature_cw); | ||||
|     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 / max_cw_ww); | ||||
|     *warm_white = this->state_ * this->brightness_ * (ww_fraction / max_cw_ww); | ||||
|     *cold_white = this->state_ * this->brightness_ * cw_fraction; | ||||
|     *warm_white = this->state_ * this->brightness_ * ww_fraction; | ||||
|     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. | ||||
|   | ||||
| @@ -718,19 +718,21 @@ void LightState::current_values_as_rgbw(float *red, float *green, float *blue, f | ||||
|   *blue = gamma_correct(*blue, 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(); | ||||
|   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_); | ||||
|   *green = gamma_correct(*green, this->gamma_correct_); | ||||
|   *blue = gamma_correct(*blue, this->gamma_correct_); | ||||
|   *cold_white = gamma_correct(*cold_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(); | ||||
|   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_); | ||||
|   *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_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: | ||||
|   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') | ||||
| RGBWWLightOutput = rgbww_ns.class_('RGBWWLightOutput', light.LightOutput) | ||||
|  | ||||
| CONF_CONSTANT_BRIGHTNESS = 'constant_brightness' | ||||
|  | ||||
| CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({ | ||||
|     cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(RGBWWLightOutput), | ||||
|     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_COLD_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]) | ||||
|     cg.add(var.set_warm_white(wwhite)) | ||||
|     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_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_constant_brightness(bool constant_brightness) { constant_brightness_ = constant_brightness; } | ||||
|   light::LightTraits get_traits() override { | ||||
|     auto traits = light::LightTraits(); | ||||
|     traits.set_supports_brightness(true); | ||||
| @@ -28,7 +29,7 @@ class RGBWWLightOutput : public light::LightOutput { | ||||
|   } | ||||
|   void write_state(light::LightState *state) override { | ||||
|     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->green_->set_level(green); | ||||
|     this->blue_->set_level(blue); | ||||
| @@ -44,6 +45,7 @@ class RGBWWLightOutput : public light::LightOutput { | ||||
|   output::FloatOutput *warm_white_; | ||||
|   float cold_white_temperature_; | ||||
|   float warm_white_temperature_; | ||||
|   bool constant_brightness_; | ||||
| }; | ||||
|  | ||||
| }  // namespace rgbww | ||||
|   | ||||
		Reference in New Issue
	
	Block a user