Support async validation of device trigger (#27333)
parent
3194dd3456
commit
fdf4f398a7
|
@ -7,9 +7,6 @@ from typing import Any, Awaitable, Callable
|
|||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.device_automation.exceptions import (
|
||||
InvalidDeviceAutomationConfig,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_NAME,
|
||||
|
@ -476,10 +473,7 @@ async def _async_process_trigger(hass, config, trigger_configs, name, action):
|
|||
for conf in trigger_configs:
|
||||
platform = importlib.import_module(".{}".format(conf[CONF_PLATFORM]), __name__)
|
||||
|
||||
try:
|
||||
remove = await platform.async_attach_trigger(hass, conf, action, info)
|
||||
except InvalidDeviceAutomationConfig:
|
||||
remove = False
|
||||
remove = await platform.async_attach_trigger(hass, conf, action, info)
|
||||
|
||||
if not remove:
|
||||
_LOGGER.error("Error setting up trigger %s", name)
|
||||
|
|
|
@ -4,6 +4,9 @@ import importlib
|
|||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.device_automation.exceptions import (
|
||||
InvalidDeviceAutomationConfig,
|
||||
)
|
||||
from homeassistant.const import CONF_PLATFORM
|
||||
from homeassistant.config import async_log_exception, config_without_domain
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
@ -52,7 +55,12 @@ async def _try_async_validate_config_item(hass, config, full_config=None):
|
|||
"""Validate config item."""
|
||||
try:
|
||||
config = await async_validate_config_item(hass, config, full_config)
|
||||
except (vol.Invalid, HomeAssistantError, IntegrationNotFound) as ex:
|
||||
except (
|
||||
vol.Invalid,
|
||||
HomeAssistantError,
|
||||
IntegrationNotFound,
|
||||
InvalidDeviceAutomationConfig,
|
||||
) as ex:
|
||||
async_log_exception(ex, DOMAIN, full_config or config, hass)
|
||||
return None
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ async def async_validate_trigger_config(hass, config):
|
|||
platform = await async_get_device_automation_platform(
|
||||
hass, config[CONF_DOMAIN], "trigger"
|
||||
)
|
||||
if hasattr(platform, "async_validate_trigger_config"):
|
||||
return await getattr(platform, "async_validate_trigger_config")(hass, config)
|
||||
|
||||
return platform.TRIGGER_SCHEMA(config)
|
||||
|
||||
|
||||
|
|
|
@ -204,8 +204,10 @@ def _get_deconz_event_from_device_id(hass, device_id):
|
|||
return None
|
||||
|
||||
|
||||
async def async_attach_trigger(hass, config, action, automation_info):
|
||||
"""Listen for state changes based on configuration."""
|
||||
async def async_validate_trigger_config(hass, config):
|
||||
"""Validate config."""
|
||||
config = TRIGGER_SCHEMA(config)
|
||||
|
||||
device_registry = await hass.helpers.device_registry.async_get_registry()
|
||||
device = device_registry.async_get(config[CONF_DEVICE_ID])
|
||||
|
||||
|
@ -214,6 +216,16 @@ async def async_attach_trigger(hass, config, action, automation_info):
|
|||
if device.model not in REMOTES or trigger not in REMOTES[device.model]:
|
||||
raise InvalidDeviceAutomationConfig
|
||||
|
||||
return config
|
||||
|
||||
|
||||
async def async_attach_trigger(hass, config, action, automation_info):
|
||||
"""Listen for state changes based on configuration."""
|
||||
device_registry = await hass.helpers.device_registry.async_get_registry()
|
||||
device = device_registry.async_get(config[CONF_DEVICE_ID])
|
||||
|
||||
trigger = (config[CONF_TYPE], config[CONF_SUBTYPE])
|
||||
|
||||
trigger = REMOTES[device.model][trigger]
|
||||
|
||||
deconz_event = _get_deconz_event_from_device_id(hass, device.id)
|
||||
|
|
|
@ -21,8 +21,10 @@ TRIGGER_SCHEMA = TRIGGER_BASE_SCHEMA.extend(
|
|||
)
|
||||
|
||||
|
||||
async def async_attach_trigger(hass, config, action, automation_info):
|
||||
"""Listen for state changes based on configuration."""
|
||||
async def async_validate_trigger_config(hass, config):
|
||||
"""Validate config."""
|
||||
config = TRIGGER_SCHEMA(config)
|
||||
|
||||
trigger = (config[CONF_TYPE], config[CONF_SUBTYPE])
|
||||
zha_device = await async_get_zha_device(hass, config[CONF_DEVICE_ID])
|
||||
|
||||
|
@ -32,6 +34,14 @@ async def async_attach_trigger(hass, config, action, automation_info):
|
|||
):
|
||||
raise InvalidDeviceAutomationConfig
|
||||
|
||||
return config
|
||||
|
||||
|
||||
async def async_attach_trigger(hass, config, action, automation_info):
|
||||
"""Listen for state changes based on configuration."""
|
||||
trigger = (config[CONF_TYPE], config[CONF_SUBTYPE])
|
||||
zha_device = await async_get_zha_device(hass, config[CONF_DEVICE_ID])
|
||||
|
||||
trigger = zha_device.device_automation_triggers[trigger]
|
||||
|
||||
event_config = {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""ZHA device automation trigger tests."""
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
import homeassistant.components.automation as automation
|
||||
|
@ -197,7 +195,7 @@ async def test_if_fires_on_event(hass, config_entry, zha_gateway, calls):
|
|||
assert calls[0].data["message"] == "service called"
|
||||
|
||||
|
||||
async def test_exception_no_triggers(hass, config_entry, zha_gateway, calls):
|
||||
async def test_exception_no_triggers(hass, config_entry, zha_gateway, calls, caplog):
|
||||
"""Test for exception on event triggers firing."""
|
||||
from zigpy.zcl.clusters.general import OnOff, Basic
|
||||
|
||||
|
@ -219,33 +217,32 @@ async def test_exception_no_triggers(hass, config_entry, zha_gateway, calls):
|
|||
ha_device_registry = await async_get_registry(hass)
|
||||
reg_device = ha_device_registry.async_get_device({("zha", ieee_address)}, set())
|
||||
|
||||
with patch("logging.Logger.error") as mock:
|
||||
await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"device_id": reg_device.id,
|
||||
"domain": "zha",
|
||||
"platform": "device",
|
||||
"type": "junk",
|
||||
"subtype": "junk",
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data": {"message": "service called"},
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
mock.assert_called_with("Error setting up trigger %s", "automation 0")
|
||||
await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"device_id": reg_device.id,
|
||||
"domain": "zha",
|
||||
"platform": "device",
|
||||
"type": "junk",
|
||||
"subtype": "junk",
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data": {"message": "service called"},
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert "Invalid config for [automation]" in caplog.text
|
||||
|
||||
|
||||
async def test_exception_bad_trigger(hass, config_entry, zha_gateway, calls):
|
||||
async def test_exception_bad_trigger(hass, config_entry, zha_gateway, calls, caplog):
|
||||
"""Test for exception on event triggers firing."""
|
||||
from zigpy.zcl.clusters.general import OnOff, Basic
|
||||
|
||||
|
@ -275,27 +272,26 @@ async def test_exception_bad_trigger(hass, config_entry, zha_gateway, calls):
|
|||
ha_device_registry = await async_get_registry(hass)
|
||||
reg_device = ha_device_registry.async_get_device({("zha", ieee_address)}, set())
|
||||
|
||||
with patch("logging.Logger.error") as mock:
|
||||
await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"device_id": reg_device.id,
|
||||
"domain": "zha",
|
||||
"platform": "device",
|
||||
"type": "junk",
|
||||
"subtype": "junk",
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data": {"message": "service called"},
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
mock.assert_called_with("Error setting up trigger %s", "automation 0")
|
||||
await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"device_id": reg_device.id,
|
||||
"domain": "zha",
|
||||
"platform": "device",
|
||||
"type": "junk",
|
||||
"subtype": "junk",
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data": {"message": "service called"},
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert "Invalid config for [automation]" in caplog.text
|
||||
|
|
Loading…
Reference in New Issue