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
@@ -34,11 +34,12 @@ size_t Select::size() const {
|
|
34
34
|
|
35
35
|
optional<size_t> Select::index_of(const std::string &option) const {
|
36
36
|
const auto &options = traits.get_options();
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
for (size_t i = 0; i < options.size(); i++) {
|
38
|
+
if (options[i] == option) {
|
39
|
+
return i;
|
40
|
+
}
|
40
41
|
}
|
41
|
-
return
|
42
|
+
return {};
|
42
43
|
}
|
43
44
|
|
44
45
|
optional<size_t> Select::active_index() const {
|
@@ -107,7 +107,7 @@ void SelectCall::perform() {
|
|
107
107
|
}
|
108
108
|
}
|
109
109
|
|
110
|
-
if (
|
110
|
+
if (!parent->has_option(target_value)) {
|
111
111
|
ESP_LOGW(TAG, "'%s' - Option %s is not a valid option", name, target_value.c_str());
|
112
112
|
return;
|
113
113
|
}
|
@@ -76,7 +76,8 @@ bool SensirionI2CDevice::write_command_(uint16_t command, CommandLen command_len
|
|
76
76
|
temp[raw_idx++] = data[i] >> 8;
|
77
77
|
#endif
|
78
78
|
// Use MSB first since Sensirion devices use CRC-8 with MSB first
|
79
|
-
|
79
|
+
uint8_t crc = crc8(&temp[raw_idx - 2], 2, 0xFF, CRC_POLYNOMIAL, true);
|
80
|
+
temp[raw_idx++] = crc;
|
80
81
|
}
|
81
82
|
this->last_error_ = this->write(temp, raw_idx);
|
82
83
|
return this->last_error_ == i2c::ERROR_OK;
|
@@ -74,6 +74,7 @@ from esphome.const import (
|
|
74
74
|
DEVICE_CLASS_OZONE,
|
75
75
|
DEVICE_CLASS_PH,
|
76
76
|
DEVICE_CLASS_PM1,
|
77
|
+
DEVICE_CLASS_PM4,
|
77
78
|
DEVICE_CLASS_PM10,
|
78
79
|
DEVICE_CLASS_PM25,
|
79
80
|
DEVICE_CLASS_POWER,
|
@@ -143,6 +144,7 @@ DEVICE_CLASSES = [
|
|
143
144
|
DEVICE_CLASS_PM1,
|
144
145
|
DEVICE_CLASS_PM10,
|
145
146
|
DEVICE_CLASS_PM25,
|
147
|
+
DEVICE_CLASS_PM4,
|
146
148
|
DEVICE_CLASS_POWER,
|
147
149
|
DEVICE_CLASS_POWER_FACTOR,
|
148
150
|
DEVICE_CLASS_PRECIPITATION,
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import esphome.codegen as cg
|
2
|
+
import esphome.config_validation as cv
|
3
|
+
from esphome.core import CORE
|
4
|
+
from esphome.helpers import IS_MACOS
|
5
|
+
from esphome.types import ConfigType
|
6
|
+
|
7
|
+
CODEOWNERS = ["@esphome/core"]
|
8
|
+
|
9
|
+
sha256_ns = cg.esphome_ns.namespace("sha256")
|
10
|
+
|
11
|
+
CONFIG_SCHEMA = cv.Schema({})
|
12
|
+
|
13
|
+
|
14
|
+
async def to_code(config: ConfigType) -> None:
|
15
|
+
# Add OpenSSL library for host platform
|
16
|
+
if not CORE.is_host:
|
17
|
+
return
|
18
|
+
if IS_MACOS:
|
19
|
+
# macOS needs special handling for Homebrew OpenSSL
|
20
|
+
cg.add_build_flag("-I/opt/homebrew/opt/openssl/include")
|
21
|
+
cg.add_build_flag("-L/opt/homebrew/opt/openssl/lib")
|
22
|
+
cg.add_build_flag("-lcrypto")
|
@@ -0,0 +1,116 @@
|
|
1
|
+
#include "sha256.h"
|
2
|
+
|
3
|
+
// Only compile SHA256 implementation on platforms that support it
|
4
|
+
#if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) || defined(USE_HOST)
|
5
|
+
|
6
|
+
#include "esphome/core/helpers.h"
|
7
|
+
#include <cstring>
|
8
|
+
|
9
|
+
namespace esphome::sha256 {
|
10
|
+
|
11
|
+
#if defined(USE_ESP32) || defined(USE_LIBRETINY)
|
12
|
+
|
13
|
+
// CRITICAL ESP32-S3 HARDWARE SHA ACCELERATION REQUIREMENTS:
|
14
|
+
//
|
15
|
+
// The ESP32-S3 uses hardware DMA for SHA acceleration. The mbedtls_sha256_context structure contains
|
16
|
+
// internal state that the DMA engine references. This imposes two critical constraints:
|
17
|
+
//
|
18
|
+
// 1. NO VARIABLE LENGTH ARRAYS (VLAs): VLAs corrupt the stack layout, causing the DMA engine to
|
19
|
+
// write to incorrect memory locations. This results in null pointer dereferences and crashes.
|
20
|
+
// ALWAYS use fixed-size arrays (e.g., char buf[65], not char buf[size+1]).
|
21
|
+
//
|
22
|
+
// 2. SAME STACK FRAME ONLY: The SHA256 object must be created and used entirely within the same
|
23
|
+
// function. NEVER pass the SHA256 object or HashBase pointer to another function. When the stack
|
24
|
+
// frame changes (function call/return), the DMA references become invalid and will produce
|
25
|
+
// truncated hash output (20 bytes instead of 32) or corrupt memory.
|
26
|
+
//
|
27
|
+
// CORRECT USAGE:
|
28
|
+
// void my_function() {
|
29
|
+
// sha256::SHA256 hasher; // Created locally
|
30
|
+
// hasher.init();
|
31
|
+
// hasher.add(data, len); // Any size, no chunking needed
|
32
|
+
// hasher.calculate();
|
33
|
+
// bool ok = hasher.equals_hex(expected);
|
34
|
+
// // hasher destroyed when function returns
|
35
|
+
// }
|
36
|
+
//
|
37
|
+
// INCORRECT USAGE (WILL FAIL ON ESP32-S3):
|
38
|
+
// void my_function() {
|
39
|
+
// sha256::SHA256 hasher;
|
40
|
+
// helper(&hasher); // WRONG: Passed to different stack frame
|
41
|
+
// }
|
42
|
+
// void helper(HashBase *h) {
|
43
|
+
// h->init(); // WRONG: Will produce truncated/corrupted output
|
44
|
+
// }
|
45
|
+
|
46
|
+
SHA256::~SHA256() { mbedtls_sha256_free(&this->ctx_); }
|
47
|
+
|
48
|
+
void SHA256::init() {
|
49
|
+
mbedtls_sha256_init(&this->ctx_);
|
50
|
+
mbedtls_sha256_starts(&this->ctx_, 0); // 0 = SHA256, not SHA224
|
51
|
+
}
|
52
|
+
|
53
|
+
void SHA256::add(const uint8_t *data, size_t len) { mbedtls_sha256_update(&this->ctx_, data, len); }
|
54
|
+
|
55
|
+
void SHA256::calculate() { mbedtls_sha256_finish(&this->ctx_, this->digest_); }
|
56
|
+
|
57
|
+
#elif defined(USE_ESP8266) || defined(USE_RP2040)
|
58
|
+
|
59
|
+
SHA256::~SHA256() = default;
|
60
|
+
|
61
|
+
void SHA256::init() {
|
62
|
+
br_sha256_init(&this->ctx_);
|
63
|
+
this->calculated_ = false;
|
64
|
+
}
|
65
|
+
|
66
|
+
void SHA256::add(const uint8_t *data, size_t len) { br_sha256_update(&this->ctx_, data, len); }
|
67
|
+
|
68
|
+
void SHA256::calculate() {
|
69
|
+
if (!this->calculated_) {
|
70
|
+
br_sha256_out(&this->ctx_, this->digest_);
|
71
|
+
this->calculated_ = true;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
#elif defined(USE_HOST)
|
76
|
+
|
77
|
+
SHA256::~SHA256() {
|
78
|
+
if (this->ctx_) {
|
79
|
+
EVP_MD_CTX_free(this->ctx_);
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
void SHA256::init() {
|
84
|
+
if (this->ctx_) {
|
85
|
+
EVP_MD_CTX_free(this->ctx_);
|
86
|
+
}
|
87
|
+
this->ctx_ = EVP_MD_CTX_new();
|
88
|
+
EVP_DigestInit_ex(this->ctx_, EVP_sha256(), nullptr);
|
89
|
+
this->calculated_ = false;
|
90
|
+
}
|
91
|
+
|
92
|
+
void SHA256::add(const uint8_t *data, size_t len) {
|
93
|
+
if (!this->ctx_) {
|
94
|
+
this->init();
|
95
|
+
}
|
96
|
+
EVP_DigestUpdate(this->ctx_, data, len);
|
97
|
+
}
|
98
|
+
|
99
|
+
void SHA256::calculate() {
|
100
|
+
if (!this->ctx_) {
|
101
|
+
this->init();
|
102
|
+
}
|
103
|
+
if (!this->calculated_) {
|
104
|
+
unsigned int len = 32;
|
105
|
+
EVP_DigestFinal_ex(this->ctx_, this->digest_, &len);
|
106
|
+
this->calculated_ = true;
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
#else
|
111
|
+
#error "SHA256 not supported on this platform"
|
112
|
+
#endif
|
113
|
+
|
114
|
+
} // namespace esphome::sha256
|
115
|
+
|
116
|
+
#endif // Platform check
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/core/defines.h"
|
4
|
+
|
5
|
+
// Only define SHA256 on platforms that support it
|
6
|
+
#if defined(USE_ESP32) || defined(USE_ESP8266) || defined(USE_RP2040) || defined(USE_LIBRETINY) || defined(USE_HOST)
|
7
|
+
|
8
|
+
#include <cstdint>
|
9
|
+
#include <string>
|
10
|
+
#include <memory>
|
11
|
+
#include "esphome/core/hash_base.h"
|
12
|
+
|
13
|
+
#if defined(USE_ESP32) || defined(USE_LIBRETINY)
|
14
|
+
#include "mbedtls/sha256.h"
|
15
|
+
#elif defined(USE_ESP8266) || defined(USE_RP2040)
|
16
|
+
#include <bearssl/bearssl_hash.h>
|
17
|
+
#elif defined(USE_HOST)
|
18
|
+
#include <openssl/evp.h>
|
19
|
+
#else
|
20
|
+
#error "SHA256 not supported on this platform"
|
21
|
+
#endif
|
22
|
+
|
23
|
+
namespace esphome::sha256 {
|
24
|
+
|
25
|
+
class SHA256 : public esphome::HashBase {
|
26
|
+
public:
|
27
|
+
SHA256() = default;
|
28
|
+
~SHA256() override;
|
29
|
+
|
30
|
+
void init() override;
|
31
|
+
void add(const uint8_t *data, size_t len) override;
|
32
|
+
using HashBase::add; // Bring base class overload into scope
|
33
|
+
void add(const std::string &data) { this->add((const uint8_t *) data.c_str(), data.length()); }
|
34
|
+
|
35
|
+
void calculate() override;
|
36
|
+
|
37
|
+
/// Get the size of the hash in bytes (32 for SHA256)
|
38
|
+
size_t get_size() const override { return 32; }
|
39
|
+
|
40
|
+
protected:
|
41
|
+
#if defined(USE_ESP32) || defined(USE_LIBRETINY)
|
42
|
+
// CRITICAL: The mbedtls context MUST be stack-allocated (not a pointer) for ESP32-S3 hardware SHA acceleration.
|
43
|
+
// The ESP32-S3 DMA engine references this structure's memory addresses. If the context is passed to another
|
44
|
+
// function (crossing stack frames) or if VLAs are present, the DMA operations will corrupt memory and produce
|
45
|
+
// truncated/incorrect hash results.
|
46
|
+
mbedtls_sha256_context ctx_{};
|
47
|
+
#elif defined(USE_ESP8266) || defined(USE_RP2040)
|
48
|
+
br_sha256_context ctx_{};
|
49
|
+
bool calculated_{false};
|
50
|
+
#elif defined(USE_HOST)
|
51
|
+
EVP_MD_CTX *ctx_{nullptr};
|
52
|
+
bool calculated_{false};
|
53
|
+
#else
|
54
|
+
#error "SHA256 not supported on this platform"
|
55
|
+
#endif
|
56
|
+
};
|
57
|
+
|
58
|
+
} // namespace esphome::sha256
|
59
|
+
|
60
|
+
#endif // Platform check
|
@@ -9,7 +9,7 @@
|
|
9
9
|
#include "lwip/tcp.h"
|
10
10
|
#include <cerrno>
|
11
11
|
#include <cstring>
|
12
|
-
#include <
|
12
|
+
#include <array>
|
13
13
|
|
14
14
|
#include "esphome/core/helpers.h"
|
15
15
|
#include "esphome/core/log.h"
|
@@ -50,12 +50,18 @@ class LWIPRawImpl : public Socket {
|
|
50
50
|
errno = EBADF;
|
51
51
|
return nullptr;
|
52
52
|
}
|
53
|
-
if (
|
53
|
+
if (this->accepted_socket_count_ == 0) {
|
54
54
|
errno = EWOULDBLOCK;
|
55
55
|
return nullptr;
|
56
56
|
}
|
57
|
-
|
58
|
-
accepted_sockets_
|
57
|
+
// Take from front for FIFO ordering
|
58
|
+
std::unique_ptr<LWIPRawImpl> sock = std::move(this->accepted_sockets_[0]);
|
59
|
+
// Shift remaining sockets forward
|
60
|
+
for (uint8_t i = 1; i < this->accepted_socket_count_; i++) {
|
61
|
+
this->accepted_sockets_[i - 1] = std::move(this->accepted_sockets_[i]);
|
62
|
+
}
|
63
|
+
this->accepted_socket_count_--;
|
64
|
+
LWIP_LOG("Connection accepted by application, queue size: %d", this->accepted_socket_count_);
|
59
65
|
if (addr != nullptr) {
|
60
66
|
sock->getpeername(addr, addrlen);
|
61
67
|
}
|
@@ -494,9 +500,18 @@ class LWIPRawImpl : public Socket {
|
|
494
500
|
// nothing to do here, we just don't push it to the queue
|
495
501
|
return ERR_OK;
|
496
502
|
}
|
503
|
+
// Check if we've reached the maximum accept queue size
|
504
|
+
if (this->accepted_socket_count_ >= MAX_ACCEPTED_SOCKETS) {
|
505
|
+
LWIP_LOG("Rejecting connection, queue full (%d)", this->accepted_socket_count_);
|
506
|
+
// Abort the connection when queue is full
|
507
|
+
tcp_abort(newpcb);
|
508
|
+
// Must return ERR_ABRT since we called tcp_abort()
|
509
|
+
return ERR_ABRT;
|
510
|
+
}
|
497
511
|
auto sock = make_unique<LWIPRawImpl>(family_, newpcb);
|
498
512
|
sock->init();
|
499
|
-
accepted_sockets_
|
513
|
+
this->accepted_sockets_[this->accepted_socket_count_++] = std::move(sock);
|
514
|
+
LWIP_LOG("Accepted connection, queue size: %d", this->accepted_socket_count_);
|
500
515
|
return ERR_OK;
|
501
516
|
}
|
502
517
|
void err_fn(err_t err) {
|
@@ -587,7 +602,20 @@ class LWIPRawImpl : public Socket {
|
|
587
602
|
}
|
588
603
|
|
589
604
|
struct tcp_pcb *pcb_;
|
590
|
-
|
605
|
+
// Accept queue - holds incoming connections briefly until the event loop calls accept()
|
606
|
+
// This is NOT a connection pool - just a temporary queue between LWIP callbacks and the main loop
|
607
|
+
// 3 slots is plenty since connections are pulled out quickly by the event loop
|
608
|
+
//
|
609
|
+
// Memory analysis: std::array<3> vs original std::queue implementation:
|
610
|
+
// - std::queue uses std::deque internally which on 32-bit systems needs:
|
611
|
+
// 24 bytes (deque object) + 32+ bytes (map array) + heap allocations
|
612
|
+
// Total: ~56+ bytes minimum, plus heap fragmentation
|
613
|
+
// - std::array<3>: 12 bytes fixed (3 pointers × 4 bytes)
|
614
|
+
// Saves ~44+ bytes RAM per listening socket + avoids ALL heap allocations
|
615
|
+
// Used on ESP8266 and RP2040 (platforms using LWIP_TCP implementation)
|
616
|
+
static constexpr size_t MAX_ACCEPTED_SOCKETS = 3;
|
617
|
+
std::array<std::unique_ptr<LWIPRawImpl>, MAX_ACCEPTED_SOCKETS> accepted_sockets_;
|
618
|
+
uint8_t accepted_socket_count_ = 0; // Number of sockets currently in queue
|
591
619
|
bool rx_closed_ = false;
|
592
620
|
pbuf *rx_buf_ = nullptr;
|
593
621
|
size_t rx_buf_offset_ = 0;
|
@@ -50,7 +50,7 @@ static const char *const TAG = "sonoff_d1";
|
|
50
50
|
|
51
51
|
uint8_t SonoffD1Output::calc_checksum_(const uint8_t *cmd, const size_t len) {
|
52
52
|
uint8_t crc = 0;
|
53
|
-
for (
|
53
|
+
for (size_t i = 2; i < len - 1; i++) {
|
54
54
|
crc += cmd[i];
|
55
55
|
}
|
56
56
|
return crc;
|
@@ -276,9 +276,6 @@ def get_spi_interface(index):
|
|
276
276
|
return ["&SPI", "&SPI1"][index]
|
277
277
|
if index == 0:
|
278
278
|
return "&SPI"
|
279
|
-
# Following code can't apply to C2, H2 or 8266 since they have only one SPI
|
280
|
-
if get_target_variant() in (VARIANT_ESP32S3, VARIANT_ESP32S2):
|
281
|
-
return "new SPIClass(FSPI)"
|
282
279
|
return "new SPIClass(HSPI)"
|
283
280
|
|
284
281
|
|
@@ -0,0 +1,133 @@
|
|
1
|
+
#include "split_buffer.h"
|
2
|
+
|
3
|
+
#include "esphome/core/helpers.h"
|
4
|
+
#include "esphome/core/log.h"
|
5
|
+
|
6
|
+
namespace esphome::split_buffer {
|
7
|
+
|
8
|
+
static constexpr const char *const TAG = "split_buffer";
|
9
|
+
|
10
|
+
SplitBuffer::~SplitBuffer() { this->free(); }
|
11
|
+
|
12
|
+
bool SplitBuffer::init(size_t total_length) {
|
13
|
+
this->free(); // Clean up any existing allocation
|
14
|
+
|
15
|
+
if (total_length == 0) {
|
16
|
+
return false;
|
17
|
+
}
|
18
|
+
|
19
|
+
this->total_length_ = total_length;
|
20
|
+
size_t current_buffer_size = total_length;
|
21
|
+
|
22
|
+
RAMAllocator<uint8_t *> ptr_allocator;
|
23
|
+
RAMAllocator<uint8_t> allocator;
|
24
|
+
|
25
|
+
// Try to allocate the entire buffer first
|
26
|
+
while (current_buffer_size > 0) {
|
27
|
+
// Calculate how many buffers we need of this size
|
28
|
+
size_t needed_buffers = (total_length + current_buffer_size - 1) / current_buffer_size;
|
29
|
+
|
30
|
+
// Try to allocate array of buffer pointers
|
31
|
+
uint8_t **temp_buffers = ptr_allocator.allocate(needed_buffers);
|
32
|
+
if (temp_buffers == nullptr) {
|
33
|
+
// If we can't even allocate the pointer array, don't need to continue
|
34
|
+
ESP_LOGE(TAG, "Failed to allocate pointers");
|
35
|
+
return false;
|
36
|
+
}
|
37
|
+
|
38
|
+
// Initialize all pointers to null
|
39
|
+
for (size_t i = 0; i < needed_buffers; i++) {
|
40
|
+
temp_buffers[i] = nullptr;
|
41
|
+
}
|
42
|
+
|
43
|
+
// Try to allocate all the buffers
|
44
|
+
bool allocation_success = true;
|
45
|
+
for (size_t i = 0; i < needed_buffers; i++) {
|
46
|
+
size_t this_buffer_size = current_buffer_size;
|
47
|
+
// Last buffer might be smaller if total_length is not divisible by current_buffer_size
|
48
|
+
if (i == needed_buffers - 1 && total_length % current_buffer_size != 0) {
|
49
|
+
this_buffer_size = total_length % current_buffer_size;
|
50
|
+
}
|
51
|
+
|
52
|
+
temp_buffers[i] = allocator.allocate(this_buffer_size);
|
53
|
+
if (temp_buffers[i] == nullptr) {
|
54
|
+
allocation_success = false;
|
55
|
+
break;
|
56
|
+
}
|
57
|
+
|
58
|
+
// Initialize buffer to zero
|
59
|
+
memset(temp_buffers[i], 0, this_buffer_size);
|
60
|
+
}
|
61
|
+
|
62
|
+
if (allocation_success) {
|
63
|
+
// Success! Store the result
|
64
|
+
this->buffers_ = temp_buffers;
|
65
|
+
this->buffer_count_ = needed_buffers;
|
66
|
+
this->buffer_size_ = current_buffer_size;
|
67
|
+
ESP_LOGD(TAG, "Allocated %zu * %zu bytes - %zu bytes", this->buffer_count_, this->buffer_size_,
|
68
|
+
this->total_length_);
|
69
|
+
return true;
|
70
|
+
}
|
71
|
+
|
72
|
+
// Allocation failed, clean up and try smaller buffers
|
73
|
+
for (size_t i = 0; i < needed_buffers; i++) {
|
74
|
+
if (temp_buffers[i] != nullptr) {
|
75
|
+
allocator.deallocate(temp_buffers[i], 0);
|
76
|
+
}
|
77
|
+
}
|
78
|
+
ptr_allocator.deallocate(temp_buffers, 0);
|
79
|
+
|
80
|
+
// Halve the buffer size and try again
|
81
|
+
current_buffer_size = current_buffer_size / 2;
|
82
|
+
}
|
83
|
+
|
84
|
+
ESP_LOGE(TAG, "Failed to allocate %zu bytes", total_length);
|
85
|
+
return false;
|
86
|
+
}
|
87
|
+
|
88
|
+
void SplitBuffer::free() {
|
89
|
+
if (this->buffers_ != nullptr) {
|
90
|
+
RAMAllocator<uint8_t> allocator;
|
91
|
+
for (size_t i = 0; i < this->buffer_count_; i++) {
|
92
|
+
if (this->buffers_[i] != nullptr) {
|
93
|
+
allocator.deallocate(this->buffers_[i], 0);
|
94
|
+
}
|
95
|
+
}
|
96
|
+
RAMAllocator<uint8_t *> ptr_allocator;
|
97
|
+
ptr_allocator.deallocate(this->buffers_, 0);
|
98
|
+
this->buffers_ = nullptr;
|
99
|
+
}
|
100
|
+
this->buffer_count_ = 0;
|
101
|
+
this->buffer_size_ = 0;
|
102
|
+
this->total_length_ = 0;
|
103
|
+
}
|
104
|
+
|
105
|
+
uint8_t &SplitBuffer::operator[](size_t index) {
|
106
|
+
if (index >= this->total_length_) {
|
107
|
+
ESP_LOGE(TAG, "Out of bounds - %zu >= %zu", index, this->total_length_);
|
108
|
+
// Return reference to a static dummy byte to avoid crash
|
109
|
+
static uint8_t dummy = 0;
|
110
|
+
return dummy;
|
111
|
+
}
|
112
|
+
|
113
|
+
size_t buffer_index = index / this->buffer_size_;
|
114
|
+
size_t offset_in_buffer = index - this->buffer_size_ * buffer_index;
|
115
|
+
|
116
|
+
return this->buffers_[buffer_index][offset_in_buffer];
|
117
|
+
}
|
118
|
+
|
119
|
+
const uint8_t &SplitBuffer::operator[](size_t index) const {
|
120
|
+
if (index >= this->total_length_) {
|
121
|
+
ESP_LOGE(TAG, "Out of bounds - %zu >= %zu", index, this->total_length_);
|
122
|
+
// Return reference to a static dummy byte to avoid crash
|
123
|
+
static const uint8_t DUMMY = 0;
|
124
|
+
return DUMMY;
|
125
|
+
}
|
126
|
+
|
127
|
+
size_t buffer_index = index / this->buffer_size_;
|
128
|
+
size_t offset_in_buffer = index - this->buffer_size_ * buffer_index;
|
129
|
+
|
130
|
+
return this->buffers_[buffer_index][offset_in_buffer];
|
131
|
+
}
|
132
|
+
|
133
|
+
} // namespace esphome::split_buffer
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <cstdint>
|
4
|
+
#include <cstdlib>
|
5
|
+
|
6
|
+
namespace esphome::split_buffer {
|
7
|
+
|
8
|
+
class SplitBuffer {
|
9
|
+
public:
|
10
|
+
SplitBuffer() = default;
|
11
|
+
~SplitBuffer();
|
12
|
+
|
13
|
+
// Initialize the buffer with the desired total length
|
14
|
+
bool init(size_t total_length);
|
15
|
+
|
16
|
+
// Free all allocated buffers
|
17
|
+
void free();
|
18
|
+
|
19
|
+
// Access operators
|
20
|
+
uint8_t &operator[](size_t index);
|
21
|
+
const uint8_t &operator[](size_t index) const;
|
22
|
+
|
23
|
+
// Get the total length
|
24
|
+
size_t size() const { return this->total_length_; }
|
25
|
+
|
26
|
+
// Get buffer information
|
27
|
+
size_t get_buffer_count() const { return this->buffer_count_; }
|
28
|
+
size_t get_buffer_size() const { return this->buffer_size_; }
|
29
|
+
|
30
|
+
// Check if successfully initialized
|
31
|
+
bool is_valid() const { return this->buffers_ != nullptr && this->buffer_count_ > 0; }
|
32
|
+
|
33
|
+
private:
|
34
|
+
uint8_t **buffers_{nullptr};
|
35
|
+
size_t buffer_count_{0};
|
36
|
+
size_t buffer_size_{0};
|
37
|
+
size_t total_length_{0};
|
38
|
+
};
|
39
|
+
|
40
|
+
} // namespace esphome::split_buffer
|
@@ -52,17 +52,19 @@ void SPS30Component::setup() {
|
|
52
52
|
} else {
|
53
53
|
result = this->write_command(SPS30_CMD_SET_AUTOMATIC_CLEANING_INTERVAL_SECONDS);
|
54
54
|
}
|
55
|
-
if (result) {
|
56
|
-
delay(20);
|
57
|
-
uint16_t secs[2];
|
58
|
-
if (this->read_data(secs, 2)) {
|
59
|
-
this->fan_interval_ = secs[0] << 16 | secs[1];
|
60
|
-
}
|
61
|
-
}
|
62
55
|
|
63
|
-
this->
|
64
|
-
|
65
|
-
|
56
|
+
this->set_timeout(20, [this, result]() {
|
57
|
+
if (result) {
|
58
|
+
uint16_t secs[2];
|
59
|
+
if (this->read_data(secs, 2)) {
|
60
|
+
this->fan_interval_ = secs[0] << 16 | secs[1];
|
61
|
+
}
|
62
|
+
}
|
63
|
+
this->status_clear_warning();
|
64
|
+
this->skipped_data_read_cycles_ = 0;
|
65
|
+
this->start_continuous_measurement_();
|
66
|
+
this->setup_complete_ = true;
|
67
|
+
});
|
66
68
|
});
|
67
69
|
}
|
68
70
|
|
@@ -111,6 +113,8 @@ void SPS30Component::dump_config() {
|
|
111
113
|
}
|
112
114
|
|
113
115
|
void SPS30Component::update() {
|
116
|
+
if (!this->setup_complete_)
|
117
|
+
return;
|
114
118
|
/// Check if warning flag active (sensor reconnected?)
|
115
119
|
if (this->status_has_warning()) {
|
116
120
|
ESP_LOGD(TAG, "Reconnecting");
|
esphome/components/sps30/sps30.h
CHANGED
@@ -30,9 +30,11 @@ class SPS30Component : public PollingComponent, public sensirion_common::Sensiri
|
|
30
30
|
bool start_fan_cleaning();
|
31
31
|
|
32
32
|
protected:
|
33
|
+
bool setup_complete_{false};
|
33
34
|
uint16_t raw_firmware_version_;
|
34
35
|
char serial_number_[17] = {0}; /// Terminating NULL character
|
35
36
|
uint8_t skipped_data_read_cycles_ = 0;
|
37
|
+
|
36
38
|
bool start_continuous_measurement_();
|
37
39
|
|
38
40
|
enum ErrorCode : uint8_t {
|
@@ -50,8 +50,10 @@ void HOT I2CST7567::write_display_data() {
|
|
50
50
|
|
51
51
|
static const size_t BLOCK_SIZE = 64;
|
52
52
|
for (uint8_t x = 0; x < (uint8_t) this->get_width_internal(); x += BLOCK_SIZE) {
|
53
|
+
size_t remaining = static_cast<size_t>(this->get_width_internal()) - x;
|
54
|
+
size_t chunk = remaining > BLOCK_SIZE ? BLOCK_SIZE : remaining;
|
53
55
|
this->write_register(esphome::st7567_base::ST7567_SET_START_LINE, &buffer_[y * this->get_width_internal() + x],
|
54
|
-
|
56
|
+
chunk);
|
55
57
|
}
|
56
58
|
}
|
57
59
|
}
|
@@ -176,8 +176,9 @@ void ST7789V::write_display_data() {
|
|
176
176
|
if (this->eightbitcolor_) {
|
177
177
|
uint8_t temp_buffer[TEMP_BUFFER_SIZE];
|
178
178
|
size_t temp_index = 0;
|
179
|
-
|
180
|
-
|
179
|
+
size_t width = static_cast<size_t>(this->get_width_internal());
|
180
|
+
for (size_t line = 0; line < this->get_buffer_length_(); line += width) {
|
181
|
+
for (size_t index = 0; index < width; ++index) {
|
181
182
|
auto color = display::ColorUtil::color_to_565(
|
182
183
|
display::ColorUtil::to_color(this->buffer_[index + line], display::ColorOrder::COLOR_ORDER_RGB,
|
183
184
|
display::ColorBitness::COLOR_BITNESS_332, true));
|
@@ -151,7 +151,7 @@ void StatsdComponent::send_(std::string *out) {
|
|
151
151
|
|
152
152
|
int n_bytes = this->sock_->sendto(out->c_str(), out->length(), 0, reinterpret_cast<sockaddr *>(&this->destination_),
|
153
153
|
sizeof(this->destination_));
|
154
|
-
if (n_bytes != out->length()) {
|
154
|
+
if (n_bytes != static_cast<int>(out->length())) {
|
155
155
|
ESP_LOGE(TAG, "Failed to send UDP packed (%d of %d)", n_bytes, out->length());
|
156
156
|
}
|
157
157
|
#endif
|
@@ -4,7 +4,7 @@ from esphome import core
|
|
4
4
|
from esphome.config_helpers import Extend, Remove, merge_config
|
5
5
|
import esphome.config_validation as cv
|
6
6
|
from esphome.const import CONF_SUBSTITUTIONS, VALID_SUBSTITUTIONS_CHARACTERS
|
7
|
-
from esphome.yaml_util import ESPHomeDataBase, make_data_base
|
7
|
+
from esphome.yaml_util import ESPHomeDataBase, ESPLiteralValue, make_data_base
|
8
8
|
|
9
9
|
from .jinja import Jinja, JinjaStr, TemplateError, TemplateRuntimeError, has_jinja
|
10
10
|
|
@@ -127,6 +127,8 @@ def _expand_substitutions(substitutions, value, path, jinja, ignore_missing):
|
|
127
127
|
|
128
128
|
|
129
129
|
def _substitute_item(substitutions, item, path, jinja, ignore_missing):
|
130
|
+
if isinstance(item, ESPLiteralValue):
|
131
|
+
return None # do not substitute inside literal blocks
|
130
132
|
if isinstance(item, list):
|
131
133
|
for i, it in enumerate(item):
|
132
134
|
sub = _substitute_item(substitutions, it, path + [i], jinja, ignore_missing)
|