ha-core/homeassistant/components/esphome/alarm_control_panel.py

157 lines
5.8 KiB
Python

"""Support for ESPHome Alarm Control Panel."""
from __future__ import annotations
from aioesphomeapi import (
AlarmControlPanelCommand,
AlarmControlPanelEntityState,
AlarmControlPanelInfo,
AlarmControlPanelState,
APIIntEnum,
EntityInfo,
)
from homeassistant.components.alarm_control_panel import (
AlarmControlPanelEntity,
AlarmControlPanelEntityFeature,
CodeFormat,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY,
STATE_ALARM_ARMED_CUSTOM_BYPASS,
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_ALARM_ARMED_VACATION,
STATE_ALARM_ARMING,
STATE_ALARM_DISARMED,
STATE_ALARM_DISARMING,
STATE_ALARM_PENDING,
STATE_ALARM_TRIGGERED,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .entity import EsphomeEntity, esphome_state_property, platform_async_setup_entry
from .enum_mapper import EsphomeEnumMapper
_ESPHOME_ACP_STATE_TO_HASS_STATE: EsphomeEnumMapper[
AlarmControlPanelState, str
] = EsphomeEnumMapper(
{
AlarmControlPanelState.DISARMED: STATE_ALARM_DISARMED,
AlarmControlPanelState.ARMED_HOME: STATE_ALARM_ARMED_HOME,
AlarmControlPanelState.ARMED_AWAY: STATE_ALARM_ARMED_AWAY,
AlarmControlPanelState.ARMED_NIGHT: STATE_ALARM_ARMED_NIGHT,
AlarmControlPanelState.ARMED_VACATION: STATE_ALARM_ARMED_VACATION,
AlarmControlPanelState.ARMED_CUSTOM_BYPASS: STATE_ALARM_ARMED_CUSTOM_BYPASS,
AlarmControlPanelState.PENDING: STATE_ALARM_PENDING,
AlarmControlPanelState.ARMING: STATE_ALARM_ARMING,
AlarmControlPanelState.DISARMING: STATE_ALARM_DISARMING,
AlarmControlPanelState.TRIGGERED: STATE_ALARM_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
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up ESPHome switches based on a config entry."""
await platform_async_setup_entry(
hass,
entry,
async_add_entities,
info_type=AlarmControlPanelInfo,
entity_type=EsphomeAlarmControlPanel,
state_type=AlarmControlPanelEntityState,
)
class EsphomeAlarmControlPanel(
EsphomeEntity[AlarmControlPanelInfo, AlarmControlPanelEntityState],
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 self._static_info.supported_features & EspHomeACPFeatures.ARM_HOME:
feature |= AlarmControlPanelEntityFeature.ARM_HOME
if self._static_info.supported_features & EspHomeACPFeatures.ARM_AWAY:
feature |= AlarmControlPanelEntityFeature.ARM_AWAY
if self._static_info.supported_features & EspHomeACPFeatures.ARM_NIGHT:
feature |= AlarmControlPanelEntityFeature.ARM_NIGHT
if self._static_info.supported_features & EspHomeACPFeatures.TRIGGER:
feature |= AlarmControlPanelEntityFeature.TRIGGER
if self._static_info.supported_features & EspHomeACPFeatures.ARM_CUSTOM_BYPASS:
feature |= AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS
if self._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 state(self) -> str | None:
"""Return the state of the device."""
return _ESPHOME_ACP_STATE_TO_HASS_STATE.from_esphome(self._state.state)
async def async_alarm_disarm(self, code: str | None = None) -> None:
"""Send disarm command."""
await self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.DISARM, code
)
async def async_alarm_arm_home(self, code: str | None = None) -> None:
"""Send arm home command."""
await self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.ARM_HOME, code
)
async def async_alarm_arm_away(self, code: str | None = None) -> None:
"""Send arm away command."""
await self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.ARM_AWAY, code
)
async def async_alarm_arm_night(self, code: str | None = None) -> None:
"""Send arm away command."""
await self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.ARM_NIGHT, code
)
async def async_alarm_arm_custom_bypass(self, code: str | None = None) -> None:
"""Send arm away command."""
await self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.ARM_CUSTOM_BYPASS, code
)
async def async_alarm_arm_vacation(self, code: str | None = None) -> None:
"""Send arm away command."""
await self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.ARM_VACATION, code
)
async def async_alarm_trigger(self, code: str | None = None) -> None:
"""Send alarm trigger command."""
await self._client.alarm_control_panel_command(
self._key, AlarmControlPanelCommand.TRIGGER, code
)