diff --git a/state.py b/state.py index eadef00..28d6bf7 100644 --- a/state.py +++ b/state.py @@ -1,4 +1,4 @@ - +from copy import deepcopy from logging import Logger from typing import Any @@ -56,3 +56,52 @@ class States: async for remove in _send_dispatches(): await self.cancel_state_callback(**remove) + + + async def get_state( + self, + name: str, + namespace: str, + entity_id: str | None = None, + attribute: str | None = None, + default: Any = None, + copy: bool = True, + ): + self.logger.debug("get_state: %s.%s %s %s", entity_id, attribute, default, copy) + + result = default + + if ns := self.state.get(namespace): + # Process entity_id input + if entity_id is None: + result = ns + # TODO: filter by attribute? + elif "." not in entity_id: + domain = entity_id + result = { + eid: state + for eid, state in ns.items() + if eid.startswith(domain) + } + elif full_state := ns.get(entity_id): + result = full_state + else: + self.logger.warning(f"Entity {entity_id} does not exist in namespace {namespace}") + return + + # Process attribute input + if attribute == "all": + result = result + elif attr := full_state.get(attribute): + result = attr + elif attr := full_state.get('attributes', {}).get(attribute): + result = attr + elif state := full_state.get("state"): + result = state + + return deepcopy(result) if copy else result + else: + self.logger.warning(f"Namespace does not exist: {namespace}") + + async def cancel_state_callback(self, handle: str, name: str, silent: bool = False) -> bool: + return await self.AD.callbacks.cancel_callback(handle, name, silent)