mirror of
https://github.com/home-assistant/core.git
synced 2025-11-09 02:49:40 +00:00
Fix invalid state (#16558)
* Fix invalid state * Make slightly more efficient in unsubscribing * Use uuid4"
This commit is contained in:
@@ -29,7 +29,7 @@ from voluptuous.humanize import humanize_error
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_DOMAIN, ATTR_FRIENDLY_NAME, ATTR_NOW, ATTR_SERVICE,
|
||||
ATTR_SERVICE_DATA, EVENT_CALL_SERVICE,
|
||||
ATTR_SERVICE_CALL_ID, ATTR_SERVICE_DATA, EVENT_CALL_SERVICE,
|
||||
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP,
|
||||
EVENT_SERVICE_EXECUTED, EVENT_SERVICE_REGISTERED, EVENT_STATE_CHANGED,
|
||||
EVENT_TIME_CHANGED, MATCH_ALL, EVENT_HOMEASSISTANT_CLOSE,
|
||||
@@ -1042,10 +1042,12 @@ class ServiceRegistry:
|
||||
This method is a coroutine.
|
||||
"""
|
||||
context = context or Context()
|
||||
call_id = uuid.uuid4().hex
|
||||
event_data = {
|
||||
ATTR_DOMAIN: domain.lower(),
|
||||
ATTR_SERVICE: service.lower(),
|
||||
ATTR_SERVICE_DATA: service_data,
|
||||
ATTR_SERVICE_CALL_ID: call_id,
|
||||
}
|
||||
|
||||
if not blocking:
|
||||
@@ -1058,8 +1060,9 @@ class ServiceRegistry:
|
||||
@callback
|
||||
def service_executed(event: Event) -> None:
|
||||
"""Handle an executed service."""
|
||||
if event.context == context:
|
||||
if event.data[ATTR_SERVICE_CALL_ID] == call_id:
|
||||
fut.set_result(True)
|
||||
unsub()
|
||||
|
||||
unsub = self._hass.bus.async_listen(
|
||||
EVENT_SERVICE_EXECUTED, service_executed)
|
||||
@@ -1069,7 +1072,8 @@ class ServiceRegistry:
|
||||
|
||||
done, _ = await asyncio.wait([fut], timeout=SERVICE_CALL_LIMIT)
|
||||
success = bool(done)
|
||||
unsub()
|
||||
if not success:
|
||||
unsub()
|
||||
return success
|
||||
|
||||
async def _event_to_service_call(self, event: Event) -> None:
|
||||
@@ -1077,6 +1081,7 @@ class ServiceRegistry:
|
||||
service_data = event.data.get(ATTR_SERVICE_DATA) or {}
|
||||
domain = event.data.get(ATTR_DOMAIN).lower() # type: ignore
|
||||
service = event.data.get(ATTR_SERVICE).lower() # type: ignore
|
||||
call_id = event.data.get(ATTR_SERVICE_CALL_ID)
|
||||
|
||||
if not self.has_service(domain, service):
|
||||
if event.origin == EventOrigin.local:
|
||||
@@ -1088,12 +1093,17 @@ class ServiceRegistry:
|
||||
|
||||
def fire_service_executed() -> None:
|
||||
"""Fire service executed event."""
|
||||
if not call_id:
|
||||
return
|
||||
|
||||
data = {ATTR_SERVICE_CALL_ID: call_id}
|
||||
|
||||
if (service_handler.is_coroutinefunction or
|
||||
service_handler.is_callback):
|
||||
self._hass.bus.async_fire(EVENT_SERVICE_EXECUTED, {},
|
||||
self._hass.bus.async_fire(EVENT_SERVICE_EXECUTED, data,
|
||||
EventOrigin.local, event.context)
|
||||
else:
|
||||
self._hass.bus.fire(EVENT_SERVICE_EXECUTED, {},
|
||||
self._hass.bus.fire(EVENT_SERVICE_EXECUTED, data,
|
||||
EventOrigin.local, event.context)
|
||||
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user