diff --git a/homeassistant/components/template/const.py b/homeassistant/components/template/const.py index 6805c0ad81282..7fc4abe92cf47 100644 --- a/homeassistant/components/template/const.py +++ b/homeassistant/components/template/const.py @@ -33,3 +33,5 @@ CONF_ATTRIBUTE_TEMPLATES = "attribute_templates" CONF_PICTURE = "picture" CONF_OBJECT_ID = "object_id" + +EVENT_TEMPLATE_TRIGGERED = "template_triggered" diff --git a/homeassistant/components/template/coordinator.py b/homeassistant/components/template/coordinator.py index 7f24fe731cc02..8bf1b72763d27 100644 --- a/homeassistant/components/template/coordinator.py +++ b/homeassistant/components/template/coordinator.py @@ -2,14 +2,20 @@ from collections.abc import Callable import logging -from homeassistant.const import EVENT_HOMEASSISTANT_START -from homeassistant.core import CoreState, callback +from homeassistant.const import CONF_UNIQUE_ID, EVENT_HOMEASSISTANT_START +from homeassistant.core import Context, CoreState, callback from homeassistant.helpers import discovery, trigger as trigger_helper from homeassistant.helpers.script import Script from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator -from .const import CONF_ACTION, CONF_TRIGGER, DOMAIN, PLATFORMS +from .const import ( + CONF_ACTION, + CONF_TRIGGER, + DOMAIN, + EVENT_TEMPLATE_TRIGGERED, + PLATFORMS, +) _LOGGER = logging.getLogger(__name__) @@ -85,10 +91,22 @@ async def _attach_triggers(self, start_event=None) -> None: ) async def _handle_triggered(self, run_variables, context=None): + # Create a new context referring to the old context. + parent_id = None if context is None else context.id + trigger_context = Context(parent_id=parent_id) + + self.hass.bus.async_fire( + EVENT_TEMPLATE_TRIGGERED, + { + CONF_UNIQUE_ID: self.unique_id, + }, + context=trigger_context, + ) + if self._script: - script_result = await self._script.async_run(run_variables, context) + script_result = await self._script.async_run(run_variables, trigger_context) if script_result: run_variables = script_result.variables self.async_set_updated_data( - {"run_variables": run_variables, "context": context} + {"run_variables": run_variables, "context": trigger_context} ) diff --git a/tests/components/template/test_binary_sensor.py b/tests/components/template/test_binary_sensor.py index 01c0f005716bd..3394d7827c090 100644 --- a/tests/components/template/test_binary_sensor.py +++ b/tests/components/template/test_binary_sensor.py @@ -1123,7 +1123,7 @@ async def test_trigger_entity( assert state.attributes.get("icon") == "mdi:pirate" assert state.attributes.get("entity_picture") == "/local/dogs.png" assert state.attributes.get("plus_one") == 3 - assert state.context is context + assert state.context.parent_id is context.id assert len(entity_registry.entities) == 2 assert ( @@ -1142,7 +1142,7 @@ async def test_trigger_entity( assert state.attributes.get("entity_picture") == "/local/dogs.png" assert state.attributes.get("plus_one") == 3 assert state.attributes.get("another") == 1 - assert state.context is context + assert state.context.parent_id is context.id # Even if state itself didn't change, attributes might have changed hass.bus.async_fire("test_event", {"beer": 2, "uno_mas": "si"}) diff --git a/tests/components/template/test_sensor.py b/tests/components/template/test_sensor.py index 0ca666d22f1e6..10f5e3c991660 100644 --- a/tests/components/template/test_sensor.py +++ b/tests/components/template/test_sensor.py @@ -1169,7 +1169,7 @@ async def test_trigger_entity( assert state.attributes.get("entity_picture") == "/local/dogs.png" assert state.attributes.get("plus_one") == 3 assert state.attributes.get("unit_of_measurement") == "%" - assert state.context is context + assert state.context.parent_id is context.id assert len(entity_registry.entities) == 2 assert ( @@ -1189,7 +1189,7 @@ async def test_trigger_entity( assert state.attributes.get("plus_one") == 3 assert state.attributes.get("unit_of_measurement") == "%" assert state.attributes.get("state_class") == "measurement" - assert state.context is context + assert state.context.parent_id is context.id @pytest.mark.parametrize(("count", "domain"), [(1, "template")]) @@ -1667,4 +1667,4 @@ async def test_trigger_action( state = hass.states.get("sensor.hello_name") assert state.state == "3" - assert state.context is context + assert state.context.parent_id is context.id diff --git a/tests/components/template/test_weather.py b/tests/components/template/test_weather.py index 524f9c41aeb8a..a555db494063d 100644 --- a/tests/components/template/test_weather.py +++ b/tests/components/template/test_weather.py @@ -635,7 +635,7 @@ async def test_trigger_action( state = hass.states.get("weather.hello_name") assert state.state == "sunny" assert state.attributes["temperature"] == 3.0 - assert state.context is context + assert state.context.parent_id is context.id @pytest.mark.parametrize(("count", "domain"), [(1, "template")]) @@ -752,7 +752,7 @@ async def test_trigger_weather_services( assert state.attributes["cloud_coverage"] == 3.0 assert state.attributes["dew_point"] == 3.0 assert state.attributes["apparent_temperature"] == 3.0 - assert state.context is context + assert state.context.parent_id is context.id response = await hass.services.async_call( WEATHER_DOMAIN,