core/homeassistant/components/sia/alarm_control_panel.py

138 lines
4.6 KiB
Python

"""Module for SIA Alarm Control Panels."""
from __future__ import annotations
from dataclasses import dataclass
import logging
from typing import TYPE_CHECKING
from pysiaalarm import SIAEvent
from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity,
AlarmControlPanelEntityDescription,
AlarmControlPanelState,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN
from homeassistant.core import HomeAssistant, State
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import CONF_ACCOUNT, CONF_ACCOUNTS, CONF_ZONES, KEY_ALARM, PREVIOUS_STATE
from .entity import SIABaseEntity, SIAEntityDescription
_LOGGER = logging.getLogger(__name__)
@dataclass(frozen=True)
class SIAAlarmControlPanelEntityDescription(
AlarmControlPanelEntityDescription,
SIAEntityDescription,
):
"""Describes SIA alarm control panel entity."""
ENTITY_DESCRIPTION_ALARM = SIAAlarmControlPanelEntityDescription(
key=KEY_ALARM,
code_consequences={
"PA": AlarmControlPanelState.TRIGGERED,
"JA": AlarmControlPanelState.TRIGGERED,
"TA": AlarmControlPanelState.TRIGGERED,
"BA": AlarmControlPanelState.TRIGGERED,
"HA": AlarmControlPanelState.TRIGGERED,
"CA": AlarmControlPanelState.ARMED_AWAY,
"CB": AlarmControlPanelState.ARMED_AWAY,
"CG": AlarmControlPanelState.ARMED_AWAY,
"CL": AlarmControlPanelState.ARMED_AWAY,
"CP": AlarmControlPanelState.ARMED_AWAY,
"CQ": AlarmControlPanelState.ARMED_AWAY,
"CS": AlarmControlPanelState.ARMED_AWAY,
"CF": AlarmControlPanelState.ARMED_CUSTOM_BYPASS,
"NP": AlarmControlPanelState.DISARMED,
"NO": AlarmControlPanelState.DISARMED,
"OA": AlarmControlPanelState.DISARMED,
"OB": AlarmControlPanelState.DISARMED,
"OG": AlarmControlPanelState.DISARMED,
"OP": AlarmControlPanelState.DISARMED,
"OQ": AlarmControlPanelState.DISARMED,
"OR": AlarmControlPanelState.DISARMED,
"OS": AlarmControlPanelState.DISARMED,
"NC": AlarmControlPanelState.ARMED_NIGHT,
"NL": AlarmControlPanelState.ARMED_NIGHT,
"NE": AlarmControlPanelState.ARMED_NIGHT,
"NF": AlarmControlPanelState.ARMED_NIGHT,
"BR": PREVIOUS_STATE,
},
)
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up SIA alarm_control_panel(s) from a config entry."""
async_add_entities(
SIAAlarmControlPanel(
entry, account_data[CONF_ACCOUNT], zone, ENTITY_DESCRIPTION_ALARM
)
for account_data in entry.data[CONF_ACCOUNTS]
for zone in range(
1,
entry.options[CONF_ACCOUNTS][account_data[CONF_ACCOUNT]][CONF_ZONES] + 1,
)
)
class SIAAlarmControlPanel(SIABaseEntity, AlarmControlPanelEntity):
"""Class for SIA Alarm Control Panels."""
entity_description: SIAAlarmControlPanelEntityDescription
def __init__(
self,
entry: ConfigEntry,
account: str,
zone: int,
entity_description: SIAAlarmControlPanelEntityDescription,
) -> None:
"""Create SIAAlarmControlPanel object."""
super().__init__(
entry,
account,
zone,
entity_description,
)
self._attr_alarm_state: AlarmControlPanelState | None = None
self._old_state: AlarmControlPanelState | None = None
def handle_last_state(self, last_state: State | None) -> None:
"""Handle the last state."""
self._attr_alarm_state = None
if last_state is not None and last_state.state not in (
STATE_UNAVAILABLE,
STATE_UNKNOWN,
):
self._attr_alarm_state = AlarmControlPanelState(last_state.state)
if self.state == STATE_UNAVAILABLE:
self._attr_available = False
def update_state(self, sia_event: SIAEvent) -> bool:
"""Update the state of the alarm control panel.
Return True if the event was relevant for this entity.
"""
new_state = None
if sia_event.code:
new_state = self.entity_description.code_consequences.get(sia_event.code)
if new_state is None:
return False
_LOGGER.debug("New state will be %s", new_state)
if new_state == PREVIOUS_STATE:
new_state = self._old_state
if TYPE_CHECKING:
assert isinstance(new_state, AlarmControlPanelState)
self._attr_alarm_state, self._old_state = new_state, self._attr_alarm_state
return True