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

@@ -20,6 +20,7 @@ from homeassistant.const import (
EVENT_HOMEASSISTANT_STOP,
)
from homeassistant.core import (
EntityServiceResponse,
Event,
HomeAssistant,
ServiceCall,
@@ -217,6 +218,40 @@ class EntityComponent(Generic[_EntityT]):
self.hass, self.entities, service_call, expand_group
)
@callback
def async_register_legacy_entity_service(
self,
name: str,
schema: dict[str | vol.Marker, Any] | vol.Schema,
func: str | Callable[..., Any],
required_features: list[int] | None = None,
supports_response: SupportsResponse = SupportsResponse.NONE,
) -> None:
"""Register an entity service with a legacy response format."""
if isinstance(schema, dict):
schema = cv.make_entity_service_schema(schema)
async def handle_service(
call: ServiceCall,
) -> ServiceResponse:
"""Handle the service."""
result = await service.entity_service_call(
self.hass, self._platforms.values(), func, call, required_features
)
if result:
if len(result) > 1:
raise HomeAssistantError(
"Deprecated service call matched more than one entity"
)
return result.popitem()[1]
return None
self.hass.services.async_register(
self.domain, name, handle_service, schema, supports_response
)
@callback
def async_register_entity_service(
self,
@@ -230,7 +265,9 @@ class EntityComponent(Generic[_EntityT]):
if isinstance(schema, dict):
schema = cv.make_entity_service_schema(schema)
async def handle_service(call: ServiceCall) -> ServiceResponse:
async def handle_service(
call: ServiceCall,
) -> EntityServiceResponse | None:
"""Handle the service."""
return await service.entity_service_call(
self.hass, self._platforms.values(), func, call, required_features