ESPHome  2021.11.3
bang_bang_climate.cpp
Go to the documentation of this file.
1 #include "bang_bang_climate.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace bang_bang {
6 
7 static const char *const TAG = "bang_bang.climate";
8 
10  this->sensor_->add_on_state_callback([this](float state) {
11  this->current_temperature = state;
12  // control may have changed, recompute
13  this->compute_state_();
14  // current temperature changed, publish state
15  this->publish_state();
16  });
17  this->current_temperature = this->sensor_->state;
18  // restore set points
19  auto restore = this->restore_state_();
20  if (restore.has_value()) {
21  restore->to_call(this).perform();
22  } else {
23  // restore from defaults, change_away handles those for us
26  else if (supports_cool_)
28  else if (supports_heat_)
30  this->change_away_(false);
31  }
32 }
34  if (call.get_mode().has_value())
35  this->mode = *call.get_mode();
40  if (call.get_preset().has_value())
42 
43  this->compute_state_();
44  this->publish_state();
45 }
51  });
52  if (supports_cool_)
54  if (supports_heat_)
59  if (supports_away_)
63  });
65  return traits;
66 }
68  if (this->mode == climate::CLIMATE_MODE_OFF) {
70  return;
71  }
72  if (std::isnan(this->current_temperature) || std::isnan(this->target_temperature_low) ||
73  std::isnan(this->target_temperature_high)) {
74  // if any control parameters are nan, go to OFF action (not IDLE!)
76  return;
77  }
78  const bool too_cold = this->current_temperature < this->target_temperature_low;
79  const bool too_hot = this->current_temperature > this->target_temperature_high;
80 
81  climate::ClimateAction target_action;
82  if (too_cold) {
83  // too cold -> enable heating if possible, else idle
84  if (this->supports_heat_)
85  target_action = climate::CLIMATE_ACTION_HEATING;
86  else
87  target_action = climate::CLIMATE_ACTION_IDLE;
88  } else if (too_hot) {
89  // too hot -> enable cooling if possible, else idle
90  if (this->supports_cool_)
91  target_action = climate::CLIMATE_ACTION_COOLING;
92  else
93  target_action = climate::CLIMATE_ACTION_IDLE;
94  } else {
95  // neither too hot nor too cold -> in range
96  if (this->supports_cool_ && this->supports_heat_) {
97  // if supports both ends, go to idle action
98  target_action = climate::CLIMATE_ACTION_IDLE;
99  } else {
100  // else use current mode and don't change (hysteresis)
101  target_action = this->action;
102  }
103  }
104 
105  this->switch_to_action_(target_action);
106 }
108  if (action == this->action)
109  // already in target mode
110  return;
111 
112  if ((action == climate::CLIMATE_ACTION_OFF && this->action == climate::CLIMATE_ACTION_IDLE) ||
113  (action == climate::CLIMATE_ACTION_IDLE && this->action == climate::CLIMATE_ACTION_OFF)) {
114  // switching from OFF to IDLE or vice-versa
115  // these only have visual difference. OFF means user manually disabled,
116  // IDLE means it's in auto mode but value is in target range.
117  this->action = action;
118  this->publish_state();
119  return;
120  }
121 
122  if (this->prev_trigger_ != nullptr) {
123  this->prev_trigger_->stop_action();
124  this->prev_trigger_ = nullptr;
125  }
126  Trigger<> *trig;
127  switch (action) {
130  trig = this->idle_trigger_;
131  break;
133  trig = this->cool_trigger_;
134  break;
136  trig = this->heat_trigger_;
137  break;
138  default:
139  trig = nullptr;
140  }
141  assert(trig != nullptr);
142  trig->trigger();
143  this->action = action;
144  this->prev_trigger_ = trig;
145  this->publish_state();
146 }
148  if (!away) {
151  } else {
154  }
156 }
158  this->normal_config_ = normal_config;
159 }
161  this->supports_away_ = true;
162  this->away_config_ = away_config;
163 }
165  : idle_trigger_(new Trigger<>()), cool_trigger_(new Trigger<>()), heat_trigger_(new Trigger<>()) {}
166 void BangBangClimate::set_sensor(sensor::Sensor *sensor) { this->sensor_ = sensor; }
169 void BangBangClimate::set_supports_cool(bool supports_cool) { this->supports_cool_ = supports_cool; }
171 void BangBangClimate::set_supports_heat(bool supports_heat) { this->supports_heat_ = supports_heat; }
173  LOG_CLIMATE("", "Bang Bang Climate", this);
174  ESP_LOGCONFIG(TAG, " Supports HEAT: %s", YESNO(this->supports_heat_));
175  ESP_LOGCONFIG(TAG, " Supports COOL: %s", YESNO(this->supports_cool_));
176  ESP_LOGCONFIG(TAG, " Supports AWAY mode: %s", YESNO(this->supports_away_));
177  ESP_LOGCONFIG(TAG, " Default Target Temperature Low: %.1f°C", this->normal_config_.default_temperature_low);
178  ESP_LOGCONFIG(TAG, " Default Target Temperature High: %.1f°C", this->normal_config_.default_temperature_high);
179 }
180 
183  float default_temperature_high)
184  : default_temperature_low(default_temperature_low), default_temperature_high(default_temperature_high) {}
185 
186 } // namespace bang_bang
187 } // namespace esphome
This class is used to encode all control actions on a climate device.
Definition: climate.h:33
sensor::Sensor * sensor_
The sensor used for getting the current temperature.
The climate device is off (inactive or no power)
Definition: climate_mode.h:33
void add_on_state_callback(std::function< void(float)> &&callback)
Add a callback that will be called every time a filtered value arrives.
Definition: sensor.cpp:71
Trigger * prev_trigger_
A reference to the trigger that was previously active.
Trigger * heat_trigger_
The trigger to call when the controller should switch to heating mode.
Device is in home preset.
Definition: climate_mode.h:84
void set_normal_config(const BangBangClimateTargetTempConfig &normal_config)
const optional< ClimateMode > & get_mode() const
Definition: climate.cpp:259
This class contains all static data for climate devices.
The climate device is set to heat to reach the target temperature.
Definition: climate_mode.h:18
ClimateMode mode
The active mode of the climate device.
Definition: climate.h:175
const optional< float > & get_target_temperature_low() const
Definition: climate.cpp:261
bool supports_cool_
Whether the controller supports cooling.
float target_temperature_high
The maximum target temperature of the climate device, for climate devices with split target temperatu...
Definition: climate.h:188
float current_temperature
The current temperature of the climate device, as reported from the integration.
Definition: climate.h:179
bool has_value() const
Definition: optional.h:87
void set_supports_heat(bool supports_heat)
void set_supported_presets(std::set< ClimatePreset > presets)
void trigger(Ts... x)
Inform the parent automation that the event has triggered.
Definition: automation.h:90
Device is in away preset.
Definition: climate_mode.h:86
Trigger * idle_trigger_
The trigger to call when the controller should switch to idle mode.
BangBangClimateTargetTempConfig away_config_
The climate device is set to cool to reach the target temperature.
Definition: climate_mode.h:16
float state
This member variable stores the last state that has passed through all filters.
Definition: sensor.h:132
void control(const climate::ClimateCall &call) override
Override control to change settings of the climate device.
const optional< ClimatePreset > & get_preset() const
Definition: climate.cpp:270
optional< ClimatePreset > preset
The active preset of the climate device.
Definition: climate.h:210
void set_supported_modes(std::set< ClimateMode > modes)
ClimateAction
Enum for the current action of the climate device. Values match those of ClimateMode.
Definition: climate_mode.h:31
void compute_state_()
Re-compute the state of this climate controller.
The climate device is set to heat/cool to reach the target temperature.
Definition: climate_mode.h:14
The climate device is actively heating.
Definition: climate_mode.h:37
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition: climate.cpp:380
void set_away_config(const BangBangClimateTargetTempConfig &away_config)
The climate device is off.
Definition: climate_mode.h:12
void set_supports_action(bool supports_action)
void change_away_(bool away)
Change the away setting, will reset target temperatures to defaults.
void set_supports_cool(bool supports_cool)
climate::ClimateTraits traits() override
Return the traits of this controller.
void switch_to_action_(climate::ClimateAction action)
Switch the climate device to the given climate mode.
void set_sensor(sensor::Sensor *sensor)
Library based on https://github.com/miguelbalboa/rfid and adapted to ESPHome by . ...
Definition: a4988.cpp:4
The climate device is idle (monitoring climate but no action needed)
Definition: climate_mode.h:39
void set_supports_two_point_target_temperature(bool supports_two_point_target_temperature)
optional< ClimateDeviceRestoreState > restore_state_()
Restore the state of the climate device, call this from your setup() method.
Definition: climate.cpp:320
void set_supports_current_temperature(bool supports_current_temperature)
const optional< float > & get_target_temperature_high() const
Definition: climate.cpp:262
Base-class for all sensors.
Definition: sensor.h:47
BangBangClimateTargetTempConfig normal_config_
The climate device is actively cooling.
Definition: climate_mode.h:35
void add_supported_mode(ClimateMode mode)
float target_temperature_low
The minimum target temperature of the climate device, for climate devices with split target temperatu...
Definition: climate.h:186
void stop_action()
Stop any action connected to this trigger.
Definition: automation.h:98
ClimateAction action
The active state of the climate device.
Definition: climate.h:177
Trigger * cool_trigger_
The trigger to call when the controller should switch to cooling mode.