diff --git a/esphome/components/light/light_call.cpp b/esphome/components/light/light_call.cpp index a3ffe22591..9a620541dc 100644 --- a/esphome/components/light/light_call.cpp +++ b/esphome/components/light/light_call.cpp @@ -9,6 +9,11 @@ namespace light { static const char *const TAG = "light"; +// Helper function to reduce code size for validation warnings +static void log_validation_warning(const char *name, const char *param_name, float val, float min, float max) { + ESP_LOGW(TAG, "'%s': %s value %.2f is out of range [%.1f - %.1f]", name, param_name, val, min, max); +} + // Macro to reduce repetitive setter code #define IMPLEMENT_LIGHT_CALL_SETTER(name, type, flag) \ LightCall &LightCall::set_##name(optional(name)) { \ @@ -223,8 +228,7 @@ LightColorValues LightCall::validate_() { if (this->has_##name_()) { \ auto val = this->name_##_; \ if (val < (min) || val > (max)) { \ - ESP_LOGW(TAG, "'%s': %s value %.2f is out of range [%.1f - %.1f]", name, LOG_STR_LITERAL(upper_name), val, \ - (min), (max)); \ + log_validation_warning(name, LOG_STR_LITERAL(upper_name), val, (min), (max)); \ this->name_##_ = clamp(val, (min), (max)); \ } \ } @@ -442,41 +446,56 @@ std::set LightCall::get_suitable_color_modes_() { bool has_rgb = (this->has_color_brightness() && this->color_brightness_ > 0.0f) || (this->has_red() || this->has_green() || this->has_blue()); + // Static sets that are only constructed once + static const std::set MODES_WHITE_ONLY = {ColorMode::WHITE, ColorMode::RGB_WHITE, + ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE, + ColorMode::RGB_COLD_WARM_WHITE}; + static const std::set MODES_CT_ONLY = {ColorMode::COLOR_TEMPERATURE, ColorMode::RGB_COLOR_TEMPERATURE, + ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLD_WARM_WHITE}; + static const std::set MODES_WHITE_CT = {ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, + ColorMode::RGB_COLD_WARM_WHITE}; + static const std::set MODES_CWWW_ONLY = {ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLD_WARM_WHITE}; + static const std::set MODES_NONE = { + ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE, ColorMode::RGB, + ColorMode::WHITE, ColorMode::COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE}; + static const std::set MODES_RGB_WHITE = {ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, + ColorMode::RGB_COLD_WARM_WHITE}; + static const std::set MODES_RGB_CT = {ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}; + static const std::set MODES_RGB_CWWW = {ColorMode::RGB_COLD_WARM_WHITE}; + static const std::set MODES_RGB_ONLY = {ColorMode::RGB, ColorMode::RGB_WHITE, + ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}; + +// Build key from flags: [rgb][cwww][ct][white] #define KEY(white, ct, cwww, rgb) ((white) << 0 | (ct) << 1 | (cwww) << 2 | (rgb) << 3) -#define ENTRY(white, ct, cwww, rgb, ...) \ - std::make_tuple>(KEY(white, ct, cwww, rgb), __VA_ARGS__) - // Flag order: white, color temperature, cwww, rgb - std::array>, 10> lookup_table{ - ENTRY(true, false, false, false, - {ColorMode::WHITE, ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE, - ColorMode::RGB_COLD_WARM_WHITE}), - ENTRY(false, true, false, false, - {ColorMode::COLOR_TEMPERATURE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE, - ColorMode::RGB_COLD_WARM_WHITE}), - ENTRY(true, true, false, false, - {ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}), - ENTRY(false, false, true, false, {ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLD_WARM_WHITE}), - ENTRY(false, false, false, false, - {ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE, ColorMode::RGB, - ColorMode::WHITE, ColorMode::COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE}), - ENTRY(true, false, false, true, - {ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}), - ENTRY(false, true, false, true, {ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}), - ENTRY(true, true, false, true, {ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}), - ENTRY(false, false, true, true, {ColorMode::RGB_COLD_WARM_WHITE}), - ENTRY(false, false, false, true, - {ColorMode::RGB, ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}), - }; + uint8_t key = KEY(has_white, has_ct, has_cwww, has_rgb); - auto key = KEY(has_white, has_ct, has_cwww, has_rgb); - for (auto &item : lookup_table) { - if (std::get<0>(item) == key) - return std::get<1>(item); + switch (key) { + case KEY(true, false, false, false): + return MODES_WHITE_ONLY; + case KEY(false, true, false, false): + return MODES_CT_ONLY; + case KEY(true, true, false, false): + return MODES_WHITE_CT; + case KEY(false, false, true, false): + return MODES_CWWW_ONLY; + case KEY(false, false, false, false): + return MODES_NONE; + case KEY(true, false, false, true): + return MODES_RGB_WHITE; + case KEY(false, true, false, true): + return MODES_RGB_CT; + case KEY(true, true, false, true): + return MODES_RGB_CT; + case KEY(false, false, true, true): + return MODES_RGB_CWWW; + case KEY(false, false, false, true): + return MODES_RGB_ONLY; + default: + return {}; // conflicting flags } - // This happens if there are conflicting flags given. - return {}; +#undef KEY } LightCall &LightCall::set_effect(const std::string &effect) {