1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-29 22:24:26 +00:00
This commit is contained in:
J. Nick Koston
2025-10-22 09:46:13 -10:00
parent d7f32bf27f
commit ce80baa3c9
2 changed files with 10 additions and 99 deletions

View File

@@ -14,87 +14,8 @@ constexpr int CLIMATE_SWING_MODE_BITMASK_SIZE = 8; // 4 values (OFF, BOTH, VERT
constexpr int CLIMATE_PRESET_BITMASK_SIZE = 8; // 8 values (NONE, HOME, AWAY, BOOST, COMFORT, ECO, SLEEP, ACTIVITY)
} // namespace esphome::climate
// Template specializations for value-to-bit conversions
// MUST be declared before any instantiation of FiniteSetMask<ClimateMode>, etc.
namespace esphome {
// ClimateMode uses 1:1 mapping (value_to_bit is just a cast)
// Only bit_to_value needs specialization
template<>
inline climate::ClimateMode FiniteSetMask<climate::ClimateMode, climate::CLIMATE_MODE_BITMASK_SIZE>::bit_to_value(
int bit) {
// Lookup array mapping bit positions to enum values
static constexpr climate::ClimateMode MODES[] = {
climate::CLIMATE_MODE_OFF, // bit 0
climate::CLIMATE_MODE_HEAT_COOL, // bit 1
climate::CLIMATE_MODE_COOL, // bit 2
climate::CLIMATE_MODE_HEAT, // bit 3
climate::CLIMATE_MODE_FAN_ONLY, // bit 4
climate::CLIMATE_MODE_DRY, // bit 5
climate::CLIMATE_MODE_AUTO, // bit 6
};
static constexpr int MODE_COUNT = 7;
return (bit >= 0 && bit < MODE_COUNT) ? MODES[bit] : climate::CLIMATE_MODE_OFF;
}
// ClimateFanMode uses 1:1 mapping (value_to_bit is just a cast)
// Only bit_to_value needs specialization
template<>
inline climate::ClimateFanMode FiniteSetMask<climate::ClimateFanMode,
climate::CLIMATE_FAN_MODE_BITMASK_SIZE>::bit_to_value(int bit) {
static constexpr climate::ClimateFanMode MODES[] = {
climate::CLIMATE_FAN_ON, // bit 0
climate::CLIMATE_FAN_OFF, // bit 1
climate::CLIMATE_FAN_AUTO, // bit 2
climate::CLIMATE_FAN_LOW, // bit 3
climate::CLIMATE_FAN_MEDIUM, // bit 4
climate::CLIMATE_FAN_HIGH, // bit 5
climate::CLIMATE_FAN_MIDDLE, // bit 6
climate::CLIMATE_FAN_FOCUS, // bit 7
climate::CLIMATE_FAN_DIFFUSE, // bit 8
climate::CLIMATE_FAN_QUIET, // bit 9
};
static constexpr int MODE_COUNT = 10;
return (bit >= 0 && bit < MODE_COUNT) ? MODES[bit] : climate::CLIMATE_FAN_ON;
}
// ClimateSwingMode uses 1:1 mapping (value_to_bit is just a cast)
// Only bit_to_value needs specialization
template<>
inline climate::ClimateSwingMode FiniteSetMask<climate::ClimateSwingMode,
climate::CLIMATE_SWING_MODE_BITMASK_SIZE>::bit_to_value(int bit) {
static constexpr climate::ClimateSwingMode MODES[] = {
climate::CLIMATE_SWING_OFF, // bit 0
climate::CLIMATE_SWING_BOTH, // bit 1
climate::CLIMATE_SWING_VERTICAL, // bit 2
climate::CLIMATE_SWING_HORIZONTAL, // bit 3
};
static constexpr int MODE_COUNT = 4;
return (bit >= 0 && bit < MODE_COUNT) ? MODES[bit] : climate::CLIMATE_SWING_OFF;
}
// ClimatePreset uses 1:1 mapping (value_to_bit is just a cast)
// Only bit_to_value needs specialization
template<>
inline climate::ClimatePreset FiniteSetMask<climate::ClimatePreset, climate::CLIMATE_PRESET_BITMASK_SIZE>::bit_to_value(
int bit) {
static constexpr climate::ClimatePreset PRESETS[] = {
climate::CLIMATE_PRESET_NONE, // bit 0
climate::CLIMATE_PRESET_HOME, // bit 1
climate::CLIMATE_PRESET_AWAY, // bit 2
climate::CLIMATE_PRESET_BOOST, // bit 3
climate::CLIMATE_PRESET_COMFORT, // bit 4
climate::CLIMATE_PRESET_ECO, // bit 5
climate::CLIMATE_PRESET_SLEEP, // bit 6
climate::CLIMATE_PRESET_ACTIVITY, // bit 7
};
static constexpr int PRESET_COUNT = 8;
return (bit >= 0 && bit < PRESET_COUNT) ? PRESETS[bit] : climate::CLIMATE_PRESET_NONE;
}
} // namespace esphome
// Now we can safely create the type aliases
// No template specializations needed - all climate enums use 1:1 mapping (enum value = bit position)
// FiniteSetMask's default implementations handle this automatically.
namespace esphome::climate {
// Type aliases for climate enum bitmasks

View File

@@ -17,26 +17,19 @@ namespace esphome {
///
/// Requirements:
/// - ValueType must have a bounded discrete range that maps to bit positions
/// - Specialization must provide bit_to_value() static method
/// - For 1:1 mappings (enum value = bit position), default value_to_bit() is used
/// - For custom mappings (like ColorMode), specialize value_to_bit() as well
/// - For 1:1 mappings (contiguous enums starting at 0), no specialization needed
/// - For custom mappings (like ColorMode), specialize value_to_bit() and/or bit_to_value()
/// - MaxBits must be sufficient to hold all possible values
///
/// Example usage (1:1 mapping - climate enums):
/// // For enums with contiguous values starting at 0, only bit_to_value() needs specialization
/// template<>
/// inline ClimateMode FiniteSetMask<ClimateMode, 8>::bit_to_value(int bit) {
/// static constexpr ClimateMode MODES[] = {CLIMATE_MODE_OFF, CLIMATE_MODE_HEAT, ...};
/// return (bit >= 0 && bit < 7) ? MODES[bit] : CLIMATE_MODE_OFF;
/// }
///
/// // For enums with contiguous values starting at 0, no specialization needed!
/// using ClimateModeMask = FiniteSetMask<ClimateMode, 8>;
/// ClimateModeMask modes({CLIMATE_MODE_HEAT, CLIMATE_MODE_COOL});
/// if (modes.count(CLIMATE_MODE_HEAT)) { ... }
/// for (auto mode : modes) { ... } // Iterate over set bits
///
/// Example usage (custom mapping - ColorMode):
/// // For custom mappings, specialize both value_to_bit() and bit_to_value()
/// // For non-contiguous enums or custom mappings, specialize value_to_bit() and/or bit_to_value()
/// // See esphome/components/light/color_mode.h for complete example
///
/// Design notes:
@@ -160,14 +153,11 @@ template<typename ValueType, int MaxBits = 16> class FiniteSetMask {
}
protected:
// Default implementation for 1:1 mapping (enum value = bit position)
// For enums with contiguous values starting at 0, this is all you need.
// If you need custom mapping (like ColorMode), provide a specialization.
// Default implementations for 1:1 mapping (enum value = bit position)
// For enums with contiguous values starting at 0, these defaults work as-is.
// If you need custom mapping (like ColorMode), provide specializations.
static constexpr int value_to_bit(ValueType value) { return static_cast<int>(value); }
// Must be provided by template specialization
// Converts bit positions (0, 1, 2, ...) to actual values
static ValueType bit_to_value(int bit); // Not constexpr: array indexing with runtime bounds checking
static constexpr ValueType bit_to_value(int bit) { return static_cast<ValueType>(bit); }
bitmask_t mask_{0};
};