esphome 2025.9.3__py3-none-any.whl → 2025.10.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +94 -31
- esphome/address_cache.py +142 -0
- esphome/automation.py +130 -32
- esphome/build_gen/platformio.py +1 -3
- esphome/codegen.py +1 -0
- esphome/components/animation/animation.cpp +2 -2
- esphome/components/api/__init__.py +166 -3
- esphome/components/api/api_connection.cpp +84 -41
- esphome/components/api/api_connection.h +22 -16
- esphome/components/api/api_frame_helper.cpp +33 -19
- esphome/components/api/api_frame_helper.h +19 -4
- esphome/components/api/api_frame_helper_noise.cpp +41 -53
- esphome/components/api/api_frame_helper_noise.h +1 -1
- esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
- esphome/components/api/api_frame_helper_plaintext.h +1 -1
- esphome/components/api/api_pb2.cpp +189 -15
- esphome/components/api/api_pb2.h +132 -20
- esphome/components/api/api_pb2_dump.cpp +97 -9
- esphome/components/api/api_pb2_service.cpp +118 -160
- esphome/components/api/api_pb2_service.h +31 -3
- esphome/components/api/api_server.cpp +68 -10
- esphome/components/api/api_server.h +32 -4
- esphome/components/api/custom_api_device.h +8 -8
- esphome/components/api/homeassistant_service.h +123 -6
- esphome/components/api/proto.h +6 -2
- esphome/components/api/user_services.h +2 -2
- esphome/components/as7341/sensor.py +1 -1
- esphome/components/audio/__init__.py +1 -1
- esphome/components/audio/audio.cpp +1 -1
- esphome/components/audio/audio_decoder.cpp +9 -9
- esphome/components/bl0906/bl0906.cpp +2 -2
- esphome/components/bl0942/bl0942.cpp +2 -2
- esphome/components/ble_client/__init__.py +1 -1
- esphome/components/bluetooth_proxy/__init__.py +4 -30
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
- esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
- esphome/components/camera_encoder/__init__.py +2 -4
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
- esphome/components/canbus/canbus.cpp +7 -5
- esphome/components/canbus/canbus.h +7 -7
- esphome/components/captive_portal/__init__.py +18 -1
- esphome/components/captive_portal/captive_portal.cpp +40 -46
- esphome/components/captive_portal/captive_portal.h +20 -22
- esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
- esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
- esphome/components/ccs811/ccs811.cpp +1 -1
- esphome/components/climate/climate.cpp +10 -7
- esphome/components/cm1106/cm1106.cpp +1 -1
- esphome/components/copy/lock/copy_lock.cpp +1 -1
- esphome/components/cover/cover.cpp +1 -0
- esphome/components/daikin_arc/daikin_arc.cpp +19 -12
- esphome/components/dashboard_import/dashboard_import.cpp +1 -1
- esphome/components/dashboard_import/dashboard_import.h +1 -1
- esphome/components/deep_sleep/__init__.py +9 -2
- esphome/components/deep_sleep/deep_sleep_component.h +11 -9
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
- esphome/components/ektf2232/touchscreen/__init__.py +8 -5
- esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
- esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
- esphome/components/epaper_spi/__init__.py +1 -0
- esphome/components/epaper_spi/display.py +80 -0
- esphome/components/epaper_spi/epaper_spi.cpp +227 -0
- esphome/components/epaper_spi/epaper_spi.h +93 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
- esphome/components/es7210/es7210.cpp +3 -3
- esphome/components/esp32/__init__.py +256 -340
- esphome/components/esp32/boards.py +81 -0
- esphome/components/esp32/preferences.cpp +23 -17
- esphome/components/esp32_ble/__init__.py +167 -44
- esphome/components/esp32_ble/ble.cpp +47 -3
- esphome/components/esp32_ble/ble.h +18 -0
- esphome/components/esp32_ble/ble_advertising.cpp +7 -3
- esphome/components/esp32_ble/ble_advertising.h +4 -0
- esphome/components/esp32_ble/ble_uuid.cpp +16 -42
- esphome/components/esp32_ble_beacon/__init__.py +3 -4
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +0 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
- esphome/components/esp32_ble_server/__init__.py +28 -14
- esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
- esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
- esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
- esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
- esphome/components/esp32_ble_server/ble_server.cpp +59 -24
- esphome/components/esp32_ble_server/ble_server.h +38 -20
- esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
- esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
- esphome/components/esp32_ble_tracker/__init__.py +25 -80
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -8
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
- esphome/components/esp32_camera/__init__.py +1 -3
- esphome/components/esp32_can/esp32_can.cpp +22 -4
- esphome/components/esp32_can/esp32_can.h +3 -0
- esphome/components/esp32_hosted/__init__.py +2 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +135 -65
- esphome/components/esp32_improv/esp32_improv_component.h +7 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp8266/__init__.py +3 -3
- esphome/components/esphome/ota/__init__.py +21 -2
- esphome/components/esphome/ota/ota_esphome.cpp +456 -146
- esphome/components/esphome/ota/ota_esphome.h +49 -2
- esphome/components/ethernet/__init__.py +39 -22
- esphome/components/ethernet/ethernet_component.cpp +28 -5
- esphome/components/ethernet/ethernet_component.h +5 -1
- esphome/components/external_components/__init__.py +8 -6
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
- esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
- esphome/components/font/__init__.py +5 -5
- esphome/components/graph/graph.cpp +1 -1
- esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
- esphome/components/haier/hon_climate.cpp +2 -2
- esphome/components/haier/hon_climate.h +1 -1
- esphome/components/hdc1080/hdc1080.cpp +42 -34
- esphome/components/hdc1080/hdc1080.h +1 -3
- esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
- esphome/components/http_request/__init__.py +3 -3
- esphome/components/htu21d/htu21d.cpp +13 -18
- esphome/components/htu21d/htu21d.h +1 -1
- esphome/components/i2s_audio/__init__.py +1 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
- esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
- esphome/components/improv_serial/improv_serial_component.cpp +12 -15
- esphome/components/improv_serial/improv_serial_component.h +6 -8
- esphome/components/json/json_util.cpp +42 -44
- esphome/components/json/json_util.h +57 -0
- esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
- esphome/components/key_collector/key_collector.h +4 -4
- esphome/components/libretiny/__init__.py +6 -6
- esphome/components/libretiny/preferences.cpp +23 -16
- esphome/components/light/light_call.cpp +98 -120
- esphome/components/light/light_call.h +17 -7
- esphome/components/lm75b/__init__.py +0 -0
- esphome/components/lm75b/lm75b.cpp +39 -0
- esphome/components/lm75b/lm75b.h +19 -0
- esphome/components/lm75b/sensor.py +34 -0
- esphome/components/lock/lock.h +12 -6
- esphome/components/logger/__init__.py +15 -27
- esphome/components/logger/logger.cpp +10 -20
- esphome/components/logger/logger.h +105 -62
- esphome/components/logger/logger_esp32.cpp +0 -48
- esphome/components/logger/logger_zephyr.cpp +2 -3
- esphome/components/logger/select/logger_level_select.cpp +6 -7
- esphome/components/logger/select/logger_level_select.h +7 -0
- esphome/components/ltr501/ltr501.cpp +7 -6
- esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
- esphome/components/matrix_keypad/matrix_keypad.h +4 -4
- esphome/components/max7219digit/max7219digit.cpp +1 -1
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +3 -3
- esphome/components/mcp2515/mcp2515.cpp +31 -3
- esphome/components/mcp2515/mcp2515_defs.h +3 -1
- esphome/components/md5/md5.cpp +0 -26
- esphome/components/md5/md5.h +10 -20
- esphome/components/mdns/__init__.py +93 -19
- esphome/components/mdns/mdns_component.cpp +57 -94
- esphome/components/mdns/mdns_component.h +35 -11
- esphome/components/mdns/mdns_esp32.cpp +7 -13
- esphome/components/mdns/mdns_esp8266.cpp +7 -7
- esphome/components/mdns/mdns_libretiny.cpp +3 -4
- esphome/components/mdns/mdns_rp2040.cpp +3 -4
- esphome/components/mipi/__init__.py +1 -5
- esphome/components/mipi_spi/display.py +24 -8
- esphome/components/mipi_spi/mipi_spi.h +3 -3
- esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
- esphome/components/mmc5603/mmc5603.cpp +3 -3
- esphome/components/modbus/modbus.cpp +27 -13
- esphome/components/modbus/modbus.h +5 -3
- esphome/components/modbus/modbus_definitions.h +86 -0
- esphome/components/modbus_controller/__init__.py +29 -1
- esphome/components/modbus_controller/const.py +4 -0
- esphome/components/modbus_controller/modbus_controller.cpp +38 -13
- esphome/components/modbus_controller/modbus_controller.h +18 -29
- esphome/components/mpr121/mpr121.cpp +41 -42
- esphome/components/mpr121/mpr121.h +0 -1
- esphome/components/nau7802/nau7802.cpp +2 -2
- esphome/components/network/__init__.py +7 -3
- esphome/components/nextion/display.py +4 -4
- esphome/components/nextion/nextion.cpp +8 -8
- esphome/components/number/__init__.py +2 -0
- esphome/components/number/number_call.cpp +23 -12
- esphome/components/number/number_call.h +5 -0
- esphome/components/online_image/bmp_image.cpp +2 -1
- esphome/components/online_image/jpeg_image.cpp +4 -2
- esphome/components/opentherm/opentherm.cpp +5 -5
- esphome/components/opentherm/opentherm.h +3 -3
- esphome/components/openthread/openthread.cpp +11 -10
- esphome/components/openthread/openthread.h +0 -1
- esphome/components/ota/ota_backend.h +1 -0
- esphome/components/packages/__init__.py +10 -8
- esphome/components/packet_transport/packet_transport.cpp +2 -0
- esphome/components/pid/pid_controller.cpp +1 -1
- esphome/components/prometheus/prometheus_handler.cpp +239 -239
- esphome/components/psram/__init__.py +30 -28
- esphome/components/qmc5883l/qmc5883l.cpp +15 -0
- esphome/components/qmc5883l/qmc5883l.h +3 -0
- esphome/components/qmc5883l/sensor.py +31 -12
- esphome/components/remote_base/gobox_protocol.cpp +3 -3
- esphome/components/remote_receiver/__init__.py +14 -2
- esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
- esphome/components/remote_receiver/remote_receiver.h +4 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
- esphome/components/remote_transmitter/__init__.py +2 -2
- esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
- esphome/components/rp2040/__init__.py +11 -11
- esphome/components/rtttl/rtttl.cpp +2 -2
- esphome/components/scd30/sensor.py +1 -1
- esphome/components/script/__init__.py +1 -1
- esphome/components/script/script.h +7 -7
- esphome/components/select/select.cpp +5 -4
- esphome/components/select/select_call.cpp +1 -1
- esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
- esphome/components/sensor/__init__.py +2 -0
- esphome/components/sha256/__init__.py +22 -0
- esphome/components/sha256/sha256.cpp +116 -0
- esphome/components/sha256/sha256.h +60 -0
- esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
- esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
- esphome/components/spi/__init__.py +0 -3
- esphome/components/split_buffer/__init__.py +5 -0
- esphome/components/split_buffer/split_buffer.cpp +133 -0
- esphome/components/split_buffer/split_buffer.h +40 -0
- esphome/components/sps30/sps30.cpp +14 -10
- esphome/components/sps30/sps30.h +2 -0
- esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
- esphome/components/st7789v/st7789v.cpp +3 -2
- esphome/components/statsd/statsd.cpp +1 -1
- esphome/components/substitutions/__init__.py +3 -1
- esphome/components/substitutions/jinja.py +13 -3
- esphome/components/sx126x/__init__.py +16 -0
- esphome/components/sx126x/sx126x.cpp +15 -1
- esphome/components/sx126x/sx126x.h +9 -1
- esphome/components/sx126x/sx126x_reg.h +2 -0
- esphome/components/text_sensor/text_sensor.cpp +16 -0
- esphome/components/text_sensor/text_sensor.h +3 -10
- esphome/components/tormatic/tormatic_cover.cpp +1 -1
- esphome/components/tuya/select/tuya_select.cpp +1 -1
- esphome/components/tuya/tuya.cpp +29 -4
- esphome/components/uart/__init__.py +37 -27
- esphome/components/uart/uart.h +6 -0
- esphome/components/uart/uart_component.cpp +8 -0
- esphome/components/uart/uart_component.h +28 -0
- esphome/components/uart/uart_component_esp_idf.cpp +64 -10
- esphome/components/uart/uart_component_esp_idf.h +5 -2
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
- esphome/components/usb_host/__init__.py +12 -2
- esphome/components/usb_host/usb_host.h +89 -14
- esphome/components/usb_host/usb_host_client.cpp +157 -22
- esphome/components/usb_host/usb_host_component.cpp +1 -1
- esphome/components/usb_uart/__init__.py +0 -1
- esphome/components/usb_uart/ch34x.cpp +4 -4
- esphome/components/usb_uart/cp210x.cpp +3 -3
- esphome/components/usb_uart/usb_uart.cpp +88 -32
- esphome/components/usb_uart/usb_uart.h +30 -6
- esphome/components/valve/valve.cpp +1 -0
- esphome/components/veml7700/veml7700.cpp +7 -6
- esphome/components/version/version_text_sensor.cpp +2 -1
- esphome/components/voice_assistant/voice_assistant.cpp +3 -2
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
- esphome/components/web_server/list_entities.cpp +3 -4
- esphome/components/web_server/list_entities.h +8 -10
- esphome/components/web_server/ota/__init__.py +1 -1
- esphome/components/web_server/ota/ota_web_server.cpp +9 -3
- esphome/components/web_server/web_server.cpp +509 -404
- esphome/components/web_server/web_server.h +5 -6
- esphome/components/web_server/web_server_v1.cpp +21 -19
- esphome/components/web_server_base/__init__.py +5 -2
- esphome/components/web_server_base/web_server_base.h +27 -7
- esphome/components/web_server_idf/__init__.py +1 -1
- esphome/components/web_server_idf/multipart.cpp +2 -2
- esphome/components/web_server_idf/multipart.h +2 -2
- esphome/components/web_server_idf/utils.cpp +2 -2
- esphome/components/web_server_idf/utils.h +2 -2
- esphome/components/web_server_idf/web_server_idf.cpp +118 -26
- esphome/components/web_server_idf/web_server_idf.h +12 -10
- esphome/components/wifi/__init__.py +13 -11
- esphome/components/wifi/wifi_component.cpp +74 -56
- esphome/components/wifi/wifi_component.h +4 -4
- esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
- esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
- esphome/components/wireguard/__init__.py +1 -1
- esphome/components/wts01/__init__.py +0 -0
- esphome/components/wts01/sensor.py +41 -0
- esphome/components/wts01/wts01.cpp +91 -0
- esphome/components/wts01/wts01.h +27 -0
- esphome/components/zephyr/__init__.py +5 -5
- esphome/components/zwave_proxy/__init__.py +43 -0
- esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
- esphome/components/zwave_proxy/zwave_proxy.h +93 -0
- esphome/config.py +79 -24
- esphome/config_validation.py +13 -15
- esphome/const.py +9 -2
- esphome/core/__init__.py +33 -22
- esphome/core/component.cpp +28 -18
- esphome/core/component_iterator.h +2 -1
- esphome/core/config.py +15 -15
- esphome/core/defines.h +21 -0
- esphome/core/entity_helpers.py +9 -6
- esphome/core/hash_base.h +56 -0
- esphome/core/helpers.cpp +19 -3
- esphome/core/helpers.h +26 -0
- esphome/core/scheduler.cpp +5 -21
- esphome/core/scheduler.h +19 -8
- esphome/core/string_ref.h +1 -1
- esphome/core/time.cpp +5 -5
- esphome/cpp_generator.py +4 -29
- esphome/dashboard/const.py +21 -4
- esphome/dashboard/core.py +10 -8
- esphome/dashboard/dns.py +15 -0
- esphome/dashboard/entries.py +15 -21
- esphome/dashboard/models.py +76 -0
- esphome/dashboard/settings.py +7 -7
- esphome/dashboard/status/mdns.py +46 -2
- esphome/dashboard/web_server.py +367 -93
- esphome/espota2.py +112 -32
- esphome/external_files.py +6 -7
- esphome/git.py +8 -0
- esphome/helpers.py +124 -77
- esphome/loader.py +8 -9
- esphome/pins.py +2 -2
- esphome/platformio_api.py +56 -18
- esphome/storage_json.py +26 -21
- esphome/types.py +30 -2
- esphome/util.py +32 -16
- esphome/vscode.py +8 -8
- esphome/wizard.py +10 -10
- esphome/writer.py +50 -15
- esphome/yaml_util.py +37 -31
- esphome/zeroconf.py +12 -3
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/METADATA +12 -12
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/RECORD +340 -320
- esphome/components/event_emitter/__init__.py +0 -5
- esphome/components/event_emitter/event_emitter.cpp +0 -14
- esphome/components/event_emitter/event_emitter.h +0 -63
- esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
- esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
- esphome/components/uart/uart_component_esp32_arduino.h +0 -60
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
- esphome/core/string_ref.cpp +0 -12
- esphome/dashboard/util/file.py +0 -63
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/WHEEL +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/top_level.txt +0 -0
esphome/writer.py
CHANGED
@@ -266,7 +266,7 @@ def generate_version_h():
|
|
266
266
|
|
267
267
|
def write_cpp(code_s):
|
268
268
|
path = CORE.relative_src_path("main.cpp")
|
269
|
-
if
|
269
|
+
if path.is_file():
|
270
270
|
text = read_file(path)
|
271
271
|
code_format = find_begin_end(
|
272
272
|
text, CPP_AUTO_GENERATE_BEGIN, CPP_AUTO_GENERATE_END
|
@@ -292,43 +292,79 @@ def write_cpp(code_s):
|
|
292
292
|
|
293
293
|
def clean_cmake_cache():
|
294
294
|
pioenvs = CORE.relative_pioenvs_path()
|
295
|
-
if
|
296
|
-
pioenvs_cmake_path = CORE.
|
297
|
-
if
|
295
|
+
if pioenvs.is_dir():
|
296
|
+
pioenvs_cmake_path = pioenvs / CORE.name / "CMakeCache.txt"
|
297
|
+
if pioenvs_cmake_path.is_file():
|
298
298
|
_LOGGER.info("Deleting %s", pioenvs_cmake_path)
|
299
|
-
|
299
|
+
pioenvs_cmake_path.unlink()
|
300
300
|
|
301
301
|
|
302
302
|
def clean_build():
|
303
303
|
import shutil
|
304
304
|
|
305
|
+
# Allow skipping cache cleaning for integration tests
|
306
|
+
if os.environ.get("ESPHOME_SKIP_CLEAN_BUILD"):
|
307
|
+
_LOGGER.warning("Skipping build cleaning (ESPHOME_SKIP_CLEAN_BUILD set)")
|
308
|
+
return
|
309
|
+
|
305
310
|
pioenvs = CORE.relative_pioenvs_path()
|
306
|
-
if
|
311
|
+
if pioenvs.is_dir():
|
307
312
|
_LOGGER.info("Deleting %s", pioenvs)
|
308
313
|
shutil.rmtree(pioenvs)
|
309
314
|
piolibdeps = CORE.relative_piolibdeps_path()
|
310
|
-
if
|
315
|
+
if piolibdeps.is_dir():
|
311
316
|
_LOGGER.info("Deleting %s", piolibdeps)
|
312
317
|
shutil.rmtree(piolibdeps)
|
313
318
|
dependencies_lock = CORE.relative_build_path("dependencies.lock")
|
314
|
-
if
|
319
|
+
if dependencies_lock.is_file():
|
315
320
|
_LOGGER.info("Deleting %s", dependencies_lock)
|
316
|
-
|
321
|
+
dependencies_lock.unlink()
|
317
322
|
|
318
323
|
# Clean PlatformIO cache to resolve CMake compiler detection issues
|
319
324
|
# This helps when toolchain paths change or get corrupted
|
320
325
|
try:
|
321
|
-
from platformio.project.
|
326
|
+
from platformio.project.config import ProjectConfig
|
322
327
|
except ImportError:
|
323
328
|
# PlatformIO is not available, skip cache cleaning
|
324
329
|
pass
|
325
330
|
else:
|
326
|
-
|
327
|
-
|
331
|
+
config = ProjectConfig.get_instance()
|
332
|
+
cache_dir = Path(config.get("platformio", "cache_dir"))
|
333
|
+
if cache_dir.is_dir():
|
328
334
|
_LOGGER.info("Deleting PlatformIO cache %s", cache_dir)
|
329
335
|
shutil.rmtree(cache_dir)
|
330
336
|
|
331
337
|
|
338
|
+
def clean_all(configuration: list[str]):
|
339
|
+
import shutil
|
340
|
+
|
341
|
+
# Clean entire build dir
|
342
|
+
for dir in configuration:
|
343
|
+
build_dir = Path(dir) / ".esphome"
|
344
|
+
if build_dir.is_dir():
|
345
|
+
_LOGGER.info("Cleaning %s", build_dir)
|
346
|
+
# Don't remove storage as it will cause the dashboard to regenerate all configs
|
347
|
+
for item in build_dir.iterdir():
|
348
|
+
if item.is_file():
|
349
|
+
item.unlink()
|
350
|
+
elif item.name != "storage" and item.is_dir():
|
351
|
+
shutil.rmtree(item)
|
352
|
+
|
353
|
+
# Clean PlatformIO project files
|
354
|
+
try:
|
355
|
+
from platformio.project.config import ProjectConfig
|
356
|
+
except ImportError:
|
357
|
+
# PlatformIO is not available, skip cleaning
|
358
|
+
pass
|
359
|
+
else:
|
360
|
+
config = ProjectConfig.get_instance()
|
361
|
+
for pio_dir in ["cache_dir", "packages_dir", "platforms_dir", "core_dir"]:
|
362
|
+
path = Path(config.get("platformio", pio_dir))
|
363
|
+
if path.is_dir():
|
364
|
+
_LOGGER.info("Deleting PlatformIO %s %s", pio_dir, path)
|
365
|
+
shutil.rmtree(path)
|
366
|
+
|
367
|
+
|
332
368
|
GITIGNORE_CONTENT = """# Gitignore settings for ESPHome
|
333
369
|
# This is an example and may include too much for your use-case.
|
334
370
|
# You can modify this file to suit your needs.
|
@@ -339,6 +375,5 @@ GITIGNORE_CONTENT = """# Gitignore settings for ESPHome
|
|
339
375
|
|
340
376
|
def write_gitignore():
|
341
377
|
path = CORE.relative_config_path(".gitignore")
|
342
|
-
if not
|
343
|
-
|
344
|
-
f.write(GITIGNORE_CONTENT)
|
378
|
+
if not path.is_file():
|
379
|
+
path.write_text(GITIGNORE_CONTENT, encoding="utf-8")
|
esphome/yaml_util.py
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from collections.abc import Callable
|
4
|
-
import fnmatch
|
5
4
|
import functools
|
6
5
|
import inspect
|
7
6
|
from io import BytesIO, TextIOBase, TextIOWrapper
|
@@ -9,6 +8,7 @@ from ipaddress import _BaseAddress, _BaseNetwork
|
|
9
8
|
import logging
|
10
9
|
import math
|
11
10
|
import os
|
11
|
+
from pathlib import Path
|
12
12
|
from typing import Any
|
13
13
|
import uuid
|
14
14
|
|
@@ -69,7 +69,7 @@ class ESPHomeDataBase:
|
|
69
69
|
self._content_offset = database.content_offset
|
70
70
|
|
71
71
|
|
72
|
-
class
|
72
|
+
class ESPLiteralValue:
|
73
73
|
pass
|
74
74
|
|
75
75
|
|
@@ -109,7 +109,9 @@ def _add_data_ref(fn):
|
|
109
109
|
class ESPHomeLoaderMixin:
|
110
110
|
"""Loader class that keeps track of line numbers."""
|
111
111
|
|
112
|
-
def __init__(
|
112
|
+
def __init__(
|
113
|
+
self, name: Path, yaml_loader: Callable[[Path], dict[str, Any]]
|
114
|
+
) -> None:
|
113
115
|
"""Initialize the loader."""
|
114
116
|
self.name = name
|
115
117
|
self.yaml_loader = yaml_loader
|
@@ -254,12 +256,8 @@ class ESPHomeLoaderMixin:
|
|
254
256
|
f"Environment variable '{node.value}' not defined", node.start_mark
|
255
257
|
)
|
256
258
|
|
257
|
-
|
258
|
-
|
259
|
-
return os.path.dirname(self.name)
|
260
|
-
|
261
|
-
def _rel_path(self, *args: str) -> str:
|
262
|
-
return os.path.join(self._directory, *args)
|
259
|
+
def _rel_path(self, *args: str) -> Path:
|
260
|
+
return self.name.parent / Path(*args)
|
263
261
|
|
264
262
|
@_add_data_ref
|
265
263
|
def construct_secret(self, node: yaml.Node) -> str:
|
@@ -269,8 +267,8 @@ class ESPHomeLoaderMixin:
|
|
269
267
|
if self.name == CORE.config_path:
|
270
268
|
raise e
|
271
269
|
try:
|
272
|
-
main_config_dir =
|
273
|
-
main_secret_yml =
|
270
|
+
main_config_dir = CORE.config_path.parent
|
271
|
+
main_secret_yml = main_config_dir / SECRET_YAML
|
274
272
|
secrets = self.yaml_loader(main_secret_yml)
|
275
273
|
except EsphomeError as er:
|
276
274
|
raise EsphomeError(f"{e}\n{er}") from er
|
@@ -329,7 +327,7 @@ class ESPHomeLoaderMixin:
|
|
329
327
|
files = filter_yaml_files(_find_files(self._rel_path(node.value), "*.yaml"))
|
330
328
|
mapping = OrderedDict()
|
331
329
|
for fname in files:
|
332
|
-
filename =
|
330
|
+
filename = fname.stem
|
333
331
|
mapping[filename] = self.yaml_loader(fname)
|
334
332
|
return mapping
|
335
333
|
|
@@ -350,9 +348,15 @@ class ESPHomeLoaderMixin:
|
|
350
348
|
return Lambda(str(node.value))
|
351
349
|
|
352
350
|
@_add_data_ref
|
353
|
-
def
|
354
|
-
obj =
|
355
|
-
|
351
|
+
def construct_literal(self, node: yaml.Node) -> ESPLiteralValue:
|
352
|
+
obj = None
|
353
|
+
if isinstance(node, yaml.ScalarNode):
|
354
|
+
obj = self.construct_scalar(node)
|
355
|
+
elif isinstance(node, yaml.SequenceNode):
|
356
|
+
obj = self.construct_sequence(node)
|
357
|
+
elif isinstance(node, yaml.MappingNode):
|
358
|
+
obj = self.construct_mapping(node)
|
359
|
+
return add_class_to_obj(obj, ESPLiteralValue)
|
356
360
|
|
357
361
|
@_add_data_ref
|
358
362
|
def construct_extend(self, node: yaml.Node) -> Extend:
|
@@ -369,8 +373,8 @@ class ESPHomeLoader(ESPHomeLoaderMixin, FastestAvailableSafeLoader):
|
|
369
373
|
def __init__(
|
370
374
|
self,
|
371
375
|
stream: TextIOBase | BytesIO,
|
372
|
-
name:
|
373
|
-
yaml_loader: Callable[[
|
376
|
+
name: Path,
|
377
|
+
yaml_loader: Callable[[Path], dict[str, Any]],
|
374
378
|
) -> None:
|
375
379
|
FastestAvailableSafeLoader.__init__(self, stream)
|
376
380
|
ESPHomeLoaderMixin.__init__(self, name, yaml_loader)
|
@@ -382,8 +386,8 @@ class ESPHomePurePythonLoader(ESPHomeLoaderMixin, PurePythonLoader):
|
|
382
386
|
def __init__(
|
383
387
|
self,
|
384
388
|
stream: TextIOBase | BytesIO,
|
385
|
-
name:
|
386
|
-
yaml_loader: Callable[[
|
389
|
+
name: Path,
|
390
|
+
yaml_loader: Callable[[Path], dict[str, Any]],
|
387
391
|
) -> None:
|
388
392
|
PurePythonLoader.__init__(self, stream)
|
389
393
|
ESPHomeLoaderMixin.__init__(self, name, yaml_loader)
|
@@ -409,29 +413,29 @@ for _loader in (ESPHomeLoader, ESPHomePurePythonLoader):
|
|
409
413
|
"!include_dir_merge_named", _loader.construct_include_dir_merge_named
|
410
414
|
)
|
411
415
|
_loader.add_constructor("!lambda", _loader.construct_lambda)
|
412
|
-
_loader.add_constructor("!
|
416
|
+
_loader.add_constructor("!literal", _loader.construct_literal)
|
413
417
|
_loader.add_constructor("!extend", _loader.construct_extend)
|
414
418
|
_loader.add_constructor("!remove", _loader.construct_remove)
|
415
419
|
|
416
420
|
|
417
|
-
def load_yaml(fname:
|
421
|
+
def load_yaml(fname: Path, clear_secrets: bool = True) -> Any:
|
418
422
|
if clear_secrets:
|
419
423
|
_SECRET_VALUES.clear()
|
420
424
|
_SECRET_CACHE.clear()
|
421
425
|
return _load_yaml_internal(fname)
|
422
426
|
|
423
427
|
|
424
|
-
def _load_yaml_internal(fname:
|
428
|
+
def _load_yaml_internal(fname: Path) -> Any:
|
425
429
|
"""Load a YAML file."""
|
426
430
|
try:
|
427
|
-
with open(
|
431
|
+
with fname.open(encoding="utf-8") as f_handle:
|
428
432
|
return parse_yaml(fname, f_handle)
|
429
433
|
except (UnicodeDecodeError, OSError) as err:
|
430
434
|
raise EsphomeError(f"Error reading file {fname}: {err}") from err
|
431
435
|
|
432
436
|
|
433
437
|
def parse_yaml(
|
434
|
-
file_name:
|
438
|
+
file_name: Path, file_handle: TextIOWrapper, yaml_loader=_load_yaml_internal
|
435
439
|
) -> Any:
|
436
440
|
"""Parse a YAML file."""
|
437
441
|
try:
|
@@ -483,9 +487,9 @@ def substitute_vars(config, vars):
|
|
483
487
|
|
484
488
|
def _load_yaml_internal_with_type(
|
485
489
|
loader_type: type[ESPHomeLoader] | type[ESPHomePurePythonLoader],
|
486
|
-
fname:
|
490
|
+
fname: Path,
|
487
491
|
content: TextIOWrapper,
|
488
|
-
yaml_loader: Any,
|
492
|
+
yaml_loader: Callable[[Path], dict[str, Any]],
|
489
493
|
) -> Any:
|
490
494
|
"""Load a YAML file."""
|
491
495
|
loader = loader_type(content, fname, yaml_loader)
|
@@ -512,13 +516,14 @@ def _is_file_valid(name: str) -> bool:
|
|
512
516
|
return not name.startswith(".")
|
513
517
|
|
514
518
|
|
515
|
-
def _find_files(directory, pattern):
|
519
|
+
def _find_files(directory: Path, pattern):
|
516
520
|
"""Recursively load files in a directory."""
|
517
|
-
for root, dirs, files in os.walk(directory
|
521
|
+
for root, dirs, files in os.walk(directory):
|
518
522
|
dirs[:] = [d for d in dirs if _is_file_valid(d)]
|
519
|
-
for
|
520
|
-
|
521
|
-
|
523
|
+
for f in files:
|
524
|
+
filename = Path(f)
|
525
|
+
if _is_file_valid(f) and filename.match(pattern):
|
526
|
+
filename = Path(root) / filename
|
522
527
|
yield filename
|
523
528
|
|
524
529
|
|
@@ -627,3 +632,4 @@ ESPHomeDumper.add_multi_representer(TimePeriod, ESPHomeDumper.represent_stringif
|
|
627
632
|
ESPHomeDumper.add_multi_representer(Lambda, ESPHomeDumper.represent_lambda)
|
628
633
|
ESPHomeDumper.add_multi_representer(core.ID, ESPHomeDumper.represent_id)
|
629
634
|
ESPHomeDumper.add_multi_representer(uuid.UUID, ESPHomeDumper.represent_stringify)
|
635
|
+
ESPHomeDumper.add_multi_representer(Path, ESPHomeDumper.represent_stringify)
|
esphome/zeroconf.py
CHANGED
@@ -68,8 +68,11 @@ class DashboardBrowser(AsyncServiceBrowser):
|
|
68
68
|
|
69
69
|
|
70
70
|
class DashboardImportDiscovery:
|
71
|
-
def __init__(
|
71
|
+
def __init__(
|
72
|
+
self, on_update: Callable[[str, DiscoveredImport | None], None] | None = None
|
73
|
+
) -> None:
|
72
74
|
self.import_state: dict[str, DiscoveredImport] = {}
|
75
|
+
self.on_update = on_update
|
73
76
|
|
74
77
|
def browser_callback(
|
75
78
|
self,
|
@@ -85,7 +88,9 @@ class DashboardImportDiscovery:
|
|
85
88
|
state_change,
|
86
89
|
)
|
87
90
|
if state_change == ServiceStateChange.Removed:
|
88
|
-
self.import_state.pop(name, None)
|
91
|
+
removed = self.import_state.pop(name, None)
|
92
|
+
if removed and self.on_update:
|
93
|
+
self.on_update(name, None)
|
89
94
|
return
|
90
95
|
|
91
96
|
if state_change == ServiceStateChange.Updated and name not in self.import_state:
|
@@ -139,7 +144,7 @@ class DashboardImportDiscovery:
|
|
139
144
|
if friendly_name is not None:
|
140
145
|
friendly_name = friendly_name.decode()
|
141
146
|
|
142
|
-
|
147
|
+
discovered = DiscoveredImport(
|
143
148
|
friendly_name=friendly_name,
|
144
149
|
device_name=node_name,
|
145
150
|
package_import_url=import_url,
|
@@ -147,6 +152,10 @@ class DashboardImportDiscovery:
|
|
147
152
|
project_version=project_version,
|
148
153
|
network=network,
|
149
154
|
)
|
155
|
+
is_new = name not in self.import_state
|
156
|
+
self.import_state[name] = discovered
|
157
|
+
if is_new and self.on_update:
|
158
|
+
self.on_update(name, discovered)
|
150
159
|
|
151
160
|
def update_device_mdns(self, node_name: str, version: str):
|
152
161
|
storage_path = ext_storage_path(node_name + ".yaml")
|
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: esphome
|
3
|
-
Version: 2025.
|
3
|
+
Version: 2025.10.0b2
|
4
4
|
Summary: ESPHome is a system to configure your microcontrollers by simple yet powerful configuration files and control them remotely through Home Automation systems.
|
5
5
|
Author-email: The ESPHome Authors <esphome@openhomefoundation.org>
|
6
|
-
License: MIT
|
6
|
+
License-Expression: MIT
|
7
7
|
Project-URL: Documentation, https://esphome.io
|
8
8
|
Project-URL: Source Code, https://github.com/esphome/esphome
|
9
9
|
Project-URL: Bug Tracker, https://github.com/esphome/esphome/issues
|
@@ -16,7 +16,6 @@ Platform: any
|
|
16
16
|
Classifier: Environment :: Console
|
17
17
|
Classifier: Intended Audience :: Developers
|
18
18
|
Classifier: Intended Audience :: End Users/Desktop
|
19
|
-
Classifier: License :: OSI Approved :: MIT License
|
20
19
|
Classifier: Programming Language :: C++
|
21
20
|
Classifier: Programming Language :: Python :: 3
|
22
21
|
Classifier: Topic :: Home Automation
|
@@ -25,7 +24,7 @@ Description-Content-Type: text/markdown
|
|
25
24
|
License-File: LICENSE
|
26
25
|
Requires-Dist: cryptography==45.0.1
|
27
26
|
Requires-Dist: voluptuous==0.15.2
|
28
|
-
Requires-Dist: PyYAML==6.0.
|
27
|
+
Requires-Dist: PyYAML==6.0.3
|
29
28
|
Requires-Dist: paho-mqtt==1.6.1
|
30
29
|
Requires-Dist: colorama==0.4.6
|
31
30
|
Requires-Dist: icmplib==3.0.4
|
@@ -34,13 +33,14 @@ Requires-Dist: tzlocal==5.3.1
|
|
34
33
|
Requires-Dist: tzdata>=2021.1
|
35
34
|
Requires-Dist: pyserial==3.5
|
36
35
|
Requires-Dist: platformio==6.1.18
|
37
|
-
Requires-Dist: esptool==5.0
|
36
|
+
Requires-Dist: esptool==5.1.0
|
38
37
|
Requires-Dist: click==8.1.7
|
39
|
-
Requires-Dist: esphome-dashboard==
|
40
|
-
Requires-Dist: aioesphomeapi==
|
41
|
-
Requires-Dist: zeroconf==0.
|
38
|
+
Requires-Dist: esphome-dashboard==20251009.0
|
39
|
+
Requires-Dist: aioesphomeapi==41.14.0
|
40
|
+
Requires-Dist: zeroconf==0.148.0
|
42
41
|
Requires-Dist: puremagic==1.30
|
43
42
|
Requires-Dist: ruamel.yaml==0.18.15
|
43
|
+
Requires-Dist: ruamel.yaml.clib==0.2.12
|
44
44
|
Requires-Dist: esphome-glyphsets==0.2.0
|
45
45
|
Requires-Dist: pillow==10.4.0
|
46
46
|
Requires-Dist: cairosvg==2.8.2
|
@@ -54,15 +54,15 @@ Requires-Dist: clang-format==13.0.1; extra == "dev"
|
|
54
54
|
Requires-Dist: clang-tidy==18.1.8; extra == "dev"
|
55
55
|
Requires-Dist: yamllint==1.37.1; extra == "dev"
|
56
56
|
Provides-Extra: test
|
57
|
-
Requires-Dist: pylint==3.3.
|
57
|
+
Requires-Dist: pylint==3.3.9; extra == "test"
|
58
58
|
Requires-Dist: flake8==7.3.0; extra == "test"
|
59
|
-
Requires-Dist: ruff==0.
|
59
|
+
Requires-Dist: ruff==0.14.0; extra == "test"
|
60
60
|
Requires-Dist: pyupgrade==3.20.0; extra == "test"
|
61
61
|
Requires-Dist: pre-commit; extra == "test"
|
62
62
|
Requires-Dist: pytest==8.4.2; extra == "test"
|
63
63
|
Requires-Dist: pytest-cov==7.0.0; extra == "test"
|
64
|
-
Requires-Dist: pytest-mock==3.15.
|
65
|
-
Requires-Dist: pytest-asyncio==1.
|
64
|
+
Requires-Dist: pytest-mock==3.15.1; extra == "test"
|
65
|
+
Requires-Dist: pytest-asyncio==1.2.0; extra == "test"
|
66
66
|
Requires-Dist: pytest-xdist==3.8.0; extra == "test"
|
67
67
|
Requires-Dist: asyncmock==0.4.2; extra == "test"
|
68
68
|
Requires-Dist: hypothesis==6.92.1; extra == "test"
|