From 8377b557da8712789e0e5abb2c5aeda1f38895b8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 5 Aug 2021 13:11:01 -0700 Subject: [PATCH] Packages to support config platforms (#54085) --- homeassistant/components/automation/__init__.py | 3 --- homeassistant/components/automation/config.py | 2 ++ homeassistant/components/script/config.py | 2 ++ homeassistant/components/template/config.py | 2 ++ homeassistant/config.py | 17 ++++++++++++++++- tests/test_config.py | 13 ++++++++++++- 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index a0ff4930b51..5e1b53c535e 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -71,9 +71,6 @@ from homeassistant.loader import bind_hass from homeassistant.util.dt import parse_datetime from .config import AutomationConfig, async_validate_config_item - -# Not used except by packages to check config structure -from .config import PLATFORM_SCHEMA # noqa: F401 from .const import ( CONF_ACTION, CONF_INITIAL_STATE, diff --git a/homeassistant/components/automation/config.py b/homeassistant/components/automation/config.py index 83076778b91..e852b6cc4c0 100644 --- a/homeassistant/components/automation/config.py +++ b/homeassistant/components/automation/config.py @@ -37,6 +37,8 @@ from .helpers import async_get_blueprints # mypy: allow-untyped-calls, allow-untyped-defs # mypy: no-check-untyped-defs, no-warn-return-any +PACKAGE_MERGE_HINT = "list" + _CONDITION_SCHEMA = vol.All(cv.ensure_list, [cv.CONDITION_SCHEMA]) PLATFORM_SCHEMA = vol.All( diff --git a/homeassistant/components/script/config.py b/homeassistant/components/script/config.py index 6993b7181e1..44b739e84c7 100644 --- a/homeassistant/components/script/config.py +++ b/homeassistant/components/script/config.py @@ -39,6 +39,8 @@ from .const import ( ) from .helpers import async_get_blueprints +PACKAGE_MERGE_HINT = "dict" + SCRIPT_ENTITY_SCHEMA = make_script_schema( { vol.Optional(CONF_ALIAS): cv.string, diff --git a/homeassistant/components/template/config.py b/homeassistant/components/template/config.py index 007f40a6d0a..165420bf404 100644 --- a/homeassistant/components/template/config.py +++ b/homeassistant/components/template/config.py @@ -13,6 +13,8 @@ from homeassistant.helpers.trigger import async_validate_trigger_config from . import binary_sensor as binary_sensor_platform, sensor as sensor_platform from .const import CONF_TRIGGER, DOMAIN +PACKAGE_MERGE_HINT = "list" + CONFIG_SECTION_SCHEMA = vol.Schema( { vol.Optional(CONF_UNIQUE_ID): cv.string, diff --git a/homeassistant/config.py b/homeassistant/config.py index e7b6e04e8cf..12a39ab291b 100644 --- a/homeassistant/config.py +++ b/homeassistant/config.py @@ -723,7 +723,22 @@ async def merge_packages_config( _log_pkg_error(pack_name, comp_name, config, str(ex)) continue - merge_list = hasattr(component, "PLATFORM_SCHEMA") + try: + config_platform: ModuleType | None = integration.get_platform("config") + # Test if config platform has a config validator + if not hasattr(config_platform, "async_validate_config"): + config_platform = None + except ImportError: + config_platform = None + + merge_list = False + + # If integration has a custom config validator, it needs to provide a hint. + if config_platform is not None: + merge_list = config_platform.PACKAGE_MERGE_HINT == "list" # type: ignore[attr-defined] + + if not merge_list: + merge_list = hasattr(component, "PLATFORM_SCHEMA") if not merge_list and hasattr(component, "CONFIG_SCHEMA"): merge_list = _identify_config_schema(component) == "list" diff --git a/tests/test_config.py b/tests/test_config.py index c1eb1ab7540..96196c943aa 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -650,19 +650,30 @@ async def test_merge(merge_log_err, hass): "pack_list": {"light": {"platform": "test"}}, "pack_list2": {"light": [{"platform": "test"}]}, "pack_none": {"wake_on_lan": None}, + "pack_special": { + "automation": [{"some": "yay"}], + "script": {"a_script": "yay"}, + "template": [{"some": "yay"}], + }, } config = { config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages}, "input_boolean": {"ib2": None}, "light": {"platform": "test"}, + "automation": [], + "script": {}, + "template": [], } await config_util.merge_packages_config(hass, config, packages) assert merge_log_err.call_count == 0 - assert len(config) == 5 + assert len(config) == 8 assert len(config["input_boolean"]) == 2 assert len(config["input_select"]) == 1 assert len(config["light"]) == 3 + assert len(config["automation"]) == 1 + assert len(config["script"]) == 1 + assert len(config["template"]) == 1 assert isinstance(config["wake_on_lan"], OrderedDict)