diff --git a/esphome/components/light/light_state.cpp b/esphome/components/light/light_state.cpp index 0ffb603818..5e9166795e 100644 --- a/esphome/components/light/light_state.cpp +++ b/esphome/components/light/light_state.cpp @@ -393,6 +393,36 @@ LightColorValues LightCall::validate_() { this->color_temperature_.reset(); } + // sets RGB to 100% if only White specified + if (this->white_.has_value()) { + if (!this->red_.has_value() && !this->green_.has_value() && !this->blue_.has_value()) { + this->red_ = optional(1.0f); + this->green_ = optional(1.0f); + this->blue_ = optional(1.0f); + } + } + // White to 0% if (exclusively) setting any RGB value + else if (this->red_.has_value() || this->green_.has_value() || this->blue_.has_value()) { + if (!this->white_.has_value()) { + this->white_ = optional(0.0f); + } + } + // if changing Kelvin alone, change to white light + else if (this->color_temperature_.has_value()) { + if (!this->red_.has_value() && !this->green_.has_value() && !this->blue_.has_value()) { + this->red_ = optional(1.0f); + this->green_ = optional(1.0f); + this->blue_ = optional(1.0f); + } + // if setting Kelvin from color (i.e. switching to white light), set White to 100% + auto cv = this->parent_->remote_values; + bool was_color = cv.get_red() != 1.0f || cv.get_blue() != 1.0f || cv.get_green() != 1.0f; + bool now_white = *this->red_ == 1.0f && *this->blue_ == 1.0f && *this->green_ == 1.0f; + if (!this->white_.has_value() && was_color && now_white) { + this->white_ = optional(1.0f); + } + } + #define VALIDATE_RANGE_(name_, upper_name) \ if (name_##_.has_value()) { \ auto val = *name_##_; \