Rename 'service' to 'action' in automations and scripts (#122845)
This commit is contained in:
parent
f14471112d
commit
8b96c7873f
11 changed files with 414 additions and 275 deletions
|
@ -113,6 +113,7 @@ SUN_EVENT_SUNRISE: Final = "sunrise"
|
|||
# #### CONFIG ####
|
||||
CONF_ABOVE: Final = "above"
|
||||
CONF_ACCESS_TOKEN: Final = "access_token"
|
||||
CONF_ACTION: Final = "action"
|
||||
CONF_ADDRESS: Final = "address"
|
||||
CONF_AFTER: Final = "after"
|
||||
CONF_ALIAS: Final = "alias"
|
||||
|
|
|
@ -34,6 +34,7 @@ from homeassistant.const import (
|
|||
ATTR_FLOOR_ID,
|
||||
ATTR_LABEL_ID,
|
||||
CONF_ABOVE,
|
||||
CONF_ACTION,
|
||||
CONF_ALIAS,
|
||||
CONF_ATTRIBUTE,
|
||||
CONF_BELOW,
|
||||
|
@ -1325,11 +1326,30 @@ EVENT_SCHEMA = vol.Schema(
|
|||
}
|
||||
)
|
||||
|
||||
|
||||
def _backward_compat_service_schema(value: Any | None) -> Any:
|
||||
"""Backward compatibility for service schemas."""
|
||||
|
||||
if not isinstance(value, dict):
|
||||
return value
|
||||
|
||||
# `service` has been renamed to `action`
|
||||
if CONF_SERVICE in value:
|
||||
if CONF_ACTION in value:
|
||||
raise vol.Invalid(
|
||||
"Cannot specify both 'service' and 'action'. Please use 'action' only."
|
||||
)
|
||||
value[CONF_ACTION] = value.pop(CONF_SERVICE)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
SERVICE_SCHEMA = vol.All(
|
||||
_backward_compat_service_schema,
|
||||
vol.Schema(
|
||||
{
|
||||
**SCRIPT_ACTION_BASE_SCHEMA,
|
||||
vol.Exclusive(CONF_SERVICE, "service name"): vol.Any(
|
||||
vol.Exclusive(CONF_ACTION, "service name"): vol.Any(
|
||||
service, dynamic_template
|
||||
),
|
||||
vol.Exclusive(CONF_SERVICE_TEMPLATE, "service name"): vol.Any(
|
||||
|
@ -1348,7 +1368,7 @@ SERVICE_SCHEMA = vol.All(
|
|||
vol.Remove("metadata"): dict,
|
||||
}
|
||||
),
|
||||
has_at_least_one_key(CONF_SERVICE, CONF_SERVICE_TEMPLATE),
|
||||
has_at_least_one_key(CONF_ACTION, CONF_SERVICE_TEMPLATE),
|
||||
)
|
||||
|
||||
NUMERIC_STATE_THRESHOLD_SCHEMA = vol.Any(
|
||||
|
@ -1844,6 +1864,7 @@ ACTIONS_MAP = {
|
|||
CONF_WAIT_FOR_TRIGGER: SCRIPT_ACTION_WAIT_FOR_TRIGGER,
|
||||
CONF_VARIABLES: SCRIPT_ACTION_VARIABLES,
|
||||
CONF_IF: SCRIPT_ACTION_IF,
|
||||
CONF_ACTION: SCRIPT_ACTION_CALL_SERVICE,
|
||||
CONF_SERVICE: SCRIPT_ACTION_CALL_SERVICE,
|
||||
CONF_SERVICE_TEMPLATE: SCRIPT_ACTION_CALL_SERVICE,
|
||||
CONF_STOP: SCRIPT_ACTION_STOP,
|
||||
|
|
|
@ -20,8 +20,8 @@ from homeassistant.const import (
|
|||
ATTR_ENTITY_ID,
|
||||
ATTR_FLOOR_ID,
|
||||
ATTR_LABEL_ID,
|
||||
CONF_ACTION,
|
||||
CONF_ENTITY_ID,
|
||||
CONF_SERVICE,
|
||||
CONF_SERVICE_DATA,
|
||||
CONF_SERVICE_DATA_TEMPLATE,
|
||||
CONF_SERVICE_TEMPLATE,
|
||||
|
@ -358,8 +358,8 @@ def async_prepare_call_from_config(
|
|||
f"Invalid config for calling service: {ex}"
|
||||
) from ex
|
||||
|
||||
if CONF_SERVICE in config:
|
||||
domain_service = config[CONF_SERVICE]
|
||||
if CONF_ACTION in config:
|
||||
domain_service = config[CONF_ACTION]
|
||||
else:
|
||||
domain_service = config[CONF_SERVICE_TEMPLATE]
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ async def test_service_data_not_a_dict(
|
|||
{
|
||||
automation.DOMAIN: {
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "data": 100},
|
||||
"action": {"action": "test.automation", "data": 100},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -111,7 +111,7 @@ async def test_service_data_single_template(
|
|||
automation.DOMAIN: {
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data": "{{ { 'foo': 'bar' } }}",
|
||||
},
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ async def test_service_specify_data(
|
|||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data_template": {
|
||||
"some": (
|
||||
"{{ trigger.platform }} - {{ trigger.event.event_type }}"
|
||||
|
@ -170,7 +170,7 @@ async def test_service_specify_entity_id(
|
|||
{
|
||||
automation.DOMAIN: {
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "entity_id": "hello.world"},
|
||||
"action": {"action": "test.automation", "entity_id": "hello.world"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -192,7 +192,7 @@ async def test_service_specify_entity_id_list(
|
|||
automation.DOMAIN: {
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"entity_id": ["hello.world", "hello.world2"],
|
||||
},
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ async def test_two_triggers(hass: HomeAssistant, calls: list[ServiceCall]) -> No
|
|||
{"platform": "event", "event_type": "test_event"},
|
||||
{"platform": "state", "entity_id": "test.entity"},
|
||||
],
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -245,7 +245,7 @@ async def test_trigger_service_ignoring_condition(
|
|||
"entity_id": "non.existing",
|
||||
"above": "1",
|
||||
},
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -301,7 +301,7 @@ async def test_two_conditions_with_and(
|
|||
"below": 150,
|
||||
},
|
||||
],
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -333,7 +333,7 @@ async def test_shorthand_conditions_template(
|
|||
automation.DOMAIN: {
|
||||
"trigger": [{"platform": "event", "event_type": "test_event"}],
|
||||
"condition": "{{ is_state('test.entity', 'hello') }}",
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -360,11 +360,11 @@ async def test_automation_list_setting(
|
|||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
},
|
||||
{
|
||||
"trigger": {"platform": "event", "event_type": "test_event_2"},
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
},
|
||||
]
|
||||
},
|
||||
|
@ -390,8 +390,8 @@ async def test_automation_calling_two_actions(
|
|||
automation.DOMAIN: {
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [
|
||||
{"service": "test.automation", "data": {"position": 0}},
|
||||
{"service": "test.automation", "data": {"position": 1}},
|
||||
{"action": "test.automation", "data": {"position": 0}},
|
||||
{"action": "test.automation", "data": {"position": 1}},
|
||||
],
|
||||
}
|
||||
},
|
||||
|
@ -420,7 +420,7 @@ async def test_shared_context(hass: HomeAssistant, calls: list[ServiceCall]) ->
|
|||
{
|
||||
"alias": "bye",
|
||||
"trigger": {"platform": "event", "event_type": "test_event2"},
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
},
|
||||
]
|
||||
},
|
||||
|
@ -486,7 +486,7 @@ async def test_services(hass: HomeAssistant, calls: list[ServiceCall]) -> None:
|
|||
automation.DOMAIN: {
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -569,7 +569,7 @@ async def test_reload_config_service(
|
|||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data_template": {"event": "{{ trigger.event.event_type }}"},
|
||||
},
|
||||
}
|
||||
|
@ -597,7 +597,7 @@ async def test_reload_config_service(
|
|||
"alias": "bye",
|
||||
"trigger": {"platform": "event", "event_type": "test_event2"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data_template": {"event": "{{ trigger.event.event_type }}"},
|
||||
},
|
||||
}
|
||||
|
@ -650,7 +650,7 @@ async def test_reload_config_when_invalid_config(
|
|||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data_template": {"event": "{{ trigger.event.event_type }}"},
|
||||
},
|
||||
}
|
||||
|
@ -690,7 +690,7 @@ async def test_reload_config_handles_load_fails(
|
|||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data_template": {"event": "{{ trigger.event.event_type }}"},
|
||||
},
|
||||
}
|
||||
|
@ -735,7 +735,7 @@ async def test_automation_stops(
|
|||
"action": [
|
||||
{"event": "running"},
|
||||
{"wait_template": "{{ is_state('test.entity', 'goodbye') }}"},
|
||||
{"service": "test.automation"},
|
||||
{"action": "test.automation"},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
@ -811,7 +811,7 @@ async def test_reload_unchanged_does_not_stop(
|
|||
"action": [
|
||||
{"event": "running"},
|
||||
{"wait_template": "{{ is_state('test.entity', 'goodbye') }}"},
|
||||
{"service": "test.automation"},
|
||||
{"action": "test.automation"},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
@ -858,7 +858,7 @@ async def test_reload_single_unchanged_does_not_stop(
|
|||
"action": [
|
||||
{"event": "running"},
|
||||
{"wait_template": "{{ is_state('test.entity', 'goodbye') }}"},
|
||||
{"service": "test.automation"},
|
||||
{"action": "test.automation"},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
@ -905,7 +905,7 @@ async def test_reload_single_add_automation(
|
|||
"id": "sun",
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
}
|
||||
}
|
||||
assert await async_setup_component(hass, automation.DOMAIN, config1)
|
||||
|
@ -942,25 +942,25 @@ async def test_reload_single_parallel_calls(
|
|||
"id": "sun",
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event_sun"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
{
|
||||
"id": "moon",
|
||||
"alias": "goodbye",
|
||||
"trigger": {"platform": "event", "event_type": "test_event_moon"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
{
|
||||
"id": "mars",
|
||||
"alias": "goodbye",
|
||||
"trigger": {"platform": "event", "event_type": "test_event_mars"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
{
|
||||
"id": "venus",
|
||||
"alias": "goodbye",
|
||||
"trigger": {"platform": "event", "event_type": "test_event_venus"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -1055,7 +1055,7 @@ async def test_reload_single_remove_automation(
|
|||
"id": "sun",
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
}
|
||||
}
|
||||
config2 = {automation.DOMAIN: {}}
|
||||
|
@ -1093,12 +1093,12 @@ async def test_reload_moved_automation_without_alias(
|
|||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
{
|
||||
"alias": "automation_with_alias",
|
||||
"trigger": {"platform": "event", "event_type": "test_event2"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -1149,17 +1149,17 @@ async def test_reload_identical_automations_without_id(
|
|||
{
|
||||
"alias": "dolly",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
{
|
||||
"alias": "dolly",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
{
|
||||
"alias": "dolly",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -1246,12 +1246,12 @@ async def test_reload_identical_automations_without_id(
|
|||
[
|
||||
{
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
# An automation using templates
|
||||
{
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [{"service": "{{ 'test.automation' }}"}],
|
||||
"action": [{"action": "{{ 'test.automation' }}"}],
|
||||
},
|
||||
# An automation using blueprint
|
||||
{
|
||||
|
@ -1278,13 +1278,13 @@ async def test_reload_identical_automations_without_id(
|
|||
{
|
||||
"id": "sun",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [{"service": "test.automation"}],
|
||||
"action": [{"action": "test.automation"}],
|
||||
},
|
||||
# An automation using templates
|
||||
{
|
||||
"id": "sun",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": [{"service": "{{ 'test.automation' }}"}],
|
||||
"action": [{"action": "{{ 'test.automation' }}"}],
|
||||
},
|
||||
# An automation using blueprint
|
||||
{
|
||||
|
@ -1424,12 +1424,12 @@ async def test_automation_restore_state(hass: HomeAssistant) -> None:
|
|||
{
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event_hello"},
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
},
|
||||
{
|
||||
"alias": "bye",
|
||||
"trigger": {"platform": "event", "event_type": "test_event_bye"},
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -1474,7 +1474,7 @@ async def test_initial_value_off(hass: HomeAssistant) -> None:
|
|||
"alias": "hello",
|
||||
"initial_state": "off",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "entity_id": "hello.world"},
|
||||
"action": {"action": "test.automation", "entity_id": "hello.world"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -1499,7 +1499,7 @@ async def test_initial_value_on(hass: HomeAssistant) -> None:
|
|||
"initial_state": "on",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"entity_id": ["hello.world", "hello.world2"],
|
||||
},
|
||||
}
|
||||
|
@ -1528,7 +1528,7 @@ async def test_initial_value_off_but_restore_on(hass: HomeAssistant) -> None:
|
|||
"alias": "hello",
|
||||
"initial_state": "off",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "entity_id": "hello.world"},
|
||||
"action": {"action": "test.automation", "entity_id": "hello.world"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -1553,7 +1553,7 @@ async def test_initial_value_on_but_restore_off(hass: HomeAssistant) -> None:
|
|||
"alias": "hello",
|
||||
"initial_state": "on",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "entity_id": "hello.world"},
|
||||
"action": {"action": "test.automation", "entity_id": "hello.world"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -1576,7 +1576,7 @@ async def test_no_initial_value_and_restore_off(hass: HomeAssistant) -> None:
|
|||
automation.DOMAIN: {
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "entity_id": "hello.world"},
|
||||
"action": {"action": "test.automation", "entity_id": "hello.world"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -1600,7 +1600,7 @@ async def test_automation_is_on_if_no_initial_state_or_restore(
|
|||
automation.DOMAIN: {
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "entity_id": "hello.world"},
|
||||
"action": {"action": "test.automation", "entity_id": "hello.world"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -1623,7 +1623,7 @@ async def test_automation_not_trigger_on_bootstrap(hass: HomeAssistant) -> None:
|
|||
automation.DOMAIN: {
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "entity_id": "hello.world"},
|
||||
"action": {"action": "test.automation", "entity_id": "hello.world"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -1714,7 +1714,7 @@ async def test_automation_bad_config_validation(
|
|||
"alias": "good_automation",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"entity_id": "hello.world",
|
||||
},
|
||||
},
|
||||
|
@ -1756,7 +1756,7 @@ async def test_automation_bad_config_validation(
|
|||
"alias": "bad_automation",
|
||||
"trigger": {"platform": "event", "event_type": "test_event2"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data_template": {"event": "{{ trigger.event.event_type }}"},
|
||||
},
|
||||
}
|
||||
|
@ -1785,7 +1785,7 @@ async def test_automation_with_error_in_script(
|
|||
automation.DOMAIN: {
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "entity_id": "hello.world"},
|
||||
"action": {"action": "test.automation", "entity_id": "hello.world"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -1811,7 +1811,7 @@ async def test_automation_with_error_in_script_2(
|
|||
automation.DOMAIN: {
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": None, "entity_id": "hello.world"},
|
||||
"action": {"action": None, "entity_id": "hello.world"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -1842,19 +1842,19 @@ async def test_automation_restore_last_triggered_with_initial_state(
|
|||
"alias": "hello",
|
||||
"initial_state": "off",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
},
|
||||
{
|
||||
"alias": "bye",
|
||||
"initial_state": "off",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
},
|
||||
{
|
||||
"alias": "solong",
|
||||
"initial_state": "on",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation"},
|
||||
"action": {"action": "test.automation"},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -2013,11 +2013,11 @@ async def test_extraction_functions(
|
|||
},
|
||||
"action": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.in_both"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.in_first"},
|
||||
},
|
||||
{
|
||||
|
@ -2027,15 +2027,15 @@ async def test_extraction_functions(
|
|||
"type": "turn_on",
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"area_id": "area-in-both"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"floor_id": "floor-in-both"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"label_id": "label-in-both"},
|
||||
},
|
||||
],
|
||||
|
@ -2087,7 +2087,7 @@ async def test_extraction_functions(
|
|||
},
|
||||
"action": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.in_both"},
|
||||
},
|
||||
{
|
||||
|
@ -2140,7 +2140,7 @@ async def test_extraction_functions(
|
|||
},
|
||||
"action": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.in_both"},
|
||||
},
|
||||
{
|
||||
|
@ -2150,27 +2150,27 @@ async def test_extraction_functions(
|
|||
},
|
||||
{"scene": "scene.hello"},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"area_id": "area-in-both"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"area_id": "area-in-last"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"floor_id": "floor-in-both"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"floor_id": "floor-in-last"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"label_id": "label-in-both"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"label_id": "label-in-last"},
|
||||
},
|
||||
],
|
||||
|
@ -2289,7 +2289,7 @@ async def test_automation_variables(
|
|||
},
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data": {
|
||||
"value": "{{ test_var }}",
|
||||
"event_type": "{{ event_type }}",
|
||||
|
@ -2308,7 +2308,7 @@ async def test_automation_variables(
|
|||
"value_template": "{{ trigger.event.data.pass_condition }}",
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -2317,7 +2317,7 @@ async def test_automation_variables(
|
|||
},
|
||||
"trigger": {"platform": "event", "event_type": "test_event_3"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
},
|
||||
},
|
||||
]
|
||||
|
@ -2373,7 +2373,7 @@ async def test_automation_trigger_variables(
|
|||
},
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data": {
|
||||
"value": "{{ test_var }}",
|
||||
"event_type": "{{ event_type }}",
|
||||
|
@ -2391,7 +2391,7 @@ async def test_automation_trigger_variables(
|
|||
},
|
||||
"trigger": {"platform": "event", "event_type": "test_event_2"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data": {
|
||||
"value": "{{ test_var }}",
|
||||
"event_type": "{{ event_type }}",
|
||||
|
@ -2438,7 +2438,7 @@ async def test_automation_bad_trigger_variables(
|
|||
},
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
},
|
||||
},
|
||||
]
|
||||
|
@ -2465,7 +2465,7 @@ async def test_automation_this_var_always(
|
|||
{
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data": {
|
||||
"this_template": "{{this.entity_id}}",
|
||||
},
|
||||
|
@ -2542,7 +2542,7 @@ async def test_blueprint_automation(
|
|||
"Blueprint 'Call service based on event' generated invalid automation",
|
||||
(
|
||||
"value should be a string for dictionary value @"
|
||||
" data['action'][0]['service']"
|
||||
" data['action'][0]['action']"
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -2640,7 +2640,7 @@ async def test_trigger_service(hass: HomeAssistant, calls: list[ServiceCall]) ->
|
|||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data_template": {"trigger": "{{ trigger }}"},
|
||||
},
|
||||
}
|
||||
|
@ -2679,14 +2679,14 @@ async def test_trigger_condition_implicit_id(
|
|||
{
|
||||
"conditions": {"condition": "trigger", "id": [0, "2"]},
|
||||
"sequence": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data": {"param": "one"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"conditions": {"condition": "trigger", "id": "1"},
|
||||
"sequence": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data": {"param": "two"},
|
||||
},
|
||||
},
|
||||
|
@ -2730,14 +2730,14 @@ async def test_trigger_condition_explicit_id(
|
|||
{
|
||||
"conditions": {"condition": "trigger", "id": "one"},
|
||||
"sequence": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data": {"param": "one"},
|
||||
},
|
||||
},
|
||||
{
|
||||
"conditions": {"condition": "trigger", "id": "two"},
|
||||
"sequence": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"data": {"param": "two"},
|
||||
},
|
||||
},
|
||||
|
@ -2822,8 +2822,8 @@ async def test_recursive_automation_starting_script(
|
|||
f" {automation_runs} }}}}"
|
||||
)
|
||||
},
|
||||
{"service": "script.script1"},
|
||||
{"service": "test.script_done"},
|
||||
{"action": "script.script1"},
|
||||
{"action": "test.script_done"},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
@ -2840,9 +2840,9 @@ async def test_recursive_automation_starting_script(
|
|||
{"platform": "event", "event_type": "trigger_automation"},
|
||||
],
|
||||
"action": [
|
||||
{"service": "test.automation_started"},
|
||||
{"action": "test.automation_started"},
|
||||
{"delay": 0.001},
|
||||
{"service": "script.script1"},
|
||||
{"action": "script.script1"},
|
||||
],
|
||||
}
|
||||
},
|
||||
|
@ -2923,7 +2923,7 @@ async def test_recursive_automation(
|
|||
],
|
||||
"action": [
|
||||
{"event": "trigger_automation"},
|
||||
{"service": "test.automation_done"},
|
||||
{"action": "test.automation_done"},
|
||||
],
|
||||
}
|
||||
},
|
||||
|
@ -2985,7 +2985,7 @@ async def test_recursive_automation_restart_mode(
|
|||
],
|
||||
"action": [
|
||||
{"event": "trigger_automation"},
|
||||
{"service": "test.automation_done"},
|
||||
{"action": "test.automation_done"},
|
||||
],
|
||||
}
|
||||
},
|
||||
|
@ -3021,7 +3021,7 @@ async def test_websocket_config(
|
|||
config = {
|
||||
"alias": "hello",
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "data": 100},
|
||||
"action": {"action": "test.automation", "data": 100},
|
||||
}
|
||||
assert await async_setup_component(
|
||||
hass, automation.DOMAIN, {automation.DOMAIN: config}
|
||||
|
@ -3095,7 +3095,7 @@ async def test_automation_turns_off_other_automation(hass: HomeAssistant) -> Non
|
|||
"from": "on",
|
||||
},
|
||||
"action": {
|
||||
"service": "automation.turn_off",
|
||||
"action": "automation.turn_off",
|
||||
"target": {
|
||||
"entity_id": "automation.automation_1",
|
||||
},
|
||||
|
@ -3118,7 +3118,7 @@ async def test_automation_turns_off_other_automation(hass: HomeAssistant) -> Non
|
|||
},
|
||||
},
|
||||
"action": {
|
||||
"service": "persistent_notification.create",
|
||||
"action": "persistent_notification.create",
|
||||
"metadata": {},
|
||||
"data": {
|
||||
"message": "Test race",
|
||||
|
@ -3185,7 +3185,7 @@ async def test_two_automations_call_restart_script_same_time(
|
|||
"fire_toggle": {
|
||||
"sequence": [
|
||||
{
|
||||
"service": "input_boolean.toggle",
|
||||
"action": "input_boolean.toggle",
|
||||
"target": {"entity_id": "input_boolean.test_1"},
|
||||
}
|
||||
]
|
||||
|
@ -3206,7 +3206,7 @@ async def test_two_automations_call_restart_script_same_time(
|
|||
"to": "on",
|
||||
},
|
||||
"action": {
|
||||
"service": "script.fire_toggle",
|
||||
"action": "script.fire_toggle",
|
||||
},
|
||||
"id": "automation_0",
|
||||
"mode": "single",
|
||||
|
@ -3218,7 +3218,7 @@ async def test_two_automations_call_restart_script_same_time(
|
|||
"to": "on",
|
||||
},
|
||||
"action": {
|
||||
"service": "script.fire_toggle",
|
||||
"action": "script.fire_toggle",
|
||||
},
|
||||
"id": "automation_1",
|
||||
"mode": "single",
|
||||
|
@ -3301,3 +3301,29 @@ async def test_two_automation_call_restart_script_right_after_each_other(
|
|||
hass.states.async_set("input_boolean.test_2", "on")
|
||||
await hass.async_block_till_done()
|
||||
assert len(events) == 1
|
||||
|
||||
|
||||
async def test_action_service_backward_compatibility(
|
||||
hass: HomeAssistant, calls: list[ServiceCall]
|
||||
) -> None:
|
||||
"""Test we can still use the service call method."""
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: {
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"entity_id": "hello.world",
|
||||
"data": {"event": "{{ trigger.event.event_type }}"},
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
hass.bus.async_fire("test_event")
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data.get(ATTR_ENTITY_ID) == ["hello.world"]
|
||||
assert calls[0].data.get("event") == "test_event"
|
||||
|
|
|
@ -40,7 +40,7 @@ async def test_exclude_attributes(
|
|||
{
|
||||
automation.DOMAIN: {
|
||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||
"action": {"service": "test.automation", "entity_id": "hello.world"},
|
||||
"action": {"action": "test.automation", "entity_id": "hello.world"},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
@ -74,7 +74,7 @@ async def test_confirmable_notification(
|
|||
"message": "Throw ring in mountain?",
|
||||
"confirm_action": [
|
||||
{
|
||||
"service": "homeassistant.turn_on",
|
||||
"action": "homeassistant.turn_on",
|
||||
"target": {"entity_id": "mount.doom"},
|
||||
}
|
||||
],
|
||||
|
|
|
@ -85,7 +85,7 @@ async def test_passing_variables(hass: HomeAssistant) -> None:
|
|||
"script": {
|
||||
"test": {
|
||||
"sequence": {
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {"hello": "{{ greeting }}"},
|
||||
}
|
||||
}
|
||||
|
@ -115,8 +115,14 @@ async def test_passing_variables(hass: HomeAssistant) -> None:
|
|||
|
||||
|
||||
@pytest.mark.parametrize("toggle", [False, True])
|
||||
async def test_turn_on_off_toggle(hass: HomeAssistant, toggle) -> None:
|
||||
"""Verify turn_on, turn_off & toggle services."""
|
||||
@pytest.mark.parametrize("action_schema_variations", ["action", "service"])
|
||||
async def test_turn_on_off_toggle(
|
||||
hass: HomeAssistant, toggle: bool, action_schema_variations: str
|
||||
) -> None:
|
||||
"""Verify turn_on, turn_off & toggle services.
|
||||
|
||||
Ensures backward compatibility with the old service action schema is maintained.
|
||||
"""
|
||||
event = "test_event"
|
||||
event_mock = Mock()
|
||||
|
||||
|
@ -132,9 +138,15 @@ async def test_turn_on_off_toggle(hass: HomeAssistant, toggle) -> None:
|
|||
async_track_state_change(hass, ENTITY_ID, state_listener, to_state="on")
|
||||
|
||||
if toggle:
|
||||
turn_off_step = {"service": "script.toggle", "entity_id": ENTITY_ID}
|
||||
turn_off_step = {
|
||||
action_schema_variations: "script.toggle",
|
||||
"entity_id": ENTITY_ID,
|
||||
}
|
||||
else:
|
||||
turn_off_step = {"service": "script.turn_off", "entity_id": ENTITY_ID}
|
||||
turn_off_step = {
|
||||
action_schema_variations: "script.turn_off",
|
||||
"entity_id": ENTITY_ID,
|
||||
}
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
"script",
|
||||
|
@ -165,7 +177,7 @@ async def test_turn_on_off_toggle(hass: HomeAssistant, toggle) -> None:
|
|||
invalid_configs = [
|
||||
{"test": {}},
|
||||
{"test hello world": {"sequence": [{"event": "bla"}]}},
|
||||
{"test": {"sequence": {"event": "test_event", "service": "homeassistant.turn_on"}}},
|
||||
{"test": {"sequence": {"event": "test_event", "action": "homeassistant.turn_on"}}},
|
||||
]
|
||||
|
||||
|
||||
|
@ -180,7 +192,7 @@ invalid_configs = [
|
|||
"test": {
|
||||
"sequence": {
|
||||
"event": "test_event",
|
||||
"service": "homeassistant.turn_on",
|
||||
"action": "homeassistant.turn_on",
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -235,7 +247,7 @@ async def test_bad_config_validation_critical(
|
|||
"good_script": {
|
||||
"alias": "good_script",
|
||||
"sequence": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"entity_id": "hello.world",
|
||||
},
|
||||
},
|
||||
|
@ -300,7 +312,7 @@ async def test_bad_config_validation(
|
|||
"good_script": {
|
||||
"alias": "good_script",
|
||||
"sequence": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"entity_id": "hello.world",
|
||||
},
|
||||
},
|
||||
|
@ -342,7 +354,7 @@ async def test_bad_config_validation(
|
|||
object_id: {
|
||||
"alias": "bad_script",
|
||||
"sequence": {
|
||||
"service": "test.automation",
|
||||
"action": "test.automation",
|
||||
"entity_id": "hello.world",
|
||||
},
|
||||
},
|
||||
|
@ -430,7 +442,7 @@ async def test_reload_unchanged_does_not_stop(
|
|||
"sequence": [
|
||||
{"event": "running"},
|
||||
{"wait_template": "{{ is_state('test.entity', 'goodbye') }}"},
|
||||
{"service": "test.script"},
|
||||
{"action": "test.script"},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
@ -473,13 +485,13 @@ async def test_reload_unchanged_does_not_stop(
|
|||
[
|
||||
{
|
||||
"test": {
|
||||
"sequence": [{"service": "test.script"}],
|
||||
"sequence": [{"action": "test.script"}],
|
||||
}
|
||||
},
|
||||
# A script using templates
|
||||
{
|
||||
"test": {
|
||||
"sequence": [{"service": "{{ 'test.script' }}"}],
|
||||
"sequence": [{"action": "{{ 'test.script' }}"}],
|
||||
}
|
||||
},
|
||||
# A script using blueprint
|
||||
|
@ -666,7 +678,7 @@ async def test_logging_script_error(
|
|||
assert await async_setup_component(
|
||||
hass,
|
||||
"script",
|
||||
{"script": {"hello": {"sequence": [{"service": "non.existing"}]}}},
|
||||
{"script": {"hello": {"sequence": [{"action": "non.existing"}]}}},
|
||||
)
|
||||
with pytest.raises(ServiceNotFound) as err:
|
||||
await hass.services.async_call("script", "hello", blocking=True)
|
||||
|
@ -690,7 +702,7 @@ async def test_async_get_descriptions_script(hass: HomeAssistant) -> None:
|
|||
"""Test async_set_service_schema for the script integration."""
|
||||
script_config = {
|
||||
DOMAIN: {
|
||||
"test1": {"sequence": [{"service": "homeassistant.restart"}]},
|
||||
"test1": {"sequence": [{"action": "homeassistant.restart"}]},
|
||||
"test2": {
|
||||
"description": "test2",
|
||||
"fields": {
|
||||
|
@ -699,7 +711,7 @@ async def test_async_get_descriptions_script(hass: HomeAssistant) -> None:
|
|||
"example": "param_example",
|
||||
}
|
||||
},
|
||||
"sequence": [{"service": "homeassistant.restart"}],
|
||||
"sequence": [{"action": "homeassistant.restart"}],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -795,11 +807,11 @@ async def test_extraction_functions(
|
|||
"test1": {
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.in_both"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.in_first"},
|
||||
},
|
||||
{
|
||||
|
@ -809,15 +821,15 @@ async def test_extraction_functions(
|
|||
"device_id": device_in_both.id,
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"area_id": "area-in-both"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"floor_id": "floor-in-both"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"label_id": "label-in-both"},
|
||||
},
|
||||
]
|
||||
|
@ -825,7 +837,7 @@ async def test_extraction_functions(
|
|||
"test2": {
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.in_both"},
|
||||
},
|
||||
{
|
||||
|
@ -851,7 +863,7 @@ async def test_extraction_functions(
|
|||
"test3": {
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.in_both"},
|
||||
},
|
||||
{
|
||||
|
@ -861,27 +873,27 @@ async def test_extraction_functions(
|
|||
},
|
||||
{"scene": "scene.hello"},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"area_id": "area-in-both"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"area_id": "area-in-last"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"floor_id": "floor-in-both"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"floor_id": "floor-in-last"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"label_id": "label-in-both"},
|
||||
},
|
||||
{
|
||||
"service": "test.test",
|
||||
"action": "test.test",
|
||||
"target": {"label_id": "label-in-last"},
|
||||
},
|
||||
],
|
||||
|
@ -1028,11 +1040,11 @@ async def test_concurrent_script(hass: HomeAssistant, concurrently) -> None:
|
|||
"""Test calling script concurrently or not."""
|
||||
if concurrently:
|
||||
call_script_2 = {
|
||||
"service": "script.turn_on",
|
||||
"action": "script.turn_on",
|
||||
"data": {"entity_id": "script.script2"},
|
||||
}
|
||||
else:
|
||||
call_script_2 = {"service": "script.script2"}
|
||||
call_script_2 = {"action": "script.script2"}
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
"script",
|
||||
|
@ -1045,17 +1057,17 @@ async def test_concurrent_script(hass: HomeAssistant, concurrently) -> None:
|
|||
{
|
||||
"wait_template": "{{ is_state('input_boolean.test1', 'on') }}"
|
||||
},
|
||||
{"service": "test.script", "data": {"value": "script1"}},
|
||||
{"action": "test.script", "data": {"value": "script1"}},
|
||||
],
|
||||
},
|
||||
"script2": {
|
||||
"mode": "parallel",
|
||||
"sequence": [
|
||||
{"service": "test.script", "data": {"value": "script2a"}},
|
||||
{"action": "test.script", "data": {"value": "script2a"}},
|
||||
{
|
||||
"wait_template": "{{ is_state('input_boolean.test2', 'on') }}"
|
||||
},
|
||||
{"service": "test.script", "data": {"value": "script2b"}},
|
||||
{"action": "test.script", "data": {"value": "script2b"}},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
@ -1126,7 +1138,7 @@ async def test_script_variables(
|
|||
},
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {
|
||||
"value": "{{ test_var }}",
|
||||
"templated_config_var": "{{ templated_config_var }}",
|
||||
|
@ -1142,7 +1154,7 @@ async def test_script_variables(
|
|||
},
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {
|
||||
"value": "{{ test_var }}",
|
||||
},
|
||||
|
@ -1155,7 +1167,7 @@ async def test_script_variables(
|
|||
},
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {
|
||||
"value": "{{ test_var }}",
|
||||
},
|
||||
|
@ -1221,7 +1233,7 @@ async def test_script_this_var_always(
|
|||
"script1": {
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {
|
||||
"this_template": "{{this.entity_id}}",
|
||||
},
|
||||
|
@ -1306,8 +1318,8 @@ async def test_recursive_script(
|
|||
"script1": {
|
||||
"mode": script_mode,
|
||||
"sequence": [
|
||||
{"service": "script.script1"},
|
||||
{"service": "test.script"},
|
||||
{"action": "script.script1"},
|
||||
{"action": "test.script"},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
@ -1356,26 +1368,26 @@ async def test_recursive_script_indirect(
|
|||
"script1": {
|
||||
"mode": script_mode,
|
||||
"sequence": [
|
||||
{"service": "script.script2"},
|
||||
{"action": "script.script2"},
|
||||
],
|
||||
},
|
||||
"script2": {
|
||||
"mode": script_mode,
|
||||
"sequence": [
|
||||
{"service": "script.script3"},
|
||||
{"action": "script.script3"},
|
||||
],
|
||||
},
|
||||
"script3": {
|
||||
"mode": script_mode,
|
||||
"sequence": [
|
||||
{"service": "script.script4"},
|
||||
{"action": "script.script4"},
|
||||
],
|
||||
},
|
||||
"script4": {
|
||||
"mode": script_mode,
|
||||
"sequence": [
|
||||
{"service": "script.script1"},
|
||||
{"service": "test.script"},
|
||||
{"action": "script.script1"},
|
||||
{"action": "test.script"},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
@ -1440,10 +1452,10 @@ async def test_recursive_script_turn_on(
|
|||
"condition": "template",
|
||||
"value_template": "{{ request == 'step_2' }}",
|
||||
},
|
||||
"sequence": {"service": "test.script_done"},
|
||||
"sequence": {"action": "test.script_done"},
|
||||
},
|
||||
"default": {
|
||||
"service": "script.turn_on",
|
||||
"action": "script.turn_on",
|
||||
"data": {
|
||||
"entity_id": "script.script1",
|
||||
"variables": {"request": "step_2"},
|
||||
|
@ -1451,7 +1463,7 @@ async def test_recursive_script_turn_on(
|
|||
},
|
||||
},
|
||||
{
|
||||
"service": "script.turn_on",
|
||||
"action": "script.turn_on",
|
||||
"data": {"entity_id": "script.script1"},
|
||||
},
|
||||
],
|
||||
|
@ -1513,7 +1525,7 @@ async def test_websocket_config(
|
|||
"""Test config command."""
|
||||
config = {
|
||||
"alias": "hello",
|
||||
"sequence": [{"service": "light.turn_on"}],
|
||||
"sequence": [{"action": "light.turn_on"}],
|
||||
}
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
|
@ -1577,7 +1589,7 @@ async def test_script_service_changed_entity_id(
|
|||
"script": {
|
||||
"test": {
|
||||
"sequence": {
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {"entity_id": "{{ this.entity_id }}"},
|
||||
}
|
||||
}
|
||||
|
@ -1658,7 +1670,7 @@ async def test_blueprint_script(hass: HomeAssistant, calls: list[ServiceCall]) -
|
|||
"a_number": 5,
|
||||
},
|
||||
"Blueprint 'Call service' generated invalid script",
|
||||
"value should be a string for dictionary value @ data['sequence'][0]['service']",
|
||||
"value should be a string for dictionary value @ data['sequence'][0]['action']",
|
||||
),
|
||||
],
|
||||
)
|
||||
|
@ -1839,10 +1851,10 @@ async def test_script_queued_mode(hass: HomeAssistant) -> None:
|
|||
"sequence": [
|
||||
{
|
||||
"parallel": [
|
||||
{"service": "script.test_sub"},
|
||||
{"service": "script.test_sub"},
|
||||
{"service": "script.test_sub"},
|
||||
{"service": "script.test_sub"},
|
||||
{"action": "script.test_sub"},
|
||||
{"action": "script.test_sub"},
|
||||
{"action": "script.test_sub"},
|
||||
{"action": "script.test_sub"},
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -1850,7 +1862,7 @@ async def test_script_queued_mode(hass: HomeAssistant) -> None:
|
|||
"test_sub": {
|
||||
"mode": "queued",
|
||||
"sequence": [
|
||||
{"service": "test.simulated_remote"},
|
||||
{"action": "test.simulated_remote"},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ async def test_exclude_attributes(
|
|||
"script": {
|
||||
"test": {
|
||||
"sequence": {
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {"hello": "{{ greeting }}"},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import enum
|
|||
import logging
|
||||
import os
|
||||
from socket import _GLOBAL_DEFAULT_TIMEOUT
|
||||
from typing import Any
|
||||
from unittest.mock import Mock, patch
|
||||
import uuid
|
||||
|
||||
|
@ -416,27 +417,9 @@ def test_service() -> None:
|
|||
schema("homeassistant.turn_on")
|
||||
|
||||
|
||||
def test_service_schema(hass: HomeAssistant) -> None:
|
||||
"""Test service_schema validation."""
|
||||
options = (
|
||||
{},
|
||||
None,
|
||||
{
|
||||
"service": "homeassistant.turn_on",
|
||||
"service_template": "homeassistant.turn_on",
|
||||
},
|
||||
{"data": {"entity_id": "light.kitchen"}},
|
||||
{"service": "homeassistant.turn_on", "data": None},
|
||||
{
|
||||
"service": "homeassistant.turn_on",
|
||||
"data_template": {"brightness": "{{ no_end"},
|
||||
},
|
||||
)
|
||||
for value in options:
|
||||
with pytest.raises(vol.MultipleInvalid):
|
||||
cv.SERVICE_SCHEMA(value)
|
||||
|
||||
options = (
|
||||
@pytest.mark.parametrize(
|
||||
"config",
|
||||
[
|
||||
{"service": "homeassistant.turn_on"},
|
||||
{"service": "homeassistant.turn_on", "entity_id": "light.kitchen"},
|
||||
{"service": "light.turn_on", "entity_id": "all"},
|
||||
|
@ -450,14 +433,70 @@ def test_service_schema(hass: HomeAssistant) -> None:
|
|||
"alias": "turn on kitchen lights",
|
||||
},
|
||||
{"service": "scene.turn_on", "metadata": {}},
|
||||
)
|
||||
for value in options:
|
||||
cv.SERVICE_SCHEMA(value)
|
||||
{"action": "homeassistant.turn_on"},
|
||||
{"action": "homeassistant.turn_on", "entity_id": "light.kitchen"},
|
||||
{"action": "light.turn_on", "entity_id": "all"},
|
||||
{
|
||||
"action": "homeassistant.turn_on",
|
||||
"entity_id": ["light.kitchen", "light.ceiling"],
|
||||
},
|
||||
{
|
||||
"action": "light.turn_on",
|
||||
"entity_id": "all",
|
||||
"alias": "turn on kitchen lights",
|
||||
},
|
||||
{"action": "scene.turn_on", "metadata": {}},
|
||||
],
|
||||
)
|
||||
def test_service_schema(hass: HomeAssistant, config: dict[str, Any]) -> None:
|
||||
"""Test service_schema validation."""
|
||||
validated = cv.SERVICE_SCHEMA(config)
|
||||
|
||||
# Check metadata is removed from the validated output
|
||||
assert cv.SERVICE_SCHEMA({"service": "scene.turn_on", "metadata": {}}) == {
|
||||
"service": "scene.turn_on"
|
||||
}
|
||||
# Ensure metadata is removed from the validated output
|
||||
assert "metadata" not in validated
|
||||
|
||||
# Ensure service is migrated to action
|
||||
assert "service" not in validated
|
||||
assert "action" in validated
|
||||
assert validated["action"] == config.get("service", config["action"])
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"config",
|
||||
[
|
||||
{},
|
||||
None,
|
||||
{"data": {"entity_id": "light.kitchen"}},
|
||||
{
|
||||
"service": "homeassistant.turn_on",
|
||||
"service_template": "homeassistant.turn_on",
|
||||
},
|
||||
{"service": "homeassistant.turn_on", "data": None},
|
||||
{
|
||||
"service": "homeassistant.turn_on",
|
||||
"data_template": {"brightness": "{{ no_end"},
|
||||
},
|
||||
{
|
||||
"service": "homeassistant.turn_on",
|
||||
"action": "homeassistant.turn_on",
|
||||
},
|
||||
{
|
||||
"action": "homeassistant.turn_on",
|
||||
"service_template": "homeassistant.turn_on",
|
||||
},
|
||||
{"action": "homeassistant.turn_on", "data": None},
|
||||
{
|
||||
"action": "homeassistant.turn_on",
|
||||
"data_template": {"brightness": "{{ no_end"},
|
||||
},
|
||||
],
|
||||
)
|
||||
def test_invalid_service_schema(
|
||||
hass: HomeAssistant, config: dict[str, Any] | None
|
||||
) -> None:
|
||||
"""Test service_schema validation fails."""
|
||||
with pytest.raises(vol.MultipleInvalid):
|
||||
cv.SERVICE_SCHEMA(config)
|
||||
|
||||
|
||||
def test_entity_service_schema() -> None:
|
||||
|
|
|
@ -249,7 +249,7 @@ async def test_calling_service_basic(
|
|||
|
||||
alias = "service step"
|
||||
sequence = cv.SCRIPT_SCHEMA(
|
||||
{"alias": alias, "service": "test.script", "data": {"hello": "world"}}
|
||||
{"alias": alias, "action": "test.script", "data": {"hello": "world"}}
|
||||
)
|
||||
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
|
||||
|
||||
|
@ -352,13 +352,13 @@ async def test_calling_service_response_data(
|
|||
[
|
||||
{
|
||||
"alias": "service step1",
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
# Store the result of the service call as a variable
|
||||
"response_variable": "my_response",
|
||||
},
|
||||
{
|
||||
"alias": "service step2",
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {
|
||||
# Result of previous service call
|
||||
"key": "{{ my_response.data }}"
|
||||
|
@ -441,7 +441,7 @@ async def test_service_response_data_errors(
|
|||
[
|
||||
{
|
||||
"alias": "service step1",
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
**params,
|
||||
},
|
||||
]
|
||||
|
@ -458,7 +458,7 @@ async def test_data_template_with_templated_key(hass: HomeAssistant) -> None:
|
|||
calls = async_mock_service(hass, "test", "script")
|
||||
|
||||
sequence = cv.SCRIPT_SCHEMA(
|
||||
{"service": "test.script", "data_template": {"{{ hello_var }}": "world"}}
|
||||
{"action": "test.script", "data_template": {"{{ hello_var }}": "world"}}
|
||||
)
|
||||
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
|
||||
|
||||
|
@ -525,11 +525,11 @@ async def test_multiple_runs_no_wait(hass: HomeAssistant) -> None:
|
|||
sequence = cv.SCRIPT_SCHEMA(
|
||||
[
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {"fire": "{{ fire1 }}", "listen": "{{ listen1 }}"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {"fire": "{{ fire2 }}", "listen": "{{ listen2 }}"},
|
||||
},
|
||||
]
|
||||
|
@ -605,7 +605,7 @@ async def test_stop_no_wait(hass: HomeAssistant, count) -> None:
|
|||
|
||||
hass.services.async_register("test", "script", async_simulate_long_service)
|
||||
|
||||
sequence = cv.SCRIPT_SCHEMA([{"service": "test.script"}, {"event": event}])
|
||||
sequence = cv.SCRIPT_SCHEMA([{"action": "test.script"}, {"event": event}])
|
||||
script_obj = script.Script(
|
||||
hass,
|
||||
sequence,
|
||||
|
@ -3894,7 +3894,7 @@ async def test_parallel_error(
|
|||
sequence = cv.SCRIPT_SCHEMA(
|
||||
{
|
||||
"parallel": [
|
||||
{"service": "epic.failure"},
|
||||
{"action": "epic.failure"},
|
||||
]
|
||||
}
|
||||
)
|
||||
|
@ -3946,7 +3946,7 @@ async def test_propagate_error_service_not_found(hass: HomeAssistant) -> None:
|
|||
await async_setup_component(hass, "homeassistant", {})
|
||||
event = "test_event"
|
||||
events = async_capture_events(hass, event)
|
||||
sequence = cv.SCRIPT_SCHEMA([{"service": "test.script"}, {"event": event}])
|
||||
sequence = cv.SCRIPT_SCHEMA([{"action": "test.script"}, {"event": event}])
|
||||
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
|
||||
|
||||
with pytest.raises(exceptions.ServiceNotFound):
|
||||
|
@ -3980,7 +3980,7 @@ async def test_propagate_error_invalid_service_data(hass: HomeAssistant) -> None
|
|||
events = async_capture_events(hass, event)
|
||||
calls = async_mock_service(hass, "test", "script", vol.Schema({"text": str}))
|
||||
sequence = cv.SCRIPT_SCHEMA(
|
||||
[{"service": "test.script", "data": {"text": 1}}, {"event": event}]
|
||||
[{"action": "test.script", "data": {"text": 1}}, {"event": event}]
|
||||
)
|
||||
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
|
||||
|
||||
|
@ -4022,7 +4022,7 @@ async def test_propagate_error_service_exception(hass: HomeAssistant) -> None:
|
|||
|
||||
hass.services.async_register("test", "script", record_call)
|
||||
|
||||
sequence = cv.SCRIPT_SCHEMA([{"service": "test.script"}, {"event": event}])
|
||||
sequence = cv.SCRIPT_SCHEMA([{"action": "test.script"}, {"event": event}])
|
||||
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -4057,35 +4057,35 @@ async def test_referenced_labels(hass: HomeAssistant) -> None:
|
|||
cv.SCRIPT_SCHEMA(
|
||||
[
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"label_id": "label_service_not_list"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {
|
||||
"label_id": ["label_service_list_1", "label_service_list_2"]
|
||||
},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"label_id": "{{ 'label_service_template' }}"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"target": {"label_id": "label_in_target"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {"label_id": "label_in_data_template"},
|
||||
},
|
||||
{"service": "test.script", "data": {"without": "label_id"}},
|
||||
{"action": "test.script", "data": {"without": "label_id"}},
|
||||
{
|
||||
"choose": [
|
||||
{
|
||||
"conditions": "{{ true == false }}",
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"label_id": "label_choice_1_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4094,7 +4094,7 @@ async def test_referenced_labels(hass: HomeAssistant) -> None:
|
|||
"conditions": "{{ true == false }}",
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"label_id": "label_choice_2_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4102,7 +4102,7 @@ async def test_referenced_labels(hass: HomeAssistant) -> None:
|
|||
],
|
||||
"default": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"label_id": "label_default_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4113,13 +4113,13 @@ async def test_referenced_labels(hass: HomeAssistant) -> None:
|
|||
"if": [],
|
||||
"then": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"label_id": "label_if_then"},
|
||||
}
|
||||
],
|
||||
"else": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"label_id": "label_if_else"},
|
||||
}
|
||||
],
|
||||
|
@ -4127,7 +4127,7 @@ async def test_referenced_labels(hass: HomeAssistant) -> None:
|
|||
{
|
||||
"parallel": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"label_id": "label_parallel"},
|
||||
}
|
||||
],
|
||||
|
@ -4161,33 +4161,33 @@ async def test_referenced_floors(hass: HomeAssistant) -> None:
|
|||
cv.SCRIPT_SCHEMA(
|
||||
[
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"floor_id": "floor_service_not_list"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"floor_id": ["floor_service_list"]},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"floor_id": "{{ 'floor_service_template' }}"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"target": {"floor_id": "floor_in_target"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {"floor_id": "floor_in_data_template"},
|
||||
},
|
||||
{"service": "test.script", "data": {"without": "floor_id"}},
|
||||
{"action": "test.script", "data": {"without": "floor_id"}},
|
||||
{
|
||||
"choose": [
|
||||
{
|
||||
"conditions": "{{ true == false }}",
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"floor_id": "floor_choice_1_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4196,7 +4196,7 @@ async def test_referenced_floors(hass: HomeAssistant) -> None:
|
|||
"conditions": "{{ true == false }}",
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"floor_id": "floor_choice_2_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4204,7 +4204,7 @@ async def test_referenced_floors(hass: HomeAssistant) -> None:
|
|||
],
|
||||
"default": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"floor_id": "floor_default_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4215,13 +4215,13 @@ async def test_referenced_floors(hass: HomeAssistant) -> None:
|
|||
"if": [],
|
||||
"then": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"floor_id": "floor_if_then"},
|
||||
}
|
||||
],
|
||||
"else": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"floor_id": "floor_if_else"},
|
||||
}
|
||||
],
|
||||
|
@ -4229,7 +4229,7 @@ async def test_referenced_floors(hass: HomeAssistant) -> None:
|
|||
{
|
||||
"parallel": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"floor_id": "floor_parallel"},
|
||||
}
|
||||
],
|
||||
|
@ -4262,33 +4262,33 @@ async def test_referenced_areas(hass: HomeAssistant) -> None:
|
|||
cv.SCRIPT_SCHEMA(
|
||||
[
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"area_id": "area_service_not_list"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"area_id": ["area_service_list"]},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"area_id": "{{ 'area_service_template' }}"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"target": {"area_id": "area_in_target"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {"area_id": "area_in_data_template"},
|
||||
},
|
||||
{"service": "test.script", "data": {"without": "area_id"}},
|
||||
{"action": "test.script", "data": {"without": "area_id"}},
|
||||
{
|
||||
"choose": [
|
||||
{
|
||||
"conditions": "{{ true == false }}",
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"area_id": "area_choice_1_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4297,7 +4297,7 @@ async def test_referenced_areas(hass: HomeAssistant) -> None:
|
|||
"conditions": "{{ true == false }}",
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"area_id": "area_choice_2_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4305,7 +4305,7 @@ async def test_referenced_areas(hass: HomeAssistant) -> None:
|
|||
],
|
||||
"default": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"area_id": "area_default_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4316,13 +4316,13 @@ async def test_referenced_areas(hass: HomeAssistant) -> None:
|
|||
"if": [],
|
||||
"then": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"area_id": "area_if_then"},
|
||||
}
|
||||
],
|
||||
"else": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"area_id": "area_if_else"},
|
||||
}
|
||||
],
|
||||
|
@ -4330,7 +4330,7 @@ async def test_referenced_areas(hass: HomeAssistant) -> None:
|
|||
{
|
||||
"parallel": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"area_id": "area_parallel"},
|
||||
}
|
||||
],
|
||||
|
@ -4364,27 +4364,27 @@ async def test_referenced_entities(hass: HomeAssistant) -> None:
|
|||
cv.SCRIPT_SCHEMA(
|
||||
[
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.service_not_list"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": ["light.service_list"]},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "{{ 'light.service_template' }}"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"entity_id": "light.direct_entity_referenced",
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"target": {"entity_id": "light.entity_in_target"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {"entity_id": "light.entity_in_data_template"},
|
||||
},
|
||||
{
|
||||
|
@ -4392,7 +4392,7 @@ async def test_referenced_entities(hass: HomeAssistant) -> None:
|
|||
"entity_id": "sensor.condition",
|
||||
"state": "100",
|
||||
},
|
||||
{"service": "test.script", "data": {"without": "entity_id"}},
|
||||
{"action": "test.script", "data": {"without": "entity_id"}},
|
||||
{"scene": "scene.hello"},
|
||||
{
|
||||
"choose": [
|
||||
|
@ -4400,7 +4400,7 @@ async def test_referenced_entities(hass: HomeAssistant) -> None:
|
|||
"conditions": "{{ states.light.choice_1_cond == 'on' }}",
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.choice_1_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4413,7 +4413,7 @@ async def test_referenced_entities(hass: HomeAssistant) -> None:
|
|||
},
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.choice_2_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4421,7 +4421,7 @@ async def test_referenced_entities(hass: HomeAssistant) -> None:
|
|||
],
|
||||
"default": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.default_seq"},
|
||||
}
|
||||
],
|
||||
|
@ -4432,13 +4432,13 @@ async def test_referenced_entities(hass: HomeAssistant) -> None:
|
|||
"if": [],
|
||||
"then": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.if_then"},
|
||||
}
|
||||
],
|
||||
"else": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.if_else"},
|
||||
}
|
||||
],
|
||||
|
@ -4446,7 +4446,7 @@ async def test_referenced_entities(hass: HomeAssistant) -> None:
|
|||
{
|
||||
"parallel": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"entity_id": "light.parallel"},
|
||||
}
|
||||
],
|
||||
|
@ -4491,19 +4491,19 @@ async def test_referenced_devices(hass: HomeAssistant) -> None:
|
|||
"domain": "switch",
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"device_id": "data-string-id"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data_template": {"device_id": "data-template-string-id"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"target": {"device_id": "target-string-id"},
|
||||
},
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"target": {"device_id": ["target-list-id-1", "target-list-id-2"]},
|
||||
},
|
||||
{
|
||||
|
@ -4515,7 +4515,7 @@ async def test_referenced_devices(hass: HomeAssistant) -> None:
|
|||
),
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"target": {
|
||||
"device_id": "choice-1-seq-device-target"
|
||||
},
|
||||
|
@ -4530,7 +4530,7 @@ async def test_referenced_devices(hass: HomeAssistant) -> None:
|
|||
},
|
||||
"sequence": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"target": {
|
||||
"device_id": "choice-2-seq-device-target"
|
||||
},
|
||||
|
@ -4540,7 +4540,7 @@ async def test_referenced_devices(hass: HomeAssistant) -> None:
|
|||
],
|
||||
"default": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"target": {"device_id": "default-device-target"},
|
||||
}
|
||||
],
|
||||
|
@ -4549,13 +4549,13 @@ async def test_referenced_devices(hass: HomeAssistant) -> None:
|
|||
"if": [],
|
||||
"then": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"device_id": "if-then"},
|
||||
}
|
||||
],
|
||||
"else": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"data": {"device_id": "if-else"},
|
||||
}
|
||||
],
|
||||
|
@ -4563,7 +4563,7 @@ async def test_referenced_devices(hass: HomeAssistant) -> None:
|
|||
{
|
||||
"parallel": [
|
||||
{
|
||||
"service": "test.script",
|
||||
"action": "test.script",
|
||||
"target": {"device_id": "parallel-device"},
|
||||
}
|
||||
],
|
||||
|
@ -5104,7 +5104,7 @@ async def test_set_variable(
|
|||
sequence = cv.SCRIPT_SCHEMA(
|
||||
[
|
||||
{"alias": alias, "variables": {"variable": "value"}},
|
||||
{"service": "test.script", "data": {"value": "{{ variable }}"}},
|
||||
{"action": "test.script", "data": {"value": "{{ variable }}"}},
|
||||
]
|
||||
)
|
||||
script_obj = script.Script(hass, sequence, "test script", "test_domain")
|
||||
|
@ -5143,9 +5143,9 @@ async def test_set_redefines_variable(
|
|||
sequence = cv.SCRIPT_SCHEMA(
|
||||
[
|
||||
{"variables": {"variable": "1"}},
|
||||
{"service": "test.script", "data": {"value": "{{ variable }}"}},
|
||||
{"action": "test.script", "data": {"value": "{{ variable }}"}},
|
||||
{"variables": {"variable": "{{ variable | int + 1 }}"}},
|
||||
{"service": "test.script", "data": {"value": "{{ variable }}"}},
|
||||
{"action": "test.script", "data": {"value": "{{ variable }}"}},
|
||||
]
|
||||
)
|
||||
script_obj = script.Script(hass, sequence, "test script", "test_domain")
|
||||
|
@ -5214,7 +5214,7 @@ async def test_validate_action_config(
|
|||
}
|
||||
|
||||
configs = {
|
||||
cv.SCRIPT_ACTION_CALL_SERVICE: {"service": "light.turn_on"},
|
||||
cv.SCRIPT_ACTION_CALL_SERVICE: {"action": "light.turn_on"},
|
||||
cv.SCRIPT_ACTION_DELAY: {"delay": 5},
|
||||
cv.SCRIPT_ACTION_WAIT_TEMPLATE: {
|
||||
"wait_template": "{{ states.light.kitchen.state == 'on' }}"
|
||||
|
@ -5349,7 +5349,7 @@ async def test_embedded_wait_for_trigger_in_automation(hass: HomeAssistant) -> N
|
|||
}
|
||||
]
|
||||
},
|
||||
{"service": "test.script"},
|
||||
{"action": "test.script"},
|
||||
],
|
||||
}
|
||||
},
|
||||
|
@ -5704,12 +5704,12 @@ async def test_continue_on_error(hass: HomeAssistant) -> None:
|
|||
{"event": "test_event"},
|
||||
{
|
||||
"continue_on_error": True,
|
||||
"service": "broken.service",
|
||||
"action": "broken.service",
|
||||
},
|
||||
{"event": "test_event"},
|
||||
{
|
||||
"continue_on_error": False,
|
||||
"service": "broken.service",
|
||||
"action": "broken.service",
|
||||
},
|
||||
{"event": "test_event"},
|
||||
]
|
||||
|
@ -5786,7 +5786,7 @@ async def test_continue_on_error_automation_issue(hass: HomeAssistant) -> None:
|
|||
[
|
||||
{
|
||||
"continue_on_error": True,
|
||||
"service": "service.not_found",
|
||||
"action": "service.not_found",
|
||||
},
|
||||
]
|
||||
)
|
||||
|
@ -5834,7 +5834,7 @@ async def test_continue_on_error_unknown_error(hass: HomeAssistant) -> None:
|
|||
[
|
||||
{
|
||||
"continue_on_error": True,
|
||||
"service": "some.service",
|
||||
"action": "some.service",
|
||||
},
|
||||
]
|
||||
)
|
||||
|
@ -5884,7 +5884,7 @@ async def test_disabled_actions(
|
|||
{
|
||||
"alias": "Hello",
|
||||
"enabled": enabled_value,
|
||||
"service": "broken.service",
|
||||
"action": "broken.service",
|
||||
},
|
||||
{
|
||||
"alias": "World",
|
||||
|
@ -6255,7 +6255,7 @@ async def test_disallowed_recursion(
|
|||
context = Context()
|
||||
calls = 0
|
||||
alias = "event step"
|
||||
sequence1 = cv.SCRIPT_SCHEMA({"alias": alias, "service": "test.call_script_2"})
|
||||
sequence1 = cv.SCRIPT_SCHEMA({"alias": alias, "action": "test.call_script_2"})
|
||||
script1_obj = script.Script(
|
||||
hass,
|
||||
sequence1,
|
||||
|
@ -6265,7 +6265,7 @@ async def test_disallowed_recursion(
|
|||
running_description="test script1",
|
||||
)
|
||||
|
||||
sequence2 = cv.SCRIPT_SCHEMA({"alias": alias, "service": "test.call_script_3"})
|
||||
sequence2 = cv.SCRIPT_SCHEMA({"alias": alias, "action": "test.call_script_3"})
|
||||
script2_obj = script.Script(
|
||||
hass,
|
||||
sequence2,
|
||||
|
@ -6275,7 +6275,7 @@ async def test_disallowed_recursion(
|
|||
running_description="test script2",
|
||||
)
|
||||
|
||||
sequence3 = cv.SCRIPT_SCHEMA({"alias": alias, "service": "test.call_script_1"})
|
||||
sequence3 = cv.SCRIPT_SCHEMA({"alias": alias, "action": "test.call_script_1"})
|
||||
script3_obj = script.Script(
|
||||
hass,
|
||||
sequence3,
|
||||
|
@ -6315,3 +6315,43 @@ async def test_disallowed_recursion(
|
|||
"- test_domain2.Test Name2\n"
|
||||
"- test_domain3.Test Name3"
|
||||
) in caplog.text
|
||||
|
||||
|
||||
async def test_calling_service_backwards_compatible(
|
||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Test the calling of a service with the service instead of the action key."""
|
||||
context = Context()
|
||||
calls = async_mock_service(hass, "test", "script")
|
||||
|
||||
alias = "service step"
|
||||
sequence = cv.SCRIPT_SCHEMA(
|
||||
{"alias": alias, "service": "test.script", "data": {"hello": "{{ 'world' }}"}}
|
||||
)
|
||||
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
|
||||
|
||||
await script_obj.async_run(context=context)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(calls) == 1
|
||||
assert calls[0].context is context
|
||||
assert calls[0].data.get("hello") == "world"
|
||||
assert f"Executing step {alias}" in caplog.text
|
||||
|
||||
assert_action_trace(
|
||||
{
|
||||
"0": [
|
||||
{
|
||||
"result": {
|
||||
"params": {
|
||||
"domain": "test",
|
||||
"service": "script",
|
||||
"service_data": {"hello": "world"},
|
||||
"target": {},
|
||||
},
|
||||
"running_script": False,
|
||||
}
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
|
|
@ -405,7 +405,7 @@ async def test_service_call(hass: HomeAssistant) -> None:
|
|||
"""Test service call with templating."""
|
||||
calls = async_mock_service(hass, "test_domain", "test_service")
|
||||
config = {
|
||||
"service": "{{ 'test_domain.test_service' }}",
|
||||
"action": "{{ 'test_domain.test_service' }}",
|
||||
"entity_id": "hello.world",
|
||||
"data": {
|
||||
"hello": "{{ 'goodbye' }}",
|
||||
|
@ -435,7 +435,7 @@ async def test_service_call(hass: HomeAssistant) -> None:
|
|||
}
|
||||
|
||||
config = {
|
||||
"service": "{{ 'test_domain.test_service' }}",
|
||||
"action": "{{ 'test_domain.test_service' }}",
|
||||
"target": {
|
||||
"area_id": ["area-42", "{{ 'area-51' }}"],
|
||||
"device_id": ["abcdef", "{{ 'fedcba' }}"],
|
||||
|
@ -455,7 +455,7 @@ async def test_service_call(hass: HomeAssistant) -> None:
|
|||
}
|
||||
|
||||
config = {
|
||||
"service": "{{ 'test_domain.test_service' }}",
|
||||
"action": "{{ 'test_domain.test_service' }}",
|
||||
"target": "{{ var_target }}",
|
||||
}
|
||||
|
||||
|
@ -542,7 +542,7 @@ async def test_split_entity_string(hass: HomeAssistant) -> None:
|
|||
await service.async_call_from_config(
|
||||
hass,
|
||||
{
|
||||
"service": "test_domain.test_service",
|
||||
"action": "test_domain.test_service",
|
||||
"entity_id": "hello.world, sensor.beer",
|
||||
},
|
||||
)
|
||||
|
@ -554,7 +554,7 @@ async def test_not_mutate_input(hass: HomeAssistant) -> None:
|
|||
"""Test for immutable input."""
|
||||
async_mock_service(hass, "test_domain", "test_service")
|
||||
config = {
|
||||
"service": "test_domain.test_service",
|
||||
"action": "test_domain.test_service",
|
||||
"entity_id": "hello.world, sensor.beer",
|
||||
"data": {"hello": 1},
|
||||
"data_template": {"nested": {"value": "{{ 1 + 1 }}"}},
|
||||
|
@ -581,7 +581,7 @@ async def test_fail_silently_if_no_service(mock_log, hass: HomeAssistant) -> Non
|
|||
await service.async_call_from_config(hass, {})
|
||||
assert mock_log.call_count == 2
|
||||
|
||||
await service.async_call_from_config(hass, {"service": "invalid"})
|
||||
await service.async_call_from_config(hass, {"action": "invalid"})
|
||||
assert mock_log.call_count == 3
|
||||
|
||||
|
||||
|
@ -597,7 +597,7 @@ async def test_service_call_entry_id(
|
|||
assert entry.entity_id == "hello.world"
|
||||
|
||||
config = {
|
||||
"service": "test_domain.test_service",
|
||||
"action": "test_domain.test_service",
|
||||
"target": {"entity_id": entry.id},
|
||||
}
|
||||
|
||||
|
@ -613,7 +613,7 @@ async def test_service_call_all_none(hass: HomeAssistant, target) -> None:
|
|||
calls = async_mock_service(hass, "test_domain", "test_service")
|
||||
|
||||
config = {
|
||||
"service": "test_domain.test_service",
|
||||
"action": "test_domain.test_service",
|
||||
"target": {"entity_id": target},
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue