1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-26 11:49:38 +01:00

Support multiple responses for service calls (#96370)

* add supports_response to platform entity services

* support multiple entities in entity_service_call

* support legacy response format for service calls

* revert changes to script/shell_command

* add back test for multiple responses for legacy service

* remove SupportsResponse.ONLY_LEGACY

* Apply suggestion

Co-authored-by: Allen Porter <allen.porter@gmail.com>

* test for entity_id remove None

* revert Apply suggestion

* return EntityServiceResponse from _handle_entity_call

* Use asyncio.gather

* EntityServiceResponse not Optional

* styling

---------

Co-authored-by: Allen Porter <allen.porter@gmail.com>
This commit is contained in:
Kevin Stillhammer
2023-11-03 02:37:35 +01:00
committed by GitHub
parent b86f3be510
commit 06c9719cd6
8 changed files with 277 additions and 37 deletions

View File

@@ -531,7 +531,7 @@ async def test_register_entity_service(hass: HomeAssistant) -> None:
async def test_register_entity_service_response_data(hass: HomeAssistant) -> None:
"""Test an enttiy service that does not support response data."""
"""Test an entity service that does support response data."""
entity = MockEntity(entity_id=f"{DOMAIN}.entity")
async def generate_response(
@@ -554,24 +554,25 @@ async def test_register_entity_service_response_data(hass: HomeAssistant) -> Non
response_data = await hass.services.async_call(
DOMAIN,
"hello",
service_data={"entity_id": entity.entity_id, "some": "data"},
service_data={"some": "data"},
target={"entity_id": [entity.entity_id]},
blocking=True,
return_response=True,
)
assert response_data == {"response-key": "response-value"}
assert response_data == {f"{DOMAIN}.entity": {"response-key": "response-value"}}
async def test_register_entity_service_response_data_multiple_matches(
hass: HomeAssistant,
) -> None:
"""Test asking for service response data but matching many entities."""
"""Test asking for service response data and matching many entities."""
entity1 = MockEntity(entity_id=f"{DOMAIN}.entity1")
entity2 = MockEntity(entity_id=f"{DOMAIN}.entity2")
async def generate_response(
target: MockEntity, call: ServiceCall
) -> ServiceResponse:
raise ValueError("Should not be invoked")
return {"response-key": f"response-value-{target.entity_id}"}
component = EntityComponent(_LOGGER, DOMAIN, hass)
await component.async_setup({})
@@ -579,7 +580,80 @@ async def test_register_entity_service_response_data_multiple_matches(
component.async_register_entity_service(
"hello",
{},
{"some": str},
generate_response,
supports_response=SupportsResponse.ONLY,
)
response_data = await hass.services.async_call(
DOMAIN,
"hello",
service_data={"some": "data"},
target={"entity_id": [entity1.entity_id, entity2.entity_id]},
blocking=True,
return_response=True,
)
assert response_data == {
f"{DOMAIN}.entity1": {"response-key": f"response-value-{DOMAIN}.entity1"},
f"{DOMAIN}.entity2": {"response-key": f"response-value-{DOMAIN}.entity2"},
}
async def test_register_entity_service_response_data_multiple_matches_raises(
hass: HomeAssistant,
) -> None:
"""Test asking for service response data and matching many entities raises exceptions."""
entity1 = MockEntity(entity_id=f"{DOMAIN}.entity1")
entity2 = MockEntity(entity_id=f"{DOMAIN}.entity2")
async def generate_response(
target: MockEntity, call: ServiceCall
) -> ServiceResponse:
if target.entity_id == f"{DOMAIN}.entity1":
raise RuntimeError("Something went wrong")
return {"response-key": f"response-value-{target.entity_id}"}
component = EntityComponent(_LOGGER, DOMAIN, hass)
await component.async_setup({})
await component.async_add_entities([entity1, entity2])
component.async_register_entity_service(
"hello",
{"some": str},
generate_response,
supports_response=SupportsResponse.ONLY,
)
with pytest.raises(RuntimeError, match="Something went wrong"):
await hass.services.async_call(
DOMAIN,
"hello",
service_data={"some": "data"},
target={"entity_id": [entity1.entity_id, entity2.entity_id]},
blocking=True,
return_response=True,
)
async def test_legacy_register_entity_service_response_data_multiple_matches(
hass: HomeAssistant,
) -> None:
"""Test asking for legacy service response data but matching many entities."""
entity1 = MockEntity(entity_id=f"{DOMAIN}.entity1")
entity2 = MockEntity(entity_id=f"{DOMAIN}.entity2")
async def generate_response(
target: MockEntity, call: ServiceCall
) -> ServiceResponse:
return {"response-key": "response-value"}
component = EntityComponent(_LOGGER, DOMAIN, hass)
await component.async_setup({})
await component.async_add_entities([entity1, entity2])
component.async_register_legacy_entity_service(
"hello",
{"some": str},
generate_response,
supports_response=SupportsResponse.ONLY,
)
@@ -588,6 +662,7 @@ async def test_register_entity_service_response_data_multiple_matches(
await hass.services.async_call(
DOMAIN,
"hello",
service_data={"some": "data"},
target={"entity_id": [entity1.entity_id, entity2.entity_id]},
blocking=True,
return_response=True,