"""A class to hold entity values.""" from __future__ import annotations from collections import OrderedDict import fnmatch from functools import lru_cache import re from typing import Any from homeassistant.core import split_entity_id _MAX_EXPECTED_ENTITIES = 16384 class EntityValues: """Class to store entity id based values. This class is expected to only be used infrequently as it caches all entity ids up to _MAX_EXPECTED_ENTITIES. The cache includes `self` so it is important to only use this in places where usage of `EntityValues` is immortal. """ def __init__( self, exact: dict[str, dict[str, str]] | None = None, domain: dict[str, dict[str, str]] | None = None, glob: dict[str, dict[str, str]] | None = None, ) -> None: """Initialize an EntityConfigDict.""" self._exact = exact self._domain = domain if glob is None: compiled: dict[re.Pattern[str], Any] | None = None else: compiled = OrderedDict() for key, value in glob.items(): compiled[re.compile(fnmatch.translate(key))] = value self._glob = compiled @lru_cache(maxsize=_MAX_EXPECTED_ENTITIES) def get(self, entity_id: str) -> dict[str, str]: """Get config for an entity id.""" domain, _ = split_entity_id(entity_id) result: dict[str, str] = {} if self._domain is not None and domain in self._domain: result.update(self._domain[domain]) if self._glob is not None: for pattern, values in self._glob.items(): if pattern.match(entity_id): result.update(values) if self._exact is not None and entity_id in self._exact: result.update(self._exact[entity_id]) return result