mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
RGBWW/CCT Lights: Fix gamma_correct when using constant_brightness (#1043)
This commit is contained in:
parent
42007d03d4
commit
8aedac81a5
2 changed files with 26 additions and 36 deletions
|
@ -17,12 +17,13 @@ namespace light {
|
||||||
* Not all values have to be populated though, for example a simple monochromatic light only needs
|
* Not all values have to be populated though, for example a simple monochromatic light only needs
|
||||||
* to access the state and brightness attributes.
|
* 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.
|
* state - Whether the light should be on/off. Represented as a float for transitions.
|
||||||
* brightness - The brightness of the light.
|
* brightness - The brightness of the light.
|
||||||
* red, green, blue - RGB values.
|
* red, green, blue - RGB values.
|
||||||
* white - The white value for RGBW lights.
|
* 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 {
|
class LightColorValues {
|
||||||
public:
|
public:
|
||||||
|
@ -173,30 +174,33 @@ class LightColorValues {
|
||||||
void as_binary(bool *binary) const { *binary = this->state_ == 1.0f; }
|
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.
|
/// 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.
|
/// 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 {
|
void as_rgb(float *red, float *green, float *blue, float gamma = 0) const {
|
||||||
*red = this->state_ * this->brightness_ * this->red_;
|
*red = gamma_correct(this->state_ * this->brightness_ * this->red_, gamma);
|
||||||
*green = this->state_ * this->brightness_ * this->green_;
|
*green = gamma_correct(this->state_ * this->brightness_ * this->green_, gamma);
|
||||||
*blue = this->state_ * this->brightness_ * this->blue_;
|
*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.
|
/// 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 {
|
void as_rgbw(float *red, float *green, float *blue, float *white, float gamma = 0) const {
|
||||||
this->as_rgb(red, green, blue);
|
this->as_rgb(red, green, blue, gamma);
|
||||||
*white = this->state_ * this->brightness_ * this->white_;
|
*white = gamma_correct(this->state_ * this->brightness_ * this->white_, gamma);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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, bool constant_brightness = false) const {
|
float *cold_white, float *warm_white, float gamma = 0, bool constant_brightness = false) const {
|
||||||
this->as_rgb(red, green, blue);
|
this->as_rgb(red, green, blue, gamma);
|
||||||
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;
|
||||||
*cold_white = this->state_ * this->brightness_ * this->white_ * cw_fraction;
|
const float white_level = gamma_correct(this->state_ * this->brightness_ * this->white_, gamma);
|
||||||
*warm_white = this->state_ * this->brightness_ * this->white_ * ww_fraction;
|
*cold_white = white_level * cw_fraction;
|
||||||
|
*warm_white = white_level * ww_fraction;
|
||||||
if (!constant_brightness) {
|
if (!constant_brightness) {
|
||||||
const float max_cw_ww = std::max(ww_fraction, cw_fraction);
|
const float max_cw_ww = std::max(ww_fraction, cw_fraction);
|
||||||
*cold_white /= max_cw_ww;
|
*cold_white /= max_cw_ww;
|
||||||
|
@ -206,12 +210,13 @@ class LightColorValues {
|
||||||
|
|
||||||
/// 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,
|
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 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;
|
||||||
*cold_white = this->state_ * this->brightness_ * cw_fraction;
|
const float white_level = gamma_correct(this->state_ * this->brightness_ * this->white_, gamma);
|
||||||
*warm_white = this->state_ * this->brightness_ * ww_fraction;
|
*cold_white = white_level * cw_fraction;
|
||||||
|
*warm_white = white_level * ww_fraction;
|
||||||
if (!constant_brightness) {
|
if (!constant_brightness) {
|
||||||
const float max_cw_ww = std::max(ww_fraction, cw_fraction);
|
const float max_cw_ww = std::max(ww_fraction, cw_fraction);
|
||||||
*cold_white /= max_cw_ww;
|
*cold_white /= max_cw_ww;
|
||||||
|
|
|
@ -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::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_binary(bool *binary) { this->current_values.as_binary(binary); }
|
||||||
void LightState::current_values_as_brightness(float *brightness) {
|
void LightState::current_values_as_brightness(float *brightness) {
|
||||||
this->current_values.as_brightness(brightness);
|
this->current_values.as_brightness(brightness, this->gamma_correct_);
|
||||||
*brightness = gamma_correct(*brightness, this->gamma_correct_);
|
|
||||||
}
|
}
|
||||||
void LightState::current_values_as_rgb(float *red, float *green, float *blue) {
|
void LightState::current_values_as_rgb(float *red, float *green, float *blue) {
|
||||||
this->current_values.as_rgb(red, green, blue);
|
this->current_values.as_rgb(red, green, blue, this->gamma_correct_);
|
||||||
*red = gamma_correct(*red, this->gamma_correct_);
|
|
||||||
*green = gamma_correct(*green, this->gamma_correct_);
|
|
||||||
*blue = gamma_correct(*blue, this->gamma_correct_);
|
|
||||||
}
|
}
|
||||||
void LightState::current_values_as_rgbw(float *red, float *green, float *blue, float *white) {
|
void LightState::current_values_as_rgbw(float *red, float *green, float *blue, float *white) {
|
||||||
this->current_values.as_rgbw(red, green, blue, white);
|
this->current_values.as_rgbw(red, green, blue, white, this->gamma_correct_);
|
||||||
*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_);
|
|
||||||
}
|
}
|
||||||
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) {
|
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, constant_brightness);
|
warm_white, this->gamma_correct_, 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, bool constant_brightness) {
|
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);
|
this->gamma_correct_, constant_brightness);
|
||||||
*cold_white = gamma_correct(*cold_white, this->gamma_correct_);
|
|
||||||
*warm_white = gamma_correct(*warm_white, this->gamma_correct_);
|
|
||||||
}
|
}
|
||||||
void LightState::add_new_remote_values_callback(std::function<void()> &&send_callback) {
|
void LightState::add_new_remote_values_callback(std::function<void()> &&send_callback) {
|
||||||
this->remote_values_callback_.add(std::move(send_callback));
|
this->remote_values_callback_.add(std::move(send_callback));
|
||||||
|
|
Loading…
Reference in a new issue