From a249c9c28290b54e0f143711c97b09ba4f5cdade Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 18 Oct 2025 13:46:49 -1000 Subject: [PATCH] preen --- esphome/components/light/color_mode.h | 24 +++------- esphome/components/light/light_call.cpp | 58 ++++++++++++++++++++----- 2 files changed, 54 insertions(+), 28 deletions(-) diff --git a/esphome/components/light/color_mode.h b/esphome/components/light/color_mode.h index 7c7239a5af..97e61e2a1c 100644 --- a/esphome/components/light/color_mode.h +++ b/esphome/components/light/color_mode.h @@ -213,6 +213,13 @@ class ColorModeMask { constexpr void add(ColorMode mode) { this->mask_ |= (1 << mode_to_bit(mode)); } + /// Add multiple modes at once using initializer list + constexpr void add(std::initializer_list modes) { + for (auto mode : modes) { + this->add(mode); + } + } + constexpr bool contains(ColorMode mode) const { return (this->mask_ & (1 << mode_to_bit(mode))) != 0; } constexpr size_t size() const { @@ -300,23 +307,6 @@ class ColorModeMask { return (this->mask_ & CAPABILITY_BITMASKS[index]) != 0; } - /// Build a bitmask of modes that match the given capability requirements - /// @param require_caps Capabilities that must be present in the mode - /// @return Raw bitmask value - static constexpr color_mode_bitmask_t build_mask_matching(uint8_t require_caps) { - color_mode_bitmask_t mask = 0; - // Check each mode to see if it matches the requirements - // Skip UNKNOWN (bit 0), iterate through actual color modes (bits 1-9) - for (int bit = 1; bit < COLOR_MODE_COUNT; ++bit) { - uint8_t mode_val = static_cast(bit_to_mode(bit)); - // Mode matches if it has all required caps - if ((mode_val & require_caps) == require_caps) { - mask |= (1 << bit); - } - } - return mask; - } - private: // Using uint16_t instead of uint32_t for more efficient iteration (fewer bits to scan). // Currently only 10 ColorMode values exist, so 16 bits is sufficient. diff --git a/esphome/components/light/light_call.cpp b/esphome/components/light/light_call.cpp index 036de98639..f209f26005 100644 --- a/esphome/components/light/light_call.cpp +++ b/esphome/components/light/light_call.cpp @@ -458,18 +458,54 @@ color_mode_bitmask_t LightCall::get_suitable_color_modes_mask_() { bool has_rgb = (this->has_color_brightness() && this->color_brightness_ > 0.0f) || (this->has_red() || this->has_green() || this->has_blue()); - // Build required capabilities mask - uint8_t require_caps = static_cast(ColorCapability::ON_OFF | ColorCapability::BRIGHTNESS); - if (has_rgb) - require_caps |= static_cast(ColorCapability::RGB); - if (has_white) - require_caps |= static_cast(ColorCapability::WHITE); - if (has_ct) - require_caps |= static_cast(ColorCapability::COLOR_TEMPERATURE); - if (has_cwww) - require_caps |= static_cast(ColorCapability::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) - return ColorModeMask::build_mask_matching(require_caps); + uint8_t key = KEY(has_white, has_ct, has_cwww, has_rgb); + + // Build bitmask from suitable ColorModes + ColorModeMask suitable; + + switch (key) { + case KEY(true, false, false, false): // white only + suitable.add({ColorMode::WHITE, ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, + ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLD_WARM_WHITE}); + break; + case KEY(false, true, false, false): // ct only + suitable.add({ColorMode::COLOR_TEMPERATURE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE, + ColorMode::RGB_COLD_WARM_WHITE}); + break; + case KEY(true, true, false, false): // white + ct + suitable.add({ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}); + break; + case KEY(false, false, true, false): // cwww only + suitable.add({ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLD_WARM_WHITE}); + break; + case KEY(false, false, false, false): // none + suitable.add({ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE, + ColorMode::RGB, ColorMode::WHITE, ColorMode::COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE}); + break; + case KEY(true, false, false, true): // rgb + white + suitable.add({ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}); + break; + case KEY(false, true, false, true): // rgb + ct + case KEY(true, true, false, true): // rgb + white + ct + suitable.add({ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}); + break; + case KEY(false, false, true, true): // rgb + cwww + suitable.add(ColorMode::RGB_COLD_WARM_WHITE); + break; + case KEY(false, false, false, true): // rgb only + suitable.add( + {ColorMode::RGB, ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}); + break; + default: + break; // conflicting flags - return empty mask + } + +#undef KEY + + return suitable.get_mask(); } LightCall &LightCall::set_effect(const std::string &effect) {