Add service entity context (#71558)

Co-authored-by: Shay Levy <levyshay1@gmail.com>
This commit is contained in:
Paulus Schoutsen 2022-05-09 14:45:53 -07:00 committed by GitHub
parent d8336a5216
commit 64636a4310
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 1 deletions

View file

@ -3,6 +3,7 @@ from __future__ import annotations
import asyncio
from collections.abc import Awaitable, Callable, Iterable
from contextvars import ContextVar
import dataclasses
from functools import partial, wraps
import logging
@ -63,6 +64,15 @@ _LOGGER = logging.getLogger(__name__)
SERVICE_DESCRIPTION_CACHE = "service_description_cache"
_current_entity: ContextVar[str | None] = ContextVar("current_entity", default=None)
@callback
def async_get_current_entity() -> str | None:
"""Get the current entity on which the service is called."""
return _current_entity.get()
class ServiceParams(TypedDict):
"""Type for service call parameters."""
@ -706,6 +716,7 @@ async def _handle_entity_call(
) -> None:
"""Handle calling service method."""
entity.async_set_context(context)
_current_entity.set(entity.entity_id)
if isinstance(func, str):
result = hass.async_run_job(partial(getattr(entity, func), **data)) # type: ignore[arg-type]

View file

@ -19,12 +19,12 @@ from homeassistant.const import (
STATE_ON,
)
from homeassistant.helpers import (
config_validation as cv,
device_registry as dev_reg,
entity_registry as ent_reg,
service,
template,
)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import EntityCategory
from homeassistant.setup import async_setup_component
@ -1205,3 +1205,17 @@ async def test_async_extract_config_entry_ids(hass):
)
assert await service.async_extract_config_entry_ids(hass, call) == {"abc"}
async def test_current_entity_context(hass, mock_entities):
"""Test we set the current entity context var."""
async def mock_service(entity, call):
assert entity.entity_id == service.async_get_current_entity()
await service.entity_service_call(
hass,
[Mock(entities=mock_entities)],
mock_service,
ha.ServiceCall("test_domain", "test_service", {"entity_id": "light.kitchen"}),
)