Add TARGET_FIELDS to config validation (#150238)

This commit is contained in:
Artur Pragacz
2025-08-26 20:40:39 +02:00
committed by GitHub
parent 376f6ce4a7
commit d5c208672e
3 changed files with 26 additions and 35 deletions

View File

@@ -373,6 +373,17 @@ def entity_id(value: Any) -> str:
raise vol.Invalid(f"Entity ID {value} is an invalid entity ID")
def strict_entity_id(value: Any) -> str:
"""Validate Entity ID, strictly."""
if not isinstance(value, str):
raise vol.Invalid(f"Entity ID {value} is not a string")
if valid_entity_id(value):
return value
raise vol.Invalid(f"Entity ID {value} is not a valid entity ID")
def entity_id_or_uuid(value: Any) -> str:
"""Validate Entity specified by entity_id or uuid."""
with contextlib.suppress(vol.Invalid):
@@ -1292,6 +1303,15 @@ PLATFORM_SCHEMA = vol.Schema(
PLATFORM_SCHEMA_BASE = PLATFORM_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA)
TARGET_FIELDS: VolDictType = {
vol.Optional(ATTR_ENTITY_ID): vol.All(ensure_list, [strict_entity_id]),
vol.Optional(ATTR_DEVICE_ID): vol.All(ensure_list, [str]),
vol.Optional(ATTR_AREA_ID): vol.All(ensure_list, [str]),
vol.Optional(ATTR_FLOOR_ID): vol.All(ensure_list, [str]),
vol.Optional(ATTR_LABEL_ID): vol.All(ensure_list, [str]),
}
ENTITY_SERVICE_FIELDS: VolDictType = {
# Either accept static entity IDs, a single dynamic template or a mixed list
# of static and dynamic templates. While this could be solved with a single

View File

@@ -828,7 +828,7 @@ def selector_serializer(schema: Any) -> Any: # noqa: C901
return {"type": "string", "enum": options}
if isinstance(schema, selector.TargetSelector):
return convert(cv.TARGET_SERVICE_FIELDS)
return convert(cv.TARGET_FIELDS)
if isinstance(schema, selector.TemplateSelector):
return {"type": "string", "format": "jinja2"}

View File

@@ -1216,43 +1216,14 @@ async def test_selector_serializer(
selector.StateSelector({"entity_id": "sensor.test"})
) == {"type": "string"}
target_schema = selector_serializer(selector.TargetSelector())
target_schema["properties"]["entity_id"]["anyOf"][0][
"enum"
].sort() # Order is not deterministic
assert target_schema == {
"type": "object",
"properties": {
"area_id": {
"anyOf": [
{"type": "string", "enum": ["none"]},
{"type": "array", "items": {"type": "string", "nullable": True}},
]
},
"device_id": {
"anyOf": [
{"type": "string", "enum": ["none"]},
{"type": "array", "items": {"type": "string", "nullable": True}},
]
},
"entity_id": {
"anyOf": [
{"type": "string", "enum": ["all", "none"], "format": "lower"},
{"type": "string", "nullable": True},
{"type": "array", "items": {"type": "string"}},
]
},
"floor_id": {
"anyOf": [
{"type": "string", "enum": ["none"]},
{"type": "array", "items": {"type": "string", "nullable": True}},
]
},
"label_id": {
"anyOf": [
{"type": "string", "enum": ["none"]},
{"type": "array", "items": {"type": "string", "nullable": True}},
]
},
"area_id": {"items": {"type": "string"}, "type": "array"},
"device_id": {"items": {"type": "string"}, "type": "array"},
"entity_id": {"items": {"type": "string"}, "type": "array"},
"floor_id": {"items": {"type": "string"}, "type": "array"},
"label_id": {"items": {"type": "string"}, "type": "array"},
},
"required": [],
}