esphome 2025.9.3__py3-none-any.whl → 2025.10.0b2__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/__main__.py +94 -31
- esphome/address_cache.py +142 -0
- esphome/automation.py +130 -32
- esphome/build_gen/platformio.py +1 -3
- esphome/codegen.py +1 -0
- esphome/components/animation/animation.cpp +2 -2
- esphome/components/api/__init__.py +166 -3
- esphome/components/api/api_connection.cpp +84 -41
- esphome/components/api/api_connection.h +22 -16
- esphome/components/api/api_frame_helper.cpp +33 -19
- esphome/components/api/api_frame_helper.h +19 -4
- esphome/components/api/api_frame_helper_noise.cpp +41 -53
- esphome/components/api/api_frame_helper_noise.h +1 -1
- esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
- esphome/components/api/api_frame_helper_plaintext.h +1 -1
- esphome/components/api/api_pb2.cpp +189 -15
- esphome/components/api/api_pb2.h +132 -20
- esphome/components/api/api_pb2_dump.cpp +97 -9
- esphome/components/api/api_pb2_service.cpp +118 -160
- esphome/components/api/api_pb2_service.h +31 -3
- esphome/components/api/api_server.cpp +68 -10
- esphome/components/api/api_server.h +32 -4
- esphome/components/api/custom_api_device.h +8 -8
- esphome/components/api/homeassistant_service.h +123 -6
- esphome/components/api/proto.h +6 -2
- esphome/components/api/user_services.h +2 -2
- esphome/components/as7341/sensor.py +1 -1
- esphome/components/audio/__init__.py +1 -1
- esphome/components/audio/audio.cpp +1 -1
- esphome/components/audio/audio_decoder.cpp +9 -9
- esphome/components/bl0906/bl0906.cpp +2 -2
- esphome/components/bl0942/bl0942.cpp +2 -2
- esphome/components/ble_client/__init__.py +1 -1
- esphome/components/bluetooth_proxy/__init__.py +4 -30
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
- esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
- esphome/components/camera_encoder/__init__.py +2 -4
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
- esphome/components/canbus/canbus.cpp +7 -5
- esphome/components/canbus/canbus.h +7 -7
- esphome/components/captive_portal/__init__.py +18 -1
- esphome/components/captive_portal/captive_portal.cpp +40 -46
- esphome/components/captive_portal/captive_portal.h +20 -22
- esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
- esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
- esphome/components/ccs811/ccs811.cpp +1 -1
- esphome/components/climate/climate.cpp +10 -7
- esphome/components/cm1106/cm1106.cpp +1 -1
- esphome/components/copy/lock/copy_lock.cpp +1 -1
- esphome/components/cover/cover.cpp +1 -0
- esphome/components/daikin_arc/daikin_arc.cpp +19 -12
- esphome/components/dashboard_import/dashboard_import.cpp +1 -1
- esphome/components/dashboard_import/dashboard_import.h +1 -1
- esphome/components/deep_sleep/__init__.py +9 -2
- esphome/components/deep_sleep/deep_sleep_component.h +11 -9
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
- esphome/components/ektf2232/touchscreen/__init__.py +8 -5
- esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
- esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
- esphome/components/epaper_spi/__init__.py +1 -0
- esphome/components/epaper_spi/display.py +80 -0
- esphome/components/epaper_spi/epaper_spi.cpp +227 -0
- esphome/components/epaper_spi/epaper_spi.h +93 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
- esphome/components/es7210/es7210.cpp +3 -3
- esphome/components/esp32/__init__.py +256 -340
- esphome/components/esp32/boards.py +81 -0
- esphome/components/esp32/preferences.cpp +23 -17
- esphome/components/esp32_ble/__init__.py +167 -44
- esphome/components/esp32_ble/ble.cpp +47 -3
- esphome/components/esp32_ble/ble.h +18 -0
- esphome/components/esp32_ble/ble_advertising.cpp +7 -3
- esphome/components/esp32_ble/ble_advertising.h +4 -0
- esphome/components/esp32_ble/ble_uuid.cpp +16 -42
- esphome/components/esp32_ble_beacon/__init__.py +3 -4
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +0 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
- esphome/components/esp32_ble_server/__init__.py +28 -14
- esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
- esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
- esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
- esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
- esphome/components/esp32_ble_server/ble_server.cpp +59 -24
- esphome/components/esp32_ble_server/ble_server.h +38 -20
- esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
- esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
- esphome/components/esp32_ble_tracker/__init__.py +25 -80
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -8
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
- esphome/components/esp32_camera/__init__.py +1 -3
- esphome/components/esp32_can/esp32_can.cpp +22 -4
- esphome/components/esp32_can/esp32_can.h +3 -0
- esphome/components/esp32_hosted/__init__.py +2 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +135 -65
- esphome/components/esp32_improv/esp32_improv_component.h +7 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp8266/__init__.py +3 -3
- esphome/components/esphome/ota/__init__.py +21 -2
- esphome/components/esphome/ota/ota_esphome.cpp +456 -146
- esphome/components/esphome/ota/ota_esphome.h +49 -2
- esphome/components/ethernet/__init__.py +39 -22
- esphome/components/ethernet/ethernet_component.cpp +28 -5
- esphome/components/ethernet/ethernet_component.h +5 -1
- esphome/components/external_components/__init__.py +8 -6
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
- esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
- esphome/components/font/__init__.py +5 -5
- esphome/components/graph/graph.cpp +1 -1
- esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
- esphome/components/haier/hon_climate.cpp +2 -2
- esphome/components/haier/hon_climate.h +1 -1
- esphome/components/hdc1080/hdc1080.cpp +42 -34
- esphome/components/hdc1080/hdc1080.h +1 -3
- esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
- esphome/components/http_request/__init__.py +3 -3
- esphome/components/htu21d/htu21d.cpp +13 -18
- esphome/components/htu21d/htu21d.h +1 -1
- esphome/components/i2s_audio/__init__.py +1 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
- esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
- esphome/components/improv_serial/improv_serial_component.cpp +12 -15
- esphome/components/improv_serial/improv_serial_component.h +6 -8
- esphome/components/json/json_util.cpp +42 -44
- esphome/components/json/json_util.h +57 -0
- esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
- esphome/components/key_collector/key_collector.h +4 -4
- esphome/components/libretiny/__init__.py +6 -6
- esphome/components/libretiny/preferences.cpp +23 -16
- esphome/components/light/light_call.cpp +98 -120
- esphome/components/light/light_call.h +17 -7
- esphome/components/lm75b/__init__.py +0 -0
- esphome/components/lm75b/lm75b.cpp +39 -0
- esphome/components/lm75b/lm75b.h +19 -0
- esphome/components/lm75b/sensor.py +34 -0
- esphome/components/lock/lock.h +12 -6
- esphome/components/logger/__init__.py +15 -27
- esphome/components/logger/logger.cpp +10 -20
- esphome/components/logger/logger.h +105 -62
- esphome/components/logger/logger_esp32.cpp +0 -48
- esphome/components/logger/logger_zephyr.cpp +2 -3
- esphome/components/logger/select/logger_level_select.cpp +6 -7
- esphome/components/logger/select/logger_level_select.h +7 -0
- esphome/components/ltr501/ltr501.cpp +7 -6
- esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
- esphome/components/matrix_keypad/matrix_keypad.h +4 -4
- esphome/components/max7219digit/max7219digit.cpp +1 -1
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +3 -3
- esphome/components/mcp2515/mcp2515.cpp +31 -3
- esphome/components/mcp2515/mcp2515_defs.h +3 -1
- esphome/components/md5/md5.cpp +0 -26
- esphome/components/md5/md5.h +10 -20
- esphome/components/mdns/__init__.py +93 -19
- esphome/components/mdns/mdns_component.cpp +57 -94
- esphome/components/mdns/mdns_component.h +35 -11
- esphome/components/mdns/mdns_esp32.cpp +7 -13
- esphome/components/mdns/mdns_esp8266.cpp +7 -7
- esphome/components/mdns/mdns_libretiny.cpp +3 -4
- esphome/components/mdns/mdns_rp2040.cpp +3 -4
- esphome/components/mipi/__init__.py +1 -5
- esphome/components/mipi_spi/display.py +24 -8
- esphome/components/mipi_spi/mipi_spi.h +3 -3
- esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
- esphome/components/mmc5603/mmc5603.cpp +3 -3
- esphome/components/modbus/modbus.cpp +27 -13
- esphome/components/modbus/modbus.h +5 -3
- esphome/components/modbus/modbus_definitions.h +86 -0
- esphome/components/modbus_controller/__init__.py +29 -1
- esphome/components/modbus_controller/const.py +4 -0
- esphome/components/modbus_controller/modbus_controller.cpp +38 -13
- esphome/components/modbus_controller/modbus_controller.h +18 -29
- esphome/components/mpr121/mpr121.cpp +41 -42
- esphome/components/mpr121/mpr121.h +0 -1
- esphome/components/nau7802/nau7802.cpp +2 -2
- esphome/components/network/__init__.py +7 -3
- esphome/components/nextion/display.py +4 -4
- esphome/components/nextion/nextion.cpp +8 -8
- esphome/components/number/__init__.py +2 -0
- esphome/components/number/number_call.cpp +23 -12
- esphome/components/number/number_call.h +5 -0
- esphome/components/online_image/bmp_image.cpp +2 -1
- esphome/components/online_image/jpeg_image.cpp +4 -2
- esphome/components/opentherm/opentherm.cpp +5 -5
- esphome/components/opentherm/opentherm.h +3 -3
- esphome/components/openthread/openthread.cpp +11 -10
- esphome/components/openthread/openthread.h +0 -1
- esphome/components/ota/ota_backend.h +1 -0
- esphome/components/packages/__init__.py +10 -8
- esphome/components/packet_transport/packet_transport.cpp +2 -0
- esphome/components/pid/pid_controller.cpp +1 -1
- esphome/components/prometheus/prometheus_handler.cpp +239 -239
- esphome/components/psram/__init__.py +30 -28
- esphome/components/qmc5883l/qmc5883l.cpp +15 -0
- esphome/components/qmc5883l/qmc5883l.h +3 -0
- esphome/components/qmc5883l/sensor.py +31 -12
- esphome/components/remote_base/gobox_protocol.cpp +3 -3
- esphome/components/remote_receiver/__init__.py +14 -2
- esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
- esphome/components/remote_receiver/remote_receiver.h +4 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
- esphome/components/remote_transmitter/__init__.py +2 -2
- esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
- esphome/components/rp2040/__init__.py +11 -11
- esphome/components/rtttl/rtttl.cpp +2 -2
- esphome/components/scd30/sensor.py +1 -1
- esphome/components/script/__init__.py +1 -1
- esphome/components/script/script.h +7 -7
- esphome/components/select/select.cpp +5 -4
- esphome/components/select/select_call.cpp +1 -1
- esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
- esphome/components/sensor/__init__.py +2 -0
- esphome/components/sha256/__init__.py +22 -0
- esphome/components/sha256/sha256.cpp +116 -0
- esphome/components/sha256/sha256.h +60 -0
- esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
- esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
- esphome/components/spi/__init__.py +0 -3
- esphome/components/split_buffer/__init__.py +5 -0
- esphome/components/split_buffer/split_buffer.cpp +133 -0
- esphome/components/split_buffer/split_buffer.h +40 -0
- esphome/components/sps30/sps30.cpp +14 -10
- esphome/components/sps30/sps30.h +2 -0
- esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
- esphome/components/st7789v/st7789v.cpp +3 -2
- esphome/components/statsd/statsd.cpp +1 -1
- esphome/components/substitutions/__init__.py +3 -1
- esphome/components/substitutions/jinja.py +13 -3
- esphome/components/sx126x/__init__.py +16 -0
- esphome/components/sx126x/sx126x.cpp +15 -1
- esphome/components/sx126x/sx126x.h +9 -1
- esphome/components/sx126x/sx126x_reg.h +2 -0
- esphome/components/text_sensor/text_sensor.cpp +16 -0
- esphome/components/text_sensor/text_sensor.h +3 -10
- esphome/components/tormatic/tormatic_cover.cpp +1 -1
- esphome/components/tuya/select/tuya_select.cpp +1 -1
- esphome/components/tuya/tuya.cpp +29 -4
- esphome/components/uart/__init__.py +37 -27
- esphome/components/uart/uart.h +6 -0
- esphome/components/uart/uart_component.cpp +8 -0
- esphome/components/uart/uart_component.h +28 -0
- esphome/components/uart/uart_component_esp_idf.cpp +64 -10
- esphome/components/uart/uart_component_esp_idf.h +5 -2
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
- esphome/components/usb_host/__init__.py +12 -2
- esphome/components/usb_host/usb_host.h +89 -14
- esphome/components/usb_host/usb_host_client.cpp +157 -22
- esphome/components/usb_host/usb_host_component.cpp +1 -1
- esphome/components/usb_uart/__init__.py +0 -1
- esphome/components/usb_uart/ch34x.cpp +4 -4
- esphome/components/usb_uart/cp210x.cpp +3 -3
- esphome/components/usb_uart/usb_uart.cpp +88 -32
- esphome/components/usb_uart/usb_uart.h +30 -6
- esphome/components/valve/valve.cpp +1 -0
- esphome/components/veml7700/veml7700.cpp +7 -6
- esphome/components/version/version_text_sensor.cpp +2 -1
- esphome/components/voice_assistant/voice_assistant.cpp +3 -2
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
- esphome/components/web_server/list_entities.cpp +3 -4
- esphome/components/web_server/list_entities.h +8 -10
- esphome/components/web_server/ota/__init__.py +1 -1
- esphome/components/web_server/ota/ota_web_server.cpp +9 -3
- esphome/components/web_server/web_server.cpp +509 -404
- esphome/components/web_server/web_server.h +5 -6
- esphome/components/web_server/web_server_v1.cpp +21 -19
- esphome/components/web_server_base/__init__.py +5 -2
- esphome/components/web_server_base/web_server_base.h +27 -7
- esphome/components/web_server_idf/__init__.py +1 -1
- esphome/components/web_server_idf/multipart.cpp +2 -2
- esphome/components/web_server_idf/multipart.h +2 -2
- esphome/components/web_server_idf/utils.cpp +2 -2
- esphome/components/web_server_idf/utils.h +2 -2
- esphome/components/web_server_idf/web_server_idf.cpp +118 -26
- esphome/components/web_server_idf/web_server_idf.h +12 -10
- esphome/components/wifi/__init__.py +13 -11
- esphome/components/wifi/wifi_component.cpp +74 -56
- esphome/components/wifi/wifi_component.h +4 -4
- esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
- esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
- esphome/components/wireguard/__init__.py +1 -1
- esphome/components/wts01/__init__.py +0 -0
- esphome/components/wts01/sensor.py +41 -0
- esphome/components/wts01/wts01.cpp +91 -0
- esphome/components/wts01/wts01.h +27 -0
- esphome/components/zephyr/__init__.py +5 -5
- esphome/components/zwave_proxy/__init__.py +43 -0
- esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
- esphome/components/zwave_proxy/zwave_proxy.h +93 -0
- esphome/config.py +79 -24
- esphome/config_validation.py +13 -15
- esphome/const.py +9 -2
- esphome/core/__init__.py +33 -22
- esphome/core/component.cpp +28 -18
- esphome/core/component_iterator.h +2 -1
- esphome/core/config.py +15 -15
- esphome/core/defines.h +21 -0
- esphome/core/entity_helpers.py +9 -6
- esphome/core/hash_base.h +56 -0
- esphome/core/helpers.cpp +19 -3
- esphome/core/helpers.h +26 -0
- esphome/core/scheduler.cpp +5 -21
- esphome/core/scheduler.h +19 -8
- esphome/core/string_ref.h +1 -1
- esphome/core/time.cpp +5 -5
- esphome/cpp_generator.py +4 -29
- esphome/dashboard/const.py +21 -4
- esphome/dashboard/core.py +10 -8
- esphome/dashboard/dns.py +15 -0
- esphome/dashboard/entries.py +15 -21
- esphome/dashboard/models.py +76 -0
- esphome/dashboard/settings.py +7 -7
- esphome/dashboard/status/mdns.py +46 -2
- esphome/dashboard/web_server.py +367 -93
- esphome/espota2.py +112 -32
- esphome/external_files.py +6 -7
- esphome/git.py +8 -0
- esphome/helpers.py +124 -77
- esphome/loader.py +8 -9
- esphome/pins.py +2 -2
- esphome/platformio_api.py +56 -18
- esphome/storage_json.py +26 -21
- esphome/types.py +30 -2
- esphome/util.py +32 -16
- esphome/vscode.py +8 -8
- esphome/wizard.py +10 -10
- esphome/writer.py +50 -15
- esphome/yaml_util.py +37 -31
- esphome/zeroconf.py +12 -3
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/METADATA +12 -12
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/RECORD +340 -320
- esphome/components/event_emitter/__init__.py +0 -5
- esphome/components/event_emitter/event_emitter.cpp +0 -14
- esphome/components/event_emitter/event_emitter.h +0 -63
- esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
- esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
- esphome/components/uart/uart_component_esp32_arduino.h +0 -60
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
- esphome/core/string_ref.cpp +0 -12
- esphome/dashboard/util/file.py +0 -63
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/WHEEL +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,5 @@
|
|
1
1
|
// Should not be needed, but it's required to pass CI clang-tidy checks
|
2
|
-
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
2
|
+
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32P4)
|
3
3
|
#include "usb_uart.h"
|
4
4
|
#include "esphome/core/log.h"
|
5
5
|
#include "esphome/components/uart/uart_debugger.h"
|
@@ -130,7 +130,7 @@ size_t RingBuffer::pop(uint8_t *data, size_t len) {
|
|
130
130
|
return len;
|
131
131
|
}
|
132
132
|
void USBUartChannel::write_array(const uint8_t *data, size_t len) {
|
133
|
-
if (!this->initialised_) {
|
133
|
+
if (!this->initialised_.load()) {
|
134
134
|
ESP_LOGV(TAG, "Channel not initialised - write ignored");
|
135
135
|
return;
|
136
136
|
}
|
@@ -152,7 +152,7 @@ bool USBUartChannel::peek_byte(uint8_t *data) {
|
|
152
152
|
return true;
|
153
153
|
}
|
154
154
|
bool USBUartChannel::read_array(uint8_t *data, size_t len) {
|
155
|
-
if (!this->initialised_) {
|
155
|
+
if (!this->initialised_.load()) {
|
156
156
|
ESP_LOGV(TAG, "Channel not initialised - read ignored");
|
157
157
|
return false;
|
158
158
|
}
|
@@ -170,7 +170,34 @@ bool USBUartChannel::read_array(uint8_t *data, size_t len) {
|
|
170
170
|
return status;
|
171
171
|
}
|
172
172
|
void USBUartComponent::setup() { USBClient::setup(); }
|
173
|
-
void USBUartComponent::loop() {
|
173
|
+
void USBUartComponent::loop() {
|
174
|
+
USBClient::loop();
|
175
|
+
|
176
|
+
// Process USB data from the lock-free queue
|
177
|
+
UsbDataChunk *chunk;
|
178
|
+
while ((chunk = this->usb_data_queue_.pop()) != nullptr) {
|
179
|
+
auto *channel = chunk->channel;
|
180
|
+
|
181
|
+
#ifdef USE_UART_DEBUGGER
|
182
|
+
if (channel->debug_) {
|
183
|
+
uart::UARTDebug::log_hex(uart::UART_DIRECTION_RX, std::vector<uint8_t>(chunk->data, chunk->data + chunk->length),
|
184
|
+
','); // NOLINT()
|
185
|
+
}
|
186
|
+
#endif
|
187
|
+
|
188
|
+
// Push data to ring buffer (now safe in main loop)
|
189
|
+
channel->input_buffer_.push(chunk->data, chunk->length);
|
190
|
+
|
191
|
+
// Return chunk to pool for reuse
|
192
|
+
this->chunk_pool_.release(chunk);
|
193
|
+
}
|
194
|
+
|
195
|
+
// Log dropped USB data periodically
|
196
|
+
uint16_t dropped = this->usb_data_queue_.get_and_reset_dropped_count();
|
197
|
+
if (dropped > 0) {
|
198
|
+
ESP_LOGW(TAG, "Dropped %u USB data chunks due to buffer overflow", dropped);
|
199
|
+
}
|
200
|
+
}
|
174
201
|
void USBUartComponent::dump_config() {
|
175
202
|
USBClient::dump_config();
|
176
203
|
for (auto &channel : this->channels_) {
|
@@ -187,49 +214,77 @@ void USBUartComponent::dump_config() {
|
|
187
214
|
}
|
188
215
|
}
|
189
216
|
void USBUartComponent::start_input(USBUartChannel *channel) {
|
190
|
-
if (!channel->initialised_ || channel->input_started_
|
191
|
-
channel->input_buffer_.get_free_space() < channel->cdc_dev_.in_ep->wMaxPacketSize)
|
217
|
+
if (!channel->initialised_.load() || channel->input_started_.load())
|
192
218
|
return;
|
219
|
+
// THREAD CONTEXT: Called from both USB task and main loop threads
|
220
|
+
// - USB task: Immediate restart after successful transfer for continuous data flow
|
221
|
+
// - Main loop: Controlled restart after consuming data (backpressure mechanism)
|
222
|
+
//
|
223
|
+
// This dual-thread access is intentional for performance:
|
224
|
+
// - USB task restarts avoid context switch delays for high-speed data
|
225
|
+
// - Main loop restarts provide flow control when buffers are full
|
226
|
+
//
|
227
|
+
// The underlying transfer_in() uses lock-free atomic allocation from the
|
228
|
+
// TransferRequest pool, making this multi-threaded access safe
|
193
229
|
const auto *ep = channel->cdc_dev_.in_ep;
|
230
|
+
// CALLBACK CONTEXT: This lambda is executed in USB task via transfer_callback
|
194
231
|
auto callback = [this, channel](const usb_host::TransferStatus &status) {
|
195
232
|
ESP_LOGV(TAG, "Transfer result: length: %u; status %X", status.data_len, status.error_code);
|
196
233
|
if (!status.success) {
|
197
234
|
ESP_LOGE(TAG, "Control transfer failed, status=%s", esp_err_to_name(status.error_code));
|
235
|
+
// On failure, don't restart - let next read_array() trigger it
|
236
|
+
channel->input_started_.store(false);
|
198
237
|
return;
|
199
238
|
}
|
200
|
-
|
201
|
-
if (channel->
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
239
|
+
|
240
|
+
if (!channel->dummy_receiver_ && status.data_len > 0) {
|
241
|
+
// Allocate a chunk from the pool
|
242
|
+
UsbDataChunk *chunk = this->chunk_pool_.allocate();
|
243
|
+
if (chunk == nullptr) {
|
244
|
+
// No chunks available - queue is full or we're out of memory
|
245
|
+
this->usb_data_queue_.increment_dropped_count();
|
246
|
+
// Mark input as not started so we can retry
|
247
|
+
channel->input_started_.store(false);
|
248
|
+
return;
|
210
249
|
}
|
250
|
+
|
251
|
+
// Copy data to chunk (this is fast, happens in USB task)
|
252
|
+
memcpy(chunk->data, status.data, status.data_len);
|
253
|
+
chunk->length = status.data_len;
|
254
|
+
chunk->channel = channel;
|
255
|
+
|
256
|
+
// Push to lock-free queue for main loop processing
|
257
|
+
// Push always succeeds because pool size == queue size
|
258
|
+
this->usb_data_queue_.push(chunk);
|
211
259
|
}
|
212
|
-
|
213
|
-
|
214
|
-
|
260
|
+
|
261
|
+
// On success, restart input immediately from USB task for performance
|
262
|
+
// The lock-free queue will handle backpressure
|
263
|
+
channel->input_started_.store(false);
|
264
|
+
this->start_input(channel);
|
215
265
|
};
|
216
|
-
channel->input_started_
|
266
|
+
channel->input_started_.store(true);
|
217
267
|
this->transfer_in(ep->bEndpointAddress, callback, ep->wMaxPacketSize);
|
218
268
|
}
|
219
269
|
|
220
270
|
void USBUartComponent::start_output(USBUartChannel *channel) {
|
221
|
-
|
271
|
+
// IMPORTANT: This function must only be called from the main loop!
|
272
|
+
// The output_buffer_ is not thread-safe and can only be accessed from main loop.
|
273
|
+
// USB callbacks use defer() to ensure this function runs in the correct context.
|
274
|
+
if (channel->output_started_.load())
|
222
275
|
return;
|
223
276
|
if (channel->output_buffer_.is_empty()) {
|
224
277
|
return;
|
225
278
|
}
|
226
279
|
const auto *ep = channel->cdc_dev_.out_ep;
|
280
|
+
// CALLBACK CONTEXT: This lambda is executed in USB task via transfer_callback
|
227
281
|
auto callback = [this, channel](const usb_host::TransferStatus &status) {
|
228
282
|
ESP_LOGV(TAG, "Output Transfer result: length: %u; status %X", status.data_len, status.error_code);
|
229
|
-
channel->output_started_
|
283
|
+
channel->output_started_.store(false);
|
284
|
+
// Defer restart to main loop (defer is thread-safe)
|
230
285
|
this->defer([this, channel] { this->start_output(channel); });
|
231
286
|
};
|
232
|
-
channel->output_started_
|
287
|
+
channel->output_started_.store(true);
|
233
288
|
uint8_t data[ep->wMaxPacketSize];
|
234
289
|
auto len = channel->output_buffer_.pop(data, ep->wMaxPacketSize);
|
235
290
|
this->transfer_out(ep->bEndpointAddress, callback, data, len);
|
@@ -249,7 +304,8 @@ static void fix_mps(const usb_ep_desc_t *ep) {
|
|
249
304
|
if (ep != nullptr) {
|
250
305
|
auto *ep_mutable = const_cast<usb_ep_desc_t *>(ep);
|
251
306
|
if (ep->wMaxPacketSize > 64) {
|
252
|
-
ESP_LOGW(TAG, "Corrected MPS of EP %
|
307
|
+
ESP_LOGW(TAG, "Corrected MPS of EP 0x%02X from %u to 64", static_cast<uint8_t>(ep->bEndpointAddress & 0xFF),
|
308
|
+
ep->wMaxPacketSize);
|
253
309
|
ep_mutable->wMaxPacketSize = 64;
|
254
310
|
}
|
255
311
|
}
|
@@ -266,13 +322,13 @@ void USBUartTypeCdcAcm::on_connected() {
|
|
266
322
|
for (auto *channel : this->channels_) {
|
267
323
|
if (i == cdc_devs.size()) {
|
268
324
|
ESP_LOGE(TAG, "No configuration found for channel %d", channel->index_);
|
269
|
-
this->status_set_warning(
|
325
|
+
this->status_set_warning("No configuration found for channel");
|
270
326
|
break;
|
271
327
|
}
|
272
328
|
channel->cdc_dev_ = cdc_devs[i++];
|
273
329
|
fix_mps(channel->cdc_dev_.in_ep);
|
274
330
|
fix_mps(channel->cdc_dev_.out_ep);
|
275
|
-
channel->initialised_
|
331
|
+
channel->initialised_.store(true);
|
276
332
|
auto err =
|
277
333
|
usb_host_interface_claim(this->handle_, this->device_handle_, channel->cdc_dev_.bulk_interface_number, 0);
|
278
334
|
if (err != ESP_OK) {
|
@@ -301,9 +357,9 @@ void USBUartTypeCdcAcm::on_disconnected() {
|
|
301
357
|
usb_host_endpoint_flush(this->device_handle_, channel->cdc_dev_.notify_ep->bEndpointAddress);
|
302
358
|
}
|
303
359
|
usb_host_interface_release(this->handle_, this->device_handle_, channel->cdc_dev_.bulk_interface_number);
|
304
|
-
channel->initialised_
|
305
|
-
channel->input_started_
|
306
|
-
channel->output_started_
|
360
|
+
channel->initialised_.store(false);
|
361
|
+
channel->input_started_.store(false);
|
362
|
+
channel->output_started_.store(false);
|
307
363
|
channel->input_buffer_.clear();
|
308
364
|
channel->output_buffer_.clear();
|
309
365
|
}
|
@@ -312,10 +368,10 @@ void USBUartTypeCdcAcm::on_disconnected() {
|
|
312
368
|
|
313
369
|
void USBUartTypeCdcAcm::enable_channels() {
|
314
370
|
for (auto *channel : this->channels_) {
|
315
|
-
if (!channel->initialised_)
|
371
|
+
if (!channel->initialised_.load())
|
316
372
|
continue;
|
317
|
-
channel->input_started_
|
318
|
-
channel->output_started_
|
373
|
+
channel->input_started_.store(false);
|
374
|
+
channel->output_started_.store(false);
|
319
375
|
this->start_input(channel);
|
320
376
|
}
|
321
377
|
}
|
@@ -1,15 +1,19 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
|
-
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
3
|
+
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32P4)
|
4
4
|
#include "esphome/core/component.h"
|
5
5
|
#include "esphome/core/helpers.h"
|
6
6
|
#include "esphome/components/uart/uart_component.h"
|
7
7
|
#include "esphome/components/usb_host/usb_host.h"
|
8
|
+
#include "esphome/core/lock_free_queue.h"
|
9
|
+
#include "esphome/core/event_pool.h"
|
10
|
+
#include <atomic>
|
8
11
|
|
9
12
|
namespace esphome {
|
10
13
|
namespace usb_uart {
|
11
14
|
class USBUartTypeCdcAcm;
|
12
15
|
class USBUartComponent;
|
16
|
+
class USBUartChannel;
|
13
17
|
|
14
18
|
static const char *const TAG = "usb_uart";
|
15
19
|
|
@@ -68,6 +72,17 @@ class RingBuffer {
|
|
68
72
|
uint8_t *buffer_;
|
69
73
|
};
|
70
74
|
|
75
|
+
// Structure for queuing received USB data chunks
|
76
|
+
struct UsbDataChunk {
|
77
|
+
static constexpr size_t MAX_CHUNK_SIZE = 64; // USB packet size
|
78
|
+
uint8_t data[MAX_CHUNK_SIZE];
|
79
|
+
uint8_t length; // Max 64 bytes, so uint8_t is sufficient
|
80
|
+
USBUartChannel *channel;
|
81
|
+
|
82
|
+
// Required for EventPool - no cleanup needed for POD types
|
83
|
+
void release() {}
|
84
|
+
};
|
85
|
+
|
71
86
|
class USBUartChannel : public uart::UARTComponent, public Parented<USBUartComponent> {
|
72
87
|
friend class USBUartComponent;
|
73
88
|
friend class USBUartTypeCdcAcm;
|
@@ -90,16 +105,20 @@ class USBUartChannel : public uart::UARTComponent, public Parented<USBUartCompon
|
|
90
105
|
void set_dummy_receiver(bool dummy_receiver) { this->dummy_receiver_ = dummy_receiver; }
|
91
106
|
|
92
107
|
protected:
|
93
|
-
|
108
|
+
// Larger structures first for better alignment
|
94
109
|
RingBuffer input_buffer_;
|
95
110
|
RingBuffer output_buffer_;
|
96
|
-
UARTParityOptions parity_{UART_CONFIG_PARITY_NONE};
|
97
|
-
bool input_started_{true};
|
98
|
-
bool output_started_{true};
|
99
111
|
CdcEps cdc_dev_{};
|
112
|
+
// Enum (likely 4 bytes)
|
113
|
+
UARTParityOptions parity_{UART_CONFIG_PARITY_NONE};
|
114
|
+
// Group atomics together (each 1 byte)
|
115
|
+
std::atomic<bool> input_started_{true};
|
116
|
+
std::atomic<bool> output_started_{true};
|
117
|
+
std::atomic<bool> initialised_{false};
|
118
|
+
// Group regular bytes together to minimize padding
|
119
|
+
const uint8_t index_;
|
100
120
|
bool debug_{};
|
101
121
|
bool dummy_receiver_{};
|
102
|
-
bool initialised_{};
|
103
122
|
};
|
104
123
|
|
105
124
|
class USBUartComponent : public usb_host::USBClient {
|
@@ -115,6 +134,11 @@ class USBUartComponent : public usb_host::USBClient {
|
|
115
134
|
void start_input(USBUartChannel *channel);
|
116
135
|
void start_output(USBUartChannel *channel);
|
117
136
|
|
137
|
+
// Lock-free data transfer from USB task to main loop
|
138
|
+
static constexpr int USB_DATA_QUEUE_SIZE = 32;
|
139
|
+
LockFreeQueue<UsbDataChunk, USB_DATA_QUEUE_SIZE> usb_data_queue_;
|
140
|
+
EventPool<UsbDataChunk, USB_DATA_QUEUE_SIZE> chunk_pool_;
|
141
|
+
|
118
142
|
protected:
|
119
143
|
std::vector<USBUartChannel *> channels_{};
|
120
144
|
};
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "veml7700.h"
|
2
2
|
#include "esphome/core/application.h"
|
3
3
|
#include "esphome/core/log.h"
|
4
|
+
#include <limits>
|
4
5
|
|
5
6
|
namespace esphome {
|
6
7
|
namespace veml7700 {
|
@@ -12,30 +13,30 @@ static float reduce_to_zero(float a, float b) { return (a > b) ? (a - b) : 0; }
|
|
12
13
|
|
13
14
|
template<typename T, size_t size> T get_next(const T (&array)[size], const T val) {
|
14
15
|
size_t i = 0;
|
15
|
-
size_t idx =
|
16
|
-
while (idx ==
|
16
|
+
size_t idx = std::numeric_limits<size_t>::max();
|
17
|
+
while (idx == std::numeric_limits<size_t>::max() && i < size) {
|
17
18
|
if (array[i] == val) {
|
18
19
|
idx = i;
|
19
20
|
break;
|
20
21
|
}
|
21
22
|
i++;
|
22
23
|
}
|
23
|
-
if (idx ==
|
24
|
+
if (idx == std::numeric_limits<size_t>::max() || i + 1 >= size)
|
24
25
|
return val;
|
25
26
|
return array[i + 1];
|
26
27
|
}
|
27
28
|
|
28
29
|
template<typename T, size_t size> T get_prev(const T (&array)[size], const T val) {
|
29
30
|
size_t i = size - 1;
|
30
|
-
size_t idx =
|
31
|
-
while (idx ==
|
31
|
+
size_t idx = std::numeric_limits<size_t>::max();
|
32
|
+
while (idx == std::numeric_limits<size_t>::max() && i > 0) {
|
32
33
|
if (array[i] == val) {
|
33
34
|
idx = i;
|
34
35
|
break;
|
35
36
|
}
|
36
37
|
i--;
|
37
38
|
}
|
38
|
-
if (idx ==
|
39
|
+
if (idx == std::numeric_limits<size_t>::max() || i == 0)
|
39
40
|
return val;
|
40
41
|
return array[i - 1];
|
41
42
|
}
|
@@ -2,6 +2,7 @@
|
|
2
2
|
#include "esphome/core/log.h"
|
3
3
|
#include "esphome/core/application.h"
|
4
4
|
#include "esphome/core/version.h"
|
5
|
+
#include "esphome/core/helpers.h"
|
5
6
|
|
6
7
|
namespace esphome {
|
7
8
|
namespace version {
|
@@ -12,7 +13,7 @@ void VersionTextSensor::setup() {
|
|
12
13
|
if (this->hide_timestamp_) {
|
13
14
|
this->publish_state(ESPHOME_VERSION);
|
14
15
|
} else {
|
15
|
-
this->publish_state(ESPHOME_VERSION " "
|
16
|
+
this->publish_state(str_sprintf(ESPHOME_VERSION " %s", App.get_compilation_time().c_str()));
|
16
17
|
}
|
17
18
|
}
|
18
19
|
float VersionTextSensor::get_setup_priority() const { return setup_priority::DATA; }
|
@@ -429,8 +429,9 @@ void VoiceAssistant::client_subscription(api::APIConnection *client, bool subscr
|
|
429
429
|
|
430
430
|
if (this->api_client_ != nullptr) {
|
431
431
|
ESP_LOGE(TAG, "Multiple API Clients attempting to connect to Voice Assistant");
|
432
|
-
ESP_LOGE(TAG, "Current client: %s", this->api_client_->
|
433
|
-
|
432
|
+
ESP_LOGE(TAG, "Current client: %s (%s)", this->api_client_->get_name().c_str(),
|
433
|
+
this->api_client_->get_peername().c_str());
|
434
|
+
ESP_LOGE(TAG, "New client: %s (%s)", client->get_name().c_str(), client->get_peername().c_str());
|
434
435
|
return;
|
435
436
|
}
|
436
437
|
|
@@ -2274,11 +2274,11 @@ void GDEW0154M09::clear_() {
|
|
2274
2274
|
uint32_t pixsize = this->get_buffer_length_();
|
2275
2275
|
for (uint8_t j = 0; j < 2; j++) {
|
2276
2276
|
this->command(CMD_DTM1_DATA_START_TRANS);
|
2277
|
-
for (
|
2277
|
+
for (uint32_t count = 0; count < pixsize; count++) {
|
2278
2278
|
this->data(0x00);
|
2279
2279
|
}
|
2280
2280
|
this->command(CMD_DTM2_DATA_START_TRANS2);
|
2281
|
-
for (
|
2281
|
+
for (uint32_t count = 0; count < pixsize; count++) {
|
2282
2282
|
this->data(0xff);
|
2283
2283
|
}
|
2284
2284
|
this->command(CMD_DISPLAY_REFRESH);
|
@@ -2291,11 +2291,11 @@ void HOT GDEW0154M09::display() {
|
|
2291
2291
|
this->init_internal_();
|
2292
2292
|
// "Mode 0 display" for now
|
2293
2293
|
this->command(CMD_DTM1_DATA_START_TRANS);
|
2294
|
-
for (
|
2294
|
+
for (uint32_t i = 0; i < this->get_buffer_length_(); i++) {
|
2295
2295
|
this->data(0xff);
|
2296
2296
|
}
|
2297
2297
|
this->command(CMD_DTM2_DATA_START_TRANS2); // write 'new' data to SRAM
|
2298
|
-
for (
|
2298
|
+
for (uint32_t i = 0; i < this->get_buffer_length_(); i++) {
|
2299
2299
|
this->data(this->buffer_[i]);
|
2300
2300
|
}
|
2301
2301
|
this->command(CMD_DISPLAY_REFRESH);
|
@@ -9,13 +9,12 @@
|
|
9
9
|
namespace esphome {
|
10
10
|
namespace web_server {
|
11
11
|
|
12
|
-
#ifdef
|
12
|
+
#ifdef USE_ESP32
|
13
|
+
ListEntitiesIterator::ListEntitiesIterator(const WebServer *ws, AsyncEventSource *es) : web_server_(ws), events_(es) {}
|
14
|
+
#elif USE_ARDUINO
|
13
15
|
ListEntitiesIterator::ListEntitiesIterator(const WebServer *ws, DeferredUpdateEventSource *es)
|
14
16
|
: web_server_(ws), events_(es) {}
|
15
17
|
#endif
|
16
|
-
#ifdef USE_ESP_IDF
|
17
|
-
ListEntitiesIterator::ListEntitiesIterator(const WebServer *ws, AsyncEventSource *es) : web_server_(ws), events_(es) {}
|
18
|
-
#endif
|
19
18
|
ListEntitiesIterator::~ListEntitiesIterator() {}
|
20
19
|
|
21
20
|
#ifdef USE_BINARY_SENSOR
|
@@ -5,25 +5,24 @@
|
|
5
5
|
#include "esphome/core/component.h"
|
6
6
|
#include "esphome/core/component_iterator.h"
|
7
7
|
namespace esphome {
|
8
|
-
#ifdef
|
8
|
+
#ifdef USE_ESP32
|
9
9
|
namespace web_server_idf {
|
10
10
|
class AsyncEventSource;
|
11
11
|
}
|
12
12
|
#endif
|
13
13
|
namespace web_server {
|
14
14
|
|
15
|
-
#
|
15
|
+
#if !defined(USE_ESP32) && defined(USE_ARDUINO)
|
16
16
|
class DeferredUpdateEventSource;
|
17
17
|
#endif
|
18
18
|
class WebServer;
|
19
19
|
|
20
20
|
class ListEntitiesIterator : public ComponentIterator {
|
21
21
|
public:
|
22
|
-
#ifdef
|
23
|
-
ListEntitiesIterator(const WebServer *ws, DeferredUpdateEventSource *es);
|
24
|
-
#endif
|
25
|
-
#ifdef USE_ESP_IDF
|
22
|
+
#ifdef USE_ESP32
|
26
23
|
ListEntitiesIterator(const WebServer *ws, esphome::web_server_idf::AsyncEventSource *es);
|
24
|
+
#elif defined(USE_ARDUINO)
|
25
|
+
ListEntitiesIterator(const WebServer *ws, DeferredUpdateEventSource *es);
|
27
26
|
#endif
|
28
27
|
virtual ~ListEntitiesIterator();
|
29
28
|
#ifdef USE_BINARY_SENSOR
|
@@ -90,11 +89,10 @@ class ListEntitiesIterator : public ComponentIterator {
|
|
90
89
|
|
91
90
|
protected:
|
92
91
|
const WebServer *web_server_;
|
93
|
-
#ifdef
|
94
|
-
DeferredUpdateEventSource *events_;
|
95
|
-
#endif
|
96
|
-
#ifdef USE_ESP_IDF
|
92
|
+
#ifdef USE_ESP32
|
97
93
|
esphome::web_server_idf::AsyncEventSource *events_;
|
94
|
+
#elif USE_ARDUINO
|
95
|
+
DeferredUpdateEventSource *events_;
|
98
96
|
#endif
|
99
97
|
};
|
100
98
|
|
@@ -17,6 +17,12 @@
|
|
17
17
|
#endif
|
18
18
|
#endif // USE_ARDUINO
|
19
19
|
|
20
|
+
#if USE_ESP32
|
21
|
+
using PlatformString = std::string;
|
22
|
+
#elif USE_ARDUINO
|
23
|
+
using PlatformString = String;
|
24
|
+
#endif
|
25
|
+
|
20
26
|
namespace esphome {
|
21
27
|
namespace web_server {
|
22
28
|
|
@@ -26,8 +32,8 @@ class OTARequestHandler : public AsyncWebHandler {
|
|
26
32
|
public:
|
27
33
|
OTARequestHandler(WebServerOTAComponent *parent) : parent_(parent) {}
|
28
34
|
void handleRequest(AsyncWebServerRequest *request) override;
|
29
|
-
void handleUpload(AsyncWebServerRequest *request, const
|
30
|
-
bool final) override;
|
35
|
+
void handleUpload(AsyncWebServerRequest *request, const PlatformString &filename, size_t index, uint8_t *data,
|
36
|
+
size_t len, bool final) override;
|
31
37
|
bool canHandle(AsyncWebServerRequest *request) const override {
|
32
38
|
// Check if this is an OTA update request
|
33
39
|
bool is_ota_request = request->url() == "/update" && request->method() == HTTP_POST;
|
@@ -100,7 +106,7 @@ void OTARequestHandler::ota_init_(const char *filename) {
|
|
100
106
|
this->ota_success_ = false;
|
101
107
|
}
|
102
108
|
|
103
|
-
void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const
|
109
|
+
void OTARequestHandler::handleUpload(AsyncWebServerRequest *request, const PlatformString &filename, size_t index,
|
104
110
|
uint8_t *data, size_t len, bool final) {
|
105
111
|
ota::OTAResponseTypes error_code = ota::OTA_RESPONSE_OK;
|
106
112
|
|