Teach state trigger about entity registry ids (#60271)

* Teach state trigger about entity registry ids

* Tweak

* Add tests

* Tweak tests

* Fix tests

* Resolve entity ids during config validation

* Update device_triggers

* Fix mistake

* Tweak trigger validator to ensure we don't modify the original config

* Add index from entry id to entry

* Update scaffold

* Pre-compile UUID regex

* Address review comment

* Tweak mock_registry

* Tweak

* Apply suggestion from code review
This commit is contained in:
Erik Montnemery 2021-12-02 14:26:45 +01:00 committed by GitHub
parent c0fb1bffce
commit c85bb27d0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 324 additions and 74 deletions

View file

@ -2,6 +2,7 @@
from __future__ import annotations
from collections.abc import Callable, Hashable
import contextlib
from datetime import (
date as date_sys,
datetime as datetime_sys,
@ -262,14 +263,34 @@ def entity_id(value: Any) -> str:
raise vol.Invalid(f"Entity ID {value} is an invalid entity ID")
def entity_ids(value: str | list) -> list[str]:
"""Validate Entity IDs."""
def entity_id_or_uuid(value: Any) -> str:
"""Validate Entity specified by entity_id or uuid."""
with contextlib.suppress(vol.Invalid):
return entity_id(value)
with contextlib.suppress(vol.Invalid):
return fake_uuid4_hex(value)
raise vol.Invalid(f"Entity {value} is neither a valid entity ID nor a valid UUID")
def _entity_ids(value: str | list, allow_uuid: bool) -> list[str]:
"""Help validate entity IDs or UUIDs."""
if value is None:
raise vol.Invalid("Entity IDs can not be None")
if isinstance(value, str):
value = [ent_id.strip() for ent_id in value.split(",")]
return [entity_id(ent_id) for ent_id in value]
validator = entity_id_or_uuid if allow_uuid else entity_id
return [validator(ent_id) for ent_id in value]
def entity_ids(value: str | list) -> list[str]:
"""Validate Entity IDs."""
return _entity_ids(value, False)
def entity_ids_or_uuids(value: str | list) -> list[str]:
"""Validate entities specified by entity IDs or UUIDs."""
return _entity_ids(value, True)
comp_entity_ids = vol.Any(
@ -682,6 +703,16 @@ def uuid4_hex(value: Any) -> str:
return result.hex
_FAKE_UUID_4_HEX = re.compile(r"^[0-9a-f]{32}$")
def fake_uuid4_hex(value: Any) -> str:
"""Validate a fake v4 UUID generated by random_uuid_hex."""
if not _FAKE_UUID_4_HEX.match(value):
raise vol.Invalid("Invalid UUID")
return cast(str, value) # Pattern.match throws if input is not a string
def ensure_list_csv(value: Any) -> list:
"""Ensure that input is a list or make one from comma-separated string."""
if isinstance(value, str):