3 from __future__
import annotations
5 from copy
import deepcopy
9 from pysiaalarm.aio
import CommunicationsProtocol, SIAAccount, SIAClient, SIAEvent
21 CONF_IGNORE_TIMESTAMPS,
27 from .utils
import get_event_data_from_sia_event
29 _LOGGER = logging.getLogger(__name__)
31 DEFAULT_TIMEBAND = (80, 40)
35 """Class for SIA Hubs."""
42 """Create the SIAHub."""
43 self._hass: HomeAssistant = hass
44 self._entry: ConfigEntry = entry
45 self._port: int = entry.data[CONF_PORT]
46 self._title: str = entry.title
47 self._accounts: list[dict[str, Any]] = deepcopy(entry.data[CONF_ACCOUNTS])
48 self._protocol: str = entry.data[CONF_PROTOCOL]
49 self.
sia_accountssia_accounts: list[SIAAccount] |
None =
None
50 self.
sia_clientsia_client: SIAClient |
None =
None
54 """Add a device to the device_registry, register shutdown listener, load reactions."""
56 device_registry = dr.async_get(self._hass)
57 for acc
in self._accounts:
58 account = acc[CONF_ACCOUNT]
59 device_registry.async_get_or_create(
60 config_entry_id=self._entry.entry_id,
61 identifiers={(DOMAIN, f
"{self._port}_{account}")},
62 name=f
"{self._port} - {account}",
64 self._entry.async_on_unload(
67 self._entry.async_on_unload(
68 self._hass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, self.
async_shutdownasync_shutdown)
72 """Shutdown the SIA server."""
77 """Create a event on HA dispatcher and then on HA's bus, with the data from the SIAEvent.
79 The created event is handled by default for only a small subset for each platform (there are about 320 SIA Codes defined, only 22 of those are used in the alarm_control_panel), a user can choose to build other automation or even entities on the same event for SIA codes not handled by the built-in platforms.
83 "Adding event to dispatch and bus for code %s for port %s and account %s",
89 self._hass, SIA_EVENT.format(self._port, event.account), event
91 self._hass.bus.async_fire(
92 event_type=SIA_EVENT.format(self._port, event.account),
97 """Update the SIA_Accounts variable."""
101 account_id=a[CONF_ACCOUNT],
102 key=a.get(CONF_ENCRYPTION_KEY),
103 allowed_timeband=
None
104 if a[CONF_IGNORE_TIMESTAMPS]
105 else DEFAULT_TIMEBAND,
107 for a
in self._accounts
118 protocol=CommunicationsProtocol(self._protocol),
122 """Store attributes to avoid property call overhead since they are called frequently."""
123 options =
dict(self._entry.options)
124 for acc
in self._accounts:
125 acc_id = acc[CONF_ACCOUNT]
126 if acc_id
in options[CONF_ACCOUNTS]:
127 acc[CONF_IGNORE_TIMESTAMPS] = options[CONF_ACCOUNTS][acc_id][
128 CONF_IGNORE_TIMESTAMPS
130 acc[CONF_ZONES] = options[CONF_ACCOUNTS][acc_id][CONF_ZONES]
134 hass: HomeAssistant, config_entry: ConfigEntry
136 """Handle signals of config entry being updated.
138 First, update the accounts, this will reflect any changes with ignore_timestamps.
139 Second, unload underlying platforms, and then setup platforms, this reflects any changes in number of zones.
142 if not (hub := hass.data[DOMAIN].
get(config_entry.entry_id)):
144 hub.update_accounts()
145 await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS)
146 await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
None async_create_and_fire_event(self, SIAEvent event)
None __init__(self, HomeAssistant hass, ConfigEntry entry)
None async_shutdown(self, Event|None _=None)
None async_setup_hub(self)
None async_config_entry_updated(HomeAssistant hass, ConfigEntry config_entry)
def update_accounts(self)
web.Response get(self, web.Request request, str config_key)
None async_stop(HomeAssistant hass)
dict[str, Any] get_event_data_from_sia_event(SIAEvent event)
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)