139 lines
5.1 KiB
Python
139 lines
5.1 KiB
Python
"""The Homee alarm control panel platform."""
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from pyHomee.const import AttributeChangedBy, AttributeType
|
|
from pyHomee.model import HomeeAttribute
|
|
|
|
from homeassistant.components.alarm_control_panel import (
|
|
AlarmControlPanelEntity,
|
|
AlarmControlPanelEntityDescription,
|
|
AlarmControlPanelEntityFeature,
|
|
AlarmControlPanelState,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.exceptions import ServiceValidationError
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
|
|
from . import DOMAIN, HomeeConfigEntry
|
|
from .entity import HomeeEntity
|
|
from .helpers import get_name_for_enum
|
|
|
|
PARALLEL_UPDATES = 0
|
|
|
|
|
|
@dataclass(frozen=True, kw_only=True)
|
|
class HomeeAlarmControlPanelEntityDescription(AlarmControlPanelEntityDescription):
|
|
"""A class that describes Homee alarm control panel entities."""
|
|
|
|
code_arm_required: bool = False
|
|
state_list: list[AlarmControlPanelState]
|
|
|
|
|
|
ALARM_DESCRIPTIONS = {
|
|
AttributeType.HOMEE_MODE: HomeeAlarmControlPanelEntityDescription(
|
|
key="homee_mode",
|
|
code_arm_required=False,
|
|
state_list=[
|
|
AlarmControlPanelState.ARMED_HOME,
|
|
AlarmControlPanelState.ARMED_NIGHT,
|
|
AlarmControlPanelState.ARMED_AWAY,
|
|
AlarmControlPanelState.ARMED_VACATION,
|
|
],
|
|
)
|
|
}
|
|
|
|
|
|
def get_supported_features(
|
|
state_list: list[AlarmControlPanelState],
|
|
) -> AlarmControlPanelEntityFeature:
|
|
"""Return supported features based on the state list."""
|
|
supported_features = AlarmControlPanelEntityFeature(0)
|
|
if AlarmControlPanelState.ARMED_HOME in state_list:
|
|
supported_features |= AlarmControlPanelEntityFeature.ARM_HOME
|
|
if AlarmControlPanelState.ARMED_AWAY in state_list:
|
|
supported_features |= AlarmControlPanelEntityFeature.ARM_AWAY
|
|
if AlarmControlPanelState.ARMED_NIGHT in state_list:
|
|
supported_features |= AlarmControlPanelEntityFeature.ARM_NIGHT
|
|
if AlarmControlPanelState.ARMED_VACATION in state_list:
|
|
supported_features |= AlarmControlPanelEntityFeature.ARM_VACATION
|
|
return supported_features
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: HomeeConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Add the Homee platform for the alarm control panel component."""
|
|
|
|
async_add_entities(
|
|
HomeeAlarmPanel(attribute, config_entry, ALARM_DESCRIPTIONS[attribute.type])
|
|
for node in config_entry.runtime_data.nodes
|
|
for attribute in node.attributes
|
|
if attribute.type in ALARM_DESCRIPTIONS and attribute.editable
|
|
)
|
|
|
|
|
|
class HomeeAlarmPanel(HomeeEntity, AlarmControlPanelEntity):
|
|
"""Representation of a Homee alarm control panel."""
|
|
|
|
entity_description: HomeeAlarmControlPanelEntityDescription
|
|
|
|
def __init__(
|
|
self,
|
|
attribute: HomeeAttribute,
|
|
entry: HomeeConfigEntry,
|
|
description: HomeeAlarmControlPanelEntityDescription,
|
|
) -> None:
|
|
"""Initialize a Homee alarm control panel entity."""
|
|
super().__init__(attribute, entry)
|
|
self.entity_description = description
|
|
self._attr_code_arm_required = description.code_arm_required
|
|
self._attr_supported_features = get_supported_features(description.state_list)
|
|
self._attr_translation_key = description.key
|
|
|
|
@property
|
|
def alarm_state(self) -> AlarmControlPanelState:
|
|
"""Return current state."""
|
|
return self.entity_description.state_list[int(self._attribute.current_value)]
|
|
|
|
@property
|
|
def changed_by(self) -> str:
|
|
"""Return by whom or what the entity was last changed."""
|
|
changed_by_name = get_name_for_enum(
|
|
AttributeChangedBy, self._attribute.changed_by
|
|
)
|
|
return f"{changed_by_name} - {self._attribute.changed_by_id}"
|
|
|
|
async def _async_set_alarm_state(self, state: AlarmControlPanelState) -> None:
|
|
"""Set the alarm state."""
|
|
if state in self.entity_description.state_list:
|
|
await self.async_set_homee_value(
|
|
self.entity_description.state_list.index(state)
|
|
)
|
|
|
|
async def async_alarm_disarm(self, code: str | None = None) -> None:
|
|
"""Send disarm command."""
|
|
# Since disarm is always present in the UI, we raise an error.
|
|
raise ServiceValidationError(
|
|
translation_domain=DOMAIN,
|
|
translation_key="disarm_not_supported",
|
|
)
|
|
|
|
async def async_alarm_arm_home(self, code: str | None = None) -> None:
|
|
"""Send arm home command."""
|
|
await self._async_set_alarm_state(AlarmControlPanelState.ARMED_HOME)
|
|
|
|
async def async_alarm_arm_night(self, code: str | None = None) -> None:
|
|
"""Send arm night command."""
|
|
await self._async_set_alarm_state(AlarmControlPanelState.ARMED_NIGHT)
|
|
|
|
async def async_alarm_arm_away(self, code: str | None = None) -> None:
|
|
"""Send arm away command."""
|
|
await self._async_set_alarm_state(AlarmControlPanelState.ARMED_AWAY)
|
|
|
|
async def async_alarm_arm_vacation(self, code: str | None = None) -> None:
|
|
"""Send arm vacation command."""
|
|
await self._async_set_alarm_state(AlarmControlPanelState.ARMED_VACATION)
|