Allow templates for enabling automation triggers (#114458)
* Allow templates for enabling automation triggers * Test exception for non-limited template * Use `cv.template` instead of `cv.template_complex` * skip trigger with invalid enable template instead of returning and thus not evaluating other triggers
This commit is contained in:
parent
2a6a0e6230
commit
ba48da7678
3 changed files with 97 additions and 4 deletions
|
@ -1648,7 +1648,7 @@ TRIGGER_BASE_SCHEMA = vol.Schema(
|
|||
vol.Required(CONF_PLATFORM): str,
|
||||
vol.Optional(CONF_ID): str,
|
||||
vol.Optional(CONF_VARIABLES): SCRIPT_VARIABLES_SCHEMA,
|
||||
vol.Optional(CONF_ENABLED): boolean,
|
||||
vol.Optional(CONF_ENABLED): vol.Any(boolean, template),
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -27,11 +27,12 @@ from homeassistant.core import (
|
|||
callback,
|
||||
is_callback,
|
||||
)
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.exceptions import HomeAssistantError, TemplateError
|
||||
from homeassistant.loader import IntegrationNotFound, async_get_integration
|
||||
from homeassistant.util.async_ import create_eager_task
|
||||
from homeassistant.util.hass_dict import HassKey
|
||||
|
||||
from .template import Template
|
||||
from .typing import ConfigType, TemplateVarsType
|
||||
|
||||
_PLATFORM_ALIASES = {
|
||||
|
@ -312,8 +313,16 @@ async def async_initialize_triggers(
|
|||
triggers: list[asyncio.Task[CALLBACK_TYPE]] = []
|
||||
for idx, conf in enumerate(trigger_config):
|
||||
# Skip triggers that are not enabled
|
||||
if not conf.get(CONF_ENABLED, True):
|
||||
continue
|
||||
if CONF_ENABLED in conf:
|
||||
enabled = conf[CONF_ENABLED]
|
||||
if isinstance(enabled, Template):
|
||||
try:
|
||||
enabled = enabled.async_render(variables, limited=True)
|
||||
except TemplateError as err:
|
||||
log_cb(logging.ERROR, f"Error rendering enabled template: {err}")
|
||||
continue
|
||||
if not enabled:
|
||||
continue
|
||||
|
||||
platform = await _async_get_trigger_platform(hass, conf)
|
||||
trigger_id = conf.get(CONF_ID, f"{idx}")
|
||||
|
|
|
@ -110,6 +110,90 @@ async def test_if_disabled_trigger_not_firing(
|
|||
assert len(calls) == 1
|
||||
|
||||
|
||||
async def test_trigger_enabled_templates(
|
||||
hass: HomeAssistant, calls: list[ServiceCall]
|
||||
) -> None:
|
||||
"""Test triggers enabled by template."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
"automation",
|
||||
{
|
||||
"automation": {
|
||||
"trigger": [
|
||||
{
|
||||
"enabled": "{{ 'some text' }}",
|
||||
"platform": "event",
|
||||
"event_type": "truthy_template_trigger_event",
|
||||
},
|
||||
{
|
||||
"enabled": "{{ 3 == 4 }}",
|
||||
"platform": "event",
|
||||
"event_type": "falsy_template_trigger_event",
|
||||
},
|
||||
{
|
||||
"enabled": False, # eg. from a blueprints input defaulting to `false`
|
||||
"platform": "event",
|
||||
"event_type": "falsy_trigger_event",
|
||||
},
|
||||
{
|
||||
"enabled": "some text", # eg. from a blueprints input value
|
||||
"platform": "event",
|
||||
"event_type": "truthy_trigger_event",
|
||||
},
|
||||
],
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
hass.bus.async_fire("falsy_template_trigger_event")
|
||||
await hass.async_block_till_done()
|
||||
assert not calls
|
||||
|
||||
hass.bus.async_fire("falsy_trigger_event")
|
||||
await hass.async_block_till_done()
|
||||
assert not calls
|
||||
|
||||
hass.bus.async_fire("truthy_template_trigger_event")
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 1
|
||||
|
||||
hass.bus.async_fire("truthy_trigger_event")
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 2
|
||||
|
||||
|
||||
async def test_trigger_enabled_template_limited(
|
||||
hass: HomeAssistant, calls: list[ServiceCall], caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Test triggers enabled invalid template."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
"automation",
|
||||
{
|
||||
"automation": {
|
||||
"trigger": [
|
||||
{
|
||||
"enabled": "{{ states('sensor.limited') }}", # only limited template supported
|
||||
"platform": "event",
|
||||
"event_type": "test_event",
|
||||
},
|
||||
],
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
hass.bus.async_fire("test_event")
|
||||
await hass.async_block_till_done()
|
||||
assert not calls
|
||||
assert "Error rendering enabled template" in caplog.text
|
||||
|
||||
|
||||
async def test_trigger_alias(
|
||||
hass: HomeAssistant, calls: list[ServiceCall], caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
|
|
Loading…
Add table
Reference in a new issue