ESPHome 2026.5.0
Loading...
Searching...
No Matches
climate_traits.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstring>
4#include <vector>
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
21// Lightweight linear search for small vectors (1-20 items) of const char* pointers
22// Avoids std::find template overhead
23inline bool vector_contains(const std::vector<const char *> &vec, const char *value, size_t len) {
24 for (const char *item : vec) {
25 if (strncmp(item, value, len) == 0 && item[len] == '\0')
26 return true;
27 }
28 return false;
29}
30
31inline bool vector_contains(const std::vector<const char *> &vec, const char *value) {
32 return vector_contains(vec, value, strlen(value));
33}
34
35// Find and return matching pointer from vector, or nullptr if not found
36inline const char *vector_find(const std::vector<const char *> &vec, const char *value, size_t len) {
37 for (const char *item : vec) {
38 if (strncmp(item, value, len) == 0 && item[len] == '\0')
39 return item;
40 }
41 return nullptr;
42}
43
71class Climate; // Forward declaration
72
74 friend class Climate; // Allow Climate to access protected find methods
75
76 public:
78 uint32_t get_feature_flags() const { return this->feature_flags_; }
79 void add_feature_flags(uint32_t feature_flags) { this->feature_flags_ |= feature_flags; }
80 void clear_feature_flags(uint32_t feature_flags) { this->feature_flags_ &= ~feature_flags; }
81 bool has_feature_flags(uint32_t feature_flags) const { return this->feature_flags_ & feature_flags; }
82 void set_feature_flags(uint32_t feature_flags) { this->feature_flags_ = feature_flags; }
83
86 bool supports_mode(ClimateMode mode) const { return this->supported_modes_.count(mode); }
87 const ClimateModeMask &get_supported_modes() const { return this->supported_modes_; }
88
91 bool supports_fan_mode(ClimateFanMode fan_mode) const { return this->supported_fan_modes_.count(fan_mode); }
93 if (!this->supported_fan_modes_.empty()) {
94 return true;
95 }
96 // Same precedence as get_supported_custom_fan_modes() getter
98 return !this->supported_custom_fan_modes_->empty();
99 }
100 return !this->compat_custom_fan_modes_.empty(); // Compat: remove in 2026.11.0
101 }
103
104 // Remove before 2026.11.0
105 ESPDEPRECATED("Call set_supported_custom_fan_modes() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0")
106 void set_supported_custom_fan_modes(std::initializer_list<const char *> modes) {
107 // Compat: store in owned vector. Copies copy the vector (deprecated path still copies this vector).
108 this->compat_custom_fan_modes_ = modes;
109 }
110 // Remove before 2026.11.0
111 ESPDEPRECATED("Call set_supported_custom_fan_modes() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0")
112 void set_supported_custom_fan_modes(const std::vector<const char *> &modes) {
113 this->compat_custom_fan_modes_ = modes;
114 }
115 // Remove before 2026.11.0
116 template<size_t N>
117 ESPDEPRECATED("Call set_supported_custom_fan_modes() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0")
118 void set_supported_custom_fan_modes(const char *const (&modes)[N]) {
119 this->compat_custom_fan_modes_.assign(modes, modes + N);
120 }
121
122 // Deleted overloads to catch incorrect std::string usage at compile time with clear error messages
123 void set_supported_custom_fan_modes(const std::vector<std::string> &modes) = delete;
124 void set_supported_custom_fan_modes(std::initializer_list<std::string> modes) = delete;
125
126 // Compat: returns const ref with empty fallback. In 2026.11.0 change to return const vector *.
127 const std::vector<const char *> &get_supported_custom_fan_modes() const;
129 return (this->supported_custom_fan_modes_ &&
130 vector_contains(*this->supported_custom_fan_modes_, custom_fan_mode)) ||
131 vector_contains(this->compat_custom_fan_modes_, custom_fan_mode); // Compat: remove in 2026.11.0
132 }
133 bool supports_custom_fan_mode(const std::string &custom_fan_mode) const {
134 return this->supports_custom_fan_mode(custom_fan_mode.c_str());
135 }
136
139 bool supports_preset(ClimatePreset preset) const { return this->supported_presets_.count(preset); }
140 bool get_supports_presets() const { return !this->supported_presets_.empty(); }
142
143 // Remove before 2026.11.0
144 ESPDEPRECATED("Call set_supported_custom_presets() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0")
145 void set_supported_custom_presets(std::initializer_list<const char *> presets) {
146 this->compat_custom_presets_ = presets;
147 }
148 // Remove before 2026.11.0
149 ESPDEPRECATED("Call set_supported_custom_presets() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0")
150 void set_supported_custom_presets(const std::vector<const char *> &presets) {
151 this->compat_custom_presets_ = presets;
152 }
153 // Remove before 2026.11.0
154 template<size_t N>
155 ESPDEPRECATED("Call set_supported_custom_presets() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0")
156 void set_supported_custom_presets(const char *const (&presets)[N]) {
157 this->compat_custom_presets_.assign(presets, presets + N);
158 }
159
160 // Deleted overloads to catch incorrect std::string usage at compile time with clear error messages
161 void set_supported_custom_presets(const std::vector<std::string> &presets) = delete;
162 void set_supported_custom_presets(std::initializer_list<std::string> presets) = delete;
163
164 // Compat: returns const ref with empty fallback. In 2026.11.0 change to return const vector *.
165 const std::vector<const char *> &get_supported_custom_presets() const;
166 bool supports_custom_preset(const char *custom_preset) const {
167 return (this->supported_custom_presets_ && vector_contains(*this->supported_custom_presets_, custom_preset)) ||
168 vector_contains(this->compat_custom_presets_, custom_preset); // Compat: remove in 2026.11.0
169 }
170 bool supports_custom_preset(const std::string &custom_preset) const {
171 return this->supports_custom_preset(custom_preset.c_str());
172 }
173
177 bool get_supports_swing_modes() const { return !this->supported_swing_modes_.empty(); }
179
181 void set_visual_min_temperature(float visual_min_temperature) {
182 this->visual_min_temperature_ = visual_min_temperature;
183 }
185 void set_visual_max_temperature(float visual_max_temperature) {
186 this->visual_max_temperature_ = visual_max_temperature;
187 }
190 void set_visual_target_temperature_step(float temperature_step) {
191 this->visual_target_temperature_step_ = temperature_step;
192 }
193 void set_visual_current_temperature_step(float temperature_step) {
194 this->visual_current_temperature_step_ = temperature_step;
195 }
196 void set_visual_temperature_step(float temperature_step) {
197 this->visual_target_temperature_step_ = temperature_step;
198 this->visual_current_temperature_step_ = temperature_step;
199 }
202
203 float get_visual_min_humidity() const { return this->visual_min_humidity_; }
204 void set_visual_min_humidity(float visual_min_humidity) { this->visual_min_humidity_ = visual_min_humidity; }
205 float get_visual_max_humidity() const { return this->visual_max_humidity_; }
206 void set_visual_max_humidity(float visual_max_humidity) { this->visual_max_humidity_ = visual_max_humidity; }
207
208 protected:
210 if (supported) {
211 this->supported_modes_.insert(mode);
212 } else {
213 this->supported_modes_.erase(mode);
214 }
215 }
217 if (supported) {
218 this->supported_fan_modes_.insert(mode);
219 } else {
220 this->supported_fan_modes_.erase(mode);
221 }
222 }
224 if (supported) {
225 this->supported_swing_modes_.insert(mode);
226 } else {
227 this->supported_swing_modes_.erase(mode);
228 }
229 }
230
232 void set_supported_custom_fan_modes_(const std::vector<const char *> *modes) {
233 this->supported_custom_fan_modes_ = modes;
234 }
235 void set_supported_custom_presets_(const std::vector<const char *> *presets) {
236 this->supported_custom_presets_ = presets;
237 }
238
241 const char *find_custom_fan_mode_(const char *custom_fan_mode) const {
242 return this->find_custom_fan_mode_(custom_fan_mode, strlen(custom_fan_mode));
243 }
244 const char *find_custom_fan_mode_(const char *custom_fan_mode, size_t len) const {
245 if (this->supported_custom_fan_modes_) {
246 return vector_find(*this->supported_custom_fan_modes_, custom_fan_mode, len);
247 }
248 // Compat: check owned vector from deprecated setters. Remove in 2026.11.0.
249 return vector_find(this->compat_custom_fan_modes_, custom_fan_mode, len);
250 }
251
254 const char *find_custom_preset_(const char *custom_preset) const {
255 return this->find_custom_preset_(custom_preset, strlen(custom_preset));
256 }
257 const char *find_custom_preset_(const char *custom_preset, size_t len) const {
258 if (this->supported_custom_presets_) {
259 return vector_find(*this->supported_custom_presets_, custom_preset, len);
260 }
261 // Compat: check owned vector from deprecated setters. Remove in 2026.11.0.
262 return vector_find(this->compat_custom_presets_, custom_preset, len);
263 }
264
272
277
283 const std::vector<const char *> *supported_custom_fan_modes_{nullptr};
284 const std::vector<const char *> *supported_custom_presets_{nullptr};
285 // Compat: owned storage for deprecated setters. Copies copy the vector (copies include this vector).
286 // Remove in 2026.11.0.
287 std::vector<const char *> compat_custom_fan_modes_;
288 std::vector<const char *> compat_custom_presets_;
289};
290
291} // namespace esphome::climate
BedjetMode mode
BedJet operating mode.
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:187
ESPDEPRECATED("Call set_supported_custom_presets() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0") void set_supported_custom_presets(const std
void set_visual_max_temperature(float visual_max_temperature)
ESPDEPRECATED("Call set_supported_custom_fan_modes() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0") void set_supported_custom_fan_modes(const std
const char * find_custom_fan_mode_(const char *custom_fan_mode, size_t len) const
void add_feature_flags(uint32_t feature_flags)
void add_supported_fan_mode(ClimateFanMode mode)
const ClimatePresetMask & get_supported_presets() const
void set_supported_custom_presets(const std::vector< std::string > &presets)=delete
void set_supported_custom_fan_modes(std::initializer_list< std::string > modes)=delete
const std::vector< const char * > * supported_custom_presets_
const std::vector< const char * > & get_supported_custom_fan_modes() const
const ClimateSwingModeMask & get_supported_swing_modes() const
void set_visual_temperature_step(float temperature_step)
void add_supported_preset(ClimatePreset preset)
const std::vector< const char * > * supported_custom_fan_modes_
Custom mode storage - pointers to vectors owned by the Climate base class.
ESPDEPRECATED("Call set_supported_custom_presets() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0") void set_supported_custom_presets(std
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_supported_custom_presets_(const std::vector< const char * > *presets)
void set_visual_min_humidity(float visual_min_humidity)
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
const char * find_custom_preset_(const char *custom_preset, size_t len) const
ESPDEPRECATED("Call set_supported_custom_fan_modes() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0") void set_supported_custom_fan_modes(const char *const (&modes)[N])
void set_supported_custom_presets(std::initializer_list< std::string > presets)=delete
void set_supported_modes(ClimateModeMask modes)
climate::ClimateFanModeMask supported_fan_modes_
bool supports_custom_preset(const char *custom_preset) const
void set_supported_custom_fan_modes_(const std::vector< const char * > *modes)
Set custom mode pointers (only Climate::get_traits() should call these).
climate::ClimateSwingModeMask supported_swing_modes_
bool has_feature_flags(uint32_t feature_flags) const
ESPDEPRECATED("Call set_supported_custom_presets() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0") void set_supported_custom_presets(const char *const (&presets)[N])
climate::ClimatePresetMask supported_presets_
int8_t get_current_temperature_accuracy_decimals() const
void set_visual_max_humidity(float visual_max_humidity)
bool supports_fan_mode(ClimateFanMode fan_mode) const
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)
const char * find_custom_fan_mode_(const char *custom_fan_mode) const
Find and return the matching custom fan mode pointer from supported modes, or nullptr if not found Th...
const char * find_custom_preset_(const char *custom_preset) const
Find and return the matching custom preset pointer from supported presets, or nullptr if not found Th...
ESPDEPRECATED("Call set_supported_custom_fan_modes() on the Climate entity instead. Removed in 2026.11.0", "2026.5.0") void set_supported_custom_fan_modes(std
const std::vector< const char * > & get_supported_custom_presets() const
void set_fan_mode_support_(climate::ClimateFanMode mode, bool supported)
const ClimateModeMask & get_supported_modes() const
void add_supported_swing_mode(ClimateSwingMode mode)
uint32_t get_feature_flags() const
Get/set feature flags (see ClimateFeatures enum in climate_mode.h)
void set_supported_custom_fan_modes(const std::vector< std::string > &modes)=delete
std::vector< const char * > compat_custom_presets_
bool supports_swing_mode(ClimateSwingMode swing_mode) const
std::vector< const char * > compat_custom_fan_modes_
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
bool vector_contains(const std::vector< const char * > &vec, const char *value, size_t len)
ClimatePreset
Enum for all preset modes NOTE: If adding values, update ClimatePresetMask in climate_traits....
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.
ClimateFanMode
NOTE: If adding values, update ClimateFanModeMask in climate_traits.h to use the new last value.
const char * vector_find(const std::vector< const char * > &vec, const char *value, size_t len)
std::string size_t len
static void uint32_t