diff --git a/homeassistant/components/template/trigger_entity.py b/homeassistant/components/template/trigger_entity.py index 60e7c761b58..27362f8243d 100644 --- a/homeassistant/components/template/trigger_entity.py +++ b/homeassistant/components/template/trigger_entity.py @@ -48,8 +48,8 @@ class TriggerEntity( # pylint: disable=hass-enforce-class-module **(run_variables or {}), } - if self._render_availability_template(variables): - self._render_templates(variables) + self._render_availability_template(variables) + self._render_templates(variables) self.async_set_context(self.coordinator.data["context"]) diff --git a/homeassistant/helpers/trigger_template_entity.py b/homeassistant/helpers/trigger_template_entity.py index 216070967aa..293ff2ebd8d 100644 --- a/homeassistant/helpers/trigger_template_entity.py +++ b/homeassistant/helpers/trigger_template_entity.py @@ -176,7 +176,7 @@ class TriggerBaseEntity(Entity): extra_state_attributes[attr] = last_state.attributes[attr] self._rendered[CONF_ATTRIBUTES] = extra_state_attributes - def _render_availability_template(self, variables: dict[str, Any]) -> bool: + def _render_availability_template(self, variables: dict[str, Any]) -> None: """Render availability template.""" rendered = dict(self._static_rendered) key = CONF_AVAILABILITY @@ -191,17 +191,18 @@ class TriggerBaseEntity(Entity): self._config[key], variables, ) - return False except TemplateError as err: logging.getLogger(f"{__package__}.{self.entity_id.split('.')[0]}").error( "Error rendering %s template for %s: %s", key, self.entity_id, err ) self._rendered = rendered - return True def _render_templates(self, variables: dict[str, Any]) -> None: """Render templates.""" rendered = dict(self._rendered) + if CONF_AVAILABILITY in rendered and rendered[CONF_AVAILABILITY] == "off": + self._rendered = self._static_rendered + return try: for key in self._to_render_simple: if key == CONF_AVAILABILITY: @@ -257,7 +258,6 @@ class ManualTriggerEntity(TriggerBaseEntity): Implementing class should call this last in update method to render templates. Ex: self._process_manual_data(payload) """ - run_variables: dict[str, Any] = {"value": value} # Silently try if variable is a json and store result in `value_json` if it is. with contextlib.suppress(*JSON_DECODE_EXCEPTIONS): @@ -267,8 +267,8 @@ class ManualTriggerEntity(TriggerBaseEntity): "this": TemplateStateFromEntityId(self.hass, self.entity_id), **(run_variables or {}), } - if self._render_availability_template(variables): - self._render_templates(variables) + self._render_availability_template(variables) + self._render_templates(variables) class ManualTriggerSensorEntity(ManualTriggerEntity, SensorEntity): diff --git a/tests/helpers/test_trigger_template_entity.py b/tests/helpers/test_trigger_template_entity.py index a18827ecb4c..0f7af9bdc46 100644 --- a/tests/helpers/test_trigger_template_entity.py +++ b/tests/helpers/test_trigger_template_entity.py @@ -38,3 +38,51 @@ async def test_template_entity_requires_hass_set(hass: HomeAssistant) -> None: assert entity.name == "test_entity" assert entity.icon == "mdi:off" assert entity.entity_picture == "/local/picture_off" + + +async def test_trigger_template_availability(hass: HomeAssistant) -> None: + """Test manual trigger template entity.""" + config = { + "name": template.Template("test_entity", hass), + "icon": template.Template( + '{% if value=="on" %} mdi:on {% else %} mdi:off {% endif %}', hass + ), + "picture": template.Template( + '{% if value=="on" %} /local/picture_on {% else %} /local/picture_off {% endif %}', + hass, + ), + "availability": template.Template('{{ has_value("test.entity") }}', hass), + } + + entity = ManualTriggerEntity(hass, config) + entity.entity_id = "test.entity" + hass.states.async_set("test.entity", "on") + await entity.async_added_to_hass() + + entity._process_manual_data("on") + await hass.async_block_till_done() + + assert entity.name == "test_entity" + assert entity.icon == "mdi:on" + assert entity.entity_picture == "/local/picture_on" + assert entity.available is True + + hass.states.async_set("test.entity", "off") + await entity.async_added_to_hass() + entity._process_manual_data("off") + await hass.async_block_till_done() + + assert entity.name == "test_entity" + assert entity.icon == "mdi:off" + assert entity.entity_picture == "/local/picture_off" + assert entity.available is True + + hass.states.async_set("test.entity", "unknown") + await entity.async_added_to_hass() + entity._process_manual_data("unknown") + await hass.async_block_till_done() + + assert entity.name == "test_entity" + assert entity.icon == "mdi:off" + assert entity.entity_picture == "/local/picture_off" + assert entity.available is False