core/homeassistant/components/esphome/alarm_control_panel.py

153 lines
5.7 KiB
Python

"""Support for ESPHome Alarm Control Panel."""
from __future__ import annotations
from functools import partial
from aioesphomeapi import (
AlarmControlPanelCommand,
AlarmControlPanelEntityState as ESPHomeAlarmControlPanelEntityState,
AlarmControlPanelInfo,
AlarmControlPanelState as ESPHomeAlarmControlPanelState,
APIIntEnum,
EntityInfo,
)
from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity,
AlarmControlPanelEntityFeature,
AlarmControlPanelState,
CodeFormat,
)
from homeassistant.core import callback
from .entity import (
EsphomeEntity,
convert_api_error_ha_error,
esphome_state_property,
platform_async_setup_entry,
)
from .enum_mapper import EsphomeEnumMapper
_ESPHOME_ACP_STATE_TO_HASS_STATE: EsphomeEnumMapper[
ESPHomeAlarmControlPanelState, AlarmControlPanelState
] = EsphomeEnumMapper(
{
ESPHomeAlarmControlPanelState.DISARMED: AlarmControlPanelState.DISARMED,
ESPHomeAlarmControlPanelState.ARMED_HOME: AlarmControlPanelState.ARMED_HOME,
ESPHomeAlarmControlPanelState.ARMED_AWAY: AlarmControlPanelState.ARMED_AWAY,
ESPHomeAlarmControlPanelState.ARMED_NIGHT: AlarmControlPanelState.ARMED_NIGHT,
ESPHomeAlarmControlPanelState.ARMED_VACATION: AlarmControlPanelState.ARMED_VACATION,
ESPHomeAlarmControlPanelState.ARMED_CUSTOM_BYPASS: AlarmControlPanelState.ARMED_CUSTOM_BYPASS,
ESPHomeAlarmControlPanelState.PENDING: AlarmControlPanelState.PENDING,
ESPHomeAlarmControlPanelState.ARMING: AlarmControlPanelState.ARMING,
ESPHomeAlarmControlPanelState.DISARMING: AlarmControlPanelState.DISARMING,
ESPHomeAlarmControlPanelState.TRIGGERED: AlarmControlPanelState.TRIGGERED,
}
)
class EspHomeACPFeatures(APIIntEnum):
"""ESPHome AlarmCintolPanel feature numbers."""
ARM_HOME = 1
ARM_AWAY = 2
ARM_NIGHT = 4
TRIGGER = 8
ARM_CUSTOM_BYPASS = 16
ARM_VACATION = 32
class EsphomeAlarmControlPanel(
EsphomeEntity[AlarmControlPanelInfo, ESPHomeAlarmControlPanelEntityState],
AlarmControlPanelEntity,
):
"""An Alarm Control Panel implementation for ESPHome."""
@callback
def _on_static_info_update(self, static_info: EntityInfo) -> None:
"""Set attrs from static info."""
super()._on_static_info_update(static_info)
static_info = self._static_info
feature = 0
if static_info.supported_features & EspHomeACPFeatures.ARM_HOME:
feature |= AlarmControlPanelEntityFeature.ARM_HOME
if static_info.supported_features & EspHomeACPFeatures.ARM_AWAY:
feature |= AlarmControlPanelEntityFeature.ARM_AWAY
if static_info.supported_features & EspHomeACPFeatures.ARM_NIGHT:
feature |= AlarmControlPanelEntityFeature.ARM_NIGHT
if static_info.supported_features & EspHomeACPFeatures.TRIGGER:
feature |= AlarmControlPanelEntityFeature.TRIGGER
if static_info.supported_features & EspHomeACPFeatures.ARM_CUSTOM_BYPASS:
feature |= AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS
if static_info.supported_features & EspHomeACPFeatures.ARM_VACATION:
feature |= AlarmControlPanelEntityFeature.ARM_VACATION
self._attr_supported_features = AlarmControlPanelEntityFeature(feature)
self._attr_code_format = (
CodeFormat.NUMBER if static_info.requires_code else None
)
self._attr_code_arm_required = bool(static_info.requires_code_to_arm)
@property
@esphome_state_property
def alarm_state(self) -> AlarmControlPanelState | None:
"""Return the state of the device."""
return _ESPHOME_ACP_STATE_TO_HASS_STATE.from_esphome(self._state.state)
@convert_api_error_ha_error
async def async_alarm_disarm(self, code: str | None = None) -> None:
"""Send disarm command."""
self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.DISARM, code
)
@convert_api_error_ha_error
async def async_alarm_arm_home(self, code: str | None = None) -> None:
"""Send arm home command."""
self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.ARM_HOME, code
)
@convert_api_error_ha_error
async def async_alarm_arm_away(self, code: str | None = None) -> None:
"""Send arm away command."""
self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.ARM_AWAY, code
)
@convert_api_error_ha_error
async def async_alarm_arm_night(self, code: str | None = None) -> None:
"""Send arm away command."""
self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.ARM_NIGHT, code
)
@convert_api_error_ha_error
async def async_alarm_arm_custom_bypass(self, code: str | None = None) -> None:
"""Send arm away command."""
self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.ARM_CUSTOM_BYPASS, code
)
@convert_api_error_ha_error
async def async_alarm_arm_vacation(self, code: str | None = None) -> None:
"""Send arm away command."""
self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.ARM_VACATION, code
)
@convert_api_error_ha_error
async def async_alarm_trigger(self, code: str | None = None) -> None:
"""Send alarm trigger command."""
self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.TRIGGER, code
)
async_setup_entry = partial(
platform_async_setup_entry,
info_type=AlarmControlPanelInfo,
entity_type=EsphomeAlarmControlPanel,
state_type=ESPHomeAlarmControlPanelEntityState,
)