esphome 2025.7.4__py3-none-any.whl → 2025.8.0b1__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 +189 -82
- esphome/automation.py +2 -4
- esphome/build_gen/__init__.py +0 -0
- esphome/build_gen/platformio.py +102 -0
- esphome/components/a4988/a4988.cpp +0 -1
- esphome/components/absolute_humidity/absolute_humidity.cpp +0 -2
- esphome/components/absolute_humidity/sensor.py +2 -2
- esphome/components/adc/__init__.py +123 -85
- esphome/components/adc/adc_sensor.h +98 -35
- esphome/components/adc/adc_sensor_common.cpp +10 -4
- esphome/components/adc/adc_sensor_esp32.cpp +291 -123
- esphome/components/adc/adc_sensor_esp8266.cpp +1 -4
- esphome/components/adc/adc_sensor_libretiny.cpp +1 -2
- esphome/components/adc/adc_sensor_rp2040.cpp +1 -2
- esphome/components/adc/adc_sensor_zephyr.cpp +207 -0
- esphome/components/adc/sensor.py +61 -27
- esphome/components/adc128s102/adc128s102.cpp +1 -4
- esphome/components/ade7880/sensor.py +75 -49
- esphome/components/ads1115/ads1115.cpp +0 -1
- esphome/components/ads1118/ads1118.cpp +0 -1
- esphome/components/ags10/ags10.cpp +0 -4
- esphome/components/aht10/aht10.cpp +0 -4
- esphome/components/aic3204/aic3204.cpp +0 -2
- esphome/components/airthings_wave_plus/__init__.py +1 -1
- esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +22 -4
- esphome/components/airthings_wave_plus/airthings_wave_plus.h +10 -1
- esphome/components/airthings_wave_plus/sensor.py +55 -28
- esphome/components/alarm_control_panel/__init__.py +4 -9
- esphome/components/am2315c/am2315c.cpp +0 -2
- esphome/components/am2320/am2320.cpp +0 -1
- esphome/components/animation/__init__.py +14 -11
- esphome/components/apds9306/apds9306.cpp +0 -4
- esphome/components/apds9960/apds9960.cpp +0 -1
- esphome/components/api/__init__.py +29 -4
- esphome/components/api/api_connection.cpp +378 -401
- esphome/components/api/api_connection.h +112 -56
- esphome/components/api/api_frame_helper.cpp +69 -896
- esphome/components/api/api_frame_helper.h +31 -126
- esphome/components/api/api_frame_helper_noise.cpp +583 -0
- esphome/components/api/api_frame_helper_noise.h +68 -0
- esphome/components/api/api_frame_helper_plaintext.cpp +290 -0
- esphome/components/api/api_frame_helper_plaintext.h +53 -0
- esphome/components/api/api_noise_context.h +2 -4
- esphome/components/api/api_pb2.cpp +1601 -1808
- esphome/components/api/api_pb2.h +367 -323
- esphome/components/api/api_pb2_dump.cpp +1137 -3466
- esphome/components/api/api_pb2_includes.h +34 -0
- esphome/components/api/api_pb2_service.cpp +94 -105
- esphome/components/api/api_pb2_service.h +27 -16
- esphome/components/api/api_server.cpp +18 -17
- esphome/components/api/api_server.h +8 -5
- esphome/components/api/client.py +16 -8
- esphome/components/api/custom_api_device.h +68 -14
- esphome/components/api/homeassistant_service.h +24 -19
- esphome/components/api/list_entities.cpp +3 -5
- esphome/components/api/list_entities.h +2 -4
- esphome/components/api/proto.cpp +3 -5
- esphome/components/api/proto.h +239 -274
- esphome/components/api/subscribe_state.cpp +2 -4
- esphome/components/api/subscribe_state.h +2 -4
- esphome/components/api/user_services.cpp +2 -4
- esphome/components/api/user_services.h +8 -8
- esphome/components/as3935/as3935.cpp +0 -2
- esphome/components/as3935_spi/as3935_spi.cpp +0 -2
- esphome/components/as5600/__init__.py +1 -1
- esphome/components/as5600/as5600.cpp +0 -2
- esphome/components/as5600/sensor/__init__.py +0 -1
- esphome/components/as7341/as7341.cpp +0 -1
- esphome/components/async_tcp/__init__.py +1 -1
- esphome/components/at581x/at581x.cpp +1 -1
- esphome/components/atm90e26/atm90e26.cpp +0 -1
- esphome/components/atm90e32/atm90e32.cpp +488 -118
- esphome/components/atm90e32/atm90e32.h +44 -5
- esphome/components/audio/audio.h +2 -2
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +0 -2
- esphome/components/beken_spi_led_strip/led_strip.cpp +0 -2
- esphome/components/bh1750/bh1750.cpp +0 -1
- esphome/components/binary_sensor/__init__.py +14 -12
- esphome/components/ble_client/__init__.py +4 -7
- esphome/components/bluetooth_proxy/__init__.py +40 -3
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +387 -82
- esphome/components/bluetooth_proxy/bluetooth_connection.h +16 -5
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +102 -311
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +30 -14
- esphome/components/bme280_base/bme280_base.cpp +15 -16
- esphome/components/bme680/bme680.cpp +2 -3
- esphome/components/bme680_bsec/bme680_bsec.cpp +0 -2
- esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +0 -2
- esphome/components/bmi160/bmi160.cpp +0 -1
- esphome/components/bmp085/bmp085.cpp +0 -1
- esphome/components/bmp280_base/bmp280_base.cpp +13 -14
- esphome/components/bmp3xx_base/bmp3xx_base.cpp +0 -1
- esphome/components/bmp581/bmp581.cpp +0 -2
- esphome/components/bp1658cj/bp1658cj.cpp +0 -1
- esphome/components/bp5758d/bp5758d.cpp +0 -1
- esphome/components/button/__init__.py +0 -1
- esphome/components/canbus/__init__.py +2 -3
- esphome/components/canbus/canbus.cpp +0 -1
- esphome/components/cap1188/cap1188.cpp +0 -2
- esphome/components/captive_portal/__init__.py +1 -1
- esphome/components/cd74hc4067/cd74hc4067.cpp +0 -2
- esphome/components/ch422g/ch422g.cpp +0 -1
- esphome/components/chsc6x/chsc6x_touchscreen.cpp +0 -3
- esphome/components/climate/__init__.py +0 -1
- esphome/components/climate/climate_traits.h +24 -0
- esphome/components/cm1106/cm1106.cpp +0 -1
- esphome/components/const/__init__.py +6 -0
- esphome/components/cover/__init__.py +0 -1
- esphome/components/cover/cover.cpp +9 -13
- esphome/components/cs5460a/cs5460a.cpp +0 -2
- esphome/components/cse7761/cse7761.cpp +0 -1
- esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +0 -2
- esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +0 -2
- esphome/components/dac7678/dac7678_output.cpp +0 -2
- esphome/components/dallas_temp/dallas_temp.cpp +0 -1
- esphome/components/datetime/__init__.py +0 -2
- esphome/components/debug/__init__.py +15 -1
- esphome/components/debug/debug_zephyr.cpp +281 -0
- esphome/components/debug/sensor.py +2 -1
- esphome/components/deep_sleep/deep_sleep_component.cpp +0 -1
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +20 -1
- esphome/components/dfrobot_sen0395/__init__.py +1 -2
- esphome/components/dht/dht.cpp +0 -1
- esphome/components/dht12/dht12.cpp +0 -1
- esphome/components/display/__init__.py +16 -3
- esphome/components/display_menu_base/__init__.py +1 -1
- esphome/components/dps310/dps310.cpp +0 -2
- esphome/components/ds1307/ds1307.cpp +0 -1
- esphome/components/ds2484/ds2484.cpp +0 -1
- esphome/components/duty_cycle/duty_cycle_sensor.cpp +0 -1
- esphome/components/ee895/ee895.cpp +0 -1
- esphome/components/ektf2232/touchscreen/ektf2232.cpp +0 -1
- esphome/components/emc2101/emc2101.cpp +0 -2
- esphome/components/ens160_base/ens160_base.cpp +0 -2
- esphome/components/ens210/ens210.cpp +0 -1
- esphome/components/es7210/es7210.cpp +0 -2
- esphome/components/es7243e/es7243e.cpp +0 -2
- esphome/components/es8156/es8156.cpp +0 -2
- esphome/components/es8311/es8311.cpp +0 -2
- esphome/components/es8388/es8388.cpp +0 -2
- esphome/components/esp32/__init__.py +199 -58
- esphome/components/esp32/boards.py +17 -0
- esphome/components/esp32/gpio.cpp +0 -1
- esphome/components/esp32/gpio.py +1 -2
- esphome/components/esp32/gpio_esp32_h2.py +2 -7
- esphome/components/esp32/gpio_esp32_p4.py +2 -7
- esphome/components/esp32/post_build.py.script +112 -61
- esphome/components/esp32_ble/__init__.py +40 -2
- esphome/components/esp32_ble/ble.cpp +12 -8
- esphome/components/esp32_ble/ble.h +18 -18
- esphome/components/esp32_ble/ble_advertising.cpp +5 -5
- esphome/components/esp32_ble/ble_advertising.h +7 -5
- esphome/components/esp32_ble/ble_event.h +2 -4
- esphome/components/esp32_ble/ble_scan_result.h +2 -4
- esphome/components/esp32_ble/ble_uuid.cpp +5 -5
- esphome/components/esp32_ble/ble_uuid.h +6 -5
- esphome/components/esp32_ble_beacon/__init__.py +4 -0
- esphome/components/esp32_ble_client/__init__.py +1 -1
- esphome/components/esp32_ble_client/ble_characteristic.cpp +4 -4
- esphome/components/esp32_ble_client/ble_characteristic.h +6 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +155 -104
- esphome/components/esp32_ble_client/ble_client_base.h +17 -6
- esphome/components/esp32_ble_client/ble_descriptor.h +6 -4
- esphome/components/esp32_ble_client/ble_service.cpp +4 -4
- esphome/components/esp32_ble_client/ble_service.h +6 -4
- esphome/components/esp32_ble_server/__init__.py +15 -12
- esphome/components/esp32_ble_tracker/__init__.py +79 -11
- esphome/components/esp32_ble_tracker/automation.h +4 -4
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +264 -261
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +103 -37
- esphome/components/esp32_camera/__init__.py +13 -1
- esphome/components/esp32_camera/esp32_camera.cpp +7 -2
- esphome/components/esp32_camera/esp32_camera.h +1 -0
- esphome/components/esp32_dac/esp32_dac.cpp +3 -19
- esphome/components/esp32_dac/esp32_dac.h +4 -8
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -6
- esphome/components/esp32_rmt_led_strip/light.py +1 -1
- esphome/components/esp32_touch/__init__.py +2 -3
- esphome/components/esp32_touch/esp32_touch.h +9 -6
- esphome/components/esp32_touch/esp32_touch_common.cpp +2 -0
- esphome/components/esp32_touch/esp32_touch_v1.cpp +7 -9
- esphome/components/esp32_touch/esp32_touch_v2.cpp +10 -6
- esphome/components/esp8266/__init__.py +3 -1
- esphome/components/esp8266_pwm/esp8266_pwm.cpp +0 -1
- esphome/components/esphome/ota/__init__.py +1 -2
- esphome/components/esphome/ota/ota_esphome.cpp +150 -77
- esphome/components/esphome/ota/ota_esphome.h +8 -1
- esphome/components/espnow/__init__.py +309 -0
- esphome/components/espnow/automation.h +175 -0
- esphome/components/espnow/espnow_component.cpp +468 -0
- esphome/components/espnow/espnow_component.h +183 -0
- esphome/components/espnow/espnow_err.h +19 -0
- esphome/components/espnow/espnow_packet.h +166 -0
- esphome/components/ethernet/__init__.py +7 -1
- esphome/components/ethernet/esp_eth_phy_jl1101.c +5 -0
- esphome/components/ethernet/ethernet_component.cpp +0 -1
- esphome/components/ethernet/ethernet_component.h +4 -0
- esphome/components/ethernet_info/ethernet_info_text_sensor.h +0 -3
- esphome/components/event/__init__.py +0 -1
- esphome/components/factory_reset/__init__.py +92 -0
- esphome/components/factory_reset/factory_reset.cpp +76 -0
- esphome/components/factory_reset/factory_reset.h +43 -0
- esphome/components/fan/__init__.py +0 -1
- esphome/components/fan/fan_traits.h +16 -0
- esphome/components/fastled_base/fastled_light.cpp +0 -1
- esphome/components/fastled_spi/light.py +1 -3
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +0 -2
- esphome/components/font/__init__.py +9 -1
- esphome/components/fs3000/fs3000.cpp +0 -2
- esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
- esphome/components/ft63x6/ft63x6.cpp +0 -1
- esphome/components/gdk101/gdk101.cpp +0 -1
- esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
- esphome/components/gl_r01_i2c/sensor.py +1 -1
- esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
- esphome/components/gpio/switch/gpio_switch.cpp +0 -2
- esphome/components/gpio_expander/cached_gpio.h +24 -15
- esphome/components/gps/__init__.py +6 -2
- esphome/components/gps/gps.cpp +50 -49
- esphome/components/gps/gps.h +4 -8
- esphome/components/gps/time/gps_time.cpp +3 -9
- esphome/components/gps/time/gps_time.h +4 -7
- esphome/components/graph/__init__.py +1 -1
- esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
- esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
- esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
- esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
- esphome/components/haier/climate.py +5 -10
- esphome/components/haier/haier_base.cpp +0 -1
- esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
- esphome/components/hdc1080/hdc1080.cpp +0 -2
- esphome/components/heatpumpir/climate.py +2 -2
- esphome/components/hlw8012/hlw8012.cpp +0 -1
- esphome/components/hm3301/hm3301.cpp +0 -1
- esphome/components/hmc5883l/hmc5883l.cpp +0 -1
- esphome/components/homeassistant/__init__.py +1 -0
- esphome/components/homeassistant/number/__init__.py +1 -0
- esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
- esphome/components/homeassistant/switch/__init__.py +1 -0
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
- esphome/components/honeywellabp/honeywellabp.cpp +1 -4
- esphome/components/host/__init__.py +2 -0
- esphome/components/hte501/hte501.cpp +0 -1
- esphome/components/http_request/__init__.py +2 -3
- esphome/components/http_request/http_request_idf.cpp +2 -2
- esphome/components/htu21d/htu21d.cpp +0 -2
- esphome/components/htu31d/htu31d.cpp +0 -2
- esphome/components/hx711/hx711.cpp +0 -1
- esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
- esphome/components/hydreon_rgxx/sensor.py +4 -5
- esphome/components/i2c/i2c_bus.h +1 -1
- esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
- esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
- esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
- esphome/components/i2s_audio/__init__.py +6 -5
- esphome/components/i2s_audio/i2s_audio.cpp +0 -2
- esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
- esphome/components/i2s_audio/microphone/__init__.py +4 -6
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +46 -19
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +4 -3
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
- esphome/components/ili9xxx/display.py +4 -3
- esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
- esphome/components/image/__init__.py +123 -92
- esphome/components/improv_serial/__init__.py +7 -8
- esphome/components/ina219/ina219.cpp +0 -1
- esphome/components/ina226/ina226.cpp +0 -2
- esphome/components/ina260/ina260.cpp +0 -2
- esphome/components/ina2xx_base/__init__.py +2 -5
- esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
- esphome/components/ina3221/ina3221.cpp +0 -1
- esphome/components/internal_temperature/internal_temperature.cpp +0 -2
- esphome/components/interval/interval.h +5 -9
- esphome/components/json/__init__.py +1 -1
- esphome/components/kmeteriso/kmeteriso.cpp +0 -2
- esphome/components/lc709203f/lc709203f.cpp +0 -2
- esphome/components/lcd_gpio/display.py +1 -3
- esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
- esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
- esphome/components/ld2410/__init__.py +4 -6
- esphome/components/ld2410/binary_sensor.py +4 -0
- esphome/components/ld2410/ld2410.cpp +56 -100
- esphome/components/ld2410/ld2410.h +17 -15
- esphome/components/ld2410/sensor.py +24 -10
- esphome/components/ld2412/__init__.py +46 -0
- esphome/components/ld2412/binary_sensor.py +70 -0
- esphome/components/ld2412/button/__init__.py +74 -0
- esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
- esphome/components/ld2412/button/factory_reset_button.h +18 -0
- esphome/components/ld2412/button/query_button.cpp +9 -0
- esphome/components/ld2412/button/query_button.h +18 -0
- esphome/components/ld2412/button/restart_button.cpp +9 -0
- esphome/components/ld2412/button/restart_button.h +18 -0
- esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
- esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
- esphome/components/ld2412/ld2412.cpp +861 -0
- esphome/components/ld2412/ld2412.h +141 -0
- esphome/components/ld2412/number/__init__.py +126 -0
- esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
- esphome/components/ld2412/number/gate_threshold_number.h +19 -0
- esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
- esphome/components/ld2412/number/light_threshold_number.h +18 -0
- esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
- esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
- esphome/components/ld2412/select/__init__.py +82 -0
- esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
- esphome/components/ld2412/select/baud_rate_select.h +18 -0
- esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
- esphome/components/ld2412/select/distance_resolution_select.h +18 -0
- esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
- esphome/components/ld2412/select/light_out_control_select.h +18 -0
- esphome/components/ld2412/sensor.py +124 -0
- esphome/components/ld2412/switch/__init__.py +45 -0
- esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
- esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
- esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
- esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
- esphome/components/ld2412/text_sensor.py +34 -0
- esphome/components/ld2420/ld2420.cpp +0 -1
- esphome/components/ld2450/__init__.py +3 -4
- esphome/components/ld2450/binary_sensor.py +3 -0
- esphome/components/ld2450/ld2450.cpp +77 -165
- esphome/components/ld2450/ld2450.h +26 -54
- esphome/components/ld2450/sensor.py +120 -6
- esphome/components/ld2450/text_sensor.py +5 -4
- esphome/components/ld24xx/__init__.py +1 -0
- esphome/components/ld24xx/ld24xx.h +65 -0
- esphome/components/ledc/ledc_output.cpp +0 -1
- esphome/components/libretiny/__init__.py +2 -0
- esphome/components/light/__init__.py +0 -1
- esphome/components/light/effects.py +70 -45
- esphome/components/light/light_call.cpp +101 -66
- esphome/components/light/light_color_values.h +16 -11
- esphome/components/light/light_json_schema.cpp +46 -44
- esphome/components/light/light_state.cpp +8 -11
- esphome/components/light/light_traits.h +17 -0
- esphome/components/lightwaverf/lightwaverf.cpp +0 -2
- esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
- esphome/components/lock/__init__.py +0 -1
- esphome/components/logger/__init__.py +31 -9
- esphome/components/logger/logger.cpp +12 -7
- esphome/components/logger/logger.h +25 -14
- esphome/components/logger/logger_esp32.cpp +2 -7
- esphome/components/logger/logger_esp8266.cpp +2 -4
- esphome/components/logger/logger_host.cpp +2 -4
- esphome/components/logger/logger_libretiny.cpp +2 -4
- esphome/components/logger/logger_rp2040.cpp +2 -4
- esphome/components/logger/logger_zephyr.cpp +86 -0
- esphome/components/logger/select/logger_level_select.cpp +2 -4
- esphome/components/logger/select/logger_level_select.h +2 -4
- esphome/components/logger/task_log_buffer.cpp +2 -4
- esphome/components/logger/task_log_buffer.h +2 -4
- esphome/components/lps22/sensor.py +5 -5
- esphome/components/ltr390/ltr390.cpp +0 -2
- esphome/components/ltr501/ltr501.cpp +0 -1
- esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
- esphome/components/lvgl/__init__.py +14 -13
- esphome/components/lvgl/automation.py +2 -4
- esphome/components/lvgl/defines.py +0 -2
- esphome/components/lvgl/helpers.py +1 -1
- esphome/components/lvgl/lv_validation.py +7 -4
- esphome/components/lvgl/lvgl_esphome.cpp +2 -3
- esphome/components/lvgl/styles.py +2 -2
- esphome/components/lvgl/types.py +1 -1
- esphome/components/lvgl/widgets/__init__.py +2 -2
- esphome/components/lvgl/widgets/arc.py +14 -11
- esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
- esphome/components/lvgl/widgets/qrcode.py +7 -7
- esphome/components/lvgl/widgets/spinner.py +6 -6
- esphome/components/lvgl/widgets/switch.py +2 -2
- esphome/components/lvgl/widgets/tabview.py +3 -3
- esphome/components/lvgl/widgets/tileview.py +15 -7
- esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
- esphome/components/matrix_keypad/__init__.py +4 -3
- esphome/components/max17043/max17043.cpp +0 -2
- esphome/components/max31855/max31855.cpp +1 -4
- esphome/components/max31856/max31856.cpp +0 -4
- esphome/components/max31865/max31865.cpp +0 -1
- esphome/components/max44009/max44009.cpp +0 -1
- esphome/components/max6675/max6675.cpp +1 -4
- esphome/components/max6956/max6956.cpp +0 -1
- esphome/components/max7219/max7219.cpp +0 -1
- esphome/components/max7219digit/display.py +1 -1
- esphome/components/max7219digit/max7219digit.cpp +0 -1
- esphome/components/max9611/max9611.cpp +0 -1
- esphome/components/mcp23008/__init__.py +1 -1
- esphome/components/mcp23008/mcp23008.cpp +0 -1
- esphome/components/mcp23016/mcp23016.cpp +0 -1
- esphome/components/mcp23017/__init__.py +1 -1
- esphome/components/mcp23017/mcp23017.cpp +0 -1
- esphome/components/mcp23s08/__init__.py +1 -1
- esphome/components/mcp23s08/mcp23s08.cpp +0 -1
- esphome/components/mcp23s17/__init__.py +1 -1
- esphome/components/mcp23s17/mcp23s17.cpp +0 -1
- esphome/components/mcp23x08_base/__init__.py +2 -0
- esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
- esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
- esphome/components/mcp23x17_base/__init__.py +2 -0
- esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
- esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
- esphome/components/mcp23xxx_base/__init__.py +11 -5
- esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
- esphome/components/mcp3008/mcp3008.cpp +1 -4
- esphome/components/mcp3204/mcp3204.cpp +1 -4
- esphome/components/mcp4461/mcp4461.cpp +0 -1
- esphome/components/mcp4725/mcp4725.cpp +0 -1
- esphome/components/mcp4728/mcp4728.cpp +0 -1
- esphome/components/mcp9600/mcp9600.cpp +0 -2
- esphome/components/mcp9808/mcp9808.cpp +0 -2
- esphome/components/mdns/__init__.py +3 -0
- esphome/components/mdns/mdns_component.cpp +2 -0
- esphome/components/mdns/mdns_component.h +4 -0
- esphome/components/media_player/__init__.py +40 -0
- esphome/components/media_player/automation.h +16 -0
- esphome/components/media_player/media_player.cpp +13 -0
- esphome/components/media_player/media_player.h +50 -3
- esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
- esphome/components/mics_4514/mics_4514.cpp +1 -6
- esphome/components/midea/ir_transmitter.h +4 -4
- esphome/components/mipi/__init__.py +416 -0
- esphome/components/mipi_dsi/__init__.py +5 -0
- esphome/components/mipi_dsi/display.py +233 -0
- esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
- esphome/components/mipi_dsi/mipi_dsi.h +123 -0
- esphome/components/mipi_dsi/models/__init__.py +0 -0
- esphome/components/mipi_dsi/models/guition.py +38 -0
- esphome/components/mipi_dsi/models/m5stack.py +57 -0
- esphome/components/mipi_dsi/models/waveshare.py +105 -0
- esphome/components/mipi_rgb/models/lilygo.py +0 -0
- esphome/components/mipi_spi/__init__.py +0 -9
- esphome/components/mipi_spi/display.py +220 -256
- esphome/components/mipi_spi/mipi_spi.cpp +1 -485
- esphome/components/mipi_spi/mipi_spi.h +556 -108
- esphome/components/mipi_spi/models/__init__.py +0 -65
- esphome/components/mipi_spi/models/adafruit.py +30 -0
- esphome/components/mipi_spi/models/amoled.py +41 -5
- esphome/components/mipi_spi/models/ili.py +5 -5
- esphome/components/mipi_spi/models/jc.py +1 -3
- esphome/components/mipi_spi/models/lilygo.py +1 -1
- esphome/components/mipi_spi/models/waveshare.py +16 -1
- esphome/components/mixer/speaker/__init__.py +4 -5
- esphome/components/mlx90393/sensor.py +7 -5
- esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
- esphome/components/mlx90614/mlx90614.cpp +0 -1
- esphome/components/mmc5603/mmc5603.cpp +0 -1
- esphome/components/mmc5983/mmc5983.cpp +0 -2
- esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
- esphome/components/mpr121/__init__.py +7 -6
- esphome/components/mpr121/mpr121.cpp +0 -1
- esphome/components/mpu6050/mpu6050.cpp +0 -1
- esphome/components/mpu6886/mpu6886.cpp +0 -1
- esphome/components/mqtt/__init__.py +1 -2
- esphome/components/mqtt/mqtt_button.cpp +1 -1
- esphome/components/mqtt/mqtt_client.cpp +0 -1
- esphome/components/mqtt/mqtt_component.cpp +8 -14
- esphome/components/mqtt/mqtt_component.h +0 -7
- esphome/components/mqtt/mqtt_sensor.cpp +0 -1
- esphome/components/mqtt/mqtt_sensor.h +0 -1
- esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
- esphome/components/mqtt/mqtt_text_sensor.h +0 -1
- esphome/components/ms5611/ms5611.cpp +0 -1
- esphome/components/ms8607/ms8607.cpp +0 -1
- esphome/components/msa3xx/msa3xx.cpp +0 -2
- esphome/components/my9231/my9231.cpp +0 -2
- esphome/components/nau7802/nau7802.cpp +0 -1
- esphome/components/neopixelbus/light.py +3 -0
- esphome/components/network/util.cpp +29 -0
- esphome/components/nextion/nextion.cpp +0 -1
- esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
- esphome/components/npi19/npi19.cpp +0 -2
- esphome/components/nrf52/__init__.py +223 -0
- esphome/components/nrf52/boards.py +34 -0
- esphome/components/nrf52/const.py +18 -0
- esphome/components/nrf52/gpio.py +79 -0
- esphome/components/number/__init__.py +2 -1
- esphome/components/one_wire/__init__.py +1 -2
- esphome/components/one_wire/one_wire.cpp +0 -2
- esphome/components/one_wire/one_wire.h +0 -2
- esphome/components/opentherm/hub.cpp +0 -1
- esphome/components/opentherm/number/__init__.py +2 -2
- esphome/components/openthread/__init__.py +2 -3
- esphome/components/openthread/openthread.cpp +30 -13
- esphome/components/openthread/openthread.h +3 -0
- esphome/components/openthread/openthread_esp.cpp +3 -1
- esphome/components/opt3001/sensor.py +2 -6
- esphome/components/output/__init__.py +38 -0
- esphome/components/output/automation.h +24 -0
- esphome/components/output/switch/output_switch.cpp +0 -2
- esphome/components/packages/__init__.py +1 -2
- esphome/components/packet_transport/__init__.py +4 -3
- esphome/components/pca6416a/pca6416a.cpp +0 -1
- esphome/components/pca9554/pca9554.cpp +0 -1
- esphome/components/pca9685/pca9685_output.cpp +0 -2
- esphome/components/pcf85063/pcf85063.cpp +0 -1
- esphome/components/pcf8563/pcf8563.cpp +0 -1
- esphome/components/pcf8574/pcf8574.cpp +0 -1
- esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
- esphome/components/pipsolar/sensor/__init__.py +1 -1
- esphome/components/pm2005/pm2005.cpp +0 -1
- esphome/components/pmsa003i/pmsa003i.cpp +0 -2
- esphome/components/pmwcs3/sensor.py +1 -2
- esphome/components/pn532/pn532.cpp +0 -2
- esphome/components/pn532_spi/pn532_spi.cpp +0 -2
- esphome/components/power_supply/power_supply.cpp +7 -10
- esphome/components/power_supply/power_supply.h +1 -1
- esphome/components/psram/__init__.py +2 -1
- esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
- esphome/components/pulse_counter/sensor.py +9 -6
- esphome/components/pylontech/pylontech.cpp +0 -1
- esphome/components/qmc5883l/qmc5883l.cpp +0 -1
- esphome/components/qmp6988/qmp6988.cpp +0 -2
- esphome/components/qspi_dbi/display.py +2 -3
- esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
- esphome/components/qwiic_pir/binary_sensor.py +2 -3
- esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
- esphome/components/rc522/rc522.cpp +9 -31
- esphome/components/rc522_spi/rc522_spi.cpp +0 -1
- esphome/components/remote_base/__init__.py +5 -6
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
- esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
- esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
- esphome/components/remote_transmitter/__init__.py +26 -0
- esphome/components/remote_transmitter/automation.h +18 -0
- esphome/components/remote_transmitter/remote_transmitter.h +2 -1
- esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
- esphome/components/resampler/speaker/__init__.py +4 -5
- esphome/components/rf_bridge/__init__.py +4 -8
- esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
- esphome/components/rp2040/__init__.py +3 -1
- esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
- esphome/components/rp2040_pio_led_strip/light.py +1 -2
- esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
- esphome/components/rpi_dpi_rgb/display.py +13 -15
- esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
- esphome/components/runtime_stats/__init__.py +34 -0
- esphome/components/runtime_stats/runtime_stats.cpp +102 -0
- esphome/components/runtime_stats/runtime_stats.h +132 -0
- esphome/components/scd30/scd30.cpp +0 -2
- esphome/components/scd30/sensor.py +1 -2
- esphome/components/scd4x/scd4x.cpp +0 -1
- esphome/components/scd4x/sensor.py +1 -3
- esphome/components/sdl/display.py +3 -1
- esphome/components/sdl/sdl_esphome.cpp +0 -2
- esphome/components/sdp3x/sdp3x.cpp +0 -2
- esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
- esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
- esphome/components/select/__init__.py +2 -3
- esphome/components/select/select_traits.cpp +1 -1
- esphome/components/select/select_traits.h +1 -1
- esphome/components/sen0321/sen0321.cpp +0 -1
- esphome/components/sen5x/sen5x.cpp +0 -2
- esphome/components/sensor/__init__.py +36 -4
- esphome/components/sensor/filter.cpp +49 -10
- esphome/components/sensor/filter.h +22 -7
- esphome/components/sensor/sensor.cpp +0 -1
- esphome/components/sensor/sensor.h +0 -9
- esphome/components/sfa30/sfa30.cpp +0 -4
- esphome/components/sgp30/sgp30.cpp +0 -2
- esphome/components/sgp4x/sensor.py +1 -1
- esphome/components/sgp4x/sgp4x.cpp +0 -2
- esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
- esphome/components/sht3xd/sht3xd.cpp +0 -2
- esphome/components/sht4x/sht4x.cpp +0 -2
- esphome/components/shtcx/shtcx.cpp +0 -1
- esphome/components/sim800l/__init__.py +2 -4
- esphome/components/sm16716/sm16716.cpp +0 -1
- esphome/components/sm2135/sm2135.cpp +0 -1
- esphome/components/sm2235/sm2235.cpp +0 -1
- esphome/components/sm2335/sm2335.cpp +0 -1
- esphome/components/sn74hc165/sn74hc165.cpp +0 -1
- esphome/components/sn74hc595/sn74hc595.cpp +0 -1
- esphome/components/sntp/sntp_component.cpp +0 -1
- esphome/components/sound_level/sensor.py +1 -1
- esphome/components/speaker/media_player/__init__.py +21 -33
- esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
- esphome/components/spi/__init__.py +29 -13
- esphome/components/spi/spi.cpp +0 -2
- esphome/components/spi_device/spi_device.cpp +1 -4
- esphome/components/sprinkler/__init__.py +4 -4
- esphome/components/sps30/sps30.cpp +0 -1
- esphome/components/ssd1306_base/__init__.py +11 -11
- esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
- esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
- esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
- esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
- esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
- esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
- esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
- esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
- esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
- esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
- esphome/components/st7567_spi/st7567_spi.cpp +0 -1
- esphome/components/st7701s/display.py +10 -14
- esphome/components/st7701s/st7701s.cpp +0 -3
- esphome/components/st7735/st7735.cpp +0 -1
- esphome/components/st7789v/st7789v.cpp +0 -1
- esphome/components/st7920/st7920.cpp +0 -1
- esphome/components/status_led/light/status_led_light.cpp +0 -2
- esphome/components/status_led/status_led.cpp +0 -1
- esphome/components/stepper/__init__.py +2 -4
- esphome/components/sts3x/sts3x.cpp +0 -1
- esphome/components/substitutions/__init__.py +10 -16
- esphome/components/substitutions/jinja.py +24 -1
- esphome/components/sun/__init__.py +2 -3
- esphome/components/switch/__init__.py +31 -1
- esphome/components/switch/automation.h +24 -0
- esphome/components/switch/switch.cpp +8 -0
- esphome/components/switch/switch.h +8 -0
- esphome/components/sx126x/sx126x.cpp +0 -2
- esphome/components/sx127x/sx127x.cpp +0 -2
- esphome/components/sx1509/__init__.py +7 -5
- esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
- esphome/components/sx1509/sx1509.cpp +0 -2
- esphome/components/syslog/esphome_syslog.cpp +1 -1
- esphome/components/tc74/tc74.cpp +0 -1
- esphome/components/tca9548a/tca9548a.cpp +0 -1
- esphome/components/tca9555/tca9555.cpp +0 -1
- esphome/components/tcs34725/tcs34725.cpp +0 -1
- esphome/components/tee501/tee501.cpp +0 -1
- esphome/components/tem3200/tem3200.cpp +0 -2
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
- esphome/components/template/cover/template_cover.cpp +0 -1
- esphome/components/template/select/template_select.cpp +0 -1
- esphome/components/template/text/template_text.cpp +0 -2
- esphome/components/template/valve/template_valve.cpp +0 -1
- esphome/components/text/__init__.py +0 -1
- esphome/components/text/text_traits.h +2 -0
- esphome/components/text_sensor/__init__.py +2 -1
- esphome/components/text_sensor/text_sensor.cpp +0 -2
- esphome/components/text_sensor/text_sensor.h +0 -8
- esphome/components/thermostat/climate.py +4 -4
- esphome/components/time/__init__.py +7 -4
- esphome/components/time/real_time_clock.cpp +16 -3
- esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
- esphome/components/tlc5947/tlc5947.cpp +0 -2
- esphome/components/tlc5971/tlc5971.cpp +0 -2
- esphome/components/tm1621/tm1621.cpp +0 -2
- esphome/components/tm1637/tm1637.cpp +0 -2
- esphome/components/tm1638/tm1638.cpp +0 -2
- esphome/components/tm1651/__init__.py +45 -48
- esphome/components/tm1651/tm1651.cpp +213 -47
- esphome/components/tm1651/tm1651.h +37 -32
- esphome/components/tmp117/tmp117.cpp +0 -2
- esphome/components/tsl2561/tsl2561.cpp +0 -1
- esphome/components/tsl2591/tsl2591.cpp +0 -1
- esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
- esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
- esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
- esphome/components/tuya/climate/__init__.py +9 -10
- esphome/components/tuya/number/__init__.py +8 -6
- esphome/components/tx20/tx20.cpp +0 -1
- esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
- esphome/components/uart/uart_component_esp8266.cpp +0 -1
- esphome/components/uart/uart_component_esp_idf.cpp +0 -2
- esphome/components/uart/uart_component_libretiny.cpp +0 -2
- esphome/components/uart/uart_component_rp2040.cpp +0 -2
- esphome/components/udp/__init__.py +1 -1
- esphome/components/ufire_ec/sensor.py +1 -2
- esphome/components/ufire_ec/ufire_ec.cpp +0 -2
- esphome/components/ufire_ise/sensor.py +1 -2
- esphome/components/ufire_ise/ufire_ise.cpp +0 -2
- esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
- esphome/components/update/__init__.py +0 -1
- esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
- esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
- esphome/components/usb_host/usb_host_client.cpp +0 -1
- esphome/components/usb_host/usb_host_component.cpp +0 -1
- esphome/components/valve/__init__.py +0 -1
- esphome/components/veml3235/veml3235.cpp +0 -3
- esphome/components/veml7700/veml7700.cpp +0 -2
- esphome/components/version/version_text_sensor.cpp +0 -1
- esphome/components/version/version_text_sensor.h +0 -1
- esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
- esphome/components/voice_assistant/voice_assistant.cpp +9 -8
- esphome/components/web_server/__init__.py +13 -0
- esphome/components/web_server/web_server.cpp +187 -352
- esphome/components/web_server/web_server.h +61 -1
- esphome/components/web_server_base/__init__.py +1 -1
- esphome/components/web_server_base/web_server_base.cpp +2 -0
- esphome/components/web_server_base/web_server_base.h +6 -0
- esphome/components/web_server_idf/web_server_idf.cpp +10 -8
- esphome/components/web_server_idf/web_server_idf.h +2 -0
- esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
- esphome/components/weikai_spi/weikai_spi.cpp +1 -1
- esphome/components/wifi/__init__.py +8 -43
- esphome/components/wifi/wifi_component.cpp +100 -36
- esphome/components/wifi/wifi_component.h +5 -1
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
- esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
- esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
- esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
- esphome/components/wireguard/wireguard.cpp +0 -2
- esphome/components/x9c/x9c.cpp +0 -2
- esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
- esphome/components/xl9535/xl9535.cpp +0 -2
- esphome/components/zephyr/__init__.py +252 -0
- esphome/components/zephyr/const.py +16 -0
- esphome/components/zephyr/core.cpp +90 -0
- esphome/components/zephyr/gpio.cpp +120 -0
- esphome/components/zephyr/gpio.h +38 -0
- esphome/components/zephyr/pre_build.py.script +4 -0
- esphome/components/zephyr/preferences.cpp +156 -0
- esphome/components/zephyr/preferences.h +13 -0
- esphome/config.py +38 -16
- esphome/config_helpers.py +1 -2
- esphome/config_validation.py +8 -15
- esphome/const.py +26 -1
- esphome/core/__init__.py +88 -51
- esphome/core/application.cpp +75 -21
- esphome/core/application.h +106 -171
- esphome/core/color.h +10 -0
- esphome/core/component.cpp +41 -25
- esphome/core/component.h +9 -6
- esphome/core/component_iterator.cpp +61 -261
- esphome/core/component_iterator.h +15 -0
- esphome/core/config.py +26 -11
- esphome/core/defines.h +40 -2
- esphome/core/entity_base.h +18 -0
- esphome/core/entity_helpers.py +41 -6
- esphome/core/helpers.cpp +8 -15
- esphome/core/helpers.h +60 -6
- esphome/core/lock_free_queue.h +1 -1
- esphome/core/scheduler.cpp +277 -74
- esphome/core/scheduler.h +89 -27
- esphome/cpp_generator.py +2 -6
- esphome/cpp_helpers.py +1 -1
- esphome/dashboard/dashboard.py +2 -3
- esphome/dashboard/dns.py +2 -8
- esphome/dashboard/web_server.py +34 -19
- esphome/espota2.py +1 -4
- esphome/git.py +3 -1
- esphome/helpers.py +23 -4
- esphome/log.py +3 -1
- esphome/mqtt.py +3 -5
- esphome/platformio_api.py +7 -4
- esphome/types.py +12 -0
- esphome/util.py +20 -8
- esphome/voluptuous_schema.py +4 -3
- esphome/vscode.py +1 -2
- esphome/wizard.py +1 -4
- esphome/writer.py +5 -107
- esphome/yaml_util.py +7 -5
- {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/METADATA +12 -13
- {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/RECORD +753 -673
- esphome/components/mipi_spi/models/commands.py +0 -82
- /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
- {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/WHEEL +0 -0
- {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/top_level.txt +0 -0
esphome/core/scheduler.h
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include "esphome/core/defines.h"
|
|
3
4
|
#include <vector>
|
|
4
5
|
#include <memory>
|
|
5
6
|
#include <cstring>
|
|
6
7
|
#include <deque>
|
|
8
|
+
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
|
9
|
+
#include <atomic>
|
|
10
|
+
#endif
|
|
7
11
|
|
|
8
12
|
#include "esphome/core/component.h"
|
|
9
13
|
#include "esphome/core/helpers.h"
|
|
@@ -11,8 +15,15 @@
|
|
|
11
15
|
namespace esphome {
|
|
12
16
|
|
|
13
17
|
class Component;
|
|
18
|
+
struct RetryArgs;
|
|
19
|
+
|
|
20
|
+
// Forward declaration of retry_handler - needs to be non-static for friend declaration
|
|
21
|
+
void retry_handler(const std::shared_ptr<RetryArgs> &args);
|
|
14
22
|
|
|
15
23
|
class Scheduler {
|
|
24
|
+
// Allow retry_handler to access protected members
|
|
25
|
+
friend void ::esphome::retry_handler(const std::shared_ptr<RetryArgs> &args);
|
|
26
|
+
|
|
16
27
|
public:
|
|
17
28
|
// Public API - accepts std::string for backward compatibility
|
|
18
29
|
void set_timeout(Component *component, const std::string &name, uint32_t timeout, std::function<void()> func);
|
|
@@ -50,11 +61,21 @@ class Scheduler {
|
|
|
50
61
|
bool cancel_interval(Component *component, const char *name);
|
|
51
62
|
void set_retry(Component *component, const std::string &name, uint32_t initial_wait_time, uint8_t max_attempts,
|
|
52
63
|
std::function<RetryResult(uint8_t)> func, float backoff_increase_factor = 1.0f);
|
|
64
|
+
void set_retry(Component *component, const char *name, uint32_t initial_wait_time, uint8_t max_attempts,
|
|
65
|
+
std::function<RetryResult(uint8_t)> func, float backoff_increase_factor = 1.0f);
|
|
53
66
|
bool cancel_retry(Component *component, const std::string &name);
|
|
67
|
+
bool cancel_retry(Component *component, const char *name);
|
|
54
68
|
|
|
55
|
-
|
|
69
|
+
// Calculate when the next scheduled item should run
|
|
70
|
+
// @param now Fresh timestamp from millis() - must not be stale/cached
|
|
71
|
+
// Returns the time in milliseconds until the next scheduled item, or nullopt if no items
|
|
72
|
+
// This method performs cleanup of removed items before checking the schedule
|
|
73
|
+
// IMPORTANT: This method should only be called from the main thread (loop task).
|
|
74
|
+
optional<uint32_t> next_schedule_in(uint32_t now);
|
|
56
75
|
|
|
57
|
-
|
|
76
|
+
// Execute all scheduled items that are ready
|
|
77
|
+
// @param now Fresh timestamp from millis() - must not be stale/cached
|
|
78
|
+
void call(uint32_t now);
|
|
58
79
|
|
|
59
80
|
void process_to_add();
|
|
60
81
|
|
|
@@ -80,11 +101,18 @@ class Scheduler {
|
|
|
80
101
|
enum Type : uint8_t { TIMEOUT, INTERVAL } type : 1;
|
|
81
102
|
bool remove : 1;
|
|
82
103
|
bool name_is_dynamic : 1; // True if name was dynamically allocated (needs delete[])
|
|
83
|
-
//
|
|
104
|
+
bool is_retry : 1; // True if this is a retry timeout
|
|
105
|
+
// 4 bits padding
|
|
84
106
|
|
|
85
107
|
// Constructor
|
|
86
108
|
SchedulerItem()
|
|
87
|
-
: component(nullptr),
|
|
109
|
+
: component(nullptr),
|
|
110
|
+
interval(0),
|
|
111
|
+
next_execution_(0),
|
|
112
|
+
type(TIMEOUT),
|
|
113
|
+
remove(false),
|
|
114
|
+
name_is_dynamic(false),
|
|
115
|
+
is_retry(false) {
|
|
88
116
|
name_.static_name = nullptr;
|
|
89
117
|
}
|
|
90
118
|
|
|
@@ -136,15 +164,22 @@ class Scheduler {
|
|
|
136
164
|
|
|
137
165
|
// Common implementation for both timeout and interval
|
|
138
166
|
void set_timer_common_(Component *component, SchedulerItem::Type type, bool is_static_string, const void *name_ptr,
|
|
139
|
-
uint32_t delay, std::function<void()> func);
|
|
167
|
+
uint32_t delay, std::function<void()> func, bool is_retry = false);
|
|
140
168
|
|
|
141
|
-
|
|
142
|
-
void
|
|
169
|
+
// Common implementation for retry
|
|
170
|
+
void set_retry_common_(Component *component, bool is_static_string, const void *name_ptr, uint32_t initial_wait_time,
|
|
171
|
+
uint8_t max_attempts, std::function<RetryResult(uint8_t)> func, float backoff_increase_factor);
|
|
172
|
+
|
|
173
|
+
uint64_t millis_64_(uint32_t now);
|
|
174
|
+
// Cleanup logically deleted items from the scheduler
|
|
175
|
+
// Returns the number of items remaining after cleanup
|
|
176
|
+
// IMPORTANT: This method should only be called from the main thread (loop task).
|
|
177
|
+
size_t cleanup_();
|
|
143
178
|
void pop_raw_();
|
|
144
179
|
|
|
145
180
|
private:
|
|
146
181
|
// Helper to cancel items by name - must be called with lock held
|
|
147
|
-
bool cancel_item_locked_(Component *component, const char *name, SchedulerItem::Type type);
|
|
182
|
+
bool cancel_item_locked_(Component *component, const char *name, SchedulerItem::Type type, bool match_retry = false);
|
|
148
183
|
|
|
149
184
|
// Helper to extract name as const char* from either static string or std::string
|
|
150
185
|
inline const char *get_name_cstr_(bool is_static_string, const void *name_ptr) {
|
|
@@ -156,8 +191,9 @@ class Scheduler {
|
|
|
156
191
|
|
|
157
192
|
// Helper function to check if item matches criteria for cancellation
|
|
158
193
|
inline bool HOT matches_item_(const std::unique_ptr<SchedulerItem> &item, Component *component, const char *name_cstr,
|
|
159
|
-
SchedulerItem::Type type) {
|
|
160
|
-
if (item->component != component || item->type != type || item->remove)
|
|
194
|
+
SchedulerItem::Type type, bool match_retry, bool skip_removed = true) const {
|
|
195
|
+
if (item->component != component || item->type != type || (skip_removed && item->remove) ||
|
|
196
|
+
(match_retry && !item->is_retry)) {
|
|
161
197
|
return false;
|
|
162
198
|
}
|
|
163
199
|
const char *item_name = item->get_name();
|
|
@@ -176,37 +212,63 @@ class Scheduler {
|
|
|
176
212
|
}
|
|
177
213
|
|
|
178
214
|
// Helper to execute a scheduler item
|
|
179
|
-
void execute_item_(SchedulerItem *item);
|
|
215
|
+
void execute_item_(SchedulerItem *item, uint32_t now);
|
|
180
216
|
|
|
181
217
|
// Helper to check if item should be skipped
|
|
182
218
|
bool should_skip_item_(const SchedulerItem *item) const {
|
|
183
219
|
return item->remove || (item->component != nullptr && item->component->is_failed());
|
|
184
220
|
}
|
|
185
221
|
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
222
|
+
// Template helper to check if any item in a container matches our criteria
|
|
223
|
+
template<typename Container>
|
|
224
|
+
bool has_cancelled_timeout_in_container_(const Container &container, Component *component, const char *name_cstr,
|
|
225
|
+
bool match_retry) const {
|
|
226
|
+
for (const auto &item : container) {
|
|
227
|
+
if (item->remove && this->matches_item_(item, component, name_cstr, SchedulerItem::TIMEOUT, match_retry,
|
|
228
|
+
/* skip_removed= */ false)) {
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return false;
|
|
195
233
|
}
|
|
196
234
|
|
|
197
235
|
Mutex lock_;
|
|
198
236
|
std::vector<std::unique_ptr<SchedulerItem>> items_;
|
|
199
237
|
std::vector<std::unique_ptr<SchedulerItem>> to_add_;
|
|
200
|
-
#
|
|
201
|
-
//
|
|
202
|
-
// ESP8266: Single-core with no preemptive multitasking
|
|
203
|
-
// RP2040: Currently has empty mutex implementation in ESPHome
|
|
204
|
-
// Both platforms save 40 bytes of RAM by excluding this
|
|
238
|
+
#ifndef ESPHOME_THREAD_SINGLE
|
|
239
|
+
// Single-core platforms don't need the defer queue and save 40 bytes of RAM
|
|
205
240
|
std::deque<std::unique_ptr<SchedulerItem>> defer_queue_; // FIFO queue for defer() calls
|
|
206
|
-
#endif
|
|
241
|
+
#endif /* ESPHOME_THREAD_SINGLE */
|
|
242
|
+
uint32_t to_remove_{0};
|
|
243
|
+
|
|
244
|
+
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
|
245
|
+
/*
|
|
246
|
+
* Multi-threaded platforms with atomic support: last_millis_ needs atomic for lock-free updates
|
|
247
|
+
*
|
|
248
|
+
* MEMORY-ORDERING NOTE
|
|
249
|
+
* --------------------
|
|
250
|
+
* `last_millis_` and `millis_major_` form a single 64-bit timestamp split in half.
|
|
251
|
+
* Writers publish `last_millis_` with memory_order_release and readers use
|
|
252
|
+
* memory_order_acquire. This ensures that once a reader sees the new low word,
|
|
253
|
+
* it also observes the corresponding increment of `millis_major_`.
|
|
254
|
+
*/
|
|
255
|
+
std::atomic<uint32_t> last_millis_{0};
|
|
256
|
+
#else /* not ESPHOME_THREAD_MULTI_ATOMICS */
|
|
257
|
+
// Platforms without atomic support or single-threaded platforms
|
|
207
258
|
uint32_t last_millis_{0};
|
|
259
|
+
#endif /* else ESPHOME_THREAD_MULTI_ATOMICS */
|
|
260
|
+
|
|
261
|
+
/*
|
|
262
|
+
* Upper 16 bits of the 64-bit millis counter. Incremented only while holding
|
|
263
|
+
* `lock_`; read concurrently. Atomic (relaxed) avoids a formal data race.
|
|
264
|
+
* Ordering relative to `last_millis_` is provided by its release store and the
|
|
265
|
+
* corresponding acquire loads.
|
|
266
|
+
*/
|
|
267
|
+
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
|
268
|
+
std::atomic<uint16_t> millis_major_{0};
|
|
269
|
+
#else /* not ESPHOME_THREAD_MULTI_ATOMICS */
|
|
208
270
|
uint16_t millis_major_{0};
|
|
209
|
-
|
|
271
|
+
#endif /* else ESPHOME_THREAD_MULTI_ATOMICS */
|
|
210
272
|
};
|
|
211
273
|
|
|
212
274
|
} // namespace esphome
|
esphome/cpp_generator.py
CHANGED
|
@@ -771,8 +771,7 @@ class MockObj(Expression):
|
|
|
771
771
|
if attr.startswith("P") and self.op not in ["::", ""]:
|
|
772
772
|
attr = attr[1:]
|
|
773
773
|
next_op = "->"
|
|
774
|
-
|
|
775
|
-
attr = attr[1:]
|
|
774
|
+
attr = attr.removeprefix("_")
|
|
776
775
|
return MockObj(f"{self.base}{self.op}{attr}", next_op)
|
|
777
776
|
|
|
778
777
|
def __call__(self, *args: SafeExpType) -> "MockObj":
|
|
@@ -1037,10 +1036,7 @@ class MockObjClass(MockObj):
|
|
|
1037
1036
|
def inherits_from(self, other: "MockObjClass") -> bool:
|
|
1038
1037
|
if str(self) == str(other):
|
|
1039
1038
|
return True
|
|
1040
|
-
for parent in self._parents
|
|
1041
|
-
if str(parent) == str(other):
|
|
1042
|
-
return True
|
|
1043
|
-
return False
|
|
1039
|
+
return any(str(parent) == str(other) for parent in self._parents)
|
|
1044
1040
|
|
|
1045
1041
|
def template(self, *args: SafeExpType) -> "MockObjClass":
|
|
1046
1042
|
if len(args) != 1 or not isinstance(args[0], TemplateArguments):
|
esphome/cpp_helpers.py
CHANGED
esphome/dashboard/dashboard.py
CHANGED
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import asyncio
|
|
4
4
|
from asyncio import events
|
|
5
5
|
from concurrent.futures import ThreadPoolExecutor
|
|
6
|
+
import contextlib
|
|
6
7
|
import logging
|
|
7
8
|
import os
|
|
8
9
|
import socket
|
|
@@ -125,10 +126,8 @@ def start_dashboard(args) -> None:
|
|
|
125
126
|
|
|
126
127
|
asyncio.set_event_loop_policy(DashboardEventLoopPolicy(settings.verbose))
|
|
127
128
|
|
|
128
|
-
|
|
129
|
+
with contextlib.suppress(KeyboardInterrupt):
|
|
129
130
|
asyncio.run(async_start(args))
|
|
130
|
-
except KeyboardInterrupt:
|
|
131
|
-
pass
|
|
132
131
|
|
|
133
132
|
|
|
134
133
|
async def async_start(args) -> None:
|
esphome/dashboard/dns.py
CHANGED
|
@@ -3,15 +3,9 @@ from __future__ import annotations
|
|
|
3
3
|
import asyncio
|
|
4
4
|
from contextlib import suppress
|
|
5
5
|
from ipaddress import ip_address
|
|
6
|
-
import sys
|
|
7
6
|
|
|
8
7
|
from icmplib import NameLookupError, async_resolve
|
|
9
8
|
|
|
10
|
-
if sys.version_info >= (3, 11):
|
|
11
|
-
from asyncio import timeout as async_timeout
|
|
12
|
-
else:
|
|
13
|
-
from async_timeout import timeout as async_timeout
|
|
14
|
-
|
|
15
9
|
RESOLVE_TIMEOUT = 3.0
|
|
16
10
|
|
|
17
11
|
|
|
@@ -20,9 +14,9 @@ async def _async_resolve_wrapper(hostname: str) -> list[str] | Exception:
|
|
|
20
14
|
with suppress(ValueError):
|
|
21
15
|
return [str(ip_address(hostname))]
|
|
22
16
|
try:
|
|
23
|
-
async with
|
|
17
|
+
async with asyncio.timeout(RESOLVE_TIMEOUT):
|
|
24
18
|
return await async_resolve(hostname)
|
|
25
|
-
except (
|
|
19
|
+
except (TimeoutError, NameLookupError, UnicodeError) as ex:
|
|
26
20
|
return ex
|
|
27
21
|
|
|
28
22
|
|
esphome/dashboard/web_server.py
CHANGED
|
@@ -144,7 +144,7 @@ def websocket_class(cls):
|
|
|
144
144
|
if not hasattr(cls, "_message_handlers"):
|
|
145
145
|
cls._message_handlers = {}
|
|
146
146
|
|
|
147
|
-
for
|
|
147
|
+
for method in cls.__dict__.values():
|
|
148
148
|
if hasattr(method, "_message_handler"):
|
|
149
149
|
cls._message_handlers[method._message_handler] = method
|
|
150
150
|
|
|
@@ -229,6 +229,7 @@ class EsphomeCommandWebSocket(tornado.websocket.WebSocketHandler):
|
|
|
229
229
|
stdin=subprocess.PIPE,
|
|
230
230
|
stdout=subprocess.PIPE,
|
|
231
231
|
stderr=subprocess.STDOUT,
|
|
232
|
+
close_fds=False,
|
|
232
233
|
)
|
|
233
234
|
stdout_thread = threading.Thread(target=self._stdout_thread)
|
|
234
235
|
stdout_thread.daemon = True
|
|
@@ -324,39 +325,53 @@ class EsphomePortCommandWebSocket(EsphomeCommandWebSocket):
|
|
|
324
325
|
configuration = json_message["configuration"]
|
|
325
326
|
config_file = settings.rel_path(configuration)
|
|
326
327
|
port = json_message["port"]
|
|
328
|
+
addresses: list[str] = []
|
|
327
329
|
if (
|
|
328
330
|
port == "OTA" # pylint: disable=too-many-boolean-expressions
|
|
329
331
|
and (entry := entries.get(config_file))
|
|
330
332
|
and entry.loaded_integrations
|
|
331
333
|
and "api" in entry.loaded_integrations
|
|
332
334
|
):
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
# Use the IP address if available but only
|
|
337
|
-
# if the API is loaded and the device is online
|
|
338
|
-
# since MQTT logging will not work otherwise
|
|
339
|
-
port = sort_ip_addresses(address_list)[0]
|
|
340
|
-
elif (
|
|
341
|
-
entry.address
|
|
335
|
+
# First priority: entry.address AKA use_address
|
|
336
|
+
if (
|
|
337
|
+
(use_address := entry.address)
|
|
342
338
|
and (
|
|
343
339
|
address_list := await dashboard.dns_cache.async_resolve(
|
|
344
|
-
|
|
340
|
+
use_address, time.monotonic()
|
|
345
341
|
)
|
|
346
342
|
)
|
|
347
343
|
and not isinstance(address_list, Exception)
|
|
348
344
|
):
|
|
349
|
-
|
|
350
|
-
port = sort_ip_addresses(address_list)[0]
|
|
345
|
+
addresses.extend(sort_ip_addresses(address_list))
|
|
351
346
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
347
|
+
# Second priority: mDNS
|
|
348
|
+
if (
|
|
349
|
+
(mdns := dashboard.mdns_status)
|
|
350
|
+
and (address_list := await mdns.async_resolve_host(entry.name))
|
|
351
|
+
and (
|
|
352
|
+
new_addresses := [
|
|
353
|
+
addr for addr in address_list if addr not in addresses
|
|
354
|
+
]
|
|
355
|
+
)
|
|
356
|
+
):
|
|
357
|
+
# Use the IP address if available but only
|
|
358
|
+
# if the API is loaded and the device is online
|
|
359
|
+
# since MQTT logging will not work otherwise
|
|
360
|
+
addresses.extend(sort_ip_addresses(new_addresses))
|
|
361
|
+
|
|
362
|
+
if not addresses:
|
|
363
|
+
# If no address was found, use the port directly
|
|
364
|
+
# as otherwise they will get the chooser which
|
|
365
|
+
# does not work with the dashboard as there is no
|
|
366
|
+
# interactive way to get keyboard input
|
|
367
|
+
addresses = [port]
|
|
368
|
+
|
|
369
|
+
device_args: list[str] = [
|
|
370
|
+
arg for address in addresses for arg in ("--device", address)
|
|
358
371
|
]
|
|
359
372
|
|
|
373
|
+
return [*DASHBOARD_COMMAND, *args, config_file, *device_args]
|
|
374
|
+
|
|
360
375
|
|
|
361
376
|
class EsphomeLogsHandler(EsphomePortCommandWebSocket):
|
|
362
377
|
async def build_command(self, json_message: dict[str, Any]) -> list[str]:
|
esphome/espota2.py
CHANGED
|
@@ -88,10 +88,7 @@ def recv_decode(sock, amount, decode=True):
|
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
def receive_exactly(sock, amount, msg, expect, decode=True):
|
|
91
|
-
if decode
|
|
92
|
-
data = []
|
|
93
|
-
else:
|
|
94
|
-
data = b""
|
|
91
|
+
data = [] if decode else b""
|
|
95
92
|
|
|
96
93
|
try:
|
|
97
94
|
data += recv_decode(sock, 1, decode=decode)
|
esphome/git.py
CHANGED
|
@@ -17,7 +17,9 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
17
17
|
def run_git_command(cmd, cwd=None) -> str:
|
|
18
18
|
_LOGGER.debug("Running git command: %s", " ".join(cmd))
|
|
19
19
|
try:
|
|
20
|
-
ret = subprocess.run(
|
|
20
|
+
ret = subprocess.run(
|
|
21
|
+
cmd, cwd=cwd, capture_output=True, check=False, close_fds=False
|
|
22
|
+
)
|
|
21
23
|
except FileNotFoundError as err:
|
|
22
24
|
raise cv.Invalid(
|
|
23
25
|
"git is not installed but required for external_components.\n"
|
esphome/helpers.py
CHANGED
|
@@ -9,6 +9,8 @@ import re
|
|
|
9
9
|
import tempfile
|
|
10
10
|
from urllib.parse import urlparse
|
|
11
11
|
|
|
12
|
+
from esphome.const import __version__ as ESPHOME_VERSION
|
|
13
|
+
|
|
12
14
|
_LOGGER = logging.getLogger(__name__)
|
|
13
15
|
|
|
14
16
|
IS_MACOS = platform.system() == "Darwin"
|
|
@@ -96,9 +98,7 @@ def cpp_string_escape(string, encoding="utf-8"):
|
|
|
96
98
|
def _should_escape(byte: int) -> bool:
|
|
97
99
|
if not 32 <= byte < 127:
|
|
98
100
|
return True
|
|
99
|
-
|
|
100
|
-
return True
|
|
101
|
-
return False
|
|
101
|
+
return byte in (ord("\\"), ord('"'))
|
|
102
102
|
|
|
103
103
|
if isinstance(string, str):
|
|
104
104
|
string = string.encode(encoding)
|
|
@@ -114,7 +114,9 @@ def cpp_string_escape(string, encoding="utf-8"):
|
|
|
114
114
|
def run_system_command(*args):
|
|
115
115
|
import subprocess
|
|
116
116
|
|
|
117
|
-
with subprocess.Popen(
|
|
117
|
+
with subprocess.Popen(
|
|
118
|
+
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=False
|
|
119
|
+
) as p:
|
|
118
120
|
stdout, stderr = p.communicate()
|
|
119
121
|
rc = p.returncode
|
|
120
122
|
return rc, stdout, stderr
|
|
@@ -505,3 +507,20 @@ _DISALLOWED_CHARS = re.compile(r"[^a-zA-Z0-9-_]")
|
|
|
505
507
|
def sanitize(value):
|
|
506
508
|
"""Same behaviour as `helpers.cpp` method `str_sanitize`."""
|
|
507
509
|
return _DISALLOWED_CHARS.sub("_", value)
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
def docs_url(path: str) -> str:
|
|
513
|
+
"""Return the URL to the documentation for a given path."""
|
|
514
|
+
# Local import to avoid circular import
|
|
515
|
+
from esphome.config_validation import Version
|
|
516
|
+
|
|
517
|
+
version = Version.parse(ESPHOME_VERSION)
|
|
518
|
+
if version.is_beta:
|
|
519
|
+
docs_format = "https://beta.esphome.io/{path}"
|
|
520
|
+
elif version.is_dev:
|
|
521
|
+
docs_format = "https://next.esphome.io/{path}"
|
|
522
|
+
else:
|
|
523
|
+
docs_format = "https://esphome.io/{path}"
|
|
524
|
+
|
|
525
|
+
path = path.removeprefix("/")
|
|
526
|
+
return docs_format.format(path=path)
|
esphome/log.py
CHANGED
|
@@ -37,6 +37,8 @@ class AnsiStyle(Enum):
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def color(col: AnsiFore, msg: str, reset: bool = True) -> str:
|
|
40
|
+
if col == AnsiFore.KEEP:
|
|
41
|
+
return msg
|
|
40
42
|
s = col.value + msg
|
|
41
43
|
if reset and col:
|
|
42
44
|
s += AnsiStyle.RESET_ALL.value
|
|
@@ -61,7 +63,7 @@ class ESPHomeLogFormatter(logging.Formatter):
|
|
|
61
63
|
}.get(record.levelname, "")
|
|
62
64
|
message = f"{prefix}{formatted}{AnsiStyle.RESET_ALL.value}"
|
|
63
65
|
if CORE.dashboard:
|
|
64
|
-
try:
|
|
66
|
+
try: # noqa: SIM105
|
|
65
67
|
message = message.replace("\033", "\\033")
|
|
66
68
|
except UnicodeEncodeError:
|
|
67
69
|
pass
|
esphome/mqtt.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import contextlib
|
|
1
2
|
from datetime import datetime
|
|
2
3
|
import hashlib
|
|
3
4
|
import json
|
|
@@ -35,7 +36,7 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
35
36
|
|
|
36
37
|
|
|
37
38
|
def config_from_env():
|
|
38
|
-
|
|
39
|
+
return {
|
|
39
40
|
CONF_MQTT: {
|
|
40
41
|
CONF_USERNAME: get_str_env("ESPHOME_DASHBOARD_MQTT_USERNAME"),
|
|
41
42
|
CONF_PASSWORD: get_str_env("ESPHOME_DASHBOARD_MQTT_PASSWORD"),
|
|
@@ -43,7 +44,6 @@ def config_from_env():
|
|
|
43
44
|
CONF_PORT: get_int_env("ESPHOME_DASHBOARD_MQTT_PORT", 1883),
|
|
44
45
|
},
|
|
45
46
|
}
|
|
46
|
-
return config
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
def initialize(
|
|
@@ -52,10 +52,8 @@ def initialize(
|
|
|
52
52
|
client = prepare(
|
|
53
53
|
config, subscriptions, on_message, on_connect, username, password, client_id
|
|
54
54
|
)
|
|
55
|
-
|
|
55
|
+
with contextlib.suppress(KeyboardInterrupt):
|
|
56
56
|
client.loop_forever()
|
|
57
|
-
except KeyboardInterrupt:
|
|
58
|
-
pass
|
|
59
57
|
return 0
|
|
60
58
|
|
|
61
59
|
|
esphome/platformio_api.py
CHANGED
|
@@ -61,6 +61,7 @@ FILTER_PLATFORMIO_LINES = [
|
|
|
61
61
|
r"Advanced Memory Usage is available via .*",
|
|
62
62
|
r"Merged .* ELF section",
|
|
63
63
|
r"esptool.py v.*",
|
|
64
|
+
r"esptool v.*",
|
|
64
65
|
r"Checking size .*",
|
|
65
66
|
r"Retrieving maximum program size .*",
|
|
66
67
|
r"PLATFORM: .*",
|
|
@@ -131,9 +132,11 @@ def _load_idedata(config):
|
|
|
131
132
|
temp_idedata = Path(CORE.relative_internal_path("idedata", f"{CORE.name}.json"))
|
|
132
133
|
|
|
133
134
|
changed = False
|
|
134
|
-
if
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
if (
|
|
136
|
+
not platformio_ini.is_file()
|
|
137
|
+
or not temp_idedata.is_file()
|
|
138
|
+
or platformio_ini.stat().st_mtime >= temp_idedata.stat().st_mtime
|
|
139
|
+
):
|
|
137
140
|
changed = True
|
|
138
141
|
|
|
139
142
|
if not changed:
|
|
@@ -208,7 +211,7 @@ def _decode_pc(config, addr):
|
|
|
208
211
|
return
|
|
209
212
|
command = [idedata.addr2line_path, "-pfiaC", "-e", idedata.firmware_elf_path, addr]
|
|
210
213
|
try:
|
|
211
|
-
translation = subprocess.check_output(command).decode().strip()
|
|
214
|
+
translation = subprocess.check_output(command, close_fds=False).decode().strip()
|
|
212
215
|
except Exception: # pylint: disable=broad-except
|
|
213
216
|
_LOGGER.debug("Caught exception for command %s", command, exc_info=1)
|
|
214
217
|
return
|
esphome/types.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""This helper module tracks commonly used types in the esphome python codebase."""
|
|
2
2
|
|
|
3
|
+
from typing import TypedDict
|
|
4
|
+
|
|
3
5
|
from esphome.core import ID, EsphomeCore, Lambda
|
|
4
6
|
|
|
5
7
|
ConfigFragmentType = (
|
|
@@ -16,3 +18,13 @@ ConfigFragmentType = (
|
|
|
16
18
|
ConfigType = dict[str, ConfigFragmentType]
|
|
17
19
|
CoreType = EsphomeCore
|
|
18
20
|
ConfigPathType = str | int
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class EntityMetadata(TypedDict):
|
|
24
|
+
"""Metadata stored for each entity to help with duplicate detection."""
|
|
25
|
+
|
|
26
|
+
name: str
|
|
27
|
+
device_id: str
|
|
28
|
+
platform: str
|
|
29
|
+
entity_id: str
|
|
30
|
+
component: str
|
esphome/util.py
CHANGED
|
@@ -6,6 +6,7 @@ from pathlib import Path
|
|
|
6
6
|
import re
|
|
7
7
|
import subprocess
|
|
8
8
|
import sys
|
|
9
|
+
from typing import Any
|
|
9
10
|
|
|
10
11
|
from esphome import const
|
|
11
12
|
|
|
@@ -59,7 +60,7 @@ def safe_print(message="", end="\n"):
|
|
|
59
60
|
from esphome.core import CORE
|
|
60
61
|
|
|
61
62
|
if CORE.dashboard:
|
|
62
|
-
try:
|
|
63
|
+
try: # noqa: SIM105
|
|
63
64
|
message = message.replace("\033", "\\033")
|
|
64
65
|
except UnicodeEncodeError:
|
|
65
66
|
pass
|
|
@@ -110,7 +111,7 @@ class RedirectText:
|
|
|
110
111
|
def __getattr__(self, item):
|
|
111
112
|
return getattr(self._out, item)
|
|
112
113
|
|
|
113
|
-
def _write_color_replace(self, s):
|
|
114
|
+
def _write_color_replace(self, s: str | bytes) -> None:
|
|
114
115
|
from esphome.core import CORE
|
|
115
116
|
|
|
116
117
|
if CORE.dashboard:
|
|
@@ -121,7 +122,7 @@ class RedirectText:
|
|
|
121
122
|
s = s.replace("\033", "\\033")
|
|
122
123
|
self._out.write(s)
|
|
123
124
|
|
|
124
|
-
def write(self, s):
|
|
125
|
+
def write(self, s: str | bytes) -> int:
|
|
125
126
|
# s is usually a str already (self._out is of type TextIOWrapper)
|
|
126
127
|
# However, s is sometimes also a bytes object in python3. Let's make sure it's a
|
|
127
128
|
# str
|
|
@@ -223,7 +224,7 @@ def run_external_command(
|
|
|
223
224
|
return retval
|
|
224
225
|
|
|
225
226
|
|
|
226
|
-
def run_external_process(*cmd, **kwargs):
|
|
227
|
+
def run_external_process(*cmd: str, **kwargs: Any) -> int | str:
|
|
227
228
|
full_cmd = " ".join(shlex_quote(x) for x in cmd)
|
|
228
229
|
_LOGGER.debug("Running: %s", full_cmd)
|
|
229
230
|
filter_lines = kwargs.get("filter_lines")
|
|
@@ -238,7 +239,12 @@ def run_external_process(*cmd, **kwargs):
|
|
|
238
239
|
|
|
239
240
|
try:
|
|
240
241
|
proc = subprocess.run(
|
|
241
|
-
cmd,
|
|
242
|
+
cmd,
|
|
243
|
+
stdout=sub_stdout,
|
|
244
|
+
stderr=sub_stderr,
|
|
245
|
+
encoding="utf-8",
|
|
246
|
+
check=False,
|
|
247
|
+
close_fds=False,
|
|
242
248
|
)
|
|
243
249
|
return proc.stdout if capture_stdout else proc.returncode
|
|
244
250
|
except KeyboardInterrupt: # pylint: disable=try-except-raise
|
|
@@ -266,7 +272,7 @@ class OrderedDict(collections.OrderedDict):
|
|
|
266
272
|
return dict(self).__repr__()
|
|
267
273
|
|
|
268
274
|
|
|
269
|
-
def list_yaml_files(folders):
|
|
275
|
+
def list_yaml_files(folders: list[str]) -> list[str]:
|
|
270
276
|
files = filter_yaml_files(
|
|
271
277
|
[os.path.join(folder, p) for folder in folders for p in os.listdir(folder)]
|
|
272
278
|
)
|
|
@@ -274,7 +280,7 @@ def list_yaml_files(folders):
|
|
|
274
280
|
return files
|
|
275
281
|
|
|
276
282
|
|
|
277
|
-
def filter_yaml_files(files):
|
|
283
|
+
def filter_yaml_files(files: list[str]) -> list[str]:
|
|
278
284
|
return [
|
|
279
285
|
f
|
|
280
286
|
for f in files
|
|
@@ -345,5 +351,11 @@ def get_esp32_arduino_flash_error_help() -> str | None:
|
|
|
345
351
|
+ "2. Clean build files and compile again\n"
|
|
346
352
|
+ "\n"
|
|
347
353
|
+ "Note: ESP-IDF uses less flash space and provides better performance.\n"
|
|
348
|
-
+ "Some Arduino-specific libraries may need alternatives.\n
|
|
354
|
+
+ "Some Arduino-specific libraries may need alternatives.\n"
|
|
355
|
+
+ "\n"
|
|
356
|
+
+ "For detailed migration instructions, see:\n"
|
|
357
|
+
+ color(
|
|
358
|
+
AnsiFore.BLUE,
|
|
359
|
+
"https://esphome.io/guides/esp32_arduino_to_idf.html\n\n",
|
|
360
|
+
)
|
|
349
361
|
)
|
esphome/voluptuous_schema.py
CHANGED
|
@@ -225,9 +225,10 @@ class _Schema(vol.Schema):
|
|
|
225
225
|
return ret
|
|
226
226
|
|
|
227
227
|
schema = schemas[0]
|
|
228
|
+
extra_schemas = self._extra_schemas.copy()
|
|
229
|
+
if isinstance(schema, _Schema):
|
|
230
|
+
extra_schemas.extend(schema._extra_schemas)
|
|
228
231
|
if isinstance(schema, vol.Schema):
|
|
229
232
|
schema = schema.schema
|
|
230
233
|
ret = super().extend(schema, extra=extra)
|
|
231
|
-
return _Schema(
|
|
232
|
-
ret.schema, extra=ret.extra, extra_schemas=self._extra_schemas.copy()
|
|
233
|
-
)
|
|
234
|
+
return _Schema(ret.schema, extra=ret.extra, extra_schemas=extra_schemas)
|
esphome/vscode.py
CHANGED
|
@@ -81,8 +81,7 @@ def _print_file_read_event(path: str) -> None:
|
|
|
81
81
|
|
|
82
82
|
def _request_and_get_stream_on_stdin(fname: str) -> StringIO:
|
|
83
83
|
_print_file_read_event(fname)
|
|
84
|
-
|
|
85
|
-
return raw_yaml_stream
|
|
84
|
+
return StringIO(_read_file_content_from_json_on_stdin())
|
|
86
85
|
|
|
87
86
|
|
|
88
87
|
def _vscode_loader(fname: str) -> dict[str, Any]:
|
esphome/wizard.py
CHANGED
|
@@ -116,10 +116,7 @@ def wizard_file(**kwargs):
|
|
|
116
116
|
kwargs["fallback_name"] = ap_name
|
|
117
117
|
kwargs["fallback_psk"] = "".join(random.choice(letters) for _ in range(12))
|
|
118
118
|
|
|
119
|
-
if kwargs.get("friendly_name")
|
|
120
|
-
base = BASE_CONFIG_FRIENDLY
|
|
121
|
-
else:
|
|
122
|
-
base = BASE_CONFIG
|
|
119
|
+
base = BASE_CONFIG_FRIENDLY if kwargs.get("friendly_name") else BASE_CONFIG
|
|
123
120
|
|
|
124
121
|
config = base.format(**kwargs)
|
|
125
122
|
|