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:
parent
c0fb1bffce
commit
c85bb27d0d
20 changed files with 324 additions and 74 deletions
|
@ -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):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue