"""The ISY/IoX integration data models.""" from __future__ import annotations from dataclasses import dataclass from typing import cast from pyisy import ISY from pyisy.constants import PROTO_INSTEON from pyisy.networking import NetworkCommand from pyisy.nodes import Group, Node from pyisy.programs import Program from pyisy.variables import Variable from homeassistant.const import Platform from homeassistant.helpers.entity import DeviceInfo from .const import ( CONF_NETWORK, NODE_AUX_PROP_PLATFORMS, NODE_PLATFORMS, PROGRAM_PLATFORMS, ROOT_NODE_PLATFORMS, VARIABLE_PLATFORMS, ) @dataclass class IsyData: """Data for the ISY/IoX integration.""" root: ISY nodes: dict[Platform, list[Node | Group]] root_nodes: dict[Platform, list[Node]] variables: dict[Platform, list[Variable]] programs: dict[Platform, list[tuple[str, Program, Program]]] net_resources: list[NetworkCommand] devices: dict[str, DeviceInfo] aux_properties: dict[Platform, list[tuple[Node, str]]] def __init__(self) -> None: """Initialize an empty ISY data class.""" self.nodes = {p: [] for p in NODE_PLATFORMS} self.root_nodes = {p: [] for p in ROOT_NODE_PLATFORMS} self.aux_properties = {p: [] for p in NODE_AUX_PROP_PLATFORMS} self.programs = {p: [] for p in PROGRAM_PLATFORMS} self.variables = {p: [] for p in VARIABLE_PLATFORMS} self.net_resources = [] self.devices = {} @property def uuid(self) -> str: """Return the ISY UUID identification.""" return cast(str, self.root.uuid) def uid_base(self, node: Node | Group | Variable | Program | NetworkCommand) -> str: """Return the unique id base string for a given node.""" if isinstance(node, NetworkCommand): return f"{self.uuid}_{CONF_NETWORK}_{node.address}" return f"{self.uuid}_{node.address}" @property def unique_ids(self) -> set[tuple[Platform, str]]: """Return all the unique ids for a config entry id.""" current_unique_ids: set[tuple[Platform, str]] = { (Platform.BUTTON, f"{self.uuid}_query") } # Structure and prefixes here must match what's added in __init__ and helpers for platform in NODE_PLATFORMS: for node in self.nodes[platform]: current_unique_ids.add((platform, self.uid_base(node))) for platform in NODE_AUX_PROP_PLATFORMS: for node, control in self.aux_properties[platform]: current_unique_ids.add((platform, f"{self.uid_base(node)}_{control}")) for platform in PROGRAM_PLATFORMS: for _, node, _ in self.programs[platform]: current_unique_ids.add((platform, self.uid_base(node))) for platform in VARIABLE_PLATFORMS: for node in self.variables[platform]: current_unique_ids.add((platform, self.uid_base(node))) if platform == Platform.NUMBER: current_unique_ids.add((platform, f"{self.uid_base(node)}_init")) for platform in ROOT_NODE_PLATFORMS: for node in self.root_nodes[platform]: current_unique_ids.add((platform, f"{self.uid_base(node)}_query")) if platform == Platform.BUTTON and node.protocol == PROTO_INSTEON: current_unique_ids.add((platform, f"{self.uid_base(node)}_beep")) for node in self.net_resources: current_unique_ids.add((Platform.BUTTON, self.uid_base(node))) return current_unique_ids