ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
climate_traits.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstring>
4#include <type_traits>
5#include "climate_mode.h"
8
9namespace esphome::climate {
10
11// Type aliases for climate enum bitmasks
12// These replace std::set<EnumType> to eliminate red-black tree overhead
13// For contiguous enums starting at 0, DefaultBitPolicy provides 1:1 mapping (enum value = bit position)
14// Bitmask size is automatically calculated from the last enum value
20
23
24// Lightweight linear search for small lists (1-20 items) of const char* pointers
25// Avoids std::find template overhead
26template<typename List> inline bool vector_contains(const List &vec, const char *value, size_t len) {
27 for (const char *item : vec) {
28 if (strncmp(item, value, len) == 0 && item[len] == '\0')
29 return true;
30 }
31 return false;
32}
33
34template<typename List> inline bool vector_contains(const List &vec, const char *value) {
35 return vector_contains(vec, value, strlen(value));
36}
37
38// Find and return matching pointer from a list, or nullptr if not found
39template<typename List> inline const char *vector_find(const List &vec, const char *value, size_t len) {
40 for (const char *item : vec) {
41 if (strncmp(item, value, len) == 0 && item[len] == '\0')
42 return item;
43 }
44 return nullptr;
45}
46
74class Climate; // Forward declaration
75
77 friend class Climate; // Climate wires its custom mode lists into traits
78
79 public:
80 // Out of line on purpose: an inlined default init makes GCC copy the defaults from a .rodata
81 // template per traits() override, and .rodata is RAM on ESP8266.
83
85 uint32_t get_feature_flags() const { return this->feature_flags_; }
86 void add_feature_flags(uint32_t feature_flags) { this->feature_flags_ |= feature_flags; }
87 void clear_feature_flags(uint32_t feature_flags) { this->feature_flags_ &= ~feature_flags; }
88 bool has_feature_flags(uint32_t feature_flags) const { return this->feature_flags_ & feature_flags; }
89 void set_feature_flags(uint32_t feature_flags) { this->feature_flags_ = feature_flags; }
90
93 bool supports_mode(ClimateMode mode) const { return this->supported_modes_.count(mode); }
94 const ClimateModeMask &get_supported_modes() const { return this->supported_modes_; }
95
98 bool supports_fan_mode(ClimateFanMode fan_mode) const { return this->supported_fan_modes_.count(fan_mode); }
100 if (!this->supported_fan_modes_.empty()) {
101 return true;
102 }
103 return this->supported_custom_fan_modes_ != nullptr && !this->supported_custom_fan_modes_->empty();
104 }
106
110 return vector_contains(this->get_supported_custom_fan_modes(), custom_fan_mode);
111 }
112 bool supports_custom_fan_mode(const std::string &custom_fan_mode) const {
113 return this->supports_custom_fan_mode(custom_fan_mode.c_str());
114 }
115
118 bool supports_preset(ClimatePreset preset) const { return this->supported_presets_.count(preset); }
119 bool get_supports_presets() const { return !this->supported_presets_.empty(); }
121
124 bool supports_custom_preset(const char *custom_preset) const {
125 return vector_contains(this->get_supported_custom_presets(), custom_preset);
126 }
127 bool supports_custom_preset(const std::string &custom_preset) const {
128 return this->supports_custom_preset(custom_preset.c_str());
129 }
130
134 bool get_supports_swing_modes() const { return !this->supported_swing_modes_.empty(); }
136
138 void set_visual_min_temperature(float visual_min_temperature) {
139 this->visual_min_temperature_ = visual_min_temperature;
140 }
142 void set_visual_max_temperature(float visual_max_temperature) {
143 this->visual_max_temperature_ = visual_max_temperature;
144 }
147 void set_visual_target_temperature_step(float temperature_step) {
148 this->visual_target_temperature_step_ = temperature_step;
149 }
150 void set_visual_current_temperature_step(float temperature_step) {
151 this->visual_current_temperature_step_ = temperature_step;
152 }
153 void set_visual_temperature_step(float temperature_step) {
154 this->visual_target_temperature_step_ = temperature_step;
155 this->visual_current_temperature_step_ = temperature_step;
156 }
159
160 float get_visual_min_humidity() const { return this->visual_min_humidity_; }
161 void set_visual_min_humidity(float visual_min_humidity) { this->visual_min_humidity_ = visual_min_humidity; }
162 float get_visual_max_humidity() const { return this->visual_max_humidity_; }
163 void set_visual_max_humidity(float visual_max_humidity) { this->visual_max_humidity_ = visual_max_humidity; }
164
167
168 protected:
170 if (supported) {
171 this->supported_modes_.insert(mode);
172 } else {
173 this->supported_modes_.erase(mode);
174 }
175 }
177 if (supported) {
178 this->supported_fan_modes_.insert(mode);
179 } else {
180 this->supported_fan_modes_.erase(mode);
181 }
182 }
184 if (supported) {
185 this->supported_swing_modes_.insert(mode);
186 } else {
187 this->supported_swing_modes_.erase(mode);
188 }
189 }
190
194
202
208
212};
213static_assert(std::is_trivially_copyable_v<ClimateTraits>, "ClimateTraits is copied on every traits() call");
214
215} // namespace esphome::climate
BedjetMode mode
BedJet operating mode.
constexpr bool empty() const
Definition helpers.h:141
constexpr size_t count(ValueType value) const
Check if the set contains a specific value (std::set compatibility) Returns 1 if present,...
constexpr void insert(ValueType value)
Add a single value to the set (std::set compatibility)
constexpr void erase(ValueType value)
Remove a value from the set (std::set compatibility)
constexpr bool empty() const
Check if the set is empty.
ClimateDevice - This is the base class for all climate integrations.
Definition climate.h:192
const ClimateCustomModes & get_supported_custom_presets() const
Empty when the climate has no custom presets. Set them on the Climate entity.
void set_visual_max_temperature(float visual_max_temperature)
void add_feature_flags(uint32_t feature_flags)
void add_supported_fan_mode(ClimateFanMode mode)
const ClimatePresetMask & get_supported_presets() const
const ClimateCustomModes & get_supported_custom_fan_modes() const
Empty when the climate has no custom fan modes. Set them on the Climate entity.
const ClimateSwingModeMask & get_supported_swing_modes() const
void set_visual_temperature_step(float temperature_step)
void add_supported_preset(ClimatePreset preset)
void set_visual_target_temperature_step(float temperature_step)
float get_visual_current_temperature_step() const
void set_supported_presets(ClimatePresetMask presets)
void set_supported_swing_modes(ClimateSwingModeMask modes)
void set_visual_min_temperature(float visual_min_temperature)
bool supports_mode(ClimateMode mode) const
int8_t get_target_temperature_accuracy_decimals() const
const ClimateFanModeMask & get_supported_fan_modes() const
float get_visual_target_temperature_step() const
void set_visual_min_humidity(float visual_min_humidity)
void set_temperature_unit(TemperatureUnit unit)
bool supports_custom_preset(const std::string &custom_preset) const
void set_visual_current_temperature_step(float temperature_step)
bool supports_custom_fan_mode(const char *custom_fan_mode) const
void set_supported_modes(ClimateModeMask modes)
climate::ClimateFanModeMask supported_fan_modes_
bool supports_custom_preset(const char *custom_preset) const
climate::ClimateSwingModeMask supported_swing_modes_
bool has_feature_flags(uint32_t feature_flags) const
climate::ClimatePresetMask supported_presets_
int8_t get_current_temperature_accuracy_decimals() const
void set_visual_max_humidity(float visual_max_humidity)
void set_supported_custom_presets_(const ClimateCustomModes *presets)
bool supports_fan_mode(ClimateFanMode fan_mode) const
const ClimateCustomModes * supported_custom_fan_modes_
Owned by the Climate entity; get_traits() wires these pointers.
void add_supported_mode(ClimateMode mode)
void set_feature_flags(uint32_t feature_flags)
bool supports_custom_fan_mode(const std::string &custom_fan_mode) const
void set_swing_mode_support_(climate::ClimateSwingMode mode, bool supported)
void clear_feature_flags(uint32_t feature_flags)
climate::ClimateModeMask supported_modes_
bool supports_preset(ClimatePreset preset) const
void set_supported_fan_modes(ClimateFanModeMask modes)
void set_supported_custom_fan_modes_(const ClimateCustomModes *modes)
Set custom mode pointers (only Climate::get_traits() should call these).
void set_fan_mode_support_(climate::ClimateFanMode mode, bool supported)
TemperatureUnit get_temperature_unit() const
const ClimateModeMask & get_supported_modes() const
const ClimateCustomModes * supported_custom_presets_
void add_supported_swing_mode(ClimateSwingMode mode)
uint32_t get_feature_flags() const
Get/set feature flags (see ClimateFeatures enum in climate_mode.h)
bool supports_swing_mode(ClimateSwingMode swing_mode) const
void set_mode_support_(climate::ClimateMode mode, bool supported)
ClimateSwingMode swing_mode
Definition climate.h:11
uint8_t custom_preset
Definition climate.h:9
ClimateFanMode fan_mode
Definition climate.h:3
ClimatePreset preset
Definition climate.h:8
uint8_t custom_fan_mode
Definition climate.h:4
ClimatePreset
Enum for all preset modes NOTE: If adding values, update ClimatePresetMask in climate_traits....
const char * vector_find(const List &vec, const char *value, size_t len)
ClimateSwingMode
Enum for all modes a climate swing can be in NOTE: If adding values, update ClimateSwingModeMask in c...
ClimateMode
Enum for all modes a climate device can be in.
@ CLIMATE_MODE_OFF
The climate device is off.
bool vector_contains(const List &vec, const char *value, size_t len)
ClimateFanMode
NOTE: If adding values, update ClimateFanModeMask in climate_traits.h to use the new last value.
const void size_t len
Definition hal.h:68
TemperatureUnit
Definition helpers.h:1789
static void uint32_t