diff --git a/esphome/components/adc/__init__.py b/esphome/components/adc/__init__.py index 5f94c61a08..c3ababbb84 100644 --- a/esphome/components/adc/__init__.py +++ b/esphome/components/adc/__init__.py @@ -11,7 +11,13 @@ from esphome.components.esp32.const import ( VARIANT_ESP32S3, ) import esphome.config_validation as cv -from esphome.const import CONF_ANALOG, CONF_INPUT, CONF_NUMBER, PLATFORM_ESP8266 +from esphome.const import ( + CONF_ANALOG, + CONF_INPUT, + CONF_NUMBER, + PLATFORM_ESP8266, + PlatformFramework, +) from esphome.core import CORE CODEOWNERS = ["@esphome/core"] @@ -229,3 +235,18 @@ def validate_adc_pin(value): )(value) raise NotImplementedError + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "adc_sensor_esp32.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP32_IDF, + }, + "adc_sensor_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "adc_sensor_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO}, + "adc_sensor_libretiny.cpp": { + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, +} diff --git a/esphome/components/debug/__init__.py b/esphome/components/debug/__init__.py index 1955b5d22c..b5cdef4f0e 100644 --- a/esphome/components/debug/__init__.py +++ b/esphome/components/debug/__init__.py @@ -7,6 +7,7 @@ from esphome.const import ( CONF_FREE, CONF_ID, CONF_LOOP_TIME, + PlatformFramework, ) CODEOWNERS = ["@OttoWinter"] @@ -44,3 +45,16 @@ CONFIG_SCHEMA = cv.All( async def to_code(config): var = cg.new_Pvariable(config[CONF_ID]) await cg.register_component(var, config) + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "debug_esp32.cpp": {PlatformFramework.ESP32_ARDUINO, PlatformFramework.ESP32_IDF}, + "debug_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "debug_host.cpp": {PlatformFramework.HOST_NATIVE}, + "debug_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO}, + "debug_libretiny.cpp": { + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, +} diff --git a/esphome/components/deep_sleep/__init__.py b/esphome/components/deep_sleep/__init__.py index 63b359bd5b..096d2eaa38 100644 --- a/esphome/components/deep_sleep/__init__.py +++ b/esphome/components/deep_sleep/__init__.py @@ -27,6 +27,7 @@ from esphome.const import ( CONF_WAKEUP_PIN, PLATFORM_ESP32, PLATFORM_ESP8266, + PlatformFramework, ) WAKEUP_PINS = { @@ -313,3 +314,12 @@ async def deep_sleep_action_to_code(config, action_id, template_arg, args): var = cg.new_Pvariable(action_id, template_arg) await cg.register_parented(var, config[CONF_ID]) return var + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "deep_sleep_esp32.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP32_IDF, + }, + "deep_sleep_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, +} diff --git a/esphome/components/http_request/__init__.py b/esphome/components/http_request/__init__.py index 18373edb77..0eaecaac45 100644 --- a/esphome/components/http_request/__init__.py +++ b/esphome/components/http_request/__init__.py @@ -13,6 +13,7 @@ from esphome.const import ( CONF_URL, CONF_WATCHDOG_TIMEOUT, PLATFORM_HOST, + PlatformFramework, __version__, ) from esphome.core import CORE, Lambda @@ -319,3 +320,17 @@ async def http_request_action_to_code(config, action_id, template_arg, args): await automation.build_automation(trigger, [], conf) return var + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "http_request_host.cpp": {PlatformFramework.HOST_NATIVE}, + "http_request_arduino.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP8266_ARDUINO, + PlatformFramework.RP2040_ARDUINO, + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, + "http_request_idf.cpp": {PlatformFramework.ESP32_IDF}, +} diff --git a/esphome/components/i2c/__init__.py b/esphome/components/i2c/__init__.py index 6adb9b71aa..db52479783 100644 --- a/esphome/components/i2c/__init__.py +++ b/esphome/components/i2c/__init__.py @@ -18,6 +18,7 @@ from esphome.const import ( PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_RP2040, + PlatformFramework, ) from esphome.core import CORE, coroutine_with_priority import esphome.final_validate as fv @@ -205,3 +206,16 @@ def final_validate_device_schema( {cv.Required(CONF_I2C_ID): fv.id_declaration_match_schema(hub_schema)}, extra=cv.ALLOW_EXTRA, ) + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "i2c_bus_arduino.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP8266_ARDUINO, + PlatformFramework.RP2040_ARDUINO, + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, + "i2c_bus_esp_idf.cpp": {PlatformFramework.ESP32_IDF}, +} diff --git a/esphome/components/libretiny/__init__.py b/esphome/components/libretiny/__init__.py index 149e5d1179..e4f6f15576 100644 --- a/esphome/components/libretiny/__init__.py +++ b/esphome/components/libretiny/__init__.py @@ -20,6 +20,7 @@ from esphome.const import ( KEY_FRAMEWORK_VERSION, KEY_TARGET_FRAMEWORK, KEY_TARGET_PLATFORM, + PlatformFramework, __version__, ) from esphome.core import CORE @@ -340,3 +341,12 @@ async def component_to_code(config): cg.add_platformio_option("custom_fw_version", __version__) await cg.register_component(var, config) + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "gpio_arduino.cpp": { + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, +} diff --git a/esphome/components/logger/__init__.py b/esphome/components/logger/__init__.py index 3d4907aa6e..4f65907210 100644 --- a/esphome/components/logger/__init__.py +++ b/esphome/components/logger/__init__.py @@ -42,6 +42,7 @@ from esphome.const import ( PLATFORM_LN882X, PLATFORM_RP2040, PLATFORM_RTL87XX, + PlatformFramework, ) from esphome.core import CORE, Lambda, coroutine_with_priority @@ -444,3 +445,20 @@ async def logger_set_level_to_code(config, action_id, template_arg, args): lambda_ = await cg.process_lambda(Lambda(text), args, return_type=cg.void) return cg.new_Pvariable(action_id, template_arg, lambda_) + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "logger_esp32.cpp": {PlatformFramework.ESP32_ARDUINO, PlatformFramework.ESP32_IDF}, + "logger_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "logger_host.cpp": {PlatformFramework.HOST_NATIVE}, + "logger_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO}, + "logger_libretiny.cpp": { + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, + "task_log_buffer.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP32_IDF, + }, +} diff --git a/esphome/components/mdns/__init__.py b/esphome/components/mdns/__init__.py index ed230d43aa..43d214d77b 100644 --- a/esphome/components/mdns/__init__.py +++ b/esphome/components/mdns/__init__.py @@ -8,6 +8,7 @@ from esphome.const import ( CONF_PROTOCOL, CONF_SERVICE, CONF_SERVICES, + PlatformFramework, ) from esphome.core import CORE, coroutine_with_priority @@ -108,3 +109,16 @@ async def to_code(config): ) cg.add(var.add_extra_service(exp)) + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "mdns_esp32.cpp": {PlatformFramework.ESP32_ARDUINO, PlatformFramework.ESP32_IDF}, + "mdns_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "mdns_host.cpp": {PlatformFramework.HOST_NATIVE}, + "mdns_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO}, + "mdns_libretiny.cpp": { + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, +} diff --git a/esphome/components/mqtt/__init__.py b/esphome/components/mqtt/__init__.py index f0d5a95d43..101761be9d 100644 --- a/esphome/components/mqtt/__init__.py +++ b/esphome/components/mqtt/__init__.py @@ -54,6 +54,7 @@ from esphome.const import ( PLATFORM_BK72XX, PLATFORM_ESP32, PLATFORM_ESP8266, + PlatformFramework, ) from esphome.core import CORE, coroutine_with_priority @@ -596,3 +597,11 @@ async def mqtt_enable_to_code(config, action_id, template_arg, args): async def mqtt_disable_to_code(config, action_id, template_arg, args): paren = await cg.get_variable(config[CONF_ID]) return cg.new_Pvariable(action_id, template_arg, paren) + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "mqtt_backend_esp32.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP32_IDF, + }, +} diff --git a/esphome/components/nextion/__init__.py b/esphome/components/nextion/__init__.py index fb75daf4ba..332c27409c 100644 --- a/esphome/components/nextion/__init__.py +++ b/esphome/components/nextion/__init__.py @@ -1,5 +1,6 @@ import esphome.codegen as cg from esphome.components import uart +from esphome.const import PlatformFramework nextion_ns = cg.esphome_ns.namespace("nextion") Nextion = nextion_ns.class_("Nextion", cg.PollingComponent, uart.UARTDevice) @@ -8,3 +9,15 @@ nextion_ref = Nextion.operator("ref") CONF_NEXTION_ID = "nextion_id" CONF_PUBLISH_STATE = "publish_state" CONF_SEND_TO_NEXTION = "send_to_nextion" + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "nextion_upload_arduino.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP8266_ARDUINO, + PlatformFramework.RP2040_ARDUINO, + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, + "nextion_upload_idf.cpp": {PlatformFramework.ESP32_IDF}, +} diff --git a/esphome/components/ota/__init__.py b/esphome/components/ota/__init__.py index 627c55e910..bd7a97536c 100644 --- a/esphome/components/ota/__init__.py +++ b/esphome/components/ota/__init__.py @@ -7,6 +7,7 @@ from esphome.const import ( CONF_OTA, CONF_PLATFORM, CONF_TRIGGER_ID, + PlatformFramework, ) from esphome.core import CORE, coroutine_with_priority @@ -120,3 +121,16 @@ async def ota_to_code(var, config): use_state_callback = True if use_state_callback: cg.add_define("USE_OTA_STATE_CALLBACK") + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "ota_backend_arduino_esp32.cpp": {PlatformFramework.ESP32_ARDUINO}, + "ota_backend_esp_idf.cpp": {PlatformFramework.ESP32_IDF}, + "ota_backend_arduino_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "ota_backend_arduino_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO}, + "ota_backend_arduino_libretiny.cpp": { + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, +} diff --git a/esphome/components/remote_receiver/__init__.py b/esphome/components/remote_receiver/__init__.py index 5de7d8c9c4..f395aea3c8 100644 --- a/esphome/components/remote_receiver/__init__.py +++ b/esphome/components/remote_receiver/__init__.py @@ -15,6 +15,7 @@ from esphome.const import ( CONF_TYPE, CONF_USE_DMA, CONF_VALUE, + PlatformFramework, ) from esphome.core import CORE, TimePeriod @@ -170,3 +171,17 @@ async def to_code(config): cg.add(var.set_buffer_size(config[CONF_BUFFER_SIZE])) cg.add(var.set_filter_us(config[CONF_FILTER])) cg.add(var.set_idle_us(config[CONF_IDLE])) + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "remote_receiver_esp32.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP32_IDF, + }, + "remote_receiver_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "remote_receiver_libretiny.cpp": { + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, +} diff --git a/esphome/components/remote_transmitter/__init__.py b/esphome/components/remote_transmitter/__init__.py index 713cee0186..1e935354f9 100644 --- a/esphome/components/remote_transmitter/__init__.py +++ b/esphome/components/remote_transmitter/__init__.py @@ -12,6 +12,7 @@ from esphome.const import ( CONF_PIN, CONF_RMT_SYMBOLS, CONF_USE_DMA, + PlatformFramework, ) from esphome.core import CORE @@ -95,3 +96,17 @@ async def to_code(config): await automation.build_automation( var.get_complete_trigger(), [], on_complete_config ) + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "remote_transmitter_esp32.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP32_IDF, + }, + "remote_transmitter_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "remote_transmitter_libretiny.cpp": { + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, +} diff --git a/esphome/components/spi/__init__.py b/esphome/components/spi/__init__.py index 55a4b9c8f6..43fd6920ac 100644 --- a/esphome/components/spi/__init__.py +++ b/esphome/components/spi/__init__.py @@ -31,6 +31,7 @@ from esphome.const import ( PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_RP2040, + PlatformFramework, ) from esphome.core import CORE, coroutine_with_priority import esphome.final_validate as fv @@ -423,3 +424,16 @@ def final_validate_device_schema(name: str, *, require_mosi: bool, require_miso: {cv.Required(CONF_SPI_ID): fv.id_declaration_match_schema(hub_schema)}, extra=cv.ALLOW_EXTRA, ) + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "spi_arduino.cpp": { + PlatformFramework.ESP32_ARDUINO, + PlatformFramework.ESP8266_ARDUINO, + PlatformFramework.RP2040_ARDUINO, + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, + "spi_esp_idf.cpp": {PlatformFramework.ESP32_IDF}, +} diff --git a/esphome/components/uart/__init__.py b/esphome/components/uart/__init__.py index a0908a299c..03341b5ff3 100644 --- a/esphome/components/uart/__init__.py +++ b/esphome/components/uart/__init__.py @@ -27,6 +27,7 @@ from esphome.const import ( CONF_TX_PIN, CONF_UART_ID, PLATFORM_HOST, + PlatformFramework, ) from esphome.core import CORE import esphome.final_validate as fv @@ -438,3 +439,17 @@ async def uart_write_to_code(config, action_id, template_arg, args): else: cg.add(var.set_data_static(data)) return var + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "uart_component_esp32_arduino.cpp": {PlatformFramework.ESP32_ARDUINO}, + "uart_component_esp_idf.cpp": {PlatformFramework.ESP32_IDF}, + "uart_component_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "uart_component_host.cpp": {PlatformFramework.HOST_NATIVE}, + "uart_component_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO}, + "uart_component_libretiny.cpp": { + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, +} diff --git a/esphome/components/wifi/__init__.py b/esphome/components/wifi/__init__.py index e8ae9b1b4e..47c59af241 100644 --- a/esphome/components/wifi/__init__.py +++ b/esphome/components/wifi/__init__.py @@ -39,6 +39,7 @@ from esphome.const import ( CONF_TTLS_PHASE_2, CONF_USE_ADDRESS, CONF_USERNAME, + PlatformFramework, ) from esphome.core import CORE, HexInt, coroutine_with_priority import esphome.final_validate as fv @@ -526,3 +527,15 @@ async def wifi_set_sta_to_code(config, action_id, template_arg, args): await automation.build_automation(var.get_error_trigger(), [], on_error_config) await cg.register_component(var, config) return var + + +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "wifi_component_esp32_arduino.cpp": {PlatformFramework.ESP32_ARDUINO}, + "wifi_component_esp_idf.cpp": {PlatformFramework.ESP32_IDF}, + "wifi_component_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO}, + "wifi_component_libretiny.cpp": { + PlatformFramework.BK72XX_ARDUINO, + PlatformFramework.RTL87XX_ARDUINO, + PlatformFramework.LN882X_ARDUINO, + }, +} diff --git a/esphome/const.py b/esphome/const.py index 4aeb5179e6..085b9b39b8 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,5 +1,9 @@ """Constants used by esphome.""" +from enum import Enum + +from esphome.enum import StrEnum + __version__ = "2025.7.0-dev" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" @@ -7,14 +11,55 @@ VALID_SUBSTITUTIONS_CHARACTERS = ( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_" ) -PLATFORM_BK72XX = "bk72xx" -PLATFORM_ESP32 = "esp32" -PLATFORM_ESP8266 = "esp8266" -PLATFORM_HOST = "host" -PLATFORM_LIBRETINY_OLDSTYLE = "libretiny" -PLATFORM_LN882X = "ln882x" -PLATFORM_RP2040 = "rp2040" -PLATFORM_RTL87XX = "rtl87xx" + +class Platform(StrEnum): + """Platform identifiers for ESPHome.""" + + BK72XX = "bk72xx" + ESP32 = "esp32" + ESP8266 = "esp8266" + HOST = "host" + LIBRETINY_OLDSTYLE = "libretiny" + LN882X = "ln882x" + RP2040 = "rp2040" + RTL87XX = "rtl87xx" + + +class Framework(StrEnum): + """Framework identifiers for ESPHome.""" + + ARDUINO = "arduino" + ESP_IDF = "esp-idf" + NATIVE = "host" + + +class PlatformFramework(Enum): + """Combined platform-framework identifiers with tuple values.""" + + # ESP32 variants + ESP32_ARDUINO = (Platform.ESP32, Framework.ARDUINO) + ESP32_IDF = (Platform.ESP32, Framework.ESP_IDF) + + # Arduino framework platforms + ESP8266_ARDUINO = (Platform.ESP8266, Framework.ARDUINO) + RP2040_ARDUINO = (Platform.RP2040, Framework.ARDUINO) + BK72XX_ARDUINO = (Platform.BK72XX, Framework.ARDUINO) + RTL87XX_ARDUINO = (Platform.RTL87XX, Framework.ARDUINO) + LN882X_ARDUINO = (Platform.LN882X, Framework.ARDUINO) + + # Host platform (native) + HOST_NATIVE = (Platform.HOST, Framework.NATIVE) + + +# Maintain backward compatibility by reassigning after enum definition +PLATFORM_BK72XX = Platform.BK72XX +PLATFORM_ESP32 = Platform.ESP32 +PLATFORM_ESP8266 = Platform.ESP8266 +PLATFORM_HOST = Platform.HOST +PLATFORM_LIBRETINY_OLDSTYLE = Platform.LIBRETINY_OLDSTYLE +PLATFORM_LN882X = Platform.LN882X +PLATFORM_RP2040 = Platform.RP2040 +PLATFORM_RTL87XX = Platform.RTL87XX SOURCE_FILE_EXTENSIONS = {".cpp", ".hpp", ".h", ".c", ".tcc", ".ino"} diff --git a/esphome/core/config.py b/esphome/core/config.py index 641c73a292..cfff50a5c8 100644 --- a/esphome/core/config.py +++ b/esphome/core/config.py @@ -35,6 +35,7 @@ from esphome.const import ( CONF_TRIGGER_ID, CONF_VERSION, KEY_CORE, + PlatformFramework, __version__ as ESPHOME_VERSION, ) from esphome.core import CORE, coroutine_with_priority @@ -551,3 +552,11 @@ async def to_code(config: ConfigType) -> None: cg.add(dev.set_area_id(area_id_hash)) cg.add(cg.App.register_device(dev)) + + +# Platform-specific source files for core +PLATFORM_SOURCE_FILES: dict[str, set[PlatformFramework]] = { + "ring_buffer.cpp": {PlatformFramework.ESP32_ARDUINO, PlatformFramework.ESP32_IDF}, + # Note: lock_free_queue.h and event_pool.h are header files and don't need to be filtered + # as they are only included when needed by the preprocessor +} diff --git a/esphome/dashboard/entries.py b/esphome/dashboard/entries.py index e4825298f7..b138cfd272 100644 --- a/esphome/dashboard/entries.py +++ b/esphome/dashboard/entries.py @@ -9,6 +9,7 @@ import os from typing import TYPE_CHECKING, Any from esphome import const, util +from esphome.enum import StrEnum from esphome.storage_json import StorageJSON, ext_storage_path from .const import ( @@ -18,7 +19,6 @@ from .const import ( EVENT_ENTRY_STATE_CHANGED, EVENT_ENTRY_UPDATED, ) -from .enum import StrEnum from .util.subprocess import async_run_system_command if TYPE_CHECKING: diff --git a/esphome/dashboard/enum.py b/esphome/enum.py similarity index 100% rename from esphome/dashboard/enum.py rename to esphome/enum.py diff --git a/esphome/loader.py b/esphome/loader.py index 79a1d7f576..21e822da73 100644 --- a/esphome/loader.py +++ b/esphome/loader.py @@ -11,13 +11,26 @@ import sys from types import ModuleType from typing import Any -from esphome.const import SOURCE_FILE_EXTENSIONS +from esphome.const import ( + KEY_CORE, + KEY_TARGET_FRAMEWORK, + KEY_TARGET_PLATFORM, + SOURCE_FILE_EXTENSIONS, + Framework, + Platform, + PlatformFramework, +) from esphome.core import CORE import esphome.core.config from esphome.types import ConfigType _LOGGER = logging.getLogger(__name__) +# Build unified lookup table from PlatformFramework enum +_PLATFORM_FRAMEWORK_LOOKUP: dict[ + tuple[Platform, Framework | None], PlatformFramework +] = {pf.value: pf for pf in PlatformFramework} + @dataclass(frozen=True, order=True) class FileResource: @@ -107,13 +120,33 @@ class ComponentManifest: @property def resources(self) -> list[FileResource]: - """Return a list of all file resources defined in the package of this component. + """Return a list of all file resources defined in the package of this component.""" + ret: list[FileResource] = [] - This will return all cpp source files that are located in the same folder as the - loaded .py file (does not look through subdirectories) - """ - ret = [] + # Get current platform-framework combination + core_data: dict[str, Any] = CORE.data.get(KEY_CORE, {}) + target_platform: Platform | None = core_data.get(KEY_TARGET_PLATFORM) + target_framework: Framework | None = core_data.get(KEY_TARGET_FRAMEWORK) + # Get platform-specific files mapping + platform_source_files: dict[str, set[PlatformFramework]] = getattr( + self.module, "PLATFORM_SOURCE_FILES", {} + ) + + # Get current PlatformFramework + lookup_key = (target_platform, target_framework) + current_platform_framework: PlatformFramework | None = ( + _PLATFORM_FRAMEWORK_LOOKUP.get(lookup_key) + ) + + # Build set of allowed filenames for current platform + allowed_filenames: set[str] = set() + if current_platform_framework and platform_source_files: + for filename, platforms in platform_source_files.items(): + if current_platform_framework in platforms: + allowed_filenames.add(filename) + + # Process all resources for resource in ( r.name for r in importlib.resources.files(self.package).iterdir() @@ -122,8 +155,13 @@ class ComponentManifest: if Path(resource).suffix not in SOURCE_FILE_EXTENSIONS: continue if not importlib.resources.files(self.package).joinpath(resource).is_file(): - # Not a resource = this is a directory (yeah this is confusing) continue + + # Check platform restrictions only if file is platform-specific + # Common files (not in platform_source_files) are always included + if resource in platform_source_files and resource not in allowed_filenames: + continue + ret.append(FileResource(self.package, resource)) return ret