ESPHome  2021.11.3
tuya_climate.cpp
Go to the documentation of this file.
1 #include "esphome/core/log.h"
2 #include "tuya_climate.h"
3 
4 namespace esphome {
5 namespace tuya {
6 
7 static const char *const TAG = "tuya.climate";
8 
10  if (this->switch_id_.has_value()) {
11  this->parent_->register_listener(*this->switch_id_, [this](const TuyaDatapoint &datapoint) {
12  ESP_LOGV(TAG, "MCU reported switch is: %s", ONOFF(datapoint.value_bool));
14  if (datapoint.value_bool) {
15  if (this->supports_heat_ && this->supports_cool_) {
17  } else if (this->supports_heat_) {
19  } else if (this->supports_cool_) {
21  }
22  }
23  this->compute_state_();
24  this->publish_state();
25  });
26  }
27  if (this->active_state_id_.has_value()) {
28  this->parent_->register_listener(*this->active_state_id_, [this](const TuyaDatapoint &datapoint) {
29  ESP_LOGV(TAG, "MCU reported active state is: %u", datapoint.value_enum);
30  this->active_state_ = datapoint.value_enum;
31  this->compute_state_();
32  this->publish_state();
33  });
34  } else {
35  if (this->heating_state_pin_ != nullptr) {
36  this->heating_state_pin_->setup();
38  }
39  if (this->cooling_state_pin_ != nullptr) {
40  this->cooling_state_pin_->setup();
42  }
43  }
44  if (this->target_temperature_id_.has_value()) {
45  this->parent_->register_listener(*this->target_temperature_id_, [this](const TuyaDatapoint &datapoint) {
47  ESP_LOGV(TAG, "MCU reported manual target temperature is: %.1f", this->manual_temperature_);
49  this->compute_state_();
50  this->publish_state();
51  });
52  }
53  if (this->current_temperature_id_.has_value()) {
54  this->parent_->register_listener(*this->current_temperature_id_, [this](const TuyaDatapoint &datapoint) {
56  ESP_LOGV(TAG, "MCU reported current temperature is: %.1f", this->current_temperature);
57  this->compute_state_();
58  this->publish_state();
59  });
60  }
61  if (this->eco_id_.has_value()) {
62  this->parent_->register_listener(*this->eco_id_, [this](const TuyaDatapoint &datapoint) {
63  this->eco_ = datapoint.value_bool;
64  ESP_LOGV(TAG, "MCU reported eco is: %s", ONOFF(this->eco_));
65  this->compute_preset_();
67  this->publish_state();
68  });
69  }
70 }
71 
73  if (this->active_state_id_.has_value())
74  return;
75 
76  bool state_changed = false;
77  if (this->heating_state_pin_ != nullptr) {
78  bool heating_state = this->heating_state_pin_->digital_read();
79  if (heating_state != this->heating_state_) {
80  ESP_LOGV(TAG, "Heating state pin changed to: %s", ONOFF(heating_state));
81  this->heating_state_ = heating_state;
82  state_changed = true;
83  }
84  }
85  if (this->cooling_state_pin_ != nullptr) {
86  bool cooling_state = this->cooling_state_pin_->digital_read();
87  if (cooling_state != this->cooling_state_) {
88  ESP_LOGV(TAG, "Cooling state pin changed to: %s", ONOFF(cooling_state));
89  this->cooling_state_ = cooling_state;
90  state_changed = true;
91  }
92  }
93 
94  if (state_changed) {
95  this->compute_state_();
96  this->publish_state();
97  }
98 }
99 
101  if (call.get_mode().has_value()) {
102  const bool switch_state = *call.get_mode() != climate::CLIMATE_MODE_OFF;
103  ESP_LOGV(TAG, "Setting switch: %s", ONOFF(switch_state));
104  this->parent_->set_boolean_datapoint_value(*this->switch_id_, switch_state);
105  }
106 
107  if (call.get_target_temperature().has_value()) {
108  const float target_temperature = *call.get_target_temperature();
109  ESP_LOGV(TAG, "Setting target temperature: %.1f", target_temperature);
111  (int) (target_temperature / this->target_temperature_multiplier_));
112  }
113 
114  if (call.get_preset().has_value()) {
115  const climate::ClimatePreset preset = *call.get_preset();
116  if (this->eco_id_.has_value()) {
117  const bool eco = preset == climate::CLIMATE_PRESET_ECO;
118  ESP_LOGV(TAG, "Setting eco: %s", ONOFF(eco));
119  this->parent_->set_boolean_datapoint_value(*this->eco_id_, eco);
120  }
121  }
122 }
123 
128  if (supports_heat_)
130  if (supports_cool_)
132  if (this->eco_id_.has_value()) {
135  }
136  return traits;
137 }
138 
140  LOG_CLIMATE("", "Tuya Climate", this);
141  if (this->switch_id_.has_value())
142  ESP_LOGCONFIG(TAG, " Switch has datapoint ID %u", *this->switch_id_);
143  if (this->active_state_id_.has_value())
144  ESP_LOGCONFIG(TAG, " Active state has datapoint ID %u", *this->active_state_id_);
145  if (this->target_temperature_id_.has_value())
146  ESP_LOGCONFIG(TAG, " Target Temperature has datapoint ID %u", *this->target_temperature_id_);
148  ESP_LOGCONFIG(TAG, " Current Temperature has datapoint ID %u", *this->current_temperature_id_);
149  LOG_PIN(" Heating State Pin: ", this->heating_state_pin_);
150  LOG_PIN(" Cooling State Pin: ", this->cooling_state_pin_);
151  if (this->eco_id_.has_value())
152  ESP_LOGCONFIG(TAG, " Eco has datapoint ID %u", *this->eco_id_);
153 }
154 
156  if (this->eco_) {
158  } else {
160  }
161 }
162 
164  if (this->eco_ && this->eco_temperature_.has_value()) {
165  this->target_temperature = *this->eco_temperature_;
166  } else {
168  }
169 }
170 
172  if (std::isnan(this->current_temperature) || std::isnan(this->target_temperature)) {
173  // if any control parameters are nan, go to OFF action (not IDLE!)
175  return;
176  }
177 
178  if (this->mode == climate::CLIMATE_MODE_OFF) {
180  return;
181  }
182 
184  if (this->active_state_id_.has_value()) {
185  // Use state from MCU datapoint
188  target_action = climate::CLIMATE_ACTION_HEATING;
189  } else if (this->supports_cool_ && this->active_state_cooling_value_.has_value() &&
191  target_action = climate::CLIMATE_ACTION_COOLING;
192  }
193  } else if (this->heating_state_pin_ != nullptr || this->cooling_state_pin_ != nullptr) {
194  // Use state from input pins
195  if (this->heating_state_) {
196  target_action = climate::CLIMATE_ACTION_HEATING;
197  } else if (this->cooling_state_) {
198  target_action = climate::CLIMATE_ACTION_COOLING;
199  }
200  } else {
201  // Fallback to active state calc based on temp and hysteresis
202  const float temp_diff = this->target_temperature - this->current_temperature;
203  if (std::abs(temp_diff) > this->hysteresis_) {
204  if (this->supports_heat_ && temp_diff > 0) {
205  target_action = climate::CLIMATE_ACTION_HEATING;
206  } else if (this->supports_cool_ && temp_diff < 0) {
207  target_action = climate::CLIMATE_ACTION_COOLING;
208  }
209  }
210  }
211 
212  this->switch_to_action_(target_action);
213 }
214 
216  // For now this just sets the current action but could include triggers later
217  this->action = action;
218 }
219 
220 } // namespace tuya
221 } // namespace esphome
This class is used to encode all control actions on a climate device.
Definition: climate.h:33
The climate device is off (inactive or no power)
Definition: climate_mode.h:33
ClimatePreset
Enum for all modes a climate swing can be in.
Definition: climate_mode.h:80
float target_temperature
The target temperature of the climate device.
Definition: climate.h:183
void switch_to_action_(climate::ClimateAction action)
Switch the climate device to the given climate mode.
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
float current_temperature
The current temperature of the climate device, as reported from the integration.
Definition: climate.h:179
optional< uint8_t > active_state_cooling_value_
Definition: tuya_climate.h:65
bool has_value() const
Definition: optional.h:87
void register_listener(uint8_t datapoint_id, const std::function< void(TuyaDatapoint)> &func)
Definition: tuya.cpp:542
virtual void setup()=0
optional< uint8_t > switch_id_
Definition: tuya_climate.h:62
void add_supported_preset(ClimatePreset preset)
void compute_target_temperature_()
Re-compute the target temperature of this climate controller.
The climate device is set to cool to reach the target temperature.
Definition: climate_mode.h:16
const optional< ClimatePreset > & get_preset() const
Definition: climate.cpp:270
void control(const climate::ClimateCall &call) override
Override control to change settings of the climate device.
optional< ClimatePreset > preset
The active preset of the climate device.
Definition: climate.h:210
optional< uint8_t > active_state_id_
Definition: tuya_climate.h:63
optional< uint8_t > eco_id_
Definition: tuya_climate.h:73
ClimateAction
Enum for the current action of the climate device. Values match those of ClimateMode.
Definition: climate_mode.h:31
optional< float > eco_temperature_
Definition: tuya_climate.h:74
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
const optional< float > & get_target_temperature() const
Definition: climate.cpp:260
optional< uint8_t > active_state_heating_value_
Definition: tuya_climate.h:64
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition: climate.cpp:380
virtual bool digital_read()=0
The climate device is off.
Definition: climate_mode.h:12
void set_supports_action(bool supports_action)
climate::ClimateTraits traits() override
Return the traits of this controller.
void set_boolean_datapoint_value(uint8_t datapoint_id, bool value)
Definition: tuya.cpp:458
void set_integer_datapoint_value(uint8_t datapoint_id, uint32_t value)
Definition: tuya.cpp:462
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
Device is running an energy-saving preset.
Definition: climate_mode.h:92
void set_supports_current_temperature(bool supports_current_temperature)
void compute_state_()
Re-compute the state of this climate controller.
optional< uint8_t > target_temperature_id_
Definition: tuya_climate.h:68
The climate device is actively cooling.
Definition: climate_mode.h:35
void add_supported_mode(ClimateMode mode)
void compute_preset_()
Re-compute the active preset of this climate controller.
optional< uint8_t > current_temperature_id_
Definition: tuya_climate.h:69
ClimateAction action
The active state of the climate device.
Definition: climate.h:177