1 """Module for SIA Base Entity."""
3 from __future__
import annotations
5 from abc
import abstractmethod
6 from dataclasses
import dataclass
9 from pysiaalarm
import SIAEvent
23 AVAILABILITY_EVENT_CODE,
32 get_attr_from_sia_event,
33 get_unavailability_interval,
34 get_unique_id_and_name,
37 _LOGGER = logging.getLogger(__name__)
40 @dataclass(frozen=True)
42 """Required keys for SIA entities."""
44 code_consequences: dict[str, StateType | bool | AlarmControlPanelState]
47 @dataclass(frozen=True)
49 """Entity Description for SIA entities."""
52 class SIABaseEntity(RestoreEntity):
53 """Base class for SIA entities."""
55 entity_description: SIAEntityDescription
62 entity_description: SIAEntityDescription,
64 """Create SIABaseEntity object."""
65 self.
portport = entry.data[CONF_PORT]
70 self.ping_interval: int = next(
71 acc[CONF_PING_INTERVAL]
72 for acc
in entry.data[CONF_ACCOUNTS]
73 if acc[CONF_ACCOUNT] == account
76 entry.entry_id, entry.data[CONF_PORT], account, zone, entity_description.key
80 identifiers={(DOMAIN, self._attr_unique_id)},
81 via_device=(DOMAIN, f
"{entry.data[CONF_PORT]}_{account}"),
89 """Run when entity about to be added to hass.
91 Overridden from Entity.
93 1. register the dispatcher and add the callback to on_remove
94 2. get previous state from storage and pass to entity specific function
95 3. if available: create availability cb
100 SIA_EVENT.format(self.
portport, self.
accountaccount),
110 """Handle the last state."""
113 """Run when entity will be removed from hass.
115 Overridden from Entity.
121 """Listen to dispatcher events for this port and account and update state and attributes.
123 If the event is for either the zone or the 0 zone (hub zone),
124 then handle it further.
126 If the event had a code that was relevant for the entity,
127 then update the attributes.
128 If the event had a code that was relevant or it was a availability event
129 then update the availability and schedule the next unavailability check.
131 _LOGGER.debug(
"Received event: %s", sia_event)
132 if (
int(sia_event.ri)
if sia_event.ri
else 0)
not in (self.
zonezone, SIA_HUB_ZONE):
135 relevant_event = self.
update_stateupdate_state(sia_event)
140 if relevant_event
or sia_event.code == AVAILABILITY_EVENT_CODE:
149 """Do the entity specific state updates.
151 Return True if the event was relevant for this entity.
156 """Create a port interval update cb and store the callback."""
165 """Set unavailable after a ping interval."""
171 """Cancel the callback."""
_post_interval_update_cb_canceller
None _cancel_post_interval_update_cb(self)
None handle_last_state(self, State|None last_state)
bool update_state(self, SIAEvent sia_event)
None async_create_post_interval_update_cb(self)
None async_will_remove_from_hass(self)
None __init__(self, ConfigEntry entry, str account, int zone, SIAEntityDescription entity_description)
None async_handle_event(self, SIAEvent sia_event)
None async_added_to_hass(self)
_attr_extra_state_attributes
None async_post_interval_update(self, _)
None async_write_ha_state(self)
None async_on_remove(self, CALLBACK_TYPE func)
State|None async_get_last_state(self)
dict[str, Any] get_attr_from_sia_event(SIAEvent event)
tuple[str, str] get_unique_id_and_name(str entry_id, int port, str account, int zone, str entity_key)
float get_unavailability_interval(int ping)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
CALLBACK_TYPE async_call_later(HomeAssistant hass, float|timedelta delay, HassJob[[datetime], Coroutine[Any, Any, None]|None]|Callable[[datetime], Coroutine[Any, Any, None]|None] action)