Home Assistant Unofficial Reference 2024.12.1
alarm_control_panel.py
Go to the documentation of this file.
1 """Support for ESPHome Alarm Control Panel."""
2 
3 from __future__ import annotations
4 
5 from functools import partial
6 
7 from aioesphomeapi import (
8  AlarmControlPanelCommand,
9  AlarmControlPanelEntityState as ESPHomeAlarmControlPanelEntityState,
10  AlarmControlPanelInfo,
11  AlarmControlPanelState as ESPHomeAlarmControlPanelState,
12  APIIntEnum,
13  EntityInfo,
14 )
15 
17  AlarmControlPanelEntity,
18  AlarmControlPanelEntityFeature,
19  AlarmControlPanelState,
20  CodeFormat,
21 )
22 from homeassistant.core import callback
23 
24 from .entity import (
25  EsphomeEntity,
26  convert_api_error_ha_error,
27  esphome_state_property,
28  platform_async_setup_entry,
29 )
30 from .enum_mapper import EsphomeEnumMapper
31 
32 _ESPHOME_ACP_STATE_TO_HASS_STATE: EsphomeEnumMapper[
33  ESPHomeAlarmControlPanelState, AlarmControlPanelState
35  {
36  ESPHomeAlarmControlPanelState.DISARMED: AlarmControlPanelState.DISARMED,
37  ESPHomeAlarmControlPanelState.ARMED_HOME: AlarmControlPanelState.ARMED_HOME,
38  ESPHomeAlarmControlPanelState.ARMED_AWAY: AlarmControlPanelState.ARMED_AWAY,
39  ESPHomeAlarmControlPanelState.ARMED_NIGHT: AlarmControlPanelState.ARMED_NIGHT,
40  ESPHomeAlarmControlPanelState.ARMED_VACATION: AlarmControlPanelState.ARMED_VACATION,
41  ESPHomeAlarmControlPanelState.ARMED_CUSTOM_BYPASS: AlarmControlPanelState.ARMED_CUSTOM_BYPASS,
42  ESPHomeAlarmControlPanelState.PENDING: AlarmControlPanelState.PENDING,
43  ESPHomeAlarmControlPanelState.ARMING: AlarmControlPanelState.ARMING,
44  ESPHomeAlarmControlPanelState.DISARMING: AlarmControlPanelState.DISARMING,
45  ESPHomeAlarmControlPanelState.TRIGGERED: AlarmControlPanelState.TRIGGERED,
46  }
47 )
48 
49 
50 class EspHomeACPFeatures(APIIntEnum):
51  """ESPHome AlarmCintolPanel feature numbers."""
52 
53  ARM_HOME = 1
54  ARM_AWAY = 2
55  ARM_NIGHT = 4
56  TRIGGER = 8
57  ARM_CUSTOM_BYPASS = 16
58  ARM_VACATION = 32
59 
60 
62  EsphomeEntity[AlarmControlPanelInfo, ESPHomeAlarmControlPanelEntityState],
63  AlarmControlPanelEntity,
64 ):
65  """An Alarm Control Panel implementation for ESPHome."""
66 
67  @callback
68  def _on_static_info_update(self, static_info: EntityInfo) -> None:
69  """Set attrs from static info."""
70  super()._on_static_info_update(static_info)
71  static_info = self._static_info_static_info
72  feature = 0
73  if static_info.supported_features & EspHomeACPFeatures.ARM_HOME:
74  feature |= AlarmControlPanelEntityFeature.ARM_HOME
75  if static_info.supported_features & EspHomeACPFeatures.ARM_AWAY:
76  feature |= AlarmControlPanelEntityFeature.ARM_AWAY
77  if static_info.supported_features & EspHomeACPFeatures.ARM_NIGHT:
78  feature |= AlarmControlPanelEntityFeature.ARM_NIGHT
79  if static_info.supported_features & EspHomeACPFeatures.TRIGGER:
80  feature |= AlarmControlPanelEntityFeature.TRIGGER
81  if static_info.supported_features & EspHomeACPFeatures.ARM_CUSTOM_BYPASS:
82  feature |= AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS
83  if static_info.supported_features & EspHomeACPFeatures.ARM_VACATION:
84  feature |= AlarmControlPanelEntityFeature.ARM_VACATION
85  self._attr_supported_features_attr_supported_features = AlarmControlPanelEntityFeature(feature)
86  self._attr_code_format_attr_code_format = (
87  CodeFormat.NUMBER if static_info.requires_code else None
88  )
89  self._attr_code_arm_required_attr_code_arm_required = bool(static_info.requires_code_to_arm)
90 
91  @property
92  @esphome_state_property
93  def alarm_state(self) -> AlarmControlPanelState | None:
94  """Return the state of the device."""
95  return _ESPHOME_ACP_STATE_TO_HASS_STATE.from_esphome(self._state_state.state)
96 
97  @convert_api_error_ha_error
98  async def async_alarm_disarm(self, code: str | None = None) -> None:
99  """Send disarm command."""
100  self._client_client.alarm_control_panel_command(
101  self._key_key, AlarmControlPanelCommand.DISARM, code
102  )
103 
104  @convert_api_error_ha_error
105  async def async_alarm_arm_home(self, code: str | None = None) -> None:
106  """Send arm home command."""
107  self._client_client.alarm_control_panel_command(
108  self._key_key, AlarmControlPanelCommand.ARM_HOME, code
109  )
110 
111  @convert_api_error_ha_error
112  async def async_alarm_arm_away(self, code: str | None = None) -> None:
113  """Send arm away command."""
114  self._client_client.alarm_control_panel_command(
115  self._key_key, AlarmControlPanelCommand.ARM_AWAY, code
116  )
117 
118  @convert_api_error_ha_error
119  async def async_alarm_arm_night(self, code: str | None = None) -> None:
120  """Send arm away command."""
121  self._client_client.alarm_control_panel_command(
122  self._key_key, AlarmControlPanelCommand.ARM_NIGHT, code
123  )
124 
125  @convert_api_error_ha_error
126  async def async_alarm_arm_custom_bypass(self, code: str | None = None) -> None:
127  """Send arm away command."""
128  self._client_client.alarm_control_panel_command(
129  self._key_key, AlarmControlPanelCommand.ARM_CUSTOM_BYPASS, code
130  )
131 
132  @convert_api_error_ha_error
133  async def async_alarm_arm_vacation(self, code: str | None = None) -> None:
134  """Send arm away command."""
135  self._client_client.alarm_control_panel_command(
136  self._key_key, AlarmControlPanelCommand.ARM_VACATION, code
137  )
138 
139  @convert_api_error_ha_error
140  async def async_alarm_trigger(self, code: str | None = None) -> None:
141  """Send alarm trigger command."""
142  self._client_client.alarm_control_panel_command(
143  self._key_key, AlarmControlPanelCommand.TRIGGER, code
144  )
145 
146 
147 async_setup_entry = partial(
148  platform_async_setup_entry,
149  info_type=AlarmControlPanelInfo,
150  entity_type=EsphomeAlarmControlPanel,
151  state_type=ESPHomeAlarmControlPanelEntityState,
152 )