esphome 2024.6.6__py3-none-any.whl → 2024.7.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. esphome/components/aht10/aht10.cpp +4 -2
  2. esphome/components/climate/climate.cpp +10 -6
  3. esphome/components/climate/climate_traits.h +3 -3
  4. esphome/components/cover/cover.h +2 -2
  5. esphome/components/esp32_camera/__init__.py +6 -3
  6. esphome/components/esp32_can/canbus.py +3 -0
  7. esphome/components/ethernet/ethernet_component.cpp +8 -3
  8. esphome/components/font/__init__.py +2 -28
  9. esphome/components/gree/climate.py +1 -0
  10. esphome/components/gree/gree.cpp +11 -3
  11. esphome/components/gree/gree.h +5 -1
  12. esphome/components/haier/binary_sensor/__init__.py +4 -4
  13. esphome/components/haier/button/__init__.py +1 -1
  14. esphome/components/haier/climate.py +43 -9
  15. esphome/components/haier/haier_base.cpp +4 -0
  16. esphome/components/haier/haier_base.h +11 -1
  17. esphome/components/haier/hon_climate.cpp +109 -55
  18. esphome/components/haier/hon_climate.h +7 -1
  19. esphome/components/haier/hon_packet.h +5 -0
  20. esphome/components/haier/sensor/__init__.py +5 -5
  21. esphome/components/haier/smartair2_climate.cpp +1 -0
  22. esphome/components/haier/text_sensor/__init__.py +4 -4
  23. esphome/components/heatpumpir/climate.py +12 -5
  24. esphome/components/heatpumpir/heatpumpir.cpp +11 -0
  25. esphome/components/heatpumpir/heatpumpir.h +11 -0
  26. esphome/components/http_request/http_request_arduino.cpp +7 -2
  27. esphome/components/http_request/update/http_request_update.cpp +6 -7
  28. esphome/components/http_request/update/http_request_update.h +0 -3
  29. esphome/components/i2s_audio/__init__.py +10 -0
  30. esphome/components/i2s_audio/microphone/__init__.py +7 -0
  31. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +2 -3
  32. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +3 -0
  33. esphome/components/image/__init__.py +2 -29
  34. esphome/components/improv_serial/improv_serial_component.cpp +9 -8
  35. esphome/components/ltr390/ltr390.cpp +44 -29
  36. esphome/components/ltr390/ltr390.h +9 -5
  37. esphome/components/ltr390/sensor.py +35 -5
  38. esphome/components/mdns/__init__.py +3 -3
  39. esphome/components/mdns/mdns_component.cpp +3 -1
  40. esphome/components/mdns/mdns_component.h +3 -1
  41. esphome/components/mdns/mdns_esp32.cpp +2 -1
  42. esphome/components/mdns/mdns_esp8266.cpp +2 -1
  43. esphome/components/mdns/mdns_host.cpp +2 -1
  44. esphome/components/mdns/mdns_libretiny.cpp +2 -1
  45. esphome/components/mdns/mdns_rp2040.cpp +2 -1
  46. esphome/components/micro_wake_word/__init__.py +205 -56
  47. esphome/components/micro_wake_word/micro_wake_word.cpp +225 -275
  48. esphome/components/micro_wake_word/micro_wake_word.h +77 -107
  49. esphome/components/micro_wake_word/preprocessor_settings.h +20 -0
  50. esphome/components/micro_wake_word/streaming_model.cpp +189 -0
  51. esphome/components/micro_wake_word/streaming_model.h +84 -0
  52. esphome/components/mitsubishi/mitsubishi.cpp +1 -0
  53. esphome/components/modbus_controller/text_sensor/__init__.py +2 -1
  54. esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp +4 -1
  55. esphome/components/modbus_controller/text_sensor/modbus_textsensor.h +1 -1
  56. esphome/components/number/__init__.py +2 -0
  57. esphome/components/ota/ota_backend_arduino_esp32.cpp +22 -7
  58. esphome/components/ota/ota_backend_arduino_esp8266.cpp +23 -8
  59. esphome/components/ota/ota_backend_arduino_libretiny.cpp +22 -7
  60. esphome/components/ota/ota_backend_arduino_rp2040.cpp +22 -7
  61. esphome/components/pmsa003i/pmsa003i.cpp +9 -0
  62. esphome/components/qspi_amoled/display.py +16 -4
  63. esphome/components/qspi_amoled/qspi_amoled.cpp +16 -0
  64. esphome/components/qspi_amoled/qspi_amoled.h +0 -3
  65. esphome/components/remote_base/dooya_protocol.cpp +4 -4
  66. esphome/components/remote_base/rc_switch_protocol.cpp +1 -1
  67. esphome/components/restart/button/__init__.py +2 -0
  68. esphome/components/script/__init__.py +1 -1
  69. esphome/components/sensor/__init__.py +2 -0
  70. esphome/components/tuya/tuya.cpp +8 -2
  71. esphome/components/tuya/tuya.h +3 -1
  72. esphome/components/uart/__init__.py +72 -9
  73. esphome/components/uart/uart_component_esp32_arduino.cpp +18 -4
  74. esphome/components/uart/uart_component_esp_idf.cpp +22 -2
  75. esphome/components/uart/uart_component_host.cpp +295 -0
  76. esphome/components/uart/uart_component_host.h +38 -0
  77. esphome/components/uptime/sensor.py +44 -11
  78. esphome/components/uptime/{uptime_sensor.cpp → uptime_seconds_sensor.cpp} +11 -7
  79. esphome/components/uptime/{uptime_sensor.h → uptime_seconds_sensor.h} +2 -2
  80. esphome/components/uptime/uptime_timestamp_sensor.cpp +39 -0
  81. esphome/components/uptime/uptime_timestamp_sensor.h +30 -0
  82. esphome/components/veml7700/veml7700.cpp +1 -1
  83. esphome/components/veml7700/veml7700.h +5 -5
  84. esphome/components/voice_assistant/voice_assistant.cpp +4 -2
  85. esphome/components/web_server/server_index_v2.h +42 -41
  86. esphome/components/web_server/server_index_v3.h +368 -367
  87. esphome/components/wifi/wifi_component_esp_idf.cpp +1 -1
  88. esphome/components/wifi/wifi_component_pico_w.cpp +18 -2
  89. esphome/components/wireguard/__init__.py +1 -1
  90. esphome/components/x9c/output.py +7 -1
  91. esphome/const.py +2 -1
  92. esphome/core/defines.h +1 -0
  93. esphome/core/helpers.cpp +2 -2
  94. esphome/core/helpers.h +1 -1
  95. esphome/external_files.py +26 -0
  96. {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/METADATA +1 -1
  97. {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/RECORD +101 -95
  98. esphome/components/micro_wake_word/audio_preprocessor_int8_model_data.h +0 -493
  99. {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/LICENSE +0 -0
  100. {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/WHEEL +0 -0
  101. {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/entry_points.txt +0 -0
  102. {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/top_level.txt +0 -0
@@ -18,12 +18,13 @@ constexpr int PROTOCOL_OUTDOOR_TEMPERATURE_OFFSET = -64;
18
18
  constexpr uint8_t CONTROL_MESSAGE_RETRIES = 5;
19
19
  constexpr std::chrono::milliseconds CONTROL_MESSAGE_RETRIES_INTERVAL = std::chrono::milliseconds(500);
20
20
  constexpr size_t ALARM_STATUS_REQUEST_INTERVAL_MS = 600000;
21
+ const uint8_t ONE_BUF[] = {0x00, 0x01};
22
+ const uint8_t ZERO_BUF[] = {0x00, 0x00};
21
23
 
22
24
  HonClimate::HonClimate()
23
25
  : cleaning_status_(CleaningState::NO_CLEANING), got_valid_outdoor_temp_(false), active_alarms_{0x00, 0x00, 0x00,
24
26
  0x00, 0x00, 0x00,
25
27
  0x00, 0x00} {
26
- last_status_message_ = std::unique_ptr<uint8_t[]>(new uint8_t[sizeof(hon_protocol::HaierPacketControl)]);
27
28
  this->fan_mode_speed_ = (uint8_t) hon_protocol::FanMode::FAN_MID;
28
29
  this->other_modes_fan_speed_ = (uint8_t) hon_protocol::FanMode::FAN_AUTO;
29
30
  }
@@ -169,11 +170,18 @@ haier_protocol::HandlerError HonClimate::status_handler_(haier_protocol::FrameTy
169
170
  this->action_request_.reset();
170
171
  this->force_send_control_ = false;
171
172
  } else {
172
- if (data_size >= sizeof(hon_protocol::HaierPacketControl) + 2) {
173
- memcpy(this->last_status_message_.get(), data + 2, sizeof(hon_protocol::HaierPacketControl));
173
+ if (!this->last_status_message_) {
174
+ this->real_control_packet_size_ = sizeof(hon_protocol::HaierPacketControl) + this->extra_control_packet_bytes_;
175
+ this->real_sensors_packet_size_ = sizeof(hon_protocol::HaierPacketSensors) + this->extra_sensors_packet_bytes_;
176
+ this->last_status_message_.reset();
177
+ this->last_status_message_ = std::unique_ptr<uint8_t[]>(new uint8_t[this->real_control_packet_size_]);
178
+ };
179
+ if (data_size >= this->real_control_packet_size_ + 2) {
180
+ memcpy(this->last_status_message_.get(), data + 2 + this->status_message_header_size_,
181
+ this->real_control_packet_size_);
182
+ this->status_message_callback_.call((const char *) data, data_size);
174
183
  } else {
175
- ESP_LOGW(TAG, "Status packet too small: %d (should be >= %d)", data_size,
176
- sizeof(hon_protocol::HaierPacketControl));
184
+ ESP_LOGW(TAG, "Status packet too small: %d (should be >= %d)", data_size, this->real_control_packet_size_);
177
185
  }
178
186
  switch (this->protocol_phase_) {
179
187
  case ProtocolPhases::SENDING_FIRST_STATUS_REQUEST:
@@ -479,8 +487,8 @@ void HonClimate::initialization() {
479
487
  }
480
488
 
481
489
  haier_protocol::HaierMessage HonClimate::get_control_message() {
482
- uint8_t control_out_buffer[sizeof(hon_protocol::HaierPacketControl)];
483
- memcpy(control_out_buffer, this->last_status_message_.get(), sizeof(hon_protocol::HaierPacketControl));
490
+ uint8_t control_out_buffer[haier_protocol::MAX_FRAME_SIZE];
491
+ memcpy(control_out_buffer, this->last_status_message_.get(), this->real_control_packet_size_);
484
492
  hon_protocol::HaierPacketControl *out_data = (hon_protocol::HaierPacketControl *) control_out_buffer;
485
493
  control_out_buffer[4] = 0; // This byte should be cleared before setting values
486
494
  bool has_hvac_settings = false;
@@ -636,7 +644,7 @@ haier_protocol::HaierMessage HonClimate::get_control_message() {
636
644
  out_data->health_mode = this->health_mode_ ? 1 : 0;
637
645
  return haier_protocol::HaierMessage(haier_protocol::FrameType::CONTROL,
638
646
  (uint16_t) hon_protocol::SubcommandsControl::SET_GROUP_PARAMETERS,
639
- control_out_buffer, sizeof(hon_protocol::HaierPacketControl));
647
+ control_out_buffer, this->real_control_packet_size_);
640
648
  }
641
649
 
642
650
  void HonClimate::process_alarm_message_(const uint8_t *packet, uint8_t size, bool check_new) {
@@ -758,15 +766,17 @@ void HonClimate::update_sub_text_sensor_(SubTextSensorType type, const std::stri
758
766
  #endif // USE_TEXT_SENSOR
759
767
 
760
768
  haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *packet_buffer, uint8_t size) {
761
- size_t expected_size = 2 + sizeof(hon_protocol::HaierPacketControl) + sizeof(hon_protocol::HaierPacketSensors) +
762
- this->extra_control_packet_bytes_;
763
- if (size < expected_size)
769
+ size_t expected_size =
770
+ 2 + this->status_message_header_size_ + this->real_control_packet_size_ + this->real_sensors_packet_size_;
771
+ if (size < expected_size) {
772
+ ESP_LOGW(TAG, "Unexpected message size %d (expexted >= %d)", size, expected_size);
764
773
  return haier_protocol::HandlerError::WRONG_MESSAGE_STRUCTURE;
774
+ }
765
775
  uint16_t subtype = (((uint16_t) packet_buffer[0]) << 8) + packet_buffer[1];
766
- if ((subtype == 0x7D01) && (size >= expected_size + 4 + sizeof(hon_protocol::HaierPacketBigData))) {
776
+ if ((subtype == 0x7D01) && (size >= expected_size + sizeof(hon_protocol::HaierPacketBigData))) {
767
777
  // Got BigData packet
768
778
  const hon_protocol::HaierPacketBigData *bd_packet =
769
- (const hon_protocol::HaierPacketBigData *) (&packet_buffer[expected_size + 4]);
779
+ (const hon_protocol::HaierPacketBigData *) (&packet_buffer[expected_size]);
770
780
  #ifdef USE_SENSOR
771
781
  this->update_sub_sensor_(SubSensorType::INDOOR_COIL_TEMPERATURE, bd_packet->indoor_coil_temperature / 2.0 - 20);
772
782
  this->update_sub_sensor_(SubSensorType::OUTDOOR_COIL_TEMPERATURE, bd_packet->outdoor_coil_temperature - 64);
@@ -795,9 +805,9 @@ haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *
795
805
  hon_protocol::HaierPacketControl control;
796
806
  hon_protocol::HaierPacketSensors sensors;
797
807
  } packet;
798
- memcpy(&packet.control, packet_buffer + 2, sizeof(hon_protocol::HaierPacketControl));
799
- memcpy(&packet.sensors,
800
- packet_buffer + 2 + sizeof(hon_protocol::HaierPacketControl) + this->extra_control_packet_bytes_,
808
+ memcpy(&packet.control, packet_buffer + 2 + this->status_message_header_size_,
809
+ sizeof(hon_protocol::HaierPacketControl));
810
+ memcpy(&packet.sensors, packet_buffer + 2 + this->status_message_header_size_ + this->real_control_packet_size_,
801
811
  sizeof(hon_protocol::HaierPacketSensors));
802
812
  if (packet.sensors.error_status != 0) {
803
813
  ESP_LOGW(TAG, "HVAC error, code=0x%02X", packet.sensors.error_status);
@@ -996,8 +1006,6 @@ haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *
996
1006
  }
997
1007
 
998
1008
  void HonClimate::fill_control_messages_queue_() {
999
- static uint8_t one_buf[] = {0x00, 0x01};
1000
- static uint8_t zero_buf[] = {0x00, 0x00};
1001
1009
  if (!this->current_hvac_settings_.valid && !this->force_send_control_)
1002
1010
  return;
1003
1011
  this->clear_control_messages_queue_();
@@ -1009,7 +1017,7 @@ void HonClimate::fill_control_messages_queue_() {
1009
1017
  haier_protocol::HaierMessage(haier_protocol::FrameType::CONTROL,
1010
1018
  (uint16_t) hon_protocol::SubcommandsControl::SET_SINGLE_PARAMETER +
1011
1019
  (uint8_t) hon_protocol::DataParameters::BEEPER_STATUS,
1012
- this->beeper_status_ ? zero_buf : one_buf, 2));
1020
+ this->beeper_status_ ? ZERO_BUF : ONE_BUF, 2));
1013
1021
  }
1014
1022
  // Health mode
1015
1023
  {
@@ -1017,7 +1025,7 @@ void HonClimate::fill_control_messages_queue_() {
1017
1025
  haier_protocol::HaierMessage(haier_protocol::FrameType::CONTROL,
1018
1026
  (uint16_t) hon_protocol::SubcommandsControl::SET_SINGLE_PARAMETER +
1019
1027
  (uint8_t) hon_protocol::DataParameters::HEALTH_MODE,
1020
- this->health_mode_ ? one_buf : zero_buf, 2));
1028
+ this->health_mode_ ? ONE_BUF : ZERO_BUF, 2));
1021
1029
  }
1022
1030
  // Climate mode
1023
1031
  bool new_power = this->mode != CLIMATE_MODE_OFF;
@@ -1092,7 +1100,7 @@ void HonClimate::fill_control_messages_queue_() {
1092
1100
  haier_protocol::HaierMessage(haier_protocol::FrameType::CONTROL,
1093
1101
  (uint16_t) hon_protocol::SubcommandsControl::SET_SINGLE_PARAMETER +
1094
1102
  (uint8_t) hon_protocol::DataParameters::AC_POWER,
1095
- new_power ? one_buf : zero_buf, 2));
1103
+ new_power ? ONE_BUF : ZERO_BUF, 2));
1096
1104
  }
1097
1105
  // CLimate preset
1098
1106
  {
@@ -1165,6 +1173,35 @@ void HonClimate::fill_control_messages_queue_() {
1165
1173
  (uint8_t) hon_protocol::DataParameters::SET_POINT,
1166
1174
  buffer, 2));
1167
1175
  }
1176
+ // Vertical swing mode
1177
+ if (climate_control.swing_mode.has_value()) {
1178
+ uint8_t vertical_swing_buf[] = {0x00, (uint8_t) hon_protocol::VerticalSwingMode::AUTO};
1179
+ uint8_t horizontal_swing_buf[] = {0x00, (uint8_t) hon_protocol::HorizontalSwingMode::AUTO};
1180
+ switch (climate_control.swing_mode.value()) {
1181
+ case CLIMATE_SWING_OFF:
1182
+ horizontal_swing_buf[1] = (uint8_t) this->settings_.last_horizontal_swing;
1183
+ vertical_swing_buf[1] = (uint8_t) this->settings_.last_vertiacal_swing;
1184
+ break;
1185
+ case CLIMATE_SWING_VERTICAL:
1186
+ horizontal_swing_buf[1] = (uint8_t) this->settings_.last_horizontal_swing;
1187
+ break;
1188
+ case CLIMATE_SWING_HORIZONTAL:
1189
+ vertical_swing_buf[1] = (uint8_t) this->settings_.last_vertiacal_swing;
1190
+ break;
1191
+ case CLIMATE_SWING_BOTH:
1192
+ break;
1193
+ }
1194
+ this->control_messages_queue_.push(
1195
+ haier_protocol::HaierMessage(haier_protocol::FrameType::CONTROL,
1196
+ (uint16_t) hon_protocol::SubcommandsControl::SET_SINGLE_PARAMETER +
1197
+ (uint8_t) hon_protocol::DataParameters::HORIZONTAL_SWING_MODE,
1198
+ horizontal_swing_buf, 2));
1199
+ this->control_messages_queue_.push(
1200
+ haier_protocol::HaierMessage(haier_protocol::FrameType::CONTROL,
1201
+ (uint16_t) hon_protocol::SubcommandsControl::SET_SINGLE_PARAMETER +
1202
+ (uint8_t) hon_protocol::DataParameters::VERTICAL_SWING_MODE,
1203
+ vertical_swing_buf, 2));
1204
+ }
1168
1205
  // Fan mode
1169
1206
  if (climate_control.fan_mode.has_value()) {
1170
1207
  switch (climate_control.fan_mode.value()) {
@@ -1202,40 +1239,56 @@ void HonClimate::clear_control_messages_queue_() {
1202
1239
 
1203
1240
  bool HonClimate::prepare_pending_action() {
1204
1241
  switch (this->action_request_.value().action) {
1205
- case ActionRequest::START_SELF_CLEAN: {
1206
- uint8_t control_out_buffer[sizeof(hon_protocol::HaierPacketControl)];
1207
- memcpy(control_out_buffer, this->last_status_message_.get(), sizeof(hon_protocol::HaierPacketControl));
1208
- hon_protocol::HaierPacketControl *out_data = (hon_protocol::HaierPacketControl *) control_out_buffer;
1209
- out_data->self_cleaning_status = 1;
1210
- out_data->steri_clean = 0;
1211
- out_data->set_point = 0x06;
1212
- out_data->vertical_swing_mode = (uint8_t) hon_protocol::VerticalSwingMode::CENTER;
1213
- out_data->horizontal_swing_mode = (uint8_t) hon_protocol::HorizontalSwingMode::CENTER;
1214
- out_data->ac_power = 1;
1215
- out_data->ac_mode = (uint8_t) hon_protocol::ConditioningMode::DRY;
1216
- out_data->light_status = 0;
1217
- this->action_request_.value().message = haier_protocol::HaierMessage(
1218
- haier_protocol::FrameType::CONTROL, (uint16_t) hon_protocol::SubcommandsControl::SET_GROUP_PARAMETERS,
1219
- control_out_buffer, sizeof(hon_protocol::HaierPacketControl));
1220
- }
1221
- return true;
1222
- case ActionRequest::START_STERI_CLEAN: {
1223
- uint8_t control_out_buffer[sizeof(hon_protocol::HaierPacketControl)];
1224
- memcpy(control_out_buffer, this->last_status_message_.get(), sizeof(hon_protocol::HaierPacketControl));
1225
- hon_protocol::HaierPacketControl *out_data = (hon_protocol::HaierPacketControl *) control_out_buffer;
1226
- out_data->self_cleaning_status = 0;
1227
- out_data->steri_clean = 1;
1228
- out_data->set_point = 0x06;
1229
- out_data->vertical_swing_mode = (uint8_t) hon_protocol::VerticalSwingMode::CENTER;
1230
- out_data->horizontal_swing_mode = (uint8_t) hon_protocol::HorizontalSwingMode::CENTER;
1231
- out_data->ac_power = 1;
1232
- out_data->ac_mode = (uint8_t) hon_protocol::ConditioningMode::DRY;
1233
- out_data->light_status = 0;
1234
- this->action_request_.value().message = haier_protocol::HaierMessage(
1235
- haier_protocol::FrameType::CONTROL, (uint16_t) hon_protocol::SubcommandsControl::SET_GROUP_PARAMETERS,
1236
- control_out_buffer, sizeof(hon_protocol::HaierPacketControl));
1237
- }
1238
- return true;
1242
+ case ActionRequest::START_SELF_CLEAN:
1243
+ if (this->control_method_ == HonControlMethod::SET_GROUP_PARAMETERS) {
1244
+ uint8_t control_out_buffer[haier_protocol::MAX_FRAME_SIZE];
1245
+ memcpy(control_out_buffer, this->last_status_message_.get(), this->real_control_packet_size_);
1246
+ hon_protocol::HaierPacketControl *out_data = (hon_protocol::HaierPacketControl *) control_out_buffer;
1247
+ out_data->self_cleaning_status = 1;
1248
+ out_data->steri_clean = 0;
1249
+ out_data->set_point = 0x06;
1250
+ out_data->vertical_swing_mode = (uint8_t) hon_protocol::VerticalSwingMode::CENTER;
1251
+ out_data->horizontal_swing_mode = (uint8_t) hon_protocol::HorizontalSwingMode::CENTER;
1252
+ out_data->ac_power = 1;
1253
+ out_data->ac_mode = (uint8_t) hon_protocol::ConditioningMode::DRY;
1254
+ out_data->light_status = 0;
1255
+ this->action_request_.value().message = haier_protocol::HaierMessage(
1256
+ haier_protocol::FrameType::CONTROL, (uint16_t) hon_protocol::SubcommandsControl::SET_GROUP_PARAMETERS,
1257
+ control_out_buffer, this->real_control_packet_size_);
1258
+ return true;
1259
+ } else if (this->control_method_ == HonControlMethod::SET_SINGLE_PARAMETER) {
1260
+ this->action_request_.value().message =
1261
+ haier_protocol::HaierMessage(haier_protocol::FrameType::CONTROL,
1262
+ (uint16_t) hon_protocol::SubcommandsControl::SET_SINGLE_PARAMETER +
1263
+ (uint8_t) hon_protocol::DataParameters::SELF_CLEANING,
1264
+ ONE_BUF, 2);
1265
+ return true;
1266
+ } else {
1267
+ this->action_request_.reset();
1268
+ return false;
1269
+ }
1270
+ case ActionRequest::START_STERI_CLEAN:
1271
+ if (this->control_method_ == HonControlMethod::SET_GROUP_PARAMETERS) {
1272
+ uint8_t control_out_buffer[haier_protocol::MAX_FRAME_SIZE];
1273
+ memcpy(control_out_buffer, this->last_status_message_.get(), this->real_control_packet_size_);
1274
+ hon_protocol::HaierPacketControl *out_data = (hon_protocol::HaierPacketControl *) control_out_buffer;
1275
+ out_data->self_cleaning_status = 0;
1276
+ out_data->steri_clean = 1;
1277
+ out_data->set_point = 0x06;
1278
+ out_data->vertical_swing_mode = (uint8_t) hon_protocol::VerticalSwingMode::CENTER;
1279
+ out_data->horizontal_swing_mode = (uint8_t) hon_protocol::HorizontalSwingMode::CENTER;
1280
+ out_data->ac_power = 1;
1281
+ out_data->ac_mode = (uint8_t) hon_protocol::ConditioningMode::DRY;
1282
+ out_data->light_status = 0;
1283
+ this->action_request_.value().message = haier_protocol::HaierMessage(
1284
+ haier_protocol::FrameType::CONTROL, (uint16_t) hon_protocol::SubcommandsControl::SET_GROUP_PARAMETERS,
1285
+ control_out_buffer, this->real_control_packet_size_);
1286
+ return true;
1287
+ } else {
1288
+ // No Steri clean support (yet?) in SET_SINGLE_PARAMETER
1289
+ this->action_request_.reset();
1290
+ return false;
1291
+ }
1239
1292
  default:
1240
1293
  return HaierClimateBase::prepare_pending_action();
1241
1294
  }
@@ -1251,6 +1304,7 @@ void HonClimate::process_protocol_reset() {
1251
1304
  #endif // USE_SENSOR
1252
1305
  this->got_valid_outdoor_temp_ = false;
1253
1306
  this->hvac_hardware_info_.reset();
1307
+ this->last_status_message_.reset(nullptr);
1254
1308
  }
1255
1309
 
1256
1310
  bool HonClimate::should_get_big_data_() {
@@ -104,6 +104,8 @@ class HonClimate : public HaierClimateBase {
104
104
  void start_self_cleaning();
105
105
  void start_steri_cleaning();
106
106
  void set_extra_control_packet_bytes_size(size_t size) { this->extra_control_packet_bytes_ = size; };
107
+ void set_extra_sensors_packet_bytes_size(size_t size) { this->extra_sensors_packet_bytes_ = size; };
108
+ void set_status_message_header_size(size_t size) { this->status_message_header_size_ = size; };
107
109
  void set_control_method(HonControlMethod method) { this->control_method_ = method; };
108
110
  void add_alarm_start_callback(std::function<void(uint8_t, const char *)> &&callback);
109
111
  void add_alarm_end_callback(std::function<void(uint8_t, const char *)> &&callback);
@@ -158,7 +160,11 @@ class HonClimate : public HaierClimateBase {
158
160
  esphome::optional<hon_protocol::HorizontalSwingMode> pending_horizontal_direction_{};
159
161
  esphome::optional<HardwareInfo> hvac_hardware_info_{};
160
162
  uint8_t active_alarms_[8];
161
- int extra_control_packet_bytes_;
163
+ int extra_control_packet_bytes_{0};
164
+ int extra_sensors_packet_bytes_{4};
165
+ int status_message_header_size_{0};
166
+ int real_control_packet_size_{sizeof(hon_protocol::HaierPacketControl)};
167
+ int real_sensors_packet_size_{sizeof(hon_protocol::HaierPacketSensors) + 4};
162
168
  HonControlMethod control_method_;
163
169
  std::queue<haier_protocol::HaierMessage> control_messages_queue_;
164
170
  CallbackManager<void(uint8_t, const char *)> alarm_start_callback_{};
@@ -41,15 +41,20 @@ enum class ConditioningMode : uint8_t {
41
41
  enum class DataParameters : uint8_t {
42
42
  AC_POWER = 0x01,
43
43
  SET_POINT = 0x02,
44
+ VERTICAL_SWING_MODE = 0x03,
44
45
  AC_MODE = 0x04,
45
46
  FAN_MODE = 0x05,
46
47
  USE_FAHRENHEIT = 0x07,
48
+ DISPLAY_STATUS = 0x09,
47
49
  TEN_DEGREE = 0x0A,
48
50
  HEALTH_MODE = 0x0B,
51
+ HORIZONTAL_SWING_MODE = 0x0C,
52
+ SELF_CLEANING = 0x0D,
49
53
  BEEPER_STATUS = 0x16,
50
54
  LOCK_REMOTE = 0x17,
51
55
  QUIET_MODE = 0x19,
52
56
  FAST_MODE = 0x1A,
57
+ SLEEP_MODE = 0x1B,
53
58
  };
54
59
 
55
60
  enum class SpecialMode : uint8_t { NONE = 0x00, ELDERLY = 0x01, CHILDREN = 0x02, PREGNANT = 0x03 };
@@ -137,16 +137,16 @@ SENSOR_TYPES = {
137
137
 
138
138
  CONFIG_SCHEMA = cv.Schema(
139
139
  {
140
- cv.Required(CONF_HAIER_ID): cv.use_id(HonClimate),
140
+ cv.GenerateID(CONF_HAIER_ID): cv.use_id(HonClimate),
141
141
  }
142
- ).extend({cv.Optional(type): schema for type, schema in SENSOR_TYPES.items()})
142
+ ).extend({cv.Optional(type_): schema for type_, schema in SENSOR_TYPES.items()})
143
143
 
144
144
 
145
145
  async def to_code(config):
146
146
  paren = await cg.get_variable(config[CONF_HAIER_ID])
147
147
 
148
- for type, _ in SENSOR_TYPES.items():
149
- if conf := config.get(type):
148
+ for type_ in SENSOR_TYPES:
149
+ if conf := config.get(type_):
150
150
  sens = await sensor.new_sensor(conf)
151
- sensor_type = getattr(SensorTypeEnum, type.upper())
151
+ sensor_type = getattr(SensorTypeEnum, type_.upper())
152
152
  cg.add(paren.set_sub_sensor(sensor_type, sens))
@@ -37,6 +37,7 @@ haier_protocol::HandlerError Smartair2Climate::status_handler_(haier_protocol::F
37
37
  } else {
38
38
  if (data_size >= sizeof(smartair2_protocol::HaierPacketControl) + 2) {
39
39
  memcpy(this->last_status_message_.get(), data + 2, sizeof(smartair2_protocol::HaierPacketControl));
40
+ this->status_message_callback_.call((const char *) data, data_size);
40
41
  } else {
41
42
  ESP_LOGW(TAG, "Status packet too small: %d (should be >= %d)", data_size,
42
43
  sizeof(smartair2_protocol::HaierPacketControl));
@@ -39,7 +39,7 @@ TEXT_SENSOR_TYPES = {
39
39
 
40
40
  CONFIG_SCHEMA = cv.Schema(
41
41
  {
42
- cv.Required(CONF_HAIER_ID): cv.use_id(HonClimate),
42
+ cv.GenerateID(CONF_HAIER_ID): cv.use_id(HonClimate),
43
43
  }
44
44
  ).extend({cv.Optional(type): schema for type, schema in TEXT_SENSOR_TYPES.items()})
45
45
 
@@ -47,8 +47,8 @@ CONFIG_SCHEMA = cv.Schema(
47
47
  async def to_code(config):
48
48
  paren = await cg.get_variable(config[CONF_HAIER_ID])
49
49
 
50
- for type, _ in TEXT_SENSOR_TYPES.items():
51
- if conf := config.get(type):
50
+ for type_ in TEXT_SENSOR_TYPES:
51
+ if conf := config.get(type_):
52
52
  sens = await text_sensor.new_text_sensor(conf)
53
- text_sensor_type = getattr(TextSensorTypeEnum, type.upper())
53
+ text_sensor_type = getattr(TextSensorTypeEnum, type_.upper())
54
54
  cg.add(paren.set_sub_text_sensor(text_sensor_type, sens))
@@ -8,7 +8,6 @@ from esphome.const import (
8
8
  CONF_PROTOCOL,
9
9
  CONF_VISUAL,
10
10
  )
11
- from esphome.core import CORE
12
11
 
13
12
  CODEOWNERS = ["@rob-deutsch"]
14
13
 
@@ -34,6 +33,7 @@ PROTOCOLS = {
34
33
  "greeyan": Protocol.PROTOCOL_GREEYAN,
35
34
  "greeyac": Protocol.PROTOCOL_GREEYAC,
36
35
  "greeyt": Protocol.PROTOCOL_GREEYT,
36
+ "greeyap": Protocol.PROTOCOL_GREEYAP,
37
37
  "hisense_aud": Protocol.PROTOCOL_HISENSE_AUD,
38
38
  "hitachi": Protocol.PROTOCOL_HITACHI,
39
39
  "hyundai": Protocol.PROTOCOL_HYUNDAI,
@@ -61,6 +61,16 @@ PROTOCOLS = {
61
61
  "toshiba_daiseikai": Protocol.PROTOCOL_TOSHIBA_DAISEIKAI,
62
62
  "toshiba": Protocol.PROTOCOL_TOSHIBA,
63
63
  "zhlt01": Protocol.PROTOCOL_ZHLT01,
64
+ "nibe": Protocol.PROTOCOL_NIBE,
65
+ "carrier_qlima_1": Protocol.PROTOCOL_QLIMA_1,
66
+ "carrier_qlima_2": Protocol.PROTOCOL_QLIMA_2,
67
+ "samsung_aqv12msan": Protocol.PROTOCOL_SAMSUNG_AQV12MSAN,
68
+ "zhjg01": Protocol.PROTOCOL_ZHJG01,
69
+ "airway": Protocol.PROTOCOL_AIRWAY,
70
+ "bgh_aud": Protocol.PROTOCOL_BGH_AUD,
71
+ "panasonic_altdke": Protocol.PROTOCOL_PANASONIC_ALTDKE,
72
+ "vaillantvai8": Protocol.PROTOCOL_VAILLANTVAI8,
73
+ "r51m": Protocol.PROTOCOL_R51M,
64
74
  }
65
75
 
66
76
  CONF_HORIZONTAL_DEFAULT = "horizontal_default"
@@ -116,7 +126,4 @@ def to_code(config):
116
126
  cg.add(var.set_max_temperature(config[CONF_MAX_TEMPERATURE]))
117
127
  cg.add(var.set_min_temperature(config[CONF_MIN_TEMPERATURE]))
118
128
 
119
- cg.add_library("tonia/HeatpumpIR", "1.0.23")
120
-
121
- if CORE.is_esp8266 or CORE.is_esp32:
122
- cg.add_library("crankyoldgit/IRremoteESP8266", "2.8.4")
129
+ cg.add_library("tonia/HeatpumpIR", "1.0.27")
@@ -28,6 +28,7 @@ const std::map<Protocol, std::function<HeatpumpIR *()>> PROTOCOL_CONSTRUCTOR_MAP
28
28
  {PROTOCOL_GREEYAN, []() { return new GreeYANHeatpumpIR(); }}, // NOLINT
29
29
  {PROTOCOL_GREEYAC, []() { return new GreeYACHeatpumpIR(); }}, // NOLINT
30
30
  {PROTOCOL_GREEYT, []() { return new GreeYTHeatpumpIR(); }}, // NOLINT
31
+ {PROTOCOL_GREEYAP, []() { return new GreeYAPHeatpumpIR(); }}, // NOLINT
31
32
  {PROTOCOL_HISENSE_AUD, []() { return new HisenseHeatpumpIR(); }}, // NOLINT
32
33
  {PROTOCOL_HITACHI, []() { return new HitachiHeatpumpIR(); }}, // NOLINT
33
34
  {PROTOCOL_HYUNDAI, []() { return new HyundaiHeatpumpIR(); }}, // NOLINT
@@ -55,6 +56,16 @@ const std::map<Protocol, std::function<HeatpumpIR *()>> PROTOCOL_CONSTRUCTOR_MAP
55
56
  {PROTOCOL_TOSHIBA_DAISEIKAI, []() { return new ToshibaDaiseikaiHeatpumpIR(); }}, // NOLINT
56
57
  {PROTOCOL_TOSHIBA, []() { return new ToshibaHeatpumpIR(); }}, // NOLINT
57
58
  {PROTOCOL_ZHLT01, []() { return new ZHLT01HeatpumpIR(); }}, // NOLINT
59
+ {PROTOCOL_NIBE, []() { return new NibeHeatpumpIR(); }}, // NOLINT
60
+ {PROTOCOL_QLIMA_1, []() { return new Qlima1HeatpumpIR(); }}, // NOLINT
61
+ {PROTOCOL_QLIMA_2, []() { return new Qlima2HeatpumpIR(); }}, // NOLINT
62
+ {PROTOCOL_SAMSUNG_AQV12MSAN, []() { return new SamsungAQV12MSANHeatpumpIR(); }}, // NOLINT
63
+ {PROTOCOL_ZHJG01, []() { return new ZHJG01HeatpumpIR(); }}, // NOLINT
64
+ {PROTOCOL_AIRWAY, []() { return new AIRWAYHeatpumpIR(); }}, // NOLINT
65
+ {PROTOCOL_BGH_AUD, []() { return new BGHHeatpumpIR(); }}, // NOLINT
66
+ {PROTOCOL_PANASONIC_ALTDKE, []() { return new PanasonicAltDKEHeatpumpIR(); }}, // NOLINT
67
+ {PROTOCOL_VAILLANTVAI8, []() { return new VaillantHeatpumpIR(); }}, // NOLINT
68
+ {PROTOCOL_R51M, []() { return new R51MHeatpumpIR(); }}, // NOLINT
58
69
  };
59
70
 
60
71
  void HeatpumpIRClimate::setup() {
@@ -28,6 +28,7 @@ enum Protocol {
28
28
  PROTOCOL_GREEYAN,
29
29
  PROTOCOL_GREEYAC,
30
30
  PROTOCOL_GREEYT,
31
+ PROTOCOL_GREEYAP,
31
32
  PROTOCOL_HISENSE_AUD,
32
33
  PROTOCOL_HITACHI,
33
34
  PROTOCOL_HYUNDAI,
@@ -55,6 +56,16 @@ enum Protocol {
55
56
  PROTOCOL_TOSHIBA_DAISEIKAI,
56
57
  PROTOCOL_TOSHIBA,
57
58
  PROTOCOL_ZHLT01,
59
+ PROTOCOL_NIBE,
60
+ PROTOCOL_QLIMA_1,
61
+ PROTOCOL_QLIMA_2,
62
+ PROTOCOL_SAMSUNG_AQV12MSAN,
63
+ PROTOCOL_ZHJG01,
64
+ PROTOCOL_AIRWAY,
65
+ PROTOCOL_BGH_AUD,
66
+ PROTOCOL_PANASONIC_ALTDKE,
67
+ PROTOCOL_VAILLANTVAI8,
68
+ PROTOCOL_R51M,
58
69
  };
59
70
 
60
71
  // Simple enum to represent horizontal directios
@@ -32,6 +32,13 @@ std::shared_ptr<HttpContainer> HttpRequestArduino::start(std::string url, std::s
32
32
 
33
33
  watchdog::WatchdogManager wdm(this->get_watchdog_timeout());
34
34
 
35
+ if (this->follow_redirects_) {
36
+ container->client_.setFollowRedirects(HTTPC_FORCE_FOLLOW_REDIRECTS);
37
+ container->client_.setRedirectLimit(this->redirect_limit_);
38
+ } else {
39
+ container->client_.setFollowRedirects(HTTPC_DISABLE_FOLLOW_REDIRECTS);
40
+ }
41
+
35
42
  #if defined(USE_ESP8266)
36
43
  std::unique_ptr<WiFiClient> stream_ptr;
37
44
  #ifdef USE_HTTP_REQUEST_ESP8266_HTTPS
@@ -59,8 +66,6 @@ std::shared_ptr<HttpContainer> HttpRequestArduino::start(std::string url, std::s
59
66
  "in your YAML, or use HTTPS");
60
67
  }
61
68
  #endif // USE_ARDUINO_VERSION_CODE
62
-
63
- container->client_.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
64
69
  bool status = container->client_.begin(*stream_ptr, url.c_str());
65
70
 
66
71
  #elif defined(USE_RP2040)
@@ -116,19 +116,18 @@ void HttpRequestUpdate::update() {
116
116
  }
117
117
  }
118
118
 
119
- std::string current_version = this->current_version_;
120
- if (current_version.empty()) {
119
+ std::string current_version;
121
120
  #ifdef ESPHOME_PROJECT_VERSION
122
- current_version = ESPHOME_PROJECT_VERSION;
121
+ current_version = ESPHOME_PROJECT_VERSION;
123
122
  #else
124
- current_version = ESPHOME_VERSION;
123
+ current_version = ESPHOME_VERSION;
125
124
  #endif
126
- }
125
+
127
126
  this->update_info_.current_version = current_version;
128
127
 
129
- if (this->update_info_.latest_version.empty()) {
128
+ if (this->update_info_.latest_version.empty() || this->update_info_.latest_version == update_info_.current_version) {
130
129
  this->state_ = update::UPDATE_STATE_NO_UPDATE;
131
- } else if (this->update_info_.latest_version != this->current_version_) {
130
+ } else {
132
131
  this->state_ = update::UPDATE_STATE_AVAILABLE;
133
132
  }
134
133
 
@@ -22,15 +22,12 @@ class HttpRequestUpdate : public update::UpdateEntity, public PollingComponent {
22
22
  void set_request_parent(HttpRequestComponent *request_parent) { this->request_parent_ = request_parent; }
23
23
  void set_ota_parent(OtaHttpRequestComponent *ota_parent) { this->ota_parent_ = ota_parent; }
24
24
 
25
- void set_current_version(const std::string &current_version) { this->current_version_ = current_version; }
26
-
27
25
  float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
28
26
 
29
27
  protected:
30
28
  HttpRequestComponent *request_parent_;
31
29
  OtaHttpRequestComponent *ota_parent_;
32
30
  std::string source_url_;
33
- std::string current_version_{""};
34
31
  };
35
32
 
36
33
  } // namespace http_request
@@ -25,6 +25,10 @@ CONF_I2S_LRCLK_PIN = "i2s_lrclk_pin"
25
25
  CONF_I2S_AUDIO = "i2s_audio"
26
26
  CONF_I2S_AUDIO_ID = "i2s_audio_id"
27
27
 
28
+ CONF_I2S_MODE = "i2s_mode"
29
+ CONF_PRIMARY = "primary"
30
+ CONF_SECONDARY = "secondary"
31
+
28
32
  i2s_audio_ns = cg.esphome_ns.namespace("i2s_audio")
29
33
  I2SAudioComponent = i2s_audio_ns.class_("I2SAudioComponent", cg.Component)
30
34
  I2SAudioIn = i2s_audio_ns.class_("I2SAudioIn", cg.Parented.template(I2SAudioComponent))
@@ -32,6 +36,12 @@ I2SAudioOut = i2s_audio_ns.class_(
32
36
  "I2SAudioOut", cg.Parented.template(I2SAudioComponent)
33
37
  )
34
38
 
39
+ i2s_mode_t = cg.global_ns.enum("i2s_mode_t")
40
+ I2S_MODE_OPTIONS = {
41
+ CONF_PRIMARY: i2s_mode_t.I2S_MODE_MASTER, # NOLINT
42
+ CONF_SECONDARY: i2s_mode_t.I2S_MODE_SLAVE, # NOLINT
43
+ }
44
+
35
45
  # https://github.com/espressif/esp-idf/blob/master/components/soc/{variant}/include/soc/soc_caps.h
36
46
  I2S_PORTS = {
37
47
  VARIANT_ESP32: 2,
@@ -7,6 +7,9 @@ from esphome.components import microphone, esp32
7
7
  from esphome.components.adc import ESP32_VARIANT_ADC1_PIN_TO_CHANNEL, validate_adc_pin
8
8
 
9
9
  from .. import (
10
+ CONF_I2S_MODE,
11
+ CONF_PRIMARY,
12
+ I2S_MODE_OPTIONS,
10
13
  i2s_audio_ns,
11
14
  I2SAudioComponent,
12
15
  I2SAudioIn,
@@ -68,6 +71,9 @@ BASE_SCHEMA = microphone.MICROPHONE_SCHEMA.extend(
68
71
  _validate_bits, cv.enum(BITS_PER_SAMPLE)
69
72
  ),
70
73
  cv.Optional(CONF_USE_APLL, default=False): cv.boolean,
74
+ cv.Optional(CONF_I2S_MODE, default=CONF_PRIMARY): cv.enum(
75
+ I2S_MODE_OPTIONS, lower=True
76
+ ),
71
77
  }
72
78
  ).extend(cv.COMPONENT_SCHEMA)
73
79
 
@@ -107,6 +113,7 @@ async def to_code(config):
107
113
  cg.add(var.set_din_pin(config[CONF_I2S_DIN_PIN]))
108
114
  cg.add(var.set_pdm(config[CONF_PDM]))
109
115
 
116
+ cg.add(var.set_i2s_mode(config[CONF_I2S_MODE]))
110
117
  cg.add(var.set_channel(config[CONF_CHANNEL]))
111
118
  cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
112
119
  cg.add(var.set_bits_per_sample(config[CONF_BITS_PER_SAMPLE]))
@@ -46,7 +46,7 @@ void I2SAudioMicrophone::start_() {
46
46
  return; // Waiting for another i2s to return lock
47
47
  }
48
48
  i2s_driver_config_t config = {
49
- .mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_RX),
49
+ .mode = (i2s_mode_t) (this->i2s_mode_ | I2S_MODE_RX),
50
50
  .sample_rate = this->sample_rate_,
51
51
  .bits_per_sample = this->bits_per_sample_,
52
52
  .channel_format = this->channel_,
@@ -174,8 +174,7 @@ size_t I2SAudioMicrophone::read(int16_t *buf, size_t len) {
174
174
  size_t samples_read = bytes_read / sizeof(int32_t);
175
175
  samples.resize(samples_read);
176
176
  for (size_t i = 0; i < samples_read; i++) {
177
- int32_t temp = reinterpret_cast<int32_t *>(buf)[i] >> 14;
178
- samples[i] = clamp<int16_t>(temp, INT16_MIN, INT16_MAX);
177
+ samples[i] = reinterpret_cast<int32_t *>(buf)[i] >> 16;
179
178
  }
180
179
  memcpy(buf, samples.data(), samples_read * sizeof(int16_t));
181
180
  return samples_read * sizeof(int16_t);
@@ -30,6 +30,8 @@ class I2SAudioMicrophone : public I2SAudioIn, public microphone::Microphone, pub
30
30
  }
31
31
  #endif
32
32
 
33
+ void set_i2s_mode(i2s_mode_t mode) { this->i2s_mode_ = mode; }
34
+
33
35
  void set_channel(i2s_channel_fmt_t channel) { this->channel_ = channel; }
34
36
  void set_sample_rate(uint32_t sample_rate) { this->sample_rate_ = sample_rate; }
35
37
  void set_bits_per_sample(i2s_bits_per_sample_t bits_per_sample) { this->bits_per_sample_ = bits_per_sample; }
@@ -46,6 +48,7 @@ class I2SAudioMicrophone : public I2SAudioIn, public microphone::Microphone, pub
46
48
  bool adc_{false};
47
49
  #endif
48
50
  bool pdm_{false};
51
+ i2s_mode_t i2s_mode_{};
49
52
  i2s_channel_fmt_t channel_;
50
53
  uint32_t sample_rate_;
51
54
  i2s_bits_per_sample_t bits_per_sample_;