Teach zone trigger about entity registry ids (#60838)

pull/60855/head
Erik Montnemery 2021-12-02 19:28:21 +01:00 committed by GitHub
parent a67a4873dc
commit 5b8d081441
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 103 additions and 5 deletions

View File

@ -89,7 +89,7 @@ async def async_attach_trigger(
CONF_ZONE: config[CONF_ZONE],
CONF_EVENT: event,
}
zone_config = zone.TRIGGER_SCHEMA(zone_config)
zone_config = await zone.async_validate_trigger_config(hass, zone_config)
return await zone.async_attach_trigger(
hass, zone_config, action, automation_info, platform_type="device"
)

View File

@ -8,9 +8,15 @@ from homeassistant.const import (
CONF_PLATFORM,
CONF_ZONE,
)
from homeassistant.core import CALLBACK_TYPE, HassJob, callback
from homeassistant.helpers import condition, config_validation as cv, location
from homeassistant.core import CALLBACK_TYPE, HassJob, HomeAssistant, callback
from homeassistant.helpers import (
condition,
config_validation as cv,
entity_registry as er,
location,
)
from homeassistant.helpers.event import async_track_state_change_event
from homeassistant.helpers.typing import ConfigType
# mypy: allow-incomplete-defs, allow-untyped-defs
# mypy: no-check-untyped-defs
@ -21,10 +27,10 @@ DEFAULT_EVENT = EVENT_ENTER
_EVENT_DESCRIPTION = {EVENT_ENTER: "entering", EVENT_LEAVE: "leaving"}
TRIGGER_SCHEMA = cv.TRIGGER_BASE_SCHEMA.extend(
_TRIGGER_SCHEMA = cv.TRIGGER_BASE_SCHEMA.extend(
{
vol.Required(CONF_PLATFORM): "zone",
vol.Required(CONF_ENTITY_ID): cv.entity_ids,
vol.Required(CONF_ENTITY_ID): cv.entity_ids_or_uuids,
vol.Required(CONF_ZONE): cv.entity_id,
vol.Required(CONF_EVENT, default=DEFAULT_EVENT): vol.Any(
EVENT_ENTER, EVENT_LEAVE
@ -33,6 +39,18 @@ TRIGGER_SCHEMA = cv.TRIGGER_BASE_SCHEMA.extend(
)
async def async_validate_trigger_config(
hass: HomeAssistant, config: ConfigType
) -> ConfigType:
"""Validate trigger config."""
config = _TRIGGER_SCHEMA(config)
registry = er.async_get(hass)
config[CONF_ENTITY_ID] = er.async_resolve_entity_ids(
registry, config[CONF_ENTITY_ID]
)
return config
async def async_attach_trigger(
hass, config, action, automation_info, *, platform_type: str = "zone"
) -> CALLBACK_TYPE:

View File

@ -4,6 +4,7 @@ import pytest
from homeassistant.components import automation, zone
from homeassistant.const import ATTR_ENTITY_ID, ENTITY_MATCH_ALL, SERVICE_TURN_OFF
from homeassistant.core import Context
from homeassistant.helpers import entity_registry as er
from homeassistant.setup import async_setup_component
from tests.common import async_mock_service, mock_component
@ -108,6 +109,85 @@ async def test_if_fires_on_zone_enter(hass, calls):
assert len(calls) == 1
async def test_if_fires_on_zone_enter_uuid(hass, calls):
"""Test for firing on zone enter when device is specified by entity registry id."""
context = Context()
registry = er.async_get(hass)
entry = registry.async_get_or_create(
"test", "hue", "1234", suggested_object_id="entity"
)
assert entry.entity_id == "test.entity"
hass.states.async_set(
"test.entity", "hello", {"latitude": 32.881011, "longitude": -117.234758}
)
await hass.async_block_till_done()
assert await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: {
"trigger": {
"platform": "zone",
"entity_id": entry.id,
"zone": "zone.test",
"event": "enter",
},
"action": {
"service": "test.automation",
"data_template": {
"some": "{{ trigger.%s }}"
% "}} - {{ trigger.".join(
(
"platform",
"entity_id",
"from_state.state",
"to_state.state",
"zone.name",
"id",
)
)
},
},
}
},
)
hass.states.async_set(
"test.entity",
"hello",
{"latitude": 32.880586, "longitude": -117.237564},
context=context,
)
await hass.async_block_till_done()
assert len(calls) == 1
assert calls[0].context.parent_id == context.id
assert calls[0].data["some"] == "zone - test.entity - hello - hello - test - 0"
# Set out of zone again so we can trigger call
hass.states.async_set(
"test.entity", "hello", {"latitude": 32.881011, "longitude": -117.234758}
)
await hass.async_block_till_done()
await hass.services.async_call(
automation.DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: ENTITY_MATCH_ALL},
blocking=True,
)
hass.states.async_set(
"test.entity", "hello", {"latitude": 32.880586, "longitude": -117.237564}
)
await hass.async_block_till_done()
assert len(calls) == 1
async def test_if_not_fires_for_enter_on_zone_leave(hass, calls):
"""Test for not firing on zone leave."""
hass.states.async_set(