mirror of
https://github.com/esphome/esphome.git
synced 2025-07-29 14:46:40 +00:00
[esp32] Improve and simplify IDF component support (#9163)
This commit is contained in:
parent
9daa9a6de8
commit
92365f133d
@ -4,7 +4,7 @@ import logging
|
|||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from esphome import git
|
from esphome import yaml_util
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
@ -23,7 +23,6 @@ from esphome.const import (
|
|||||||
CONF_REFRESH,
|
CONF_REFRESH,
|
||||||
CONF_SOURCE,
|
CONF_SOURCE,
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
CONF_URL,
|
|
||||||
CONF_VARIANT,
|
CONF_VARIANT,
|
||||||
CONF_VERSION,
|
CONF_VERSION,
|
||||||
KEY_CORE,
|
KEY_CORE,
|
||||||
@ -32,14 +31,13 @@ from esphome.const import (
|
|||||||
KEY_TARGET_FRAMEWORK,
|
KEY_TARGET_FRAMEWORK,
|
||||||
KEY_TARGET_PLATFORM,
|
KEY_TARGET_PLATFORM,
|
||||||
PLATFORM_ESP32,
|
PLATFORM_ESP32,
|
||||||
TYPE_GIT,
|
|
||||||
TYPE_LOCAL,
|
|
||||||
__version__,
|
__version__,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, HexInt, TimePeriod
|
from esphome.core import CORE, HexInt, TimePeriod
|
||||||
from esphome.cpp_generator import RawExpression
|
from esphome.cpp_generator import RawExpression
|
||||||
import esphome.final_validate as fv
|
import esphome.final_validate as fv
|
||||||
from esphome.helpers import copy_file_if_changed, mkdir_p, write_file_if_changed
|
from esphome.helpers import copy_file_if_changed, mkdir_p, write_file_if_changed
|
||||||
|
from esphome.types import ConfigType
|
||||||
|
|
||||||
from .boards import BOARDS
|
from .boards import BOARDS
|
||||||
from .const import ( # noqa
|
from .const import ( # noqa
|
||||||
@ -49,10 +47,8 @@ from .const import ( # noqa
|
|||||||
KEY_EXTRA_BUILD_FILES,
|
KEY_EXTRA_BUILD_FILES,
|
||||||
KEY_PATH,
|
KEY_PATH,
|
||||||
KEY_REF,
|
KEY_REF,
|
||||||
KEY_REFRESH,
|
|
||||||
KEY_REPO,
|
KEY_REPO,
|
||||||
KEY_SDKCONFIG_OPTIONS,
|
KEY_SDKCONFIG_OPTIONS,
|
||||||
KEY_SUBMODULES,
|
|
||||||
KEY_VARIANT,
|
KEY_VARIANT,
|
||||||
VARIANT_ESP32,
|
VARIANT_ESP32,
|
||||||
VARIANT_ESP32C2,
|
VARIANT_ESP32C2,
|
||||||
@ -235,7 +231,7 @@ def add_idf_sdkconfig_option(name: str, value: SdkconfigValueType):
|
|||||||
def add_idf_component(
|
def add_idf_component(
|
||||||
*,
|
*,
|
||||||
name: str,
|
name: str,
|
||||||
repo: str,
|
repo: str = None,
|
||||||
ref: str = None,
|
ref: str = None,
|
||||||
path: str = None,
|
path: str = None,
|
||||||
refresh: TimePeriod = None,
|
refresh: TimePeriod = None,
|
||||||
@ -245,30 +241,27 @@ def add_idf_component(
|
|||||||
"""Add an esp-idf component to the project."""
|
"""Add an esp-idf component to the project."""
|
||||||
if not CORE.using_esp_idf:
|
if not CORE.using_esp_idf:
|
||||||
raise ValueError("Not an esp-idf project")
|
raise ValueError("Not an esp-idf project")
|
||||||
if components is None:
|
if not repo and not ref and not path:
|
||||||
components = []
|
raise ValueError("Requires at least one of repo, ref or path")
|
||||||
if name not in CORE.data[KEY_ESP32][KEY_COMPONENTS]:
|
if refresh or submodules or components:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"The refresh, components and submodules parameters in add_idf_component() are "
|
||||||
|
"deprecated and will be removed in ESPHome 2026.1. If you are seeing this, report "
|
||||||
|
"an issue to the external_component author and ask them to update it."
|
||||||
|
)
|
||||||
|
if components:
|
||||||
|
for comp in components:
|
||||||
|
CORE.data[KEY_ESP32][KEY_COMPONENTS][comp] = {
|
||||||
|
KEY_REPO: repo,
|
||||||
|
KEY_REF: ref,
|
||||||
|
KEY_PATH: f"{path}/{comp}" if path else comp,
|
||||||
|
}
|
||||||
|
else:
|
||||||
CORE.data[KEY_ESP32][KEY_COMPONENTS][name] = {
|
CORE.data[KEY_ESP32][KEY_COMPONENTS][name] = {
|
||||||
KEY_REPO: repo,
|
KEY_REPO: repo,
|
||||||
KEY_REF: ref,
|
KEY_REF: ref,
|
||||||
KEY_PATH: path,
|
KEY_PATH: path,
|
||||||
KEY_REFRESH: refresh,
|
|
||||||
KEY_COMPONENTS: components,
|
|
||||||
KEY_SUBMODULES: submodules,
|
|
||||||
}
|
}
|
||||||
else:
|
|
||||||
component_config = CORE.data[KEY_ESP32][KEY_COMPONENTS][name]
|
|
||||||
if components is not None:
|
|
||||||
component_config[KEY_COMPONENTS] = list(
|
|
||||||
set(component_config[KEY_COMPONENTS] + components)
|
|
||||||
)
|
|
||||||
if submodules is not None:
|
|
||||||
if component_config[KEY_SUBMODULES] is None:
|
|
||||||
component_config[KEY_SUBMODULES] = submodules
|
|
||||||
else:
|
|
||||||
component_config[KEY_SUBMODULES] = list(
|
|
||||||
set(component_config[KEY_SUBMODULES] + submodules)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def add_extra_script(stage: str, filename: str, path: str):
|
def add_extra_script(stage: str, filename: str, path: str):
|
||||||
@ -575,6 +568,17 @@ CONF_ENABLE_LWIP_DHCP_SERVER = "enable_lwip_dhcp_server"
|
|||||||
CONF_ENABLE_LWIP_MDNS_QUERIES = "enable_lwip_mdns_queries"
|
CONF_ENABLE_LWIP_MDNS_QUERIES = "enable_lwip_mdns_queries"
|
||||||
CONF_ENABLE_LWIP_BRIDGE_INTERFACE = "enable_lwip_bridge_interface"
|
CONF_ENABLE_LWIP_BRIDGE_INTERFACE = "enable_lwip_bridge_interface"
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_idf_component(config: ConfigType) -> ConfigType:
|
||||||
|
"""Validate IDF component config and warn about deprecated options."""
|
||||||
|
if CONF_REFRESH in config:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"The 'refresh' option for IDF components is deprecated and has no effect. "
|
||||||
|
"It will be removed in ESPHome 2026.1. Please remove it from your configuration."
|
||||||
|
)
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
ESP_IDF_FRAMEWORK_SCHEMA = cv.All(
|
ESP_IDF_FRAMEWORK_SCHEMA = cv.All(
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
{
|
{
|
||||||
@ -614,15 +618,19 @@ ESP_IDF_FRAMEWORK_SCHEMA = cv.All(
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_COMPONENTS, default=[]): cv.ensure_list(
|
cv.Optional(CONF_COMPONENTS, default=[]): cv.ensure_list(
|
||||||
cv.Schema(
|
cv.All(
|
||||||
{
|
cv.Schema(
|
||||||
cv.Required(CONF_NAME): cv.string_strict,
|
{
|
||||||
cv.Required(CONF_SOURCE): cv.SOURCE_SCHEMA,
|
cv.Required(CONF_NAME): cv.string_strict,
|
||||||
cv.Optional(CONF_PATH): cv.string,
|
cv.Optional(CONF_SOURCE): cv.git_ref,
|
||||||
cv.Optional(CONF_REFRESH, default="1d"): cv.All(
|
cv.Optional(CONF_REF): cv.string,
|
||||||
cv.string, cv.source_refresh
|
cv.Optional(CONF_PATH): cv.string,
|
||||||
),
|
cv.Optional(CONF_REFRESH): cv.All(
|
||||||
}
|
cv.string, cv.source_refresh
|
||||||
|
),
|
||||||
|
}
|
||||||
|
),
|
||||||
|
_validate_idf_component,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -814,18 +822,12 @@ async def to_code(config):
|
|||||||
add_idf_sdkconfig_option(name, RawSdkconfigValue(value))
|
add_idf_sdkconfig_option(name, RawSdkconfigValue(value))
|
||||||
|
|
||||||
for component in conf[CONF_COMPONENTS]:
|
for component in conf[CONF_COMPONENTS]:
|
||||||
source = component[CONF_SOURCE]
|
add_idf_component(
|
||||||
if source[CONF_TYPE] == TYPE_GIT:
|
name=component[CONF_NAME],
|
||||||
add_idf_component(
|
repo=component.get(CONF_SOURCE),
|
||||||
name=component[CONF_NAME],
|
ref=component.get(CONF_REF),
|
||||||
repo=source[CONF_URL],
|
path=component.get(CONF_PATH),
|
||||||
ref=source.get(CONF_REF),
|
)
|
||||||
path=component.get(CONF_PATH),
|
|
||||||
refresh=component[CONF_REFRESH],
|
|
||||||
)
|
|
||||||
elif source[CONF_TYPE] == TYPE_LOCAL:
|
|
||||||
_LOGGER.warning("Local components are not implemented yet.")
|
|
||||||
|
|
||||||
elif conf[CONF_TYPE] == FRAMEWORK_ARDUINO:
|
elif conf[CONF_TYPE] == FRAMEWORK_ARDUINO:
|
||||||
cg.add_platformio_option("framework", "arduino")
|
cg.add_platformio_option("framework", "arduino")
|
||||||
cg.add_build_flag("-DUSE_ARDUINO")
|
cg.add_build_flag("-DUSE_ARDUINO")
|
||||||
@ -924,6 +926,26 @@ def _write_sdkconfig():
|
|||||||
write_file_if_changed(sdk_path, contents)
|
write_file_if_changed(sdk_path, contents)
|
||||||
|
|
||||||
|
|
||||||
|
def _write_idf_component_yml():
|
||||||
|
yml_path = Path(CORE.relative_build_path("src/idf_component.yml"))
|
||||||
|
if CORE.data[KEY_ESP32][KEY_COMPONENTS]:
|
||||||
|
components: dict = CORE.data[KEY_ESP32][KEY_COMPONENTS]
|
||||||
|
dependencies = {}
|
||||||
|
for name, component in components.items():
|
||||||
|
dependency = {}
|
||||||
|
if component[KEY_REF]:
|
||||||
|
dependency["version"] = component[KEY_REF]
|
||||||
|
if component[KEY_REPO]:
|
||||||
|
dependency["git"] = component[KEY_REPO]
|
||||||
|
if component[KEY_PATH]:
|
||||||
|
dependency["path"] = component[KEY_PATH]
|
||||||
|
dependencies[name] = dependency
|
||||||
|
contents = yaml_util.dump({"dependencies": dependencies})
|
||||||
|
else:
|
||||||
|
contents = ""
|
||||||
|
write_file_if_changed(yml_path, contents)
|
||||||
|
|
||||||
|
|
||||||
# Called by writer.py
|
# Called by writer.py
|
||||||
def copy_files():
|
def copy_files():
|
||||||
if CORE.using_arduino:
|
if CORE.using_arduino:
|
||||||
@ -936,6 +958,7 @@ def copy_files():
|
|||||||
)
|
)
|
||||||
if CORE.using_esp_idf:
|
if CORE.using_esp_idf:
|
||||||
_write_sdkconfig()
|
_write_sdkconfig()
|
||||||
|
_write_idf_component_yml()
|
||||||
if "partitions.csv" not in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES]:
|
if "partitions.csv" not in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES]:
|
||||||
write_file_if_changed(
|
write_file_if_changed(
|
||||||
CORE.relative_build_path("partitions.csv"),
|
CORE.relative_build_path("partitions.csv"),
|
||||||
@ -952,55 +975,6 @@ def copy_files():
|
|||||||
__version__,
|
__version__,
|
||||||
)
|
)
|
||||||
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
shutil.rmtree(CORE.relative_build_path("components"), ignore_errors=True)
|
|
||||||
|
|
||||||
if CORE.data[KEY_ESP32][KEY_COMPONENTS]:
|
|
||||||
components: dict = CORE.data[KEY_ESP32][KEY_COMPONENTS]
|
|
||||||
|
|
||||||
for name, component in components.items():
|
|
||||||
repo_dir, _ = git.clone_or_update(
|
|
||||||
url=component[KEY_REPO],
|
|
||||||
ref=component[KEY_REF],
|
|
||||||
refresh=component[KEY_REFRESH],
|
|
||||||
domain="idf_components",
|
|
||||||
submodules=component[KEY_SUBMODULES],
|
|
||||||
)
|
|
||||||
mkdir_p(CORE.relative_build_path("components"))
|
|
||||||
component_dir = repo_dir
|
|
||||||
if component[KEY_PATH] is not None:
|
|
||||||
component_dir = component_dir / component[KEY_PATH]
|
|
||||||
|
|
||||||
if component[KEY_COMPONENTS] == ["*"]:
|
|
||||||
shutil.copytree(
|
|
||||||
component_dir,
|
|
||||||
CORE.relative_build_path("components"),
|
|
||||||
dirs_exist_ok=True,
|
|
||||||
ignore=shutil.ignore_patterns(".git*"),
|
|
||||||
symlinks=True,
|
|
||||||
ignore_dangling_symlinks=True,
|
|
||||||
)
|
|
||||||
elif len(component[KEY_COMPONENTS]) > 0:
|
|
||||||
for comp in component[KEY_COMPONENTS]:
|
|
||||||
shutil.copytree(
|
|
||||||
component_dir / comp,
|
|
||||||
CORE.relative_build_path(f"components/{comp}"),
|
|
||||||
dirs_exist_ok=True,
|
|
||||||
ignore=shutil.ignore_patterns(".git*"),
|
|
||||||
symlinks=True,
|
|
||||||
ignore_dangling_symlinks=True,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
shutil.copytree(
|
|
||||||
component_dir,
|
|
||||||
CORE.relative_build_path(f"components/{name}"),
|
|
||||||
dirs_exist_ok=True,
|
|
||||||
ignore=shutil.ignore_patterns(".git*"),
|
|
||||||
symlinks=True,
|
|
||||||
ignore_dangling_symlinks=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
for _, file in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES].items():
|
for _, file in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES].items():
|
||||||
if file[KEY_PATH].startswith("http"):
|
if file[KEY_PATH].startswith("http"):
|
||||||
import requests
|
import requests
|
||||||
|
Loading…
x
Reference in New Issue
Block a user