diff --git a/esphome/components/light/light_color_values.h b/esphome/components/light/light_color_values.h index 39a93cbbcd..90f5570b90 100644 --- a/esphome/components/light/light_color_values.h +++ b/esphome/components/light/light_color_values.h @@ -17,12 +17,13 @@ namespace light { * Not all values have to be populated though, for example a simple monochromatic light only needs * to access the state and brightness attributes. * - * PLease note all float values are automatically clamped. + * Please note all float values are automatically clamped. * * state - Whether the light should be on/off. Represented as a float for transitions. * brightness - The brightness of the light. * red, green, blue - RGB values. * white - The white value for RGBW lights. + * color_temperature - Temperature of the white value, range from 0.0 (cold) to 1.0 (warm) */ class LightColorValues { public: @@ -173,30 +174,33 @@ class LightColorValues { void as_binary(bool *binary) const { *binary = this->state_ == 1.0f; } /// Convert these light color values to a brightness-only representation and write them to brightness. - void as_brightness(float *brightness) const { *brightness = this->state_ * this->brightness_; } + void as_brightness(float *brightness, float gamma = 0) const { + *brightness = gamma_correct(this->state_ * this->brightness_, gamma); + } /// Convert these light color values to an RGB representation and write them to red, green, blue. - void as_rgb(float *red, float *green, float *blue) const { - *red = this->state_ * this->brightness_ * this->red_; - *green = this->state_ * this->brightness_ * this->green_; - *blue = this->state_ * this->brightness_ * this->blue_; + void as_rgb(float *red, float *green, float *blue, float gamma = 0) const { + *red = gamma_correct(this->state_ * this->brightness_ * this->red_, gamma); + *green = gamma_correct(this->state_ * this->brightness_ * this->green_, gamma); + *blue = gamma_correct(this->state_ * this->brightness_ * this->blue_, gamma); } /// Convert these light color values to an RGBW representation and write them to red, green, blue, white. - void as_rgbw(float *red, float *green, float *blue, float *white) const { - this->as_rgb(red, green, blue); - *white = this->state_ * this->brightness_ * this->white_; + void as_rgbw(float *red, float *green, float *blue, float *white, float gamma = 0) const { + this->as_rgb(red, green, blue, gamma); + *white = gamma_correct(this->state_ * this->brightness_ * this->white_, gamma); } /// 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, bool constant_brightness = false) const { - this->as_rgb(red, green, blue); + float *cold_white, float *warm_white, float gamma = 0, bool constant_brightness = false) const { + this->as_rgb(red, green, blue, gamma); 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; - *cold_white = this->state_ * this->brightness_ * this->white_ * cw_fraction; - *warm_white = this->state_ * this->brightness_ * this->white_ * ww_fraction; + const float white_level = gamma_correct(this->state_ * this->brightness_ * this->white_, gamma); + *cold_white = white_level * cw_fraction; + *warm_white = white_level * ww_fraction; if (!constant_brightness) { const float max_cw_ww = std::max(ww_fraction, cw_fraction); *cold_white /= max_cw_ww; @@ -206,12 +210,13 @@ class LightColorValues { /// 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, - bool constant_brightness = false) const { + float gamma = 0, 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; - *cold_white = this->state_ * this->brightness_ * cw_fraction; - *warm_white = this->state_ * this->brightness_ * ww_fraction; + const float white_level = gamma_correct(this->state_ * this->brightness_ * this->white_, gamma); + *cold_white = white_level * cw_fraction; + *warm_white = white_level * ww_fraction; if (!constant_brightness) { const float max_cw_ww = std::max(ww_fraction, cw_fraction); *cold_white /= max_cw_ww; diff --git a/esphome/components/light/light_state.cpp b/esphome/components/light/light_state.cpp index c6e7df0811..9aa32f6904 100644 --- a/esphome/components/light/light_state.cpp +++ b/esphome/components/light/light_state.cpp @@ -702,39 +702,24 @@ LightOutput *LightState::get_output() const { return this->output_; } void LightState::set_gamma_correct(float gamma_correct) { this->gamma_correct_ = gamma_correct; } void LightState::current_values_as_binary(bool *binary) { this->current_values.as_binary(binary); } void LightState::current_values_as_brightness(float *brightness) { - this->current_values.as_brightness(brightness); - *brightness = gamma_correct(*brightness, this->gamma_correct_); + this->current_values.as_brightness(brightness, this->gamma_correct_); } void LightState::current_values_as_rgb(float *red, float *green, float *blue) { - this->current_values.as_rgb(red, green, blue); - *red = gamma_correct(*red, this->gamma_correct_); - *green = gamma_correct(*green, this->gamma_correct_); - *blue = gamma_correct(*blue, this->gamma_correct_); + this->current_values.as_rgb(red, green, blue, this->gamma_correct_); } void LightState::current_values_as_rgbw(float *red, float *green, float *blue, float *white) { - this->current_values.as_rgbw(red, green, blue, white); - *red = gamma_correct(*red, this->gamma_correct_); - *green = gamma_correct(*green, this->gamma_correct_); - *blue = gamma_correct(*blue, this->gamma_correct_); - *white = gamma_correct(*white, this->gamma_correct_); + this->current_values.as_rgbw(red, green, blue, white, this->gamma_correct_); } 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, 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_); + warm_white, this->gamma_correct_, constant_brightness); } 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, - constant_brightness); - *cold_white = gamma_correct(*cold_white, this->gamma_correct_); - *warm_white = gamma_correct(*warm_white, this->gamma_correct_); + this->gamma_correct_, constant_brightness); } void LightState::add_new_remote_values_callback(std::function &&send_callback) { this->remote_values_callback_.add(std::move(send_callback));