Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b157afa

Browse files
Remove templates from schemas for service fields validation (home-assistant#150063)
1 parent edaf5c8 commit b157afa

File tree

3 files changed

+32
-25
lines changed

3 files changed

+32
-25
lines changed

‎homeassistant/components/websocket_api/commands.py‎

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,6 @@ async def handle_call_service(
260260
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
261261
) -> None:
262262
"""Handle call service command."""
263-
# We do not support templates.
264-
target = msg.get("target")
265-
if template.is_complex(target):
266-
raise vol.Invalid("Templates are not supported here")
267-
268263
try:
269264
context = connection.context(msg)
270265
response = await hass.services.async_call(
@@ -273,7 +268,7 @@ async def handle_call_service(
273268
service_data=msg.get("service_data"),
274269
blocking=True,
275270
context=context,
276-
target=target,
271+
target=msg.get("target"),
277272
return_response=msg["return_response"],
278273
)
279274
result: dict[str, Context | ServiceResponse] = {"context": context}

‎homeassistant/helpers/config_validation.py‎

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ def temperature_unit(value: Any) -> UnitOfTemperature:
732732
raise vol.Invalid("invalid temperature unit (expected C or F)")
733733

734734

735-
def template(value: Any|None) -> template_helper.Template:
735+
def template(value: Any) -> template_helper.Template:
736736
"""Validate a jinja2 template."""
737737
if value is None:
738738
raise vol.Invalid("template value is None")
@@ -750,7 +750,7 @@ def template(value: Any | None) -> template_helper.Template:
750750
return template_value
751751

752752

753-
def dynamic_template(value: Any|None) -> template_helper.Template:
753+
def dynamic_template(value: Any) -> template_helper.Template:
754754
"""Validate a dynamic (non static) jinja2 template."""
755755
if value is None:
756756
raise vol.Invalid("template value is None")
@@ -1319,34 +1319,44 @@ def platform_only_config_schema(domain: str) -> Callable[[dict], dict]:
13191319
}
13201320

13211321
ENTITY_SERVICE_FIELDS: VolDictType = {
1322-
# Either accept static entity IDs, a single dynamic template or a mixed list
1323-
# of static and dynamic templates. While this could be solved with a single
1324-
# complex template, handling it like this, keeps config validation useful.
1325-
vol.Optional(ATTR_ENTITY_ID): vol.Any(
1326-
comp_entity_ids, dynamic_template, vol.All(list, template_complex)
1327-
),
1322+
vol.Optional(ATTR_ENTITY_ID): comp_entity_ids,
13281323
vol.Optional(ATTR_DEVICE_ID): vol.Any(
1329-
ENTITY_MATCH_NONE, vol.All(ensure_list, [vol.Any(dynamic_template, str)])
1324+
ENTITY_MATCH_NONE,
1325+
vol.All(ensure_list, [str]),
13301326
),
13311327
vol.Optional(ATTR_AREA_ID): vol.Any(
1332-
ENTITY_MATCH_NONE, vol.All(ensure_list, [vol.Any(dynamic_template, str)])
1328+
ENTITY_MATCH_NONE,
1329+
vol.All(ensure_list, [str]),
13331330
),
13341331
vol.Optional(ATTR_FLOOR_ID): vol.Any(
1335-
ENTITY_MATCH_NONE, vol.All(ensure_list, [vol.Any(dynamic_template, str)])
1332+
ENTITY_MATCH_NONE,
1333+
vol.All(ensure_list, [str]),
13361334
),
13371335
vol.Optional(ATTR_LABEL_ID): vol.Any(
1338-
ENTITY_MATCH_NONE, vol.All(ensure_list, [vol.Any(dynamic_template, str)])
1336+
ENTITY_MATCH_NONE,
1337+
vol.All(ensure_list, [str]),
13391338
),
13401339
}
13411340

1342-
TARGET_SERVICE_FIELDS = {
1343-
# Same as ENTITY_SERVICE_FIELDS but supports specifying entity by entity registry
1344-
# ID.
1341+
TARGET_SERVICE_FIELDS: VolDictType = {
1342+
# Same as ENTITY_SERVICE_FIELDS but supports specifying entity
1343+
# by entity registry ID.
1344+
**ENTITY_SERVICE_FIELDS,
1345+
vol.Optional(ATTR_ENTITY_ID): comp_entity_ids_or_uuids,
1346+
}
1347+
1348+
_TARGET_SERVICE_FIELDS_TEMPLATED: VolDictType = {
13451349
# Either accept static entity IDs, a single dynamic template or a mixed list
13461350
# of static and dynamic templates. While this could be solved with a single
13471351
# complex template, handling it like this, keeps config validation useful.
1352+
# Entity ID can be specified as either a user visible one or by entity registry ID.
1353+
#
1354+
# The schema supports templates as it is meant to be used in the initial validation
1355+
# before templates are automatically rendered by the core logic.
13481356
vol.Optional(ATTR_ENTITY_ID): vol.Any(
1349-
comp_entity_ids_or_uuids, dynamic_template, vol.All(list, template_complex)
1357+
comp_entity_ids_or_uuids,
1358+
dynamic_template,
1359+
vol.All(list, template_complex),
13501360
),
13511361
vol.Optional(ATTR_DEVICE_ID): vol.Any(
13521362
ENTITY_MATCH_NONE, vol.All(ensure_list, [vol.Any(dynamic_template, str)])
@@ -1362,7 +1372,6 @@ def platform_only_config_schema(domain: str) -> Callable[[dict], dict]:
13621372
),
13631373
}
13641374

1365-
13661375
_HAS_ENTITY_SERVICE_FIELD = has_at_least_one_key(*ENTITY_SERVICE_FIELDS)
13671376

13681377

@@ -1494,7 +1503,9 @@ def _backward_compat_service_schema(value: Any | None) -> Any:
14941503
template, vol.All(dict, template_complex)
14951504
),
14961505
vol.Optional(CONF_ENTITY_ID): comp_entity_ids,
1497-
vol.Optional(CONF_TARGET): vol.Any(TARGET_SERVICE_FIELDS, dynamic_template),
1506+
vol.Optional(CONF_TARGET): vol.Any(
1507+
_TARGET_SERVICE_FIELDS_TEMPLATED, dynamic_template
1508+
),
14981509
vol.Optional(CONF_RESPONSE_VARIABLE): str,
14991510
# The frontend stores data here. Don't use in core.
15001511
vol.Remove("metadata"): dict,

‎homeassistant/helpers/selector.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1463,7 +1463,8 @@ class TargetSelector(Selector[TargetSelectorConfig]):
14631463
}
14641464
)
14651465

1466-
TARGET_SELECTION_SCHEMA = vol.Schema(cv.TARGET_SERVICE_FIELDS)
1466+
# We want to transition to not including templates in the target selector.
1467+
TARGET_SELECTION_SCHEMA = vol.Schema(cv._TARGET_SERVICE_FIELDS_TEMPLATED) # noqa: SLF001
14671468

14681469
def __init__(self, config: TargetSelectorConfig | None = None) -> None:
14691470
"""Instantiate a selector."""

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /