ESPHome  2024.4.1
smartair2_climate.cpp
Go to the documentation of this file.
1 #include <chrono>
4 #include "smartair2_climate.h"
5 #include "smartair2_packet.h"
6 
7 using namespace esphome::climate;
8 using namespace esphome::uart;
9 
10 namespace esphome {
11 namespace haier {
12 
13 static const char *const TAG = "haier.climate";
14 constexpr size_t SIGNAL_LEVEL_UPDATE_INTERVAL_MS = 10000;
15 constexpr uint8_t CONTROL_MESSAGE_RETRIES = 5;
16 constexpr std::chrono::milliseconds CONTROL_MESSAGE_RETRIES_INTERVAL = std::chrono::milliseconds(500);
17 constexpr uint8_t INIT_REQUESTS_RETRY = 2;
18 constexpr std::chrono::milliseconds INIT_REQUESTS_RETRY_INTERVAL = std::chrono::milliseconds(2000);
19 
20 Smartair2Climate::Smartair2Climate() {
21  last_status_message_ = std::unique_ptr<uint8_t[]>(new uint8_t[sizeof(smartair2_protocol::HaierPacketControl)]);
22 }
23 
24 haier_protocol::HandlerError Smartair2Climate::status_handler_(haier_protocol::FrameType request_type,
25  haier_protocol::FrameType message_type,
26  const uint8_t *data, size_t data_size) {
27  haier_protocol::HandlerError result =
28  this->answer_preprocess_(request_type, haier_protocol::FrameType::CONTROL, message_type,
29  haier_protocol::FrameType::STATUS, ProtocolPhases::UNKNOWN);
30  if (result == haier_protocol::HandlerError::HANDLER_OK) {
31  result = this->process_status_message_(data, data_size);
32  if (result != haier_protocol::HandlerError::HANDLER_OK) {
33  ESP_LOGW(TAG, "Error %d while parsing Status packet", (int) result);
34  this->reset_phase_();
35  this->action_request_.reset();
36  this->force_send_control_ = false;
37  } else {
38  if (data_size >= sizeof(smartair2_protocol::HaierPacketControl) + 2) {
39  memcpy(this->last_status_message_.get(), data + 2, sizeof(smartair2_protocol::HaierPacketControl));
40  } else {
41  ESP_LOGW(TAG, "Status packet too small: %d (should be >= %d)", data_size,
43  }
44  switch (this->protocol_phase_) {
45  case ProtocolPhases::SENDING_FIRST_STATUS_REQUEST:
46  ESP_LOGI(TAG, "First HVAC status received");
47  this->set_phase(ProtocolPhases::IDLE);
48  break;
49  case ProtocolPhases::SENDING_ACTION_COMMAND:
50  // Do nothing, phase will be changed in process_phase
51  break;
52  case ProtocolPhases::SENDING_STATUS_REQUEST:
53  this->set_phase(ProtocolPhases::IDLE);
54  break;
55  case ProtocolPhases::SENDING_CONTROL:
56  this->set_phase(ProtocolPhases::IDLE);
57  this->force_send_control_ = false;
58  if (this->current_hvac_settings_.valid)
59  this->current_hvac_settings_.reset();
60  break;
61  default:
62  break;
63  }
64  }
65  return result;
66  } else {
67  this->action_request_.reset();
68  this->force_send_control_ = false;
69  this->reset_phase_();
70  return result;
71  }
72 }
73 
74 haier_protocol::HandlerError Smartair2Climate::get_device_version_answer_handler_(
75  haier_protocol::FrameType request_type, haier_protocol::FrameType message_type, const uint8_t *data,
76  size_t data_size) {
77  if (request_type != haier_protocol::FrameType::GET_DEVICE_VERSION)
78  return haier_protocol::HandlerError::UNSUPPORTED_MESSAGE;
79  if (ProtocolPhases::SENDING_INIT_1 != this->protocol_phase_)
80  return haier_protocol::HandlerError::UNEXPECTED_MESSAGE;
81  // Invalid packet is expected answer
82  if ((message_type == haier_protocol::FrameType::GET_DEVICE_VERSION_RESPONSE) && (data_size >= 39) &&
83  ((data[37] & 0x04) != 0)) {
84  ESP_LOGW(TAG, "It looks like your ESPHome Haier climate configuration is wrong. You should use the hOn protocol "
85  "instead of smartAir2");
86  }
87  this->set_phase(ProtocolPhases::SENDING_INIT_2);
88  return haier_protocol::HandlerError::HANDLER_OK;
89 }
90 
91 haier_protocol::HandlerError Smartair2Climate::messages_timeout_handler_with_cycle_for_init_(
92  haier_protocol::FrameType message_type) {
93  if (this->protocol_phase_ >= ProtocolPhases::IDLE)
94  return HaierClimateBase::timeout_default_handler_(message_type);
95  ESP_LOGI(TAG, "Answer timeout for command %02X, phase %s", (uint8_t) message_type,
96  phase_to_string_(this->protocol_phase_));
97  ProtocolPhases new_phase = (ProtocolPhases) ((int) this->protocol_phase_ + 1);
98  if (new_phase >= ProtocolPhases::SENDING_FIRST_ALARM_STATUS_REQUEST)
99  new_phase = ProtocolPhases::SENDING_INIT_1;
100  this->set_phase(new_phase);
101  return haier_protocol::HandlerError::HANDLER_OK;
102 }
103 
104 void Smartair2Climate::set_handlers() {
105  // Set handlers
106  this->haier_protocol_.set_answer_handler(
107  haier_protocol::FrameType::GET_DEVICE_VERSION,
108  std::bind(&Smartair2Climate::get_device_version_answer_handler_, this, std::placeholders::_1,
109  std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
110  this->haier_protocol_.set_answer_handler(
111  haier_protocol::FrameType::CONTROL,
112  std::bind(&Smartair2Climate::status_handler_, this, std::placeholders::_1, std::placeholders::_2,
113  std::placeholders::_3, std::placeholders::_4));
114  this->haier_protocol_.set_answer_handler(
115  haier_protocol::FrameType::REPORT_NETWORK_STATUS,
116  std::bind(&Smartair2Climate::report_network_status_answer_handler_, this, std::placeholders::_1,
117  std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
118  this->haier_protocol_.set_default_timeout_handler(
119  std::bind(&Smartair2Climate::messages_timeout_handler_with_cycle_for_init_, this, std::placeholders::_1));
120 }
121 
122 void Smartair2Climate::dump_config() {
123  HaierClimateBase::dump_config();
124  ESP_LOGCONFIG(TAG, " Protocol version: smartAir2");
125 }
126 
127 void Smartair2Climate::process_phase(std::chrono::steady_clock::time_point now) {
128  switch (this->protocol_phase_) {
129  case ProtocolPhases::SENDING_INIT_1:
130  if (this->can_send_message() && this->is_protocol_initialisation_interval_exceeded_(now)) {
131  // Indicate device capabilities:
132  // bit 0 - if 1 module support interactive mode
133  // bit 1 - if 1 module support controller-device mode
134  // bit 2 - if 1 module support crc
135  // bit 3 - if 1 module support multiple devices
136  // bit 4..bit 15 - not used
137  uint8_t module_capabilities[2] = {0b00000000, 0b00000111};
138  static const haier_protocol::HaierMessage DEVICE_VERSION_REQUEST(
139  haier_protocol::FrameType::GET_DEVICE_VERSION, module_capabilities, sizeof(module_capabilities));
140  this->send_message_(DEVICE_VERSION_REQUEST, this->use_crc_, INIT_REQUESTS_RETRY, INIT_REQUESTS_RETRY_INTERVAL);
141  }
142  break;
143  case ProtocolPhases::SENDING_INIT_2:
144  this->set_phase(ProtocolPhases::SENDING_FIRST_STATUS_REQUEST);
145  break;
146  case ProtocolPhases::SENDING_FIRST_STATUS_REQUEST:
147  case ProtocolPhases::SENDING_STATUS_REQUEST:
148  if (this->can_send_message() && this->is_message_interval_exceeded_(now)) {
149  static const haier_protocol::HaierMessage STATUS_REQUEST(haier_protocol::FrameType::CONTROL, 0x4D01);
150  if (this->protocol_phase_ == ProtocolPhases::SENDING_FIRST_STATUS_REQUEST) {
151  this->send_message_(STATUS_REQUEST, this->use_crc_, INIT_REQUESTS_RETRY, INIT_REQUESTS_RETRY_INTERVAL);
152  } else {
153  this->send_message_(STATUS_REQUEST, this->use_crc_);
154  }
155  this->last_status_request_ = now;
156  }
157  break;
158 #ifdef USE_WIFI
159  case ProtocolPhases::SENDING_SIGNAL_LEVEL:
160  if (this->can_send_message() && this->is_message_interval_exceeded_(now)) {
161  this->send_message_(this->get_wifi_signal_message_(), this->use_crc_);
162  this->last_signal_request_ = now;
163  }
164  break;
165 #else
166  case ProtocolPhases::SENDING_SIGNAL_LEVEL:
167  this->set_phase(ProtocolPhases::IDLE);
168  break;
169 #endif
170  case ProtocolPhases::SENDING_UPDATE_SIGNAL_REQUEST:
171  this->set_phase(ProtocolPhases::SENDING_SIGNAL_LEVEL);
172  break;
173  case ProtocolPhases::SENDING_FIRST_ALARM_STATUS_REQUEST:
174  this->set_phase(ProtocolPhases::SENDING_INIT_1);
175  break;
176  case ProtocolPhases::SENDING_ALARM_STATUS_REQUEST:
177  this->set_phase(ProtocolPhases::IDLE);
178  break;
179  case ProtocolPhases::SENDING_CONTROL:
180  if (this->can_send_message() && this->is_control_message_interval_exceeded_(now)) {
181  ESP_LOGI(TAG, "Sending control packet");
182  this->send_message_(get_control_message(), this->use_crc_, CONTROL_MESSAGE_RETRIES,
183  CONTROL_MESSAGE_RETRIES_INTERVAL);
184  }
185  break;
186  case ProtocolPhases::SENDING_ACTION_COMMAND:
187  if (this->action_request_.has_value()) {
188  if (this->action_request_.value().message.has_value()) {
189  this->send_message_(this->action_request_.value().message.value(), this->use_crc_);
190  this->action_request_.value().message.reset();
191  } else {
192  // Message already sent, reseting request and return to idle
193  this->action_request_.reset();
194  this->set_phase(ProtocolPhases::IDLE);
195  }
196  } else {
197  ESP_LOGW(TAG, "SENDING_ACTION_COMMAND phase without action request!");
198  this->set_phase(ProtocolPhases::IDLE);
199  }
200  break;
201  case ProtocolPhases::IDLE: {
202  if (this->forced_request_status_ || this->is_status_request_interval_exceeded_(now)) {
203  this->set_phase(ProtocolPhases::SENDING_STATUS_REQUEST);
204  this->forced_request_status_ = false;
205  }
206 #ifdef USE_WIFI
207  else if (this->send_wifi_signal_ &&
208  (std::chrono::duration_cast<std::chrono::milliseconds>(now - this->last_signal_request_).count() >
209  SIGNAL_LEVEL_UPDATE_INTERVAL_MS))
210  this->set_phase(ProtocolPhases::SENDING_UPDATE_SIGNAL_REQUEST);
211 #endif
212  } break;
213  default:
214  // Shouldn't get here
215  ESP_LOGE(TAG, "Wrong protocol handler state: %s (%d), resetting communication",
216  phase_to_string_(this->protocol_phase_), (int) this->protocol_phase_);
217  this->set_phase(ProtocolPhases::SENDING_INIT_1);
218  break;
219  }
220 }
221 
222 haier_protocol::HaierMessage Smartair2Climate::get_power_message(bool state) {
223  if (state) {
224  static haier_protocol::HaierMessage power_on_message(haier_protocol::FrameType::CONTROL, 0x4D02);
225  return power_on_message;
226  } else {
227  static haier_protocol::HaierMessage power_off_message(haier_protocol::FrameType::CONTROL, 0x4D03);
228  return power_off_message;
229  }
230 }
231 
232 haier_protocol::HaierMessage Smartair2Climate::get_control_message() {
233  uint8_t control_out_buffer[sizeof(smartair2_protocol::HaierPacketControl)];
234  memcpy(control_out_buffer, this->last_status_message_.get(), sizeof(smartair2_protocol::HaierPacketControl));
236  out_data->cntrl = 0;
237  if (this->current_hvac_settings_.valid) {
238  HvacSettings &climate_control = this->current_hvac_settings_;
239  if (climate_control.mode.has_value()) {
240  switch (climate_control.mode.value()) {
241  case CLIMATE_MODE_OFF:
242  out_data->ac_power = 0;
243  break;
245  out_data->ac_power = 1;
246  out_data->ac_mode = (uint8_t) smartair2_protocol::ConditioningMode::AUTO;
247  out_data->fan_mode = this->other_modes_fan_speed_;
248  break;
249  case CLIMATE_MODE_HEAT:
250  out_data->ac_power = 1;
251  out_data->ac_mode = (uint8_t) smartair2_protocol::ConditioningMode::HEAT;
252  out_data->fan_mode = this->other_modes_fan_speed_;
253  break;
254  case CLIMATE_MODE_DRY:
255  out_data->ac_power = 1;
256  out_data->ac_mode = (uint8_t) smartair2_protocol::ConditioningMode::DRY;
257  out_data->fan_mode = this->other_modes_fan_speed_;
258  break;
260  out_data->ac_power = 1;
261  out_data->ac_mode = (uint8_t) smartair2_protocol::ConditioningMode::FAN;
262  out_data->fan_mode = this->fan_mode_speed_; // Auto doesn't work in fan only mode
263  break;
264  case CLIMATE_MODE_COOL:
265  out_data->ac_power = 1;
266  out_data->ac_mode = (uint8_t) smartair2_protocol::ConditioningMode::COOL;
267  out_data->fan_mode = this->other_modes_fan_speed_;
268  break;
269  default:
270  ESP_LOGE("Control", "Unsupported climate mode");
271  break;
272  }
273  }
274  // Set fan speed, if we are in fan mode, reject auto in fan mode
275  if (climate_control.fan_mode.has_value()) {
276  switch (climate_control.fan_mode.value()) {
277  case CLIMATE_FAN_LOW:
278  out_data->fan_mode = (uint8_t) smartair2_protocol::FanMode::FAN_LOW;
279  break;
280  case CLIMATE_FAN_MEDIUM:
281  out_data->fan_mode = (uint8_t) smartair2_protocol::FanMode::FAN_MID;
282  break;
283  case CLIMATE_FAN_HIGH:
284  out_data->fan_mode = (uint8_t) smartair2_protocol::FanMode::FAN_HIGH;
285  break;
286  case CLIMATE_FAN_AUTO:
287  if (this->mode != CLIMATE_MODE_FAN_ONLY) // if we are not in fan only mode
288  out_data->fan_mode = (uint8_t) smartair2_protocol::FanMode::FAN_AUTO;
289  break;
290  default:
291  ESP_LOGE("Control", "Unsupported fan mode");
292  break;
293  }
294  }
295  // Set swing mode
296  if (climate_control.swing_mode.has_value()) {
297  if (this->use_alternative_swing_control_) {
298  switch (climate_control.swing_mode.value()) {
299  case CLIMATE_SWING_OFF:
300  out_data->swing_mode = 0;
301  break;
303  out_data->swing_mode = 1;
304  break;
306  out_data->swing_mode = 2;
307  break;
308  case CLIMATE_SWING_BOTH:
309  out_data->swing_mode = 3;
310  break;
311  }
312  } else {
313  switch (climate_control.swing_mode.value()) {
314  case CLIMATE_SWING_OFF:
315  out_data->use_swing_bits = 0;
316  out_data->swing_mode = 0;
317  break;
319  out_data->swing_mode = 0;
320  out_data->vertical_swing = 1;
321  out_data->horizontal_swing = 0;
322  break;
324  out_data->swing_mode = 0;
325  out_data->vertical_swing = 0;
326  out_data->horizontal_swing = 1;
327  break;
328  case CLIMATE_SWING_BOTH:
329  out_data->swing_mode = 1;
330  out_data->use_swing_bits = 0;
331  out_data->vertical_swing = 0;
332  out_data->horizontal_swing = 0;
333  break;
334  }
335  }
336  }
337  if (climate_control.target_temperature.has_value()) {
338  float target_temp = climate_control.target_temperature.value();
339  out_data->set_point = ((int) target_temp) - 16; // set the temperature with offset 16
340  out_data->half_degree = (target_temp - ((int) target_temp) >= 0.49) ? 1 : 0;
341  }
342  if (out_data->ac_power == 0) {
343  // If AC is off - no presets allowed
344  out_data->turbo_mode = 0;
345  out_data->quiet_mode = 0;
346  } else if (climate_control.preset.has_value()) {
347  switch (climate_control.preset.value()) {
348  case CLIMATE_PRESET_NONE:
349  out_data->ten_degree = 0;
350  out_data->turbo_mode = 0;
351  out_data->quiet_mode = 0;
352  break;
354  out_data->ten_degree = 0;
355  out_data->turbo_mode = 1;
356  out_data->quiet_mode = 0;
357  break;
359  out_data->ten_degree = 0;
360  out_data->turbo_mode = 0;
361  out_data->quiet_mode = 1;
362  break;
363  case CLIMATE_PRESET_AWAY:
364  // Only allowed in heat mode
365  out_data->ten_degree = (this->mode == CLIMATE_MODE_HEAT) ? 1 : 0;
366  out_data->turbo_mode = 0;
367  out_data->quiet_mode = 0;
368  break;
369  default:
370  ESP_LOGE("Control", "Unsupported preset");
371  out_data->ten_degree = 0;
372  out_data->turbo_mode = 0;
373  out_data->quiet_mode = 0;
374  break;
375  }
376  }
377  }
378  out_data->display_status = this->display_status_ ? 0 : 1;
379  out_data->health_mode = this->health_mode_ ? 1 : 0;
380  return haier_protocol::HaierMessage(haier_protocol::FrameType::CONTROL, 0x4D5F, control_out_buffer,
382 }
383 
384 haier_protocol::HandlerError Smartair2Climate::process_status_message_(const uint8_t *packet_buffer, uint8_t size) {
385  if (size < sizeof(smartair2_protocol::HaierStatus))
386  return haier_protocol::HandlerError::WRONG_MESSAGE_STRUCTURE;
388  memcpy(&packet, packet_buffer, size);
389  bool should_publish = false;
390  {
391  // Extra modes/presets
392  optional<ClimatePreset> old_preset = this->preset;
393  if (packet.control.turbo_mode != 0) {
395  } else if (packet.control.quiet_mode != 0) {
397  } else if (packet.control.ten_degree != 0) {
398  this->preset = CLIMATE_PRESET_AWAY;
399  } else {
400  this->preset = CLIMATE_PRESET_NONE;
401  }
402  should_publish = should_publish || (!old_preset.has_value()) || (old_preset.value() != this->preset.value());
403  }
404  {
405  // Target temperature
406  float old_target_temperature = this->target_temperature;
407  this->target_temperature = packet.control.set_point + 16.0f + ((packet.control.half_degree == 1) ? 0.5f : 0.0f);
408  should_publish = should_publish || (old_target_temperature != this->target_temperature);
409  }
410  {
411  // Current temperature
412  float old_current_temperature = this->current_temperature;
413  this->current_temperature = packet.control.room_temperature;
414  should_publish = should_publish || (old_current_temperature != this->current_temperature);
415  }
416  {
417  // Fan mode
418  optional<ClimateFanMode> old_fan_mode = this->fan_mode;
419  // remember the fan speed we last had for climate vs fan
420  if (packet.control.ac_mode == (uint8_t) smartair2_protocol::ConditioningMode::FAN) {
422  this->fan_mode_speed_ = packet.control.fan_mode;
423  } else {
424  this->other_modes_fan_speed_ = packet.control.fan_mode;
425  }
426  switch (packet.control.fan_mode) {
428  // Sometimes AC reports in fan only mode that fan speed is auto
429  // but never accept this value back
430  if (packet.control.ac_mode != (uint8_t) smartair2_protocol::ConditioningMode::FAN) {
431  this->fan_mode = CLIMATE_FAN_AUTO;
432  } else {
433  should_publish = true;
434  }
435  break;
436  case (uint8_t) smartair2_protocol::FanMode::FAN_MID:
438  break;
440  this->fan_mode = CLIMATE_FAN_LOW;
441  break;
443  this->fan_mode = CLIMATE_FAN_HIGH;
444  break;
445  }
446  should_publish = should_publish || (!old_fan_mode.has_value()) || (old_fan_mode.value() != fan_mode.value());
447  }
448  {
449  // Display status
450  // should be before "Climate mode" because it is changing this->mode
451  if (packet.control.ac_power != 0) {
452  // if AC is off display status always ON so process it only when AC is on
453  bool disp_status = packet.control.display_status == 0;
454  if (disp_status != this->display_status_) {
455  // Do something only if display status changed
456  if (this->mode == CLIMATE_MODE_OFF) {
457  // AC just turned on from remote need to turn off display
458  this->force_send_control_ = true;
459  } else {
460  this->display_status_ = disp_status;
461  }
462  }
463  }
464  }
465  {
466  // Health mode
467  bool old_health_mode = this->health_mode_;
468  this->health_mode_ = packet.control.health_mode == 1;
469  should_publish = should_publish || (old_health_mode != this->health_mode_);
470  }
471  {
472  // Climate mode
473  ClimateMode old_mode = this->mode;
474  if (packet.control.ac_power == 0) {
475  this->mode = CLIMATE_MODE_OFF;
476  } else {
477  // Check current hvac mode
478  switch (packet.control.ac_mode) {
479  case (uint8_t) smartair2_protocol::ConditioningMode::COOL:
480  this->mode = CLIMATE_MODE_COOL;
481  break;
482  case (uint8_t) smartair2_protocol::ConditioningMode::HEAT:
483  this->mode = CLIMATE_MODE_HEAT;
484  break;
485  case (uint8_t) smartair2_protocol::ConditioningMode::DRY:
486  this->mode = CLIMATE_MODE_DRY;
487  break;
488  case (uint8_t) smartair2_protocol::ConditioningMode::FAN:
489  this->mode = CLIMATE_MODE_FAN_ONLY;
490  break;
491  case (uint8_t) smartair2_protocol::ConditioningMode::AUTO:
493  break;
494  }
495  }
496  should_publish = should_publish || (old_mode != this->mode);
497  }
498  {
499  // Swing mode
500  ClimateSwingMode old_swing_mode = this->swing_mode;
501  if (this->use_alternative_swing_control_) {
502  switch (packet.control.swing_mode) {
503  case 1:
505  break;
506  case 2:
508  break;
509  case 3:
511  break;
512  default:
514  break;
515  }
516  } else {
517  if (packet.control.swing_mode == 0) {
518  if (packet.control.vertical_swing != 0) {
520  } else if (packet.control.horizontal_swing != 0) {
522  } else {
524  }
525  } else {
527  }
528  }
529  should_publish = should_publish || (old_swing_mode != this->swing_mode);
530  }
531  this->last_valid_status_timestamp_ = std::chrono::steady_clock::now();
532  if (should_publish) {
533  this->publish_state();
534  }
535  if (should_publish) {
536  ESP_LOGI(TAG, "HVAC values changed");
537  }
538  int log_level = should_publish ? ESPHOME_LOG_LEVEL_INFO : ESPHOME_LOG_LEVEL_DEBUG;
539  esp_log_printf_(log_level, TAG, __LINE__, "HVAC Mode = 0x%X", packet.control.ac_mode);
540  esp_log_printf_(log_level, TAG, __LINE__, "Fan speed Status = 0x%X", packet.control.fan_mode);
541  esp_log_printf_(log_level, TAG, __LINE__, "Horizontal Swing Status = 0x%X", packet.control.horizontal_swing);
542  esp_log_printf_(log_level, TAG, __LINE__, "Vertical Swing Status = 0x%X", packet.control.vertical_swing);
543  esp_log_printf_(log_level, TAG, __LINE__, "Set Point Status = 0x%X", packet.control.set_point);
544  return haier_protocol::HandlerError::HANDLER_OK;
545 }
546 
547 void Smartair2Climate::set_alternative_swing_control(bool swing_control) {
548  this->use_alternative_swing_control_ = swing_control;
549 }
550 
551 } // namespace haier
552 } // namespace esphome
The fan mode is set to Low.
Definition: climate_mode.h:54
value_type const & value() const
Definition: optional.h:89
esphome::optional< float > target_temperature
Definition: haier_base.h:115
The fan mode is set to Both.
Definition: climate_mode.h:74
esphome::optional< esphome::climate::ClimatePreset > preset
Definition: haier_base.h:116
constexpr std::chrono::milliseconds CONTROL_MESSAGE_RETRIES_INTERVAL
Definition: hon_climate.cpp:19
The climate device is set to heat to reach the target temperature.
Definition: climate_mode.h:18
const uint32_t FAN_HIGH
Definition: whynter.cpp:31
bool has_value() const
Definition: optional.h:87
The climate device is set to dry/humidity mode.
Definition: climate_mode.h:22
const uint32_t FAN_LOW
Definition: whynter.cpp:33
ClimateSwingMode swing_mode
Definition: climate.h:581
ClimateSwingMode
Enum for all modes a climate swing can be in.
Definition: climate_mode.h:70
Device is in away preset.
Definition: climate_mode.h:88
Device is in comfort preset.
Definition: climate_mode.h:92
The fan mode is set to Horizontal.
Definition: climate_mode.h:78
The climate device is set to cool to reach the target temperature.
Definition: climate_mode.h:16
constexpr std::chrono::milliseconds INIT_REQUESTS_RETRY_INTERVAL
The fan mode is set to Auto.
Definition: climate_mode.h:52
constexpr size_t SIGNAL_LEVEL_UPDATE_INTERVAL_MS
Definition: hon_climate.cpp:16
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:151
const uint32_t FAN_AUTO
esphome::optional< esphome::climate::ClimateFanMode > fan_mode
Definition: haier_base.h:113
The climate device is set to heat/cool to reach the target temperature.
Definition: climate_mode.h:14
The fan mode is set to Vertical.
Definition: climate_mode.h:76
The fan mode is set to High.
Definition: climate_mode.h:58
void HOT esp_log_printf_(int level, const char *tag, int line, const char *format,...)
Definition: log.cpp:11
ClimateMode
Enum for all modes a climate device can be in.
Definition: climate_mode.h:10
The swing mode is set to Off.
Definition: climate_mode.h:72
The climate device is off.
Definition: climate_mode.h:12
ClimateFanMode fan_mode
Definition: climate.h:573
Device is in boost preset.
Definition: climate_mode.h:90
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
The fan mode is set to Medium.
Definition: climate_mode.h:56
constexpr uint8_t CONTROL_MESSAGE_RETRIES
Definition: hon_climate.cpp:18
The climate device only has the fan enabled, no heating or cooling is taking place.
Definition: climate_mode.h:20
float target_temperature
Definition: climate.h:583
constexpr uint8_t INIT_REQUESTS_RETRY
ClimatePreset preset
Definition: climate.h:578
esphome::optional< esphome::climate::ClimateSwingMode > swing_mode
Definition: haier_base.h:114
bool state
Definition: fan.h:34
esphome::optional< esphome::climate::ClimateMode > mode
Definition: haier_base.h:112