"""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 )