esphome 2025.9.3__py3-none-any.whl → 2025.10.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 +87 -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 +4 -4
- 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/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 +254 -339
- esphome/components/esp32/boards.py +81 -0
- esphome/components/esp32/preferences.cpp +23 -17
- esphome/components/esp32_ble/__init__.py +159 -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_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 -4
- 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 +102 -44
- esphome/components/esp32_improv/esp32_improv_component.h +6 -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 +455 -145
- 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 +35 -43
- 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/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 +19 -6
- esphome/components/mdns/mdns_component.cpp +27 -59
- esphome/components/mdns/mdns_component.h +23 -10
- esphome/components/mdns/mdns_esp32.cpp +7 -7
- esphome/components/mdns/mdns_esp8266.cpp +6 -6
- esphome/components/mdns/mdns_libretiny.cpp +3 -3
- esphome/components/mdns/mdns_rp2040.cpp +3 -3
- 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/openthread/openthread.cpp +6 -7
- 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 +36 -26
- 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 +2 -1
- esphome/components/usb_host/usb_host.h +82 -13
- esphome/components/usb_host/usb_host_client.cpp +180 -24
- 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 +73 -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 +31 -22
- esphome/core/component.cpp +28 -18
- esphome/core/component_iterator.h +2 -1
- esphome/core/config.py +15 -15
- esphome/core/defines.h +19 -0
- 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 +111 -31
- esphome/external_files.py +6 -7
- esphome/git.py +8 -0
- esphome/helpers.py +124 -77
- esphome/loader.py +8 -9
- esphome/platformio_api.py +25 -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.0b1.dist-info}/METADATA +11 -11
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/RECORD +332 -312
- 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.0b1.dist-info}/WHEEL +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/top_level.txt +0 -0
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.0b1
|
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
38
|
Requires-Dist: esphome-dashboard==20250904.0
|
40
|
-
Requires-Dist: aioesphomeapi==
|
41
|
-
Requires-Dist: zeroconf==0.
|
39
|
+
Requires-Dist: aioesphomeapi==41.13.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"
|