esphome 2025.6.3__py3-none-any.whl → 2025.7.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 +1 -3
- esphome/codegen.py +2 -0
- esphome/components/ac_dimmer/ac_dimmer.cpp +6 -6
- esphome/components/adc/__init__.py +25 -1
- esphome/components/adc/adc_sensor.h +11 -11
- esphome/components/adc/adc_sensor_common.cpp +1 -1
- esphome/components/adc/adc_sensor_esp32.cpp +16 -8
- esphome/components/ade7880/ade7880.h +0 -2
- esphome/components/ads1115/ads1115.h +0 -1
- esphome/components/ads1118/ads1118.h +0 -1
- esphome/components/ags10/ags10.h +0 -2
- esphome/components/aic3204/aic3204.h +0 -1
- esphome/components/alarm_control_panel/__init__.py +5 -2
- esphome/components/alpha3/alpha3.h +0 -1
- esphome/components/am43/cover/am43_cover.h +0 -1
- esphome/components/am43/sensor/am43_sensor.h +0 -1
- esphome/components/analog_threshold/analog_threshold_binary_sensor.h +0 -2
- esphome/components/anova/anova.cpp +5 -1
- esphome/components/anova/anova.h +0 -1
- esphome/components/apds9960/apds9960.cpp +1 -1
- esphome/components/api/__init__.py +57 -21
- esphome/components/api/api_connection.cpp +344 -539
- esphome/components/api/api_connection.h +224 -141
- esphome/components/api/api_frame_helper.cpp +91 -127
- esphome/components/api/api_frame_helper.h +64 -54
- esphome/components/api/api_pb2.cpp +1837 -9044
- esphome/components/api/api_pb2.h +532 -685
- esphome/components/api/api_pb2_dump.cpp +4432 -0
- esphome/components/api/api_pb2_service.cpp +184 -425
- esphome/components/api/api_pb2_service.h +13 -6
- esphome/components/api/api_server.cpp +131 -167
- esphome/components/api/api_server.h +38 -10
- esphome/components/api/client.py +8 -2
- esphome/components/api/custom_api_device.h +8 -0
- esphome/components/api/list_entities.cpp +37 -104
- esphome/components/api/list_entities.h +33 -23
- esphome/components/api/proto.h +532 -26
- esphome/components/api/subscribe_state.cpp +23 -29
- esphome/components/api/subscribe_state.h +26 -19
- esphome/components/api/user_services.h +2 -0
- esphome/components/as5600/as5600.h +0 -1
- esphome/components/async_tcp/__init__.py +14 -5
- esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
- esphome/components/atm90e32/atm90e32.cpp +2 -1
- esphome/components/audio/audio_decoder.cpp +1 -1
- esphome/components/audio/audio_transfer_buffer.cpp +2 -2
- esphome/components/b_parasite/b_parasite.h +0 -1
- esphome/components/bedjet/bedjet_hub.cpp +5 -1
- esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
- esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
- esphome/components/bh1750/bh1750.cpp +5 -5
- esphome/components/binary_sensor/__init__.py +82 -5
- esphome/components/binary_sensor/automation.h +19 -1
- esphome/components/binary_sensor/binary_sensor.cpp +12 -30
- esphome/components/binary_sensor/binary_sensor.h +11 -25
- esphome/components/binary_sensor/filter.cpp +29 -24
- esphome/components/binary_sensor/filter.h +20 -10
- esphome/components/ble_client/output/ble_binary_output.h +0 -1
- esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
- esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
- esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
- esphome/components/ble_client/sensor/ble_sensor.h +0 -1
- esphome/components/ble_client/switch/ble_switch.h +0 -1
- esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
- esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
- esphome/components/ble_presence/ble_presence_device.h +0 -1
- esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
- esphome/components/ble_scanner/ble_scanner.h +0 -1
- esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
- esphome/components/bme680/sensor.py +1 -1
- esphome/components/bmp581/bmp581.h +0 -2
- esphome/components/button/__init__.py +5 -2
- esphome/components/camera/__init__.py +1 -0
- esphome/components/camera/camera.cpp +22 -0
- esphome/components/camera/camera.h +80 -0
- esphome/components/canbus/__init__.py +1 -0
- esphome/components/cap1188/cap1188.h +0 -1
- esphome/components/captive_portal/__init__.py +12 -2
- esphome/components/captive_portal/captive_portal.cpp +12 -2
- esphome/components/captive_portal/captive_portal.h +5 -2
- esphome/components/ccs811/ccs811.h +0 -2
- esphome/components/climate/__init__.py +5 -2
- esphome/components/cm1106/sensor.py +2 -2
- esphome/components/const/__init__.py +2 -0
- esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
- esphome/components/copy/button/copy_button.h +0 -1
- esphome/components/copy/cover/copy_cover.h +0 -1
- esphome/components/copy/fan/copy_fan.h +0 -1
- esphome/components/copy/lock/copy_lock.h +0 -1
- esphome/components/copy/number/copy_number.h +0 -1
- esphome/components/copy/select/copy_select.h +0 -1
- esphome/components/copy/sensor/copy_sensor.h +0 -1
- esphome/components/copy/switch/copy_switch.h +0 -1
- esphome/components/copy/text/copy_text.h +0 -1
- esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
- esphome/components/cover/__init__.py +5 -2
- esphome/components/cs5460a/cs5460a.h +0 -1
- esphome/components/datetime/__init__.py +4 -2
- esphome/components/debug/__init__.py +20 -0
- esphome/components/debug/debug_esp32.cpp +2 -0
- esphome/components/deep_sleep/__init__.py +43 -9
- esphome/components/demo/__init__.py +2 -2
- esphome/components/display/display.cpp +4 -3
- esphome/components/display/display.h +0 -2
- esphome/components/display/display_buffer.cpp +1 -1
- esphome/components/ds2484/__init__.py +1 -0
- esphome/components/ds2484/ds2484.cpp +209 -0
- esphome/components/ds2484/ds2484.h +43 -0
- esphome/components/ds2484/one_wire.py +37 -0
- esphome/components/duty_time/duty_time_sensor.h +0 -1
- esphome/components/ens160_base/ens160_base.h +0 -1
- esphome/components/es7210/es7210.h +0 -1
- esphome/components/es7243e/es7243e.h +0 -1
- esphome/components/es8156/es8156.h +0 -1
- esphome/components/es8311/es8311.h +0 -1
- esphome/components/es8388/es8388.h +0 -1
- esphome/components/esp32/__init__.py +103 -135
- esphome/components/esp32/core.cpp +0 -4
- esphome/components/esp32/gpio.h +1 -1
- esphome/components/esp32/helpers.cpp +69 -0
- esphome/components/esp32_ble/ble.cpp +5 -6
- esphome/components/esp32_ble/ble.h +29 -14
- esphome/components/esp32_ble/ble_event.h +6 -6
- esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
- esphome/components/esp32_ble_client/ble_client_base.h +24 -9
- esphome/components/esp32_ble_tracker/__init__.py +2 -8
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
- esphome/components/esp32_camera/__init__.py +112 -98
- esphome/components/esp32_camera/esp32_camera.cpp +41 -31
- esphome/components/esp32_camera/esp32_camera.h +35 -30
- esphome/components/esp32_camera_web_server/__init__.py +2 -1
- esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
- esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
- esphome/components/esp32_hall/sensor.py +2 -21
- esphome/components/esp32_hosted/__init__.py +101 -0
- esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
- esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
- esphome/components/esp32_rmt/__init__.py +0 -58
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
- esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
- esphome/components/esp32_rmt_led_strip/light.py +14 -76
- esphome/components/esp32_touch/esp32_touch.h +174 -28
- esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
- esphome/components/esp32_touch/esp32_touch_v1.cpp +240 -0
- esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
- esphome/components/esp8266/__init__.py +2 -0
- esphome/components/esp8266/gpio.cpp +10 -10
- esphome/components/esp8266/helpers.cpp +31 -0
- esphome/components/esphome/ota/__init__.py +1 -0
- esphome/components/esphome/ota/ota_esphome.cpp +24 -19
- esphome/components/ethernet/__init__.py +42 -23
- esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
- esphome/components/ethernet/ethernet_component.cpp +69 -29
- esphome/components/ethernet/ethernet_component.h +18 -10
- esphome/components/event/__init__.py +5 -2
- esphome/components/ezo/ezo.h +0 -1
- esphome/components/ezo_pmp/ezo_pmp.h +0 -1
- esphome/components/fan/__init__.py +5 -2
- esphome/components/feedback/feedback_cover.h +0 -1
- esphome/components/font/__init__.py +92 -82
- esphome/components/font/font.cpp +9 -2
- esphome/components/font/font.h +20 -5
- esphome/components/fs3000/fs3000.h +0 -1
- esphome/components/gcja5/gcja5.h +0 -1
- esphome/components/gl_r01_i2c/__init__.py +0 -0
- esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
- esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
- esphome/components/gl_r01_i2c/sensor.py +36 -0
- esphome/components/gp8403/gp8403.h +0 -1
- esphome/components/gpio/binary_sensor/__init__.py +17 -0
- esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
- esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
- esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
- esphome/components/he60r/he60r.h +0 -1
- esphome/components/heatpumpir/climate.py +2 -1
- esphome/components/heatpumpir/heatpumpir.cpp +1 -0
- esphome/components/heatpumpir/heatpumpir.h +1 -0
- esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
- esphome/components/host/__init__.py +3 -1
- esphome/components/host/helpers.cpp +57 -0
- esphome/components/http_request/__init__.py +19 -1
- esphome/components/http_request/http_request.h +1 -1
- esphome/components/http_request/http_request_arduino.h +1 -0
- esphome/components/http_request/ota/ota_http_request.cpp +1 -1
- esphome/components/http_request/update/http_request_update.cpp +28 -9
- esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +3 -9
- esphome/components/hydreon_rgxx/sensor.py +1 -1
- esphome/components/i2c/__init__.py +23 -11
- esphome/components/i2c/i2c_bus.h +8 -1
- esphome/components/i2c/i2c_bus_arduino.cpp +4 -3
- esphome/components/i2c/i2c_bus_arduino.h +6 -3
- esphome/components/i2c/i2c_bus_esp_idf.h +5 -3
- esphome/components/i2c_device/i2c_device.h +0 -1
- esphome/components/i2s_audio/__init__.py +2 -10
- esphome/components/i2s_audio/i2s_audio.cpp +1 -5
- esphome/components/i2s_audio/media_player/__init__.py +2 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +2 -2
- esphome/components/iaqcore/iaqcore.h +0 -2
- esphome/components/image/__init__.py +123 -24
- esphome/components/improv_serial/improv_serial_component.cpp +0 -4
- esphome/components/ina219/ina219.cpp +7 -0
- esphome/components/ina219/ina219.h +1 -0
- esphome/components/ina260/ina260.h +0 -2
- esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h +0 -1
- esphome/components/inkplate6/display.py +15 -0
- esphome/components/inkplate6/inkplate.cpp +2 -2
- esphome/components/integration/integration_sensor.h +0 -1
- esphome/components/internal_temperature/internal_temperature.cpp +8 -27
- esphome/components/internal_temperature/sensor.py +0 -26
- esphome/components/interval/interval.h +0 -2
- esphome/components/ld2410/button/__init__.py +3 -3
- esphome/components/ld2410/button/factory_reset_button.cpp +9 -0
- esphome/components/ld2410/button/{reset_button.h → factory_reset_button.h} +2 -2
- esphome/components/ld2410/ld2410.cpp +421 -268
- esphome/components/ld2410/ld2410.h +44 -146
- esphome/components/ld2410/number/__init__.py +2 -2
- esphome/components/ld2410/sensor.py +1 -1
- esphome/components/ld2410/switch/__init__.py +1 -1
- esphome/components/ld2420/ld2420.cpp +196 -100
- esphome/components/ld2420/ld2420.h +46 -118
- esphome/components/ld2420/number/__init__.py +2 -2
- esphome/components/ld2420/sensor/__init__.py +6 -2
- esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
- esphome/components/ld2450/button/__init__.py +3 -3
- esphome/components/ld2450/button/factory_reset_button.cpp +9 -0
- esphome/components/ld2450/button/{reset_button.h → factory_reset_button.h} +2 -2
- esphome/components/ld2450/ld2450.cpp +384 -232
- esphome/components/ld2450/ld2450.h +60 -69
- esphome/components/ld2450/switch/__init__.py +1 -1
- esphome/components/ledc/ledc_output.cpp +1 -63
- esphome/components/libretiny/__init__.py +5 -3
- esphome/components/libretiny/const.py +5 -0
- esphome/components/libretiny/generate_components.py +1 -0
- esphome/components/libretiny/helpers.cpp +35 -0
- esphome/components/libretiny/lt_component.cpp +5 -3
- esphome/components/light/__init__.py +4 -2
- esphome/components/light/addressable_light.h +3 -3
- esphome/components/light/light_call.cpp +180 -243
- esphome/components/light/light_call.h +72 -20
- esphome/components/light/light_color_values.h +14 -14
- esphome/components/light/light_state.h +15 -13
- esphome/components/light/transformers.h +2 -2
- esphome/components/ln882x/__init__.py +52 -0
- esphome/components/ln882x/boards.py +285 -0
- esphome/components/lock/__init__.py +5 -2
- esphome/components/logger/__init__.py +40 -3
- esphome/components/logger/logger.cpp +47 -12
- esphome/components/logger/logger.h +80 -49
- esphome/components/logger/logger_esp32.cpp +3 -3
- esphome/components/lps22/__init__.py +0 -0
- esphome/components/lps22/lps22.cpp +75 -0
- esphome/components/lps22/lps22.h +27 -0
- esphome/components/lps22/sensor.py +58 -0
- esphome/components/ltr390/ltr390.h +0 -1
- esphome/components/ltr501/ltr501.h +0 -1
- esphome/components/ltr_als_ps/ltr_als_ps.h +0 -1
- esphome/components/lvgl/__init__.py +1 -1
- esphome/components/lvgl/schemas.py +66 -6
- esphome/components/lvgl/styles.py +24 -16
- esphome/components/lvgl/widgets/__init__.py +12 -2
- esphome/components/lvgl/widgets/lv_bar.py +40 -19
- esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +1 -1
- esphome/components/max9611/max9611.h +0 -1
- esphome/components/mcp23016/__init__.py +1 -1
- esphome/components/mcp23xxx_base/__init__.py +1 -1
- esphome/components/mcp4461/__init__.py +1 -1
- esphome/components/mcp4461/output/__init__.py +3 -2
- esphome/components/mcp9600/mcp9600.h +0 -2
- esphome/components/md5/md5.cpp +3 -3
- esphome/components/md5/md5.h +1 -6
- esphome/components/mdns/__init__.py +22 -11
- esphome/components/media_player/__init__.py +4 -3
- esphome/components/micro_wake_word/__init__.py +1 -5
- esphome/components/micro_wake_word/streaming_model.cpp +2 -2
- esphome/components/microphone/microphone.cpp +7 -9
- esphome/components/microphone/microphone.h +0 -2
- esphome/components/mipi_spi/display.py +1 -0
- esphome/components/mmc5603/mmc5603.cpp +1 -1
- esphome/components/modbus/modbus.cpp +33 -15
- esphome/components/modbus/modbus.h +9 -0
- esphome/components/modbus_controller/__init__.py +42 -10
- esphome/components/modbus_controller/modbus_controller.cpp +92 -11
- esphome/components/modbus_controller/modbus_controller.h +61 -7
- esphome/components/mopeka_pro_check/mopeka_pro_check.h +0 -1
- esphome/components/mopeka_std_check/mopeka_std_check.h +0 -1
- esphome/components/mpl3115a2/mpl3115a2.h +0 -2
- esphome/components/mqtt/__init__.py +16 -0
- esphome/components/mqtt/mqtt_backend.h +2 -1
- esphome/components/mqtt/mqtt_backend_esp32.cpp +132 -47
- esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
- esphome/components/mqtt/mqtt_client.cpp +15 -9
- esphome/components/mqtt/mqtt_client.h +8 -3
- esphome/components/ms8607/ms8607.h +0 -1
- esphome/components/neopixelbus/light.py +4 -1
- esphome/components/neopixelbus/neopixelbus_light.h +1 -1
- esphome/components/network/__init__.py +4 -1
- esphome/components/network/ip_address.h +1 -0
- esphome/components/nextion/__init__.py +16 -0
- esphome/components/nextion/base_component.py +1 -0
- esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
- esphome/components/nextion/display.py +14 -4
- esphome/components/nextion/nextion.cpp +166 -101
- esphome/components/nextion/nextion.h +84 -53
- esphome/components/nextion/nextion_commands.cpp +11 -10
- esphome/components/nextion/nextion_component.cpp +28 -28
- esphome/components/nextion/nextion_component.h +53 -18
- esphome/components/nextion/nextion_component_base.h +3 -0
- esphome/components/nextion/nextion_upload.cpp +36 -0
- esphome/components/nextion/nextion_upload_arduino.cpp +10 -35
- esphome/components/nextion/nextion_upload_idf.cpp +9 -33
- esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
- esphome/components/nextion/switch/nextion_switch.cpp +1 -1
- esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
- esphome/components/nfc/nfc.cpp +3 -22
- esphome/components/nfc/nfc.h +3 -3
- esphome/components/number/__init__.py +5 -2
- esphome/components/online_image/__init__.py +5 -0
- esphome/components/online_image/online_image.cpp +6 -2
- esphome/components/online_image/online_image.h +4 -1
- esphome/components/opentherm/opentherm.cpp +7 -12
- esphome/components/openthread/__init__.py +47 -40
- esphome/components/openthread/const.py +1 -0
- esphome/components/openthread/openthread_esp.cpp +27 -5
- esphome/components/opt3001/__init__.py +0 -0
- esphome/components/opt3001/opt3001.cpp +122 -0
- esphome/components/opt3001/opt3001.h +27 -0
- esphome/components/opt3001/sensor.py +35 -0
- esphome/components/ota/__init__.py +17 -0
- esphome/components/ota/ota_backend.h +27 -1
- esphome/components/ota/ota_backend_arduino_esp32.cpp +12 -2
- esphome/components/ota/ota_backend_arduino_esp32.h +3 -0
- esphome/components/ota/ota_backend_arduino_esp8266.cpp +18 -4
- esphome/components/ota/ota_backend_arduino_esp8266.h +3 -0
- esphome/components/ota/ota_backend_arduino_libretiny.cpp +12 -2
- esphome/components/ota/ota_backend_arduino_libretiny.h +3 -0
- esphome/components/ota/ota_backend_arduino_rp2040.cpp +9 -2
- esphome/components/ota/ota_backend_arduino_rp2040.h +3 -0
- esphome/components/ota/ota_backend_esp_idf.cpp +10 -16
- esphome/components/ota/ota_backend_esp_idf.h +1 -0
- esphome/components/packages/__init__.py +5 -2
- esphome/components/packet_transport/binary_sensor.py +61 -4
- esphome/components/packet_transport/packet_transport.cpp +34 -1
- esphome/components/packet_transport/packet_transport.h +11 -5
- esphome/components/pcf8574/__init__.py +1 -1
- esphome/components/pi4ioe5v6408/__init__.py +84 -0
- esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +171 -0
- esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +70 -0
- esphome/components/pmsa003i/pmsa003i.h +0 -1
- esphome/components/pmsx003/pmsx003.h +0 -1
- esphome/components/pn7150/pn7150.cpp +7 -7
- esphome/components/pn7150/pn7150.h +0 -1
- esphome/components/pn7160/pn7160.cpp +7 -7
- esphome/components/pn7160/pn7160.h +0 -1
- esphome/components/preferences/syncer.h +2 -0
- esphome/components/prometheus/prometheus_handler.h +1 -1
- esphome/components/psram/psram.cpp +0 -20
- esphome/components/pulse_counter/pulse_counter_sensor.h +0 -1
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +8 -4
- esphome/components/pulse_width/pulse_width.h +0 -1
- esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +0 -4
- esphome/components/pvvx_mithermometer/display/pvvx_display.h +0 -2
- esphome/components/pvvx_mithermometer/pvvx_mithermometer.h +0 -1
- esphome/components/qr_code/__init__.py +13 -10
- esphome/components/qwiic_pir/qwiic_pir.h +0 -1
- esphome/components/radon_eye_ble/radon_eye_listener.cpp +1 -1
- esphome/components/rc522/rc522.h +0 -1
- esphome/components/rdm6300/rdm6300.h +0 -2
- esphome/components/remote_base/__init__.py +7 -5
- esphome/components/remote_base/remote_base.cpp +24 -21
- esphome/components/remote_base/remote_base.h +3 -26
- esphome/components/remote_receiver/__init__.py +40 -46
- esphome/components/remote_receiver/remote_receiver.h +4 -18
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -87
- esphome/components/remote_receiver/remote_receiver_esp8266.cpp +1 -1
- esphome/components/remote_transmitter/__init__.py +42 -43
- esphome/components/remote_transmitter/remote_transmitter.h +2 -14
- esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -77
- esphome/components/resistance/resistance_sensor.h +0 -1
- esphome/components/rp2040/__init__.py +2 -0
- esphome/components/rp2040/helpers.cpp +55 -0
- esphome/components/rp2040_pio_led_strip/led_strip.cpp +2 -2
- esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -4
- esphome/components/rtttl/__init__.py +4 -4
- esphome/components/rtttl/rtttl.cpp +10 -1
- esphome/components/ruuvitag/ruuvitag.h +0 -1
- esphome/components/safe_mode/safe_mode.cpp +2 -0
- esphome/components/safe_mode/safe_mode.h +4 -1
- esphome/components/scd30/scd30.h +0 -1
- esphome/components/scd30/sensor.py +2 -2
- esphome/components/scd4x/scd4x.cpp +61 -54
- esphome/components/scd4x/scd4x.h +17 -15
- esphome/components/scd4x/sensor.py +4 -4
- esphome/components/script/script.h +0 -2
- esphome/components/sdp3x/sensor.py +1 -1
- esphome/components/select/__init__.py +5 -2
- esphome/components/sen5x/sen5x.h +0 -1
- esphome/components/senseair/senseair.h +0 -1
- esphome/components/sensor/__init__.py +4 -2
- esphome/components/sensor/filter.cpp +1 -1
- esphome/components/sensor/sensor.cpp +12 -6
- esphome/components/sensor/sensor.h +13 -5
- esphome/components/servo/servo.h +0 -1
- esphome/components/sfa30/sfa30.h +0 -1
- esphome/components/sgp30/sgp30.h +0 -1
- esphome/components/sgp4x/sgp4x.h +0 -1
- esphome/components/shelly_dimmer/stm32flash.cpp +1 -2
- esphome/components/sht4x/sht4x.h +0 -1
- esphome/components/sm300d2/sm300d2.h +0 -2
- esphome/components/smt100/sensor.py +8 -4
- esphome/components/smt100/smt100.cpp +5 -5
- esphome/components/smt100/smt100.h +3 -3
- esphome/components/sn74hc595/__init__.py +1 -1
- esphome/components/sn74hc595/sn74hc595.cpp +5 -4
- esphome/components/sntp/sntp_component.cpp +9 -3
- esphome/components/sntp/time.py +2 -0
- esphome/components/socket/__init__.py +17 -0
- esphome/components/spi/__init__.py +27 -6
- esphome/components/spi/spi.cpp +3 -2
- esphome/components/spi/spi.h +9 -3
- esphome/components/spi/spi_arduino.cpp +3 -5
- esphome/components/spi/spi_esp_idf.cpp +40 -21
- esphome/components/spi_led_strip/spi_led_strip.cpp +1 -1
- esphome/components/sps30/sps30.h +0 -1
- esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
- esphome/components/st7701s/st7701s.cpp +0 -4
- esphome/components/status/status_binary_sensor.h +0 -2
- esphome/components/substitutions/__init__.py +76 -19
- esphome/components/substitutions/jinja.py +99 -0
- esphome/components/sun/sun.cpp +3 -4
- esphome/components/switch/__init__.py +5 -2
- esphome/components/switch/binary_sensor/switch_binary_sensor.h +0 -1
- esphome/components/sx126x/__init__.py +317 -0
- esphome/components/sx126x/automation.h +62 -0
- esphome/components/sx126x/packet_transport/__init__.py +26 -0
- esphome/components/sx126x/packet_transport/sx126x_transport.cpp +26 -0
- esphome/components/sx126x/packet_transport/sx126x_transport.h +25 -0
- esphome/components/sx126x/sx126x.cpp +523 -0
- esphome/components/sx126x/sx126x.h +140 -0
- esphome/components/sx126x/sx126x_reg.h +163 -0
- esphome/components/sx127x/__init__.py +325 -0
- esphome/components/sx127x/automation.h +62 -0
- esphome/components/sx127x/packet_transport/__init__.py +26 -0
- esphome/components/sx127x/packet_transport/sx127x_transport.cpp +26 -0
- esphome/components/sx127x/packet_transport/sx127x_transport.h +25 -0
- esphome/components/sx127x/sx127x.cpp +498 -0
- esphome/components/sx127x/sx127x.h +128 -0
- esphome/components/sx127x/sx127x_reg.h +295 -0
- esphome/components/syslog/esphome_syslog.cpp +5 -3
- esphome/components/syslog/esphome_syslog.h +1 -1
- esphome/components/tca9555/__init__.py +1 -1
- esphome/components/template/binary_sensor/template_binary_sensor.cpp +1 -9
- esphome/components/text/__init__.py +5 -2
- esphome/components/text_sensor/__init__.py +5 -2
- esphome/components/thermostat/thermostat_climate.cpp +34 -31
- esphome/components/thermostat/thermostat_climate.h +43 -39
- esphome/components/time/__init__.py +16 -2
- esphome/components/time/real_time_clock.cpp +4 -0
- esphome/components/time/real_time_clock.h +5 -1
- esphome/components/tlc5971/tlc5971.cpp +4 -1
- esphome/components/tmp1075/tmp1075.h +0 -2
- esphome/components/tof10120/tof10120_sensor.h +0 -1
- esphome/components/tormatic/tormatic_cover.h +0 -1
- esphome/components/total_daily_energy/total_daily_energy.h +0 -1
- esphome/components/tsl2591/tsl2591.cpp +1 -1
- esphome/components/ttp229_bsf/ttp229_bsf.h +0 -1
- esphome/components/ttp229_lsf/ttp229_lsf.h +0 -1
- esphome/components/tx20/tx20.cpp +2 -2
- esphome/components/uart/__init__.py +18 -0
- esphome/components/uart/uart_component_esp_idf.cpp +0 -4
- esphome/components/update/__init__.py +5 -2
- esphome/components/update/update_entity.h +8 -0
- esphome/components/usb_host/__init__.py +5 -2
- esphome/components/usb_host/usb_host_client.cpp +10 -10
- esphome/components/usb_uart/cp210x.cpp +1 -1
- esphome/components/usb_uart/usb_uart.cpp +41 -44
- esphome/components/usb_uart/usb_uart.h +4 -3
- esphome/components/valve/__init__.py +5 -2
- esphome/components/vbus/vbus.h +0 -1
- esphome/components/veml3235/veml3235.h +0 -1
- esphome/components/veml7700/veml7700.h +0 -1
- esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
- esphome/components/voice_assistant/voice_assistant.cpp +4 -4
- esphome/components/watchdog/watchdog.cpp +0 -4
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
- esphome/components/web_server/__init__.py +34 -19
- esphome/components/web_server/ota/__init__.py +32 -0
- esphome/components/web_server/ota/ota_web_server.cpp +210 -0
- esphome/components/web_server/ota/ota_web_server.h +26 -0
- esphome/components/web_server/web_server.cpp +305 -427
- esphome/components/web_server/web_server.h +33 -23
- esphome/components/web_server/web_server_v1.cpp +4 -5
- esphome/components/web_server_base/__init__.py +5 -2
- esphome/components/web_server_base/web_server_base.cpp +2 -94
- esphome/components/web_server_base/web_server_base.h +5 -25
- esphome/components/web_server_idf/multipart.cpp +254 -0
- esphome/components/web_server_idf/multipart.h +86 -0
- esphome/components/web_server_idf/utils.cpp +32 -0
- esphome/components/web_server_idf/utils.h +10 -0
- esphome/components/web_server_idf/web_server_idf.cpp +162 -16
- esphome/components/web_server_idf/web_server_idf.h +11 -10
- esphome/components/wiegand/wiegand.cpp +2 -2
- esphome/components/wifi/__init__.py +18 -0
- esphome/components/wifi/wifi_component.cpp +17 -22
- esphome/components/wifi/wifi_component.h +27 -23
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
- esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
- esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
- esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
- esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
- esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
- esphome/components/wireguard/__init__.py +2 -11
- esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
- esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
- esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
- esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
- esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
- esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
- esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
- esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
- esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
- esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
- esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
- esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
- esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
- esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
- esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
- esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
- esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
- esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
- esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
- esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
- esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
- esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
- esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
- esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
- esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
- esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
- esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
- esphome/components/zyaura/zyaura.h +0 -1
- esphome/config.py +88 -22
- esphome/config_helpers.py +74 -1
- esphome/config_validation.py +12 -1
- esphome/const.py +65 -10
- esphome/core/__init__.py +18 -2
- esphome/core/application.cpp +163 -10
- esphome/core/application.h +145 -165
- esphome/core/area.h +19 -0
- esphome/core/automation.h +58 -9
- esphome/core/color.cpp +3 -5
- esphome/core/color.h +16 -16
- esphome/core/component.cpp +151 -18
- esphome/core/component.h +98 -4
- esphome/core/component_iterator.cpp +11 -9
- esphome/core/component_iterator.h +12 -10
- esphome/core/config.py +155 -6
- esphome/core/controller.cpp +4 -2
- esphome/core/controller.h +1 -1
- esphome/core/datatypes.h +2 -2
- esphome/core/defines.h +17 -2
- esphome/core/device.h +20 -0
- esphome/core/entity_base.cpp +20 -15
- esphome/core/entity_base.h +76 -0
- esphome/core/entity_helpers.py +168 -1
- esphome/core/event_pool.h +81 -0
- esphome/core/helpers.cpp +75 -230
- esphome/core/helpers.h +164 -104
- esphome/core/lock_free_queue.h +151 -0
- esphome/core/log.cpp +2 -2
- esphome/core/log.h +2 -0
- esphome/core/optional.h +5 -0
- esphome/core/ring_buffer.cpp +2 -2
- esphome/core/scheduler.cpp +275 -103
- esphome/core/scheduler.h +154 -17
- esphome/core/time.cpp +5 -5
- esphome/core/time.h +5 -5
- esphome/cpp_generator.py +17 -0
- esphome/cpp_helpers.py +0 -22
- esphome/cpp_types.py +3 -1
- esphome/dashboard/entries.py +1 -1
- esphome/dashboard/util/text.py +5 -21
- esphome/dashboard/web_server.py +9 -1
- esphome/helpers.py +47 -0
- esphome/loader.py +15 -1
- esphome/pins.py +14 -8
- esphome/wizard.py +17 -4
- esphome/writer.py +21 -3
- esphome/yaml_util.py +0 -2
- {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/METADATA +10 -9
- {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/RECORD +597 -538
- esphome/components/api/api_pb2_size.h +0 -361
- esphome/components/esp32_ble/ble_event_pool.h +0 -72
- esphome/components/esp32_ble/queue.h +0 -85
- esphome/components/esp32_hall/esp32_hall.cpp +0 -25
- esphome/components/esp32_hall/esp32_hall.h +0 -23
- esphome/components/esp32_touch/esp32_touch.cpp +0 -355
- esphome/components/ld2410/button/reset_button.cpp +0 -9
- esphome/components/ld2450/button/reset_button.cpp +0 -9
- esphome/components/openthread/tlv.py +0 -65
- /esphome/{dashboard/enum.py → enum.py} +0 -0
- {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/WHEEL +0 -0
- {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import esphome.codegen as cg
|
|
2
|
+
import esphome.config_validation as cv
|
|
3
|
+
from esphome.components import i2c, sensor
|
|
4
|
+
from esphome.const import (
|
|
5
|
+
DEVICE_CLASS_ILLUMINANCE,
|
|
6
|
+
STATE_CLASS_MEASUREMENT,
|
|
7
|
+
UNIT_LUX,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
DEPENDENCIES = ["i2c"]
|
|
11
|
+
CODEOWNERS = ["@ccutrer"]
|
|
12
|
+
|
|
13
|
+
opt3001_ns = cg.esphome_ns.namespace("opt3001")
|
|
14
|
+
|
|
15
|
+
OPT3001Sensor = opt3001_ns.class_(
|
|
16
|
+
"OPT3001Sensor", sensor.Sensor, cg.PollingComponent, i2c.I2CDevice
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
CONFIG_SCHEMA = (
|
|
20
|
+
sensor.sensor_schema(
|
|
21
|
+
OPT3001Sensor,
|
|
22
|
+
unit_of_measurement=UNIT_LUX,
|
|
23
|
+
accuracy_decimals=1,
|
|
24
|
+
device_class=DEVICE_CLASS_ILLUMINANCE,
|
|
25
|
+
state_class=STATE_CLASS_MEASUREMENT,
|
|
26
|
+
)
|
|
27
|
+
.extend(cv.polling_component_schema("60s"))
|
|
28
|
+
.extend(i2c.i2c_device_schema(0x44))
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async def to_code(config):
|
|
33
|
+
var = await sensor.new_sensor(config)
|
|
34
|
+
await cg.register_component(var, config)
|
|
35
|
+
await i2c.register_i2c_device(var, config)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from esphome import automation
|
|
2
2
|
import esphome.codegen as cg
|
|
3
|
+
from esphome.config_helpers import filter_source_files_from_platform
|
|
3
4
|
import esphome.config_validation as cv
|
|
4
5
|
from esphome.const import (
|
|
5
6
|
CONF_ESPHOME,
|
|
@@ -7,6 +8,7 @@ from esphome.const import (
|
|
|
7
8
|
CONF_OTA,
|
|
8
9
|
CONF_PLATFORM,
|
|
9
10
|
CONF_TRIGGER_ID,
|
|
11
|
+
PlatformFramework,
|
|
10
12
|
)
|
|
11
13
|
from esphome.core import CORE, coroutine_with_priority
|
|
12
14
|
|
|
@@ -120,3 +122,18 @@ async def ota_to_code(var, config):
|
|
|
120
122
|
use_state_callback = True
|
|
121
123
|
if use_state_callback:
|
|
122
124
|
cg.add_define("USE_OTA_STATE_CALLBACK")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
FILTER_SOURCE_FILES = filter_source_files_from_platform(
|
|
128
|
+
{
|
|
129
|
+
"ota_backend_arduino_esp32.cpp": {PlatformFramework.ESP32_ARDUINO},
|
|
130
|
+
"ota_backend_esp_idf.cpp": {PlatformFramework.ESP32_IDF},
|
|
131
|
+
"ota_backend_arduino_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO},
|
|
132
|
+
"ota_backend_arduino_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO},
|
|
133
|
+
"ota_backend_arduino_libretiny.cpp": {
|
|
134
|
+
PlatformFramework.BK72XX_ARDUINO,
|
|
135
|
+
PlatformFramework.RTL87XX_ARDUINO,
|
|
136
|
+
PlatformFramework.LN882X_ARDUINO,
|
|
137
|
+
},
|
|
138
|
+
}
|
|
139
|
+
)
|
|
@@ -67,7 +67,28 @@ class OTAComponent : public Component {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
protected:
|
|
70
|
-
|
|
70
|
+
/** Extended callback manager with deferred call support.
|
|
71
|
+
*
|
|
72
|
+
* This adds a call_deferred() method for thread-safe execution from other tasks.
|
|
73
|
+
*/
|
|
74
|
+
class StateCallbackManager : public CallbackManager<void(OTAState, float, uint8_t)> {
|
|
75
|
+
public:
|
|
76
|
+
StateCallbackManager(OTAComponent *component) : component_(component) {}
|
|
77
|
+
|
|
78
|
+
/** Call callbacks with deferral to main loop (for thread safety).
|
|
79
|
+
*
|
|
80
|
+
* This should be used by OTA implementations that run in separate tasks
|
|
81
|
+
* (like web_server OTA) to ensure callbacks execute in the main loop.
|
|
82
|
+
*/
|
|
83
|
+
void call_deferred(ota::OTAState state, float progress, uint8_t error) {
|
|
84
|
+
component_->defer([this, state, progress, error]() { this->call(state, progress, error); });
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private:
|
|
88
|
+
OTAComponent *component_;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
StateCallbackManager state_callback_{this};
|
|
71
92
|
#endif
|
|
72
93
|
};
|
|
73
94
|
|
|
@@ -89,6 +110,11 @@ class OTAGlobalCallback {
|
|
|
89
110
|
|
|
90
111
|
OTAGlobalCallback *get_global_ota_callback();
|
|
91
112
|
void register_ota_platform(OTAComponent *ota_caller);
|
|
113
|
+
|
|
114
|
+
// OTA implementations should use:
|
|
115
|
+
// - state_callback_.call() when already in main loop (e.g., esphome OTA)
|
|
116
|
+
// - state_callback_.call_deferred() when in separate task (e.g., web_server OTA)
|
|
117
|
+
// This ensures proper callback execution in all contexts.
|
|
92
118
|
#endif
|
|
93
119
|
std::unique_ptr<ota::OTABackend> make_ota_backend();
|
|
94
120
|
|
|
@@ -15,6 +15,11 @@ static const char *const TAG = "ota.arduino_esp32";
|
|
|
15
15
|
std::unique_ptr<ota::OTABackend> make_ota_backend() { return make_unique<ota::ArduinoESP32OTABackend>(); }
|
|
16
16
|
|
|
17
17
|
OTAResponseTypes ArduinoESP32OTABackend::begin(size_t image_size) {
|
|
18
|
+
// Handle UPDATE_SIZE_UNKNOWN (0) which is used by web server OTA
|
|
19
|
+
// where the exact firmware size is unknown due to multipart encoding
|
|
20
|
+
if (image_size == 0) {
|
|
21
|
+
image_size = UPDATE_SIZE_UNKNOWN;
|
|
22
|
+
}
|
|
18
23
|
bool ret = Update.begin(image_size, U_FLASH);
|
|
19
24
|
if (ret) {
|
|
20
25
|
return OTA_RESPONSE_OK;
|
|
@@ -29,7 +34,10 @@ OTAResponseTypes ArduinoESP32OTABackend::begin(size_t image_size) {
|
|
|
29
34
|
return OTA_RESPONSE_ERROR_UNKNOWN;
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
void ArduinoESP32OTABackend::set_update_md5(const char *md5) {
|
|
37
|
+
void ArduinoESP32OTABackend::set_update_md5(const char *md5) {
|
|
38
|
+
Update.setMD5(md5);
|
|
39
|
+
this->md5_set_ = true;
|
|
40
|
+
}
|
|
33
41
|
|
|
34
42
|
OTAResponseTypes ArduinoESP32OTABackend::write(uint8_t *data, size_t len) {
|
|
35
43
|
size_t written = Update.write(data, len);
|
|
@@ -44,7 +52,9 @@ OTAResponseTypes ArduinoESP32OTABackend::write(uint8_t *data, size_t len) {
|
|
|
44
52
|
}
|
|
45
53
|
|
|
46
54
|
OTAResponseTypes ArduinoESP32OTABackend::end() {
|
|
47
|
-
|
|
55
|
+
// Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
|
|
56
|
+
// This matches the behavior of the old web_server OTA implementation
|
|
57
|
+
if (Update.end(!this->md5_set_)) {
|
|
48
58
|
return OTA_RESPONSE_OK;
|
|
49
59
|
}
|
|
50
60
|
|
|
@@ -17,6 +17,11 @@ static const char *const TAG = "ota.arduino_esp8266";
|
|
|
17
17
|
std::unique_ptr<ota::OTABackend> make_ota_backend() { return make_unique<ota::ArduinoESP8266OTABackend>(); }
|
|
18
18
|
|
|
19
19
|
OTAResponseTypes ArduinoESP8266OTABackend::begin(size_t image_size) {
|
|
20
|
+
// Handle UPDATE_SIZE_UNKNOWN (0) by calculating available space
|
|
21
|
+
if (image_size == 0) {
|
|
22
|
+
// NOLINTNEXTLINE(readability-static-accessed-through-instance)
|
|
23
|
+
image_size = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
|
|
24
|
+
}
|
|
20
25
|
bool ret = Update.begin(image_size, U_FLASH);
|
|
21
26
|
if (ret) {
|
|
22
27
|
esp8266::preferences_prevent_write(true);
|
|
@@ -38,7 +43,10 @@ OTAResponseTypes ArduinoESP8266OTABackend::begin(size_t image_size) {
|
|
|
38
43
|
return OTA_RESPONSE_ERROR_UNKNOWN;
|
|
39
44
|
}
|
|
40
45
|
|
|
41
|
-
void ArduinoESP8266OTABackend::set_update_md5(const char *md5) {
|
|
46
|
+
void ArduinoESP8266OTABackend::set_update_md5(const char *md5) {
|
|
47
|
+
Update.setMD5(md5);
|
|
48
|
+
this->md5_set_ = true;
|
|
49
|
+
}
|
|
42
50
|
|
|
43
51
|
OTAResponseTypes ArduinoESP8266OTABackend::write(uint8_t *data, size_t len) {
|
|
44
52
|
size_t written = Update.write(data, len);
|
|
@@ -53,13 +61,19 @@ OTAResponseTypes ArduinoESP8266OTABackend::write(uint8_t *data, size_t len) {
|
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
OTAResponseTypes ArduinoESP8266OTABackend::end() {
|
|
56
|
-
|
|
64
|
+
// Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
|
|
65
|
+
// This matches the behavior of the old web_server OTA implementation
|
|
66
|
+
bool success = Update.end(!this->md5_set_);
|
|
67
|
+
|
|
68
|
+
// On ESP8266, Update.end() might return false even with error code 0
|
|
69
|
+
// Check the actual error code to determine success
|
|
70
|
+
uint8_t error = Update.getError();
|
|
71
|
+
|
|
72
|
+
if (success || error == UPDATE_ERROR_OK) {
|
|
57
73
|
return OTA_RESPONSE_OK;
|
|
58
74
|
}
|
|
59
75
|
|
|
60
|
-
uint8_t error = Update.getError();
|
|
61
76
|
ESP_LOGE(TAG, "End error: %d", error);
|
|
62
|
-
|
|
63
77
|
return OTA_RESPONSE_ERROR_UPDATE_END;
|
|
64
78
|
}
|
|
65
79
|
|
|
@@ -15,6 +15,11 @@ static const char *const TAG = "ota.arduino_libretiny";
|
|
|
15
15
|
std::unique_ptr<ota::OTABackend> make_ota_backend() { return make_unique<ota::ArduinoLibreTinyOTABackend>(); }
|
|
16
16
|
|
|
17
17
|
OTAResponseTypes ArduinoLibreTinyOTABackend::begin(size_t image_size) {
|
|
18
|
+
// Handle UPDATE_SIZE_UNKNOWN (0) which is used by web server OTA
|
|
19
|
+
// where the exact firmware size is unknown due to multipart encoding
|
|
20
|
+
if (image_size == 0) {
|
|
21
|
+
image_size = UPDATE_SIZE_UNKNOWN;
|
|
22
|
+
}
|
|
18
23
|
bool ret = Update.begin(image_size, U_FLASH);
|
|
19
24
|
if (ret) {
|
|
20
25
|
return OTA_RESPONSE_OK;
|
|
@@ -29,7 +34,10 @@ OTAResponseTypes ArduinoLibreTinyOTABackend::begin(size_t image_size) {
|
|
|
29
34
|
return OTA_RESPONSE_ERROR_UNKNOWN;
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
void ArduinoLibreTinyOTABackend::set_update_md5(const char *md5) {
|
|
37
|
+
void ArduinoLibreTinyOTABackend::set_update_md5(const char *md5) {
|
|
38
|
+
Update.setMD5(md5);
|
|
39
|
+
this->md5_set_ = true;
|
|
40
|
+
}
|
|
33
41
|
|
|
34
42
|
OTAResponseTypes ArduinoLibreTinyOTABackend::write(uint8_t *data, size_t len) {
|
|
35
43
|
size_t written = Update.write(data, len);
|
|
@@ -44,7 +52,9 @@ OTAResponseTypes ArduinoLibreTinyOTABackend::write(uint8_t *data, size_t len) {
|
|
|
44
52
|
}
|
|
45
53
|
|
|
46
54
|
OTAResponseTypes ArduinoLibreTinyOTABackend::end() {
|
|
47
|
-
|
|
55
|
+
// Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
|
|
56
|
+
// This matches the behavior of the old web_server OTA implementation
|
|
57
|
+
if (Update.end(!this->md5_set_)) {
|
|
48
58
|
return OTA_RESPONSE_OK;
|
|
49
59
|
}
|
|
50
60
|
|
|
@@ -17,6 +17,8 @@ static const char *const TAG = "ota.arduino_rp2040";
|
|
|
17
17
|
std::unique_ptr<ota::OTABackend> make_ota_backend() { return make_unique<ota::ArduinoRP2040OTABackend>(); }
|
|
18
18
|
|
|
19
19
|
OTAResponseTypes ArduinoRP2040OTABackend::begin(size_t image_size) {
|
|
20
|
+
// OTA size of 0 is not currently handled, but
|
|
21
|
+
// web_server is not supported for RP2040, so this is not an issue.
|
|
20
22
|
bool ret = Update.begin(image_size, U_FLASH);
|
|
21
23
|
if (ret) {
|
|
22
24
|
rp2040::preferences_prevent_write(true);
|
|
@@ -38,7 +40,10 @@ OTAResponseTypes ArduinoRP2040OTABackend::begin(size_t image_size) {
|
|
|
38
40
|
return OTA_RESPONSE_ERROR_UNKNOWN;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
void ArduinoRP2040OTABackend::set_update_md5(const char *md5) {
|
|
43
|
+
void ArduinoRP2040OTABackend::set_update_md5(const char *md5) {
|
|
44
|
+
Update.setMD5(md5);
|
|
45
|
+
this->md5_set_ = true;
|
|
46
|
+
}
|
|
42
47
|
|
|
43
48
|
OTAResponseTypes ArduinoRP2040OTABackend::write(uint8_t *data, size_t len) {
|
|
44
49
|
size_t written = Update.write(data, len);
|
|
@@ -53,7 +58,9 @@ OTAResponseTypes ArduinoRP2040OTABackend::write(uint8_t *data, size_t len) {
|
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
OTAResponseTypes ArduinoRP2040OTABackend::end() {
|
|
56
|
-
|
|
61
|
+
// Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
|
|
62
|
+
// This matches the behavior of the old web_server OTA implementation
|
|
63
|
+
if (Update.end(!this->md5_set_)) {
|
|
57
64
|
return OTA_RESPONSE_OK;
|
|
58
65
|
}
|
|
59
66
|
|
|
@@ -6,10 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
#include <esp_ota_ops.h>
|
|
8
8
|
#include <esp_task_wdt.h>
|
|
9
|
-
|
|
10
|
-
#if ESP_IDF_VERSION_MAJOR >= 5
|
|
11
9
|
#include <spi_flash_mmap.h>
|
|
12
|
-
#endif
|
|
13
10
|
|
|
14
11
|
namespace esphome {
|
|
15
12
|
namespace ota {
|
|
@@ -24,7 +21,6 @@ OTAResponseTypes IDFOTABackend::begin(size_t image_size) {
|
|
|
24
21
|
|
|
25
22
|
#if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15
|
|
26
23
|
// The following function takes longer than the 5 seconds timeout of WDT
|
|
27
|
-
#if ESP_IDF_VERSION_MAJOR >= 5
|
|
28
24
|
esp_task_wdt_config_t wdtc;
|
|
29
25
|
wdtc.idle_core_mask = 0;
|
|
30
26
|
#if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
|
|
@@ -36,21 +32,14 @@ OTAResponseTypes IDFOTABackend::begin(size_t image_size) {
|
|
|
36
32
|
wdtc.timeout_ms = 15000;
|
|
37
33
|
wdtc.trigger_panic = false;
|
|
38
34
|
esp_task_wdt_reconfigure(&wdtc);
|
|
39
|
-
#else
|
|
40
|
-
esp_task_wdt_init(15, false);
|
|
41
|
-
#endif
|
|
42
35
|
#endif
|
|
43
36
|
|
|
44
37
|
esp_err_t err = esp_ota_begin(this->partition_, image_size, &this->update_handle_);
|
|
45
38
|
|
|
46
39
|
#if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15
|
|
47
40
|
// Set the WDT back to the configured timeout
|
|
48
|
-
#if ESP_IDF_VERSION_MAJOR >= 5
|
|
49
41
|
wdtc.timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000;
|
|
50
42
|
esp_task_wdt_reconfigure(&wdtc);
|
|
51
|
-
#else
|
|
52
|
-
esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false);
|
|
53
|
-
#endif
|
|
54
43
|
#endif
|
|
55
44
|
|
|
56
45
|
if (err != ESP_OK) {
|
|
@@ -67,7 +56,10 @@ OTAResponseTypes IDFOTABackend::begin(size_t image_size) {
|
|
|
67
56
|
return OTA_RESPONSE_OK;
|
|
68
57
|
}
|
|
69
58
|
|
|
70
|
-
void IDFOTABackend::set_update_md5(const char *expected_md5) {
|
|
59
|
+
void IDFOTABackend::set_update_md5(const char *expected_md5) {
|
|
60
|
+
memcpy(this->expected_bin_md5_, expected_md5, 32);
|
|
61
|
+
this->md5_set_ = true;
|
|
62
|
+
}
|
|
71
63
|
|
|
72
64
|
OTAResponseTypes IDFOTABackend::write(uint8_t *data, size_t len) {
|
|
73
65
|
esp_err_t err = esp_ota_write(this->update_handle_, data, len);
|
|
@@ -84,10 +76,12 @@ OTAResponseTypes IDFOTABackend::write(uint8_t *data, size_t len) {
|
|
|
84
76
|
}
|
|
85
77
|
|
|
86
78
|
OTAResponseTypes IDFOTABackend::end() {
|
|
87
|
-
this->
|
|
88
|
-
|
|
89
|
-
this->
|
|
90
|
-
|
|
79
|
+
if (this->md5_set_) {
|
|
80
|
+
this->md5_.calculate();
|
|
81
|
+
if (!this->md5_.equals_hex(this->expected_bin_md5_)) {
|
|
82
|
+
this->abort();
|
|
83
|
+
return OTA_RESPONSE_ERROR_MD5_MISMATCH;
|
|
84
|
+
}
|
|
91
85
|
}
|
|
92
86
|
esp_err_t err = esp_ota_end(this->update_handle_);
|
|
93
87
|
this->update_handle_ = 0;
|
|
@@ -63,6 +63,7 @@ BASE_SCHEMA = cv.All(
|
|
|
63
63
|
cv.Schema(
|
|
64
64
|
{
|
|
65
65
|
cv.Required(CONF_URL): cv.url,
|
|
66
|
+
cv.Optional(CONF_PATH): cv.string,
|
|
66
67
|
cv.Optional(CONF_USERNAME): cv.string,
|
|
67
68
|
cv.Optional(CONF_PASSWORD): cv.string,
|
|
68
69
|
cv.Exclusive(CONF_FILE, CONF_FILES): validate_yaml_filename,
|
|
@@ -74,7 +75,7 @@ BASE_SCHEMA = cv.All(
|
|
|
74
75
|
{
|
|
75
76
|
cv.Required(CONF_PATH): validate_yaml_filename,
|
|
76
77
|
cv.Optional(CONF_VARS, default={}): cv.Schema(
|
|
77
|
-
{cv.string:
|
|
78
|
+
{cv.string: object}
|
|
78
79
|
),
|
|
79
80
|
}
|
|
80
81
|
),
|
|
@@ -116,6 +117,9 @@ def _process_base_package(config: dict) -> dict:
|
|
|
116
117
|
)
|
|
117
118
|
files = []
|
|
118
119
|
|
|
120
|
+
if base_path := config.get(CONF_PATH):
|
|
121
|
+
repo_dir = repo_dir / base_path
|
|
122
|
+
|
|
119
123
|
for file in config[CONF_FILES]:
|
|
120
124
|
if isinstance(file, str):
|
|
121
125
|
files.append({CONF_PATH: file, CONF_VARS: {}})
|
|
@@ -148,7 +152,6 @@ def _process_base_package(config: dict) -> dict:
|
|
|
148
152
|
raise cv.Invalid(
|
|
149
153
|
f"Current ESPHome Version is too old to use this package: {ESPHOME_VERSION} < {min_version}"
|
|
150
154
|
)
|
|
151
|
-
vars = {k: str(v) for k, v in vars.items()}
|
|
152
155
|
new_yaml = yaml_util.substitute_vars(new_yaml, vars)
|
|
153
156
|
packages[f"{filename}{idx}"] = new_yaml
|
|
154
157
|
except EsphomeError as e:
|
|
@@ -1,19 +1,76 @@
|
|
|
1
1
|
import esphome.codegen as cg
|
|
2
2
|
from esphome.components import binary_sensor
|
|
3
|
-
|
|
3
|
+
import esphome.config_validation as cv
|
|
4
|
+
from esphome.const import (
|
|
5
|
+
CONF_DATA,
|
|
6
|
+
CONF_ID,
|
|
7
|
+
CONF_NAME,
|
|
8
|
+
CONF_STATUS,
|
|
9
|
+
CONF_TYPE,
|
|
10
|
+
DEVICE_CLASS_CONNECTIVITY,
|
|
11
|
+
ENTITY_CATEGORY_DIAGNOSTIC,
|
|
12
|
+
)
|
|
13
|
+
import esphome.final_validate as fv
|
|
4
14
|
|
|
5
15
|
from . import (
|
|
16
|
+
CONF_ENCRYPTION,
|
|
17
|
+
CONF_PING_PONG_ENABLE,
|
|
6
18
|
CONF_PROVIDER,
|
|
19
|
+
CONF_PROVIDERS,
|
|
7
20
|
CONF_REMOTE_ID,
|
|
8
21
|
CONF_TRANSPORT_ID,
|
|
22
|
+
PacketTransport,
|
|
9
23
|
packet_transport_sensor_schema,
|
|
24
|
+
provider_name_validate,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
STATUS_SENSOR_SCHEMA = binary_sensor.binary_sensor_schema(
|
|
28
|
+
device_class=DEVICE_CLASS_CONNECTIVITY,
|
|
29
|
+
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
|
|
30
|
+
).extend(
|
|
31
|
+
{
|
|
32
|
+
cv.GenerateID(CONF_TRANSPORT_ID): cv.use_id(PacketTransport),
|
|
33
|
+
cv.Required(CONF_PROVIDER): provider_name_validate,
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
CONFIG_SCHEMA = cv.typed_schema(
|
|
38
|
+
{
|
|
39
|
+
CONF_DATA: packet_transport_sensor_schema(binary_sensor.binary_sensor_schema()),
|
|
40
|
+
CONF_STATUS: STATUS_SENSOR_SCHEMA,
|
|
41
|
+
},
|
|
42
|
+
key=CONF_TYPE,
|
|
43
|
+
default_type=CONF_DATA,
|
|
10
44
|
)
|
|
11
45
|
|
|
12
|
-
|
|
46
|
+
|
|
47
|
+
def _final_validate(config):
|
|
48
|
+
if config[CONF_TYPE] != CONF_STATUS:
|
|
49
|
+
# Only run this validation if a status sensor is being configured
|
|
50
|
+
return config
|
|
51
|
+
full_config = fv.full_config.get()
|
|
52
|
+
transport_path = full_config.get_path_for_id(config[CONF_TRANSPORT_ID])[:-1]
|
|
53
|
+
transport_config = full_config.get_config_for_path(transport_path)
|
|
54
|
+
if transport_config[CONF_PING_PONG_ENABLE] and any(
|
|
55
|
+
CONF_ENCRYPTION in p
|
|
56
|
+
for p in transport_config[CONF_PROVIDERS]
|
|
57
|
+
if p[CONF_NAME] == config[CONF_PROVIDER]
|
|
58
|
+
):
|
|
59
|
+
return config
|
|
60
|
+
raise cv.Invalid(
|
|
61
|
+
"Status sensor requires ping-pong to be enabled and the nominated provider to use encryption."
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
FINAL_VALIDATE_SCHEMA = _final_validate
|
|
13
66
|
|
|
14
67
|
|
|
15
68
|
async def to_code(config):
|
|
16
69
|
var = await binary_sensor.new_binary_sensor(config)
|
|
17
70
|
comp = await cg.get_variable(config[CONF_TRANSPORT_ID])
|
|
18
|
-
|
|
19
|
-
|
|
71
|
+
if config[CONF_TYPE] == CONF_STATUS:
|
|
72
|
+
cg.add(comp.set_provider_status_sensor(config[CONF_PROVIDER], var))
|
|
73
|
+
cg.add_define("USE_STATUS_SENSOR")
|
|
74
|
+
else: # CONF_DATA is default
|
|
75
|
+
remote_id = str(config.get(CONF_REMOTE_ID) or config.get(CONF_ID))
|
|
76
|
+
cg.add(comp.add_remote_binary_sensor(config[CONF_PROVIDER], remote_id, var))
|
|
@@ -314,11 +314,43 @@ void PacketTransport::send_data_(bool all) {
|
|
|
314
314
|
}
|
|
315
315
|
|
|
316
316
|
void PacketTransport::update() {
|
|
317
|
+
if (!this->ping_pong_enable_) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
317
320
|
auto now = millis() / 1000;
|
|
318
321
|
if (this->last_key_time_ + this->ping_pong_recyle_time_ < now) {
|
|
319
322
|
this->resend_ping_key_ = this->ping_pong_enable_;
|
|
323
|
+
ESP_LOGV(TAG, "Ping request, age %u", now - this->last_key_time_);
|
|
320
324
|
this->last_key_time_ = now;
|
|
321
325
|
}
|
|
326
|
+
for (const auto &provider : this->providers_) {
|
|
327
|
+
uint32_t key_response_age = now - provider.second.last_key_response_time;
|
|
328
|
+
if (key_response_age > (this->ping_pong_recyle_time_ * 2u)) {
|
|
329
|
+
#ifdef USE_STATUS_SENSOR
|
|
330
|
+
if (provider.second.status_sensor != nullptr && provider.second.status_sensor->state) {
|
|
331
|
+
ESP_LOGI(TAG, "Ping status for %s timeout at %u with age %u", provider.first.c_str(), now, key_response_age);
|
|
332
|
+
provider.second.status_sensor->publish_state(false);
|
|
333
|
+
}
|
|
334
|
+
#endif
|
|
335
|
+
#ifdef USE_SENSOR
|
|
336
|
+
for (auto &sensor : this->remote_sensors_[provider.first]) {
|
|
337
|
+
sensor.second->publish_state(NAN);
|
|
338
|
+
}
|
|
339
|
+
#endif
|
|
340
|
+
#ifdef USE_BINARY_SENSOR
|
|
341
|
+
for (auto &sensor : this->remote_binary_sensors_[provider.first]) {
|
|
342
|
+
sensor.second->invalidate_state();
|
|
343
|
+
}
|
|
344
|
+
#endif
|
|
345
|
+
} else {
|
|
346
|
+
#ifdef USE_STATUS_SENSOR
|
|
347
|
+
if (provider.second.status_sensor != nullptr && !provider.second.status_sensor->state) {
|
|
348
|
+
ESP_LOGI(TAG, "Ping status for %s restored at %u with age %u", provider.first.c_str(), now, key_response_age);
|
|
349
|
+
provider.second.status_sensor->publish_state(true);
|
|
350
|
+
}
|
|
351
|
+
#endif
|
|
352
|
+
}
|
|
353
|
+
}
|
|
322
354
|
}
|
|
323
355
|
|
|
324
356
|
void PacketTransport::add_key_(const char *name, uint32_t key) {
|
|
@@ -437,7 +469,8 @@ void PacketTransport::process_(const std::vector<uint8_t> &data) {
|
|
|
437
469
|
if (decoder.decode(PING_KEY, key) == DECODE_OK) {
|
|
438
470
|
if (key == this->ping_key_) {
|
|
439
471
|
ping_key_seen = true;
|
|
440
|
-
|
|
472
|
+
provider.last_key_response_time = millis() / 1000;
|
|
473
|
+
ESP_LOGV(TAG, "Found good ping key %X at timestamp %" PRIu32, (unsigned) key, provider.last_key_response_time);
|
|
441
474
|
} else {
|
|
442
475
|
ESP_LOGV(TAG, "Unknown ping key %X", (unsigned) key);
|
|
443
476
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
#ifdef USE_BINARY_SENSOR
|
|
9
9
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
|
10
10
|
#endif
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
#include <vector>
|
|
13
13
|
#include <map>
|
|
14
14
|
|
|
@@ -27,6 +27,10 @@ struct Provider {
|
|
|
27
27
|
std::vector<uint8_t> encryption_key;
|
|
28
28
|
const char *name;
|
|
29
29
|
uint32_t last_code[2];
|
|
30
|
+
uint32_t last_key_response_time;
|
|
31
|
+
#ifdef USE_STATUS_SENSOR
|
|
32
|
+
binary_sensor::BinarySensor *status_sensor{nullptr};
|
|
33
|
+
#endif
|
|
30
34
|
};
|
|
31
35
|
|
|
32
36
|
#ifdef USE_SENSOR
|
|
@@ -75,10 +79,7 @@ class PacketTransport : public PollingComponent {
|
|
|
75
79
|
|
|
76
80
|
void add_provider(const char *hostname) {
|
|
77
81
|
if (this->providers_.count(hostname) == 0) {
|
|
78
|
-
Provider provider;
|
|
79
|
-
provider.encryption_key = std::vector<uint8_t>{};
|
|
80
|
-
provider.last_code[0] = 0;
|
|
81
|
-
provider.last_code[1] = 0;
|
|
82
|
+
Provider provider{};
|
|
82
83
|
provider.name = hostname;
|
|
83
84
|
this->providers_[hostname] = provider;
|
|
84
85
|
#ifdef USE_SENSOR
|
|
@@ -97,6 +98,11 @@ class PacketTransport : public PollingComponent {
|
|
|
97
98
|
void set_provider_encryption(const char *name, std::vector<uint8_t> key) {
|
|
98
99
|
this->providers_[name].encryption_key = std::move(key);
|
|
99
100
|
}
|
|
101
|
+
#ifdef USE_STATUS_SENSOR
|
|
102
|
+
void set_provider_status_sensor(const char *name, binary_sensor::BinarySensor *sensor) {
|
|
103
|
+
this->providers_[name].status_sensor = sensor;
|
|
104
|
+
}
|
|
105
|
+
#endif
|
|
100
106
|
void set_platform_name(const char *name) { this->platform_name_ = name; }
|
|
101
107
|
|
|
102
108
|
protected:
|
|
@@ -53,7 +53,7 @@ PCF8574_PIN_SCHEMA = pins.gpio_base_schema(
|
|
|
53
53
|
cv.int_range(min=0, max=17),
|
|
54
54
|
modes=[CONF_INPUT, CONF_OUTPUT],
|
|
55
55
|
mode_validator=validate_mode,
|
|
56
|
-
|
|
56
|
+
invertible=True,
|
|
57
57
|
).extend(
|
|
58
58
|
{
|
|
59
59
|
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
|