from logging import Logger from typing import Any from appdaemon import AppDaemon class States: AD: AppDaemon logger: Logger async def process_state_callbacks(self, namespace: str, state: dict[str, Any]): data: dict[str, Any] = state["data"] self.logger.debug(data) entity_id: str = data["entity_id"] device, entity = entity_id.split(".") async def _generate_dispatch_kwargs(): state_callback_dict = await self.AD.callbacks.get_callbacks(namespace, type="state") for uuid_, callback in state_callback_dict.items(): dispatch_kwargs = { 'name': callback["name"], 'funcref': callback["function"], 'entity': entity_id, 'attribute': callback['kwargs'].get('attribute', 'state'), 'new_state': data["new_state"], 'old_state': data["old_state"], 'cold': callback["kwargs"].get("old"), 'cnew': callback["kwargs"].get("new"), 'kwargs': callback["kwargs"], 'uuid_': uuid_, 'pin_app': callback["pin_app"], 'pin_thread': callback["pin_thread"], } is_oneshot = callback["kwargs"].get("oneshot", False) remove = {'name': callback["name"], 'handle': uuid_} if (centity := callback.get('entity')) and "." in centity: cdevice, centity = centity.split(".") else: cdevice = None if ( (cdevice is None) or (centity is None and device == cdevice) or (centity == entity and device == cdevice) ): yield dispatch_kwargs, is_oneshot, remove async def _send_dispatches(): async for dispatch_kwargs, is_oneshot, remove in _generate_dispatch_kwargs(): executed = await self.AD.threading.check_and_dispatch_state(**dispatch_kwargs) if executed and is_oneshot: yield remove async for remove in _send_dispatches(): await self.cancel_state_callback(**remove)