Allow overriding blueprinted templates (#143874)

* Allow overriding blueprinted templates

* Remove duplicated line
This commit is contained in:
Erik Montnemery 2025-04-30 12:14:28 +02:00 committed by GitHub
parent a7af0eaccd
commit 40217e764d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 98 additions and 10 deletions

View File

@ -9,7 +9,6 @@ import voluptuous as vol
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.blueprint import (
BLUEPRINT_INSTANCE_FIELDS,
is_blueprint_instance_config,
schemas as blueprint_schemas,
)
@ -141,13 +140,6 @@ TEMPLATE_BLUEPRINT_SCHEMA = vol.All(
_backward_compat_schema, blueprint_schemas.BLUEPRINT_SCHEMA
)
TEMPLATE_BLUEPRINT_INSTANCE_SCHEMA = vol.Schema(
{
vol.Optional(CONF_NAME): cv.string,
vol.Optional(CONF_UNIQUE_ID): cv.string,
}
).extend(BLUEPRINT_INSTANCE_FIELDS.schema)
async def _async_resolve_blueprints(
hass: HomeAssistant,
@ -161,10 +153,11 @@ async def _async_resolve_blueprints(
raw_config = dict(config)
if is_blueprint_instance_config(config):
config = TEMPLATE_BLUEPRINT_INSTANCE_SCHEMA(config)
blueprints = async_get_blueprints(hass)
blueprint_inputs = await blueprints.async_inputs_from_config(config)
blueprint_inputs = await blueprints.async_inputs_from_config(
_backward_compat_schema(config)
)
raw_blueprint_inputs = blueprint_inputs.config_with_inputs
config = blueprint_inputs.async_substitute()

View File

@ -272,6 +272,101 @@ async def test_trigger_event_sensor(
await template.async_get_blueprints(hass).async_remove_blueprint(blueprint)
@pytest.mark.parametrize(
("blueprint", "override"),
[
# Override a blueprint with modern schema with legacy schema
(
"test_event_sensor.yaml",
{"trigger": {"platform": "event", "event_type": "override"}},
),
# Override a blueprint with modern schema with modern schema
(
"test_event_sensor.yaml",
{"triggers": {"platform": "event", "event_type": "override"}},
),
# Override a blueprint with legacy schema with legacy schema
(
"test_event_sensor_legacy_schema.yaml",
{"trigger": {"platform": "event", "event_type": "override"}},
),
# Override a blueprint with legacy schema with modern schema
(
"test_event_sensor_legacy_schema.yaml",
{"triggers": {"platform": "event", "event_type": "override"}},
),
],
)
async def test_blueprint_template_override(
hass: HomeAssistant, blueprint: str, override: dict
) -> None:
"""Test blueprint template where the template config overrides the blueprint."""
assert await async_setup_component(
hass,
"template",
{
"template": [
{
"use_blueprint": {
"path": blueprint,
"input": {
"event_type": "my_custom_event",
"event_data": {"foo": "bar"},
},
},
"name": "My Custom Event",
}
| override,
]
},
)
await hass.async_block_till_done()
date_state = hass.states.get("sensor.my_custom_event")
assert date_state is not None
assert date_state.state == "unknown"
context = Context()
now = dt_util.utcnow()
with patch("homeassistant.util.dt.now", return_value=now):
hass.bus.async_fire(
"my_custom_event", {"foo": "bar", "beer": 2}, context=context
)
await hass.async_block_till_done()
date_state = hass.states.get("sensor.my_custom_event")
assert date_state is not None
assert date_state.state == "unknown"
context = Context()
now = dt_util.utcnow()
with patch("homeassistant.util.dt.now", return_value=now):
hass.bus.async_fire("override", {"foo": "bar", "beer": 2}, context=context)
await hass.async_block_till_done()
date_state = hass.states.get("sensor.my_custom_event")
assert date_state is not None
assert date_state.state == now.isoformat(timespec="seconds")
data = date_state.attributes.get("data")
assert data is not None
assert data != ""
assert data.get("foo") == "bar"
assert data.get("beer") == 2
inverted_foo_template = template.helpers.blueprint_in_template(
hass, "sensor.my_custom_event"
)
assert inverted_foo_template == blueprint
inverted_binary_sensor_blueprint_entity_ids = (
template.helpers.templates_with_blueprint(hass, blueprint)
)
assert len(inverted_binary_sensor_blueprint_entity_ids) == 1
with pytest.raises(BlueprintInUse):
await template.async_get_blueprints(hass).async_remove_blueprint(blueprint)
async def test_domain_blueprint(hass: HomeAssistant) -> None:
"""Test DomainBlueprint services."""
reload_handler_calls = async_mock_service(hass, DOMAIN, SERVICE_RELOAD)