ESPHome 2026.5.1
Loading...
Searching...
No Matches
bang_bang_climate.cpp
Go to the documentation of this file.
1#include "bang_bang_climate.h"
2#include "esphome/core/log.h"
3
5
6static const char *const TAG = "bang_bang.climate";
7
9
11 this->sensor_->add_on_state_callback([this](float state) {
13 // control may have changed, recompute
14 this->compute_state_();
15 // current temperature changed, publish state
16 this->publish_state();
17 });
18 this->current_temperature = this->sensor_->state;
19
20 // register for humidity values and get initial state
21 if (this->humidity_sensor_ != nullptr) {
22 this->humidity_sensor_->add_on_state_callback([this](float state) {
23 this->current_humidity = state;
24 this->publish_state();
25 });
27 }
28
29 // restore set points
30 auto restore = this->restore_state_();
31 if (restore.has_value()) {
32 restore->to_call(this).perform();
33 } else {
34 // restore from defaults, change_away handles those for us
35 if (this->supports_cool_ && this->supports_heat_) {
37 } else if (this->supports_cool_) {
39 } else if (this->supports_heat_) {
41 }
42 this->change_away_(false);
43 }
44}
45
47 auto mode = call.get_mode();
48 if (mode.has_value()) {
49 this->mode = *mode;
50 }
52 if (target_temperature_low.has_value()) {
54 }
56 if (target_temperature_high.has_value()) {
58 }
59 auto preset = call.get_preset();
60 if (preset.has_value()) {
62 }
63
64 this->compute_state_();
65 this->publish_state();
66}
67
95
97 if (this->mode == climate::CLIMATE_MODE_OFF) {
99 return;
100 }
101 if (std::isnan(this->current_temperature) || std::isnan(this->target_temperature_low) ||
102 std::isnan(this->target_temperature_high)) {
103 // if any control parameters are nan, go to OFF action (not IDLE!)
105 return;
106 }
107 const bool too_cold = this->current_temperature < this->target_temperature_low;
108 const bool too_hot = this->current_temperature > this->target_temperature_high;
109
110 climate::ClimateAction target_action;
111 if (too_cold) {
112 // too cold -> enable heating if possible and enabled, else idle
113 if (this->supports_heat_ &&
115 target_action = climate::CLIMATE_ACTION_HEATING;
116 } else {
117 target_action = climate::CLIMATE_ACTION_IDLE;
118 }
119 } else if (too_hot) {
120 // too hot -> enable cooling if possible and enabled, else idle
121 if (this->supports_cool_ &&
123 target_action = climate::CLIMATE_ACTION_COOLING;
124 } else {
125 target_action = climate::CLIMATE_ACTION_IDLE;
126 }
127 } else {
128 // neither too hot nor too cold -> in range
129 if (this->supports_cool_ && this->supports_heat_ && this->mode == climate::CLIMATE_MODE_HEAT_COOL) {
130 // if supports both ends and both cooling and heating enabled, go to idle action
131 target_action = climate::CLIMATE_ACTION_IDLE;
132 } else {
133 // else use current mode and don't change (hysteresis)
134 target_action = this->action;
135 }
136 }
137
138 this->switch_to_action_(target_action);
139}
140
142 if (action == this->action) {
143 // already in target mode
144 return;
145 }
146
149 // switching from OFF to IDLE or vice-versa
150 // these only have visual difference. OFF means user manually disabled,
151 // IDLE means it's in auto mode but value is in target range.
152 this->action = action;
153 this->publish_state();
154 return;
155 }
156
157 if (this->prev_trigger_ != nullptr) {
158 this->prev_trigger_->stop_action();
159 this->prev_trigger_ = nullptr;
160 }
161 Trigger<> *trig;
162 switch (action) {
165 trig = &this->idle_trigger_;
166 break;
168 trig = &this->cool_trigger_;
169 break;
171 trig = &this->heat_trigger_;
172 break;
173 default:
174 trig = nullptr;
175 }
176 if (trig != nullptr) {
177 trig->trigger();
178 } else {
179 ESP_LOGW(TAG, "trig not set - unsupported action");
180 }
181 this->action = action;
182 this->prev_trigger_ = trig;
183 this->publish_state();
184}
185
196
198 this->normal_config_ = normal_config;
199}
200
202 this->supports_away_ = true;
203 this->away_config_ = away_config;
204}
205
206void BangBangClimate::set_sensor(sensor::Sensor *sensor) { this->sensor_ = sensor; }
207void BangBangClimate::set_humidity_sensor(sensor::Sensor *humidity_sensor) { this->humidity_sensor_ = humidity_sensor; }
208
212
213void BangBangClimate::set_supports_cool(bool supports_cool) { this->supports_cool_ = supports_cool; }
214void BangBangClimate::set_supports_heat(bool supports_heat) { this->supports_heat_ = supports_heat; }
215
217 LOG_CLIMATE("", "Bang Bang Climate", this);
218 ESP_LOGCONFIG(TAG,
219 " Supports HEAT: %s\n"
220 " Supports COOL: %s\n"
221 " Supports AWAY mode: %s\n"
222 " Default Target Temperature Low: %.2f°C\n"
223 " Default Target Temperature High: %.2f°C",
224 YESNO(this->supports_heat_), YESNO(this->supports_cool_), YESNO(this->supports_away_),
225 this->normal_config_.default_temperature_low, this->normal_config_.default_temperature_high);
226}
227
230 float default_temperature_high)
231 : default_temperature_low(default_temperature_low), default_temperature_high(default_temperature_high) {}
232
233} // namespace esphome::bang_bang
void stop_action()
Stop any action connected to this trigger.
Definition automation.h:490
void trigger(const Ts &...x) ESPHOME_ALWAYS_INLINE
Inform the parent automation that the event has triggered.
Definition automation.h:482
void compute_state_()
Re-compute the state of this climate controller.
BangBangClimateTargetTempConfig away_config_
void set_away_config(const BangBangClimateTargetTempConfig &away_config)
bool supports_cool_
Whether the controller supports cooling/heating.
void set_supports_heat(bool supports_heat)
climate::ClimateTraits traits() override
Return the traits of this controller.
Trigger idle_trigger_
The trigger to call when the controller should switch to idle mode.
void control(const climate::ClimateCall &call) override
Override control to change settings of the climate device.
void set_sensor(sensor::Sensor *sensor)
void set_supports_cool(bool supports_cool)
void change_away_(bool away)
Change the away setting, will reset target temperatures to defaults.
void set_normal_config(const BangBangClimateTargetTempConfig &normal_config)
Trigger * prev_trigger_
A reference to the trigger that was previously active.
sensor::Sensor * sensor_
The sensor used for getting the current temperature.
void switch_to_action_(climate::ClimateAction action)
Switch the climate device to the given climate mode.
Trigger cool_trigger_
The trigger to call when the controller should switch to cooling mode.
BangBangClimateTargetTempConfig normal_config_
sensor::Sensor * humidity_sensor_
The sensor used for getting the current humidity.
Trigger heat_trigger_
The trigger to call when the controller should switch to heating mode.
void set_humidity_sensor(sensor::Sensor *humidity_sensor)
This class is used to encode all control actions on a climate device.
Definition climate.h:34
const optional< float > & get_target_temperature_low() const
Definition climate.cpp:308
const optional< ClimatePreset > & get_preset() const
Definition climate.cpp:315
const optional< float > & get_target_temperature_high() const
Definition climate.cpp:309
ClimateMode mode
The active mode of the climate device.
Definition climate.h:293
float current_humidity
The current humidity of the climate device, as reported from the integration.
Definition climate.h:270
float target_temperature_low
The minimum target temperature of the climate device, for climate devices with split target temperatu...
Definition climate.h:277
float current_temperature
The current temperature of the climate device, as reported from the integration.
Definition climate.h:267
ClimateAction action
The active state of the climate device.
Definition climate.h:296
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition climate.cpp:437
optional< ClimatePreset > preset
The active preset of the climate device.
Definition climate.h:290
optional< ClimateDeviceRestoreState > restore_state_()
Restore the state of the climate device, call this from your setup() method.
Definition climate.cpp:362
float target_temperature_high
The maximum target temperature of the climate device, for climate devices with split target temperatu...
Definition climate.h:279
void add_feature_flags(uint32_t feature_flags)
void set_supported_presets(ClimatePresetMask presets)
void set_supported_modes(ClimateModeMask modes)
void add_supported_mode(ClimateMode mode)
Base-class for all sensors.
Definition sensor.h:47
void add_on_state_callback(F &&callback)
Add a callback that will be called every time a filtered value arrives.
Definition sensor.h:119
float state
This member variable stores the last state that has passed through all filters.
Definition sensor.h:138
bool state
Definition fan.h:2
@ CLIMATE_SUPPORTS_CURRENT_HUMIDITY
@ CLIMATE_SUPPORTS_CURRENT_TEMPERATURE
@ CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE
@ CLIMATE_PRESET_AWAY
Device is in away preset.
@ CLIMATE_PRESET_HOME
Device is in home preset.
@ CLIMATE_MODE_HEAT
The climate device is set to heat to reach the target temperature.
@ CLIMATE_MODE_COOL
The climate device is set to cool to reach the target temperature.
@ CLIMATE_MODE_HEAT_COOL
The climate device is set to heat/cool to reach the target temperature.
@ CLIMATE_MODE_OFF
The climate device is off.
ClimateAction
Enum for the current action of the climate device. Values match those of ClimateMode.
@ CLIMATE_ACTION_OFF
The climate device is off (inactive or no power)
@ CLIMATE_ACTION_IDLE
The climate device is idle (monitoring climate but no action needed)
@ CLIMATE_ACTION_HEATING
The climate device is actively heating.
@ CLIMATE_ACTION_COOLING
The climate device is actively cooling.