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.
- esphome/components/aht10/aht10.cpp +4 -2
- esphome/components/climate/climate.cpp +10 -6
- esphome/components/climate/climate_traits.h +3 -3
- esphome/components/cover/cover.h +2 -2
- esphome/components/esp32_camera/__init__.py +6 -3
- esphome/components/esp32_can/canbus.py +3 -0
- esphome/components/ethernet/ethernet_component.cpp +8 -3
- esphome/components/font/__init__.py +2 -28
- esphome/components/gree/climate.py +1 -0
- esphome/components/gree/gree.cpp +11 -3
- esphome/components/gree/gree.h +5 -1
- esphome/components/haier/binary_sensor/__init__.py +4 -4
- esphome/components/haier/button/__init__.py +1 -1
- esphome/components/haier/climate.py +43 -9
- esphome/components/haier/haier_base.cpp +4 -0
- esphome/components/haier/haier_base.h +11 -1
- esphome/components/haier/hon_climate.cpp +109 -55
- esphome/components/haier/hon_climate.h +7 -1
- esphome/components/haier/hon_packet.h +5 -0
- esphome/components/haier/sensor/__init__.py +5 -5
- esphome/components/haier/smartair2_climate.cpp +1 -0
- esphome/components/haier/text_sensor/__init__.py +4 -4
- esphome/components/heatpumpir/climate.py +12 -5
- esphome/components/heatpumpir/heatpumpir.cpp +11 -0
- esphome/components/heatpumpir/heatpumpir.h +11 -0
- esphome/components/http_request/http_request_arduino.cpp +7 -2
- esphome/components/http_request/update/http_request_update.cpp +6 -7
- esphome/components/http_request/update/http_request_update.h +0 -3
- esphome/components/i2s_audio/__init__.py +10 -0
- esphome/components/i2s_audio/microphone/__init__.py +7 -0
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +2 -3
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +3 -0
- esphome/components/image/__init__.py +2 -29
- esphome/components/improv_serial/improv_serial_component.cpp +9 -8
- esphome/components/ltr390/ltr390.cpp +44 -29
- esphome/components/ltr390/ltr390.h +9 -5
- esphome/components/ltr390/sensor.py +35 -5
- esphome/components/mdns/__init__.py +3 -3
- esphome/components/mdns/mdns_component.cpp +3 -1
- esphome/components/mdns/mdns_component.h +3 -1
- esphome/components/mdns/mdns_esp32.cpp +2 -1
- esphome/components/mdns/mdns_esp8266.cpp +2 -1
- esphome/components/mdns/mdns_host.cpp +2 -1
- esphome/components/mdns/mdns_libretiny.cpp +2 -1
- esphome/components/mdns/mdns_rp2040.cpp +2 -1
- esphome/components/micro_wake_word/__init__.py +205 -56
- esphome/components/micro_wake_word/micro_wake_word.cpp +225 -275
- esphome/components/micro_wake_word/micro_wake_word.h +77 -107
- esphome/components/micro_wake_word/preprocessor_settings.h +20 -0
- esphome/components/micro_wake_word/streaming_model.cpp +189 -0
- esphome/components/micro_wake_word/streaming_model.h +84 -0
- esphome/components/mitsubishi/mitsubishi.cpp +1 -0
- esphome/components/modbus_controller/text_sensor/__init__.py +2 -1
- esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp +4 -1
- esphome/components/modbus_controller/text_sensor/modbus_textsensor.h +1 -1
- esphome/components/number/__init__.py +2 -0
- esphome/components/ota/ota_backend_arduino_esp32.cpp +22 -7
- esphome/components/ota/ota_backend_arduino_esp8266.cpp +23 -8
- esphome/components/ota/ota_backend_arduino_libretiny.cpp +22 -7
- esphome/components/ota/ota_backend_arduino_rp2040.cpp +22 -7
- esphome/components/pmsa003i/pmsa003i.cpp +9 -0
- esphome/components/qspi_amoled/display.py +16 -4
- esphome/components/qspi_amoled/qspi_amoled.cpp +16 -0
- esphome/components/qspi_amoled/qspi_amoled.h +0 -3
- esphome/components/remote_base/dooya_protocol.cpp +4 -4
- esphome/components/remote_base/rc_switch_protocol.cpp +1 -1
- esphome/components/restart/button/__init__.py +2 -0
- esphome/components/script/__init__.py +1 -1
- esphome/components/sensor/__init__.py +2 -0
- esphome/components/tuya/tuya.cpp +8 -2
- esphome/components/tuya/tuya.h +3 -1
- esphome/components/uart/__init__.py +72 -9
- esphome/components/uart/uart_component_esp32_arduino.cpp +18 -4
- esphome/components/uart/uart_component_esp_idf.cpp +22 -2
- esphome/components/uart/uart_component_host.cpp +295 -0
- esphome/components/uart/uart_component_host.h +38 -0
- esphome/components/uptime/sensor.py +44 -11
- esphome/components/uptime/{uptime_sensor.cpp → uptime_seconds_sensor.cpp} +11 -7
- esphome/components/uptime/{uptime_sensor.h → uptime_seconds_sensor.h} +2 -2
- esphome/components/uptime/uptime_timestamp_sensor.cpp +39 -0
- esphome/components/uptime/uptime_timestamp_sensor.h +30 -0
- esphome/components/veml7700/veml7700.cpp +1 -1
- esphome/components/veml7700/veml7700.h +5 -5
- esphome/components/voice_assistant/voice_assistant.cpp +4 -2
- esphome/components/web_server/server_index_v2.h +42 -41
- esphome/components/web_server/server_index_v3.h +368 -367
- esphome/components/wifi/wifi_component_esp_idf.cpp +1 -1
- esphome/components/wifi/wifi_component_pico_w.cpp +18 -2
- esphome/components/wireguard/__init__.py +1 -1
- esphome/components/x9c/output.py +7 -1
- esphome/const.py +2 -1
- esphome/core/defines.h +1 -0
- esphome/core/helpers.cpp +2 -2
- esphome/core/helpers.h +1 -1
- esphome/external_files.py +26 -0
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/METADATA +1 -1
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/RECORD +101 -95
- esphome/components/micro_wake_word/audio_preprocessor_int8_model_data.h +0 -493
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/LICENSE +0 -0
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/WHEEL +0 -0
- {esphome-2024.6.6.dist-info → esphome-2024.7.0.dist-info}/entry_points.txt +0 -0
- {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 (
|
173
|
-
|
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[
|
483
|
-
memcpy(control_out_buffer, this->last_status_message_.get(),
|
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,
|
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 =
|
762
|
-
|
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 +
|
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
|
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,
|
799
|
-
|
800
|
-
|
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_ ?
|
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_ ?
|
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 ?
|
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
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1234
|
-
this->
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
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.
|
140
|
+
cv.GenerateID(CONF_HAIER_ID): cv.use_id(HonClimate),
|
141
141
|
}
|
142
|
-
).extend({cv.Optional(
|
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
|
149
|
-
if conf := config.get(
|
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,
|
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.
|
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
|
51
|
-
if conf := config.get(
|
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,
|
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.
|
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
|
120
|
-
if (current_version.empty()) {
|
119
|
+
std::string current_version;
|
121
120
|
#ifdef ESPHOME_PROJECT_VERSION
|
122
|
-
|
121
|
+
current_version = ESPHOME_PROJECT_VERSION;
|
123
122
|
#else
|
124
|
-
|
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
|
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 ¤t_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) (
|
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
|
-
|
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_;
|