Home Assistant Unofficial Reference 2024.12.1
alarm_control_panel.py
Go to the documentation of this file.
1 """Support for AlarmDecoder-based alarm control panels (Honeywell/DSC)."""
2 
3 from __future__ import annotations
4 
5 import voluptuous as vol
6 
8  AlarmControlPanelEntity,
9  AlarmControlPanelEntityFeature,
10  AlarmControlPanelState,
11  CodeFormat,
12 )
13 from homeassistant.const import ATTR_CODE
14 from homeassistant.core import HomeAssistant
15 from homeassistant.helpers import entity_platform
17 from homeassistant.helpers.dispatcher import async_dispatcher_connect
18 from homeassistant.helpers.entity_platform import AddEntitiesCallback
19 
20 from . import AlarmDecoderConfigEntry
21 from .const import (
22  CONF_ALT_NIGHT_MODE,
23  CONF_AUTO_BYPASS,
24  CONF_CODE_ARM_REQUIRED,
25  DEFAULT_ARM_OPTIONS,
26  OPTIONS_ARM,
27  SIGNAL_PANEL_MESSAGE,
28 )
29 from .entity import AlarmDecoderEntity
30 
31 SERVICE_ALARM_TOGGLE_CHIME = "alarm_toggle_chime"
32 
33 SERVICE_ALARM_KEYPRESS = "alarm_keypress"
34 ATTR_KEYPRESS = "keypress"
35 
36 
38  hass: HomeAssistant,
39  entry: AlarmDecoderConfigEntry,
40  async_add_entities: AddEntitiesCallback,
41 ) -> None:
42  """Set up for AlarmDecoder alarm panels."""
43  options = entry.options
44  arm_options = options.get(OPTIONS_ARM, DEFAULT_ARM_OPTIONS)
45 
46  entity = AlarmDecoderAlarmPanel(
47  client=entry.runtime_data.client,
48  auto_bypass=arm_options[CONF_AUTO_BYPASS],
49  code_arm_required=arm_options[CONF_CODE_ARM_REQUIRED],
50  alt_night_mode=arm_options[CONF_ALT_NIGHT_MODE],
51  )
52  async_add_entities([entity])
53 
54  platform = entity_platform.async_get_current_platform()
55  platform.async_register_entity_service(
56  SERVICE_ALARM_TOGGLE_CHIME,
57  {
58  vol.Required(ATTR_CODE): cv.string,
59  },
60  "alarm_toggle_chime",
61  )
62 
63  platform.async_register_entity_service(
64  SERVICE_ALARM_KEYPRESS,
65  {
66  vol.Required(ATTR_KEYPRESS): cv.string,
67  },
68  "alarm_keypress",
69  )
70 
71 
73  """Representation of an AlarmDecoder-based alarm panel."""
74 
75  _attr_name = "Alarm Panel"
76  _attr_should_poll = False
77  _attr_code_format = CodeFormat.NUMBER
78  _attr_supported_features = (
79  AlarmControlPanelEntityFeature.ARM_HOME
80  | AlarmControlPanelEntityFeature.ARM_AWAY
81  | AlarmControlPanelEntityFeature.ARM_NIGHT
82  )
83 
84  def __init__(self, client, auto_bypass, code_arm_required, alt_night_mode):
85  """Initialize the alarm panel."""
86  super().__init__(client)
87  self._attr_unique_id_attr_unique_id = f"{client.serial_number}-panel"
88  self._auto_bypass_auto_bypass = auto_bypass
89  self._attr_code_arm_required_attr_code_arm_required = code_arm_required
90  self._alt_night_mode_alt_night_mode = alt_night_mode
91 
92  async def async_added_to_hass(self) -> None:
93  """Register callbacks."""
94  self.async_on_removeasync_on_remove(
96  self.hasshass, SIGNAL_PANEL_MESSAGE, self._message_callback_message_callback
97  )
98  )
99 
100  def _message_callback(self, message):
101  """Handle received messages."""
102  if message.alarm_sounding or message.fire_alarm:
103  self._attr_alarm_state_attr_alarm_state = AlarmControlPanelState.TRIGGERED
104  elif message.armed_away:
105  self._attr_alarm_state_attr_alarm_state = AlarmControlPanelState.ARMED_AWAY
106  elif message.armed_home and (message.entry_delay_off or message.perimeter_only):
107  self._attr_alarm_state_attr_alarm_state = AlarmControlPanelState.ARMED_NIGHT
108  elif message.armed_home:
109  self._attr_alarm_state_attr_alarm_state = AlarmControlPanelState.ARMED_HOME
110  else:
111  self._attr_alarm_state_attr_alarm_state = AlarmControlPanelState.DISARMED
112 
113  self._attr_extra_state_attributes_attr_extra_state_attributes = {
114  "ac_power": message.ac_power,
115  "alarm_event_occurred": message.alarm_event_occurred,
116  "backlight_on": message.backlight_on,
117  "battery_low": message.battery_low,
118  "check_zone": message.check_zone,
119  "chime": message.chime_on,
120  "entry_delay_off": message.entry_delay_off,
121  "programming_mode": message.programming_mode,
122  "ready": message.ready,
123  "zone_bypassed": message.zone_bypassed,
124  }
125  self.schedule_update_ha_stateschedule_update_ha_state()
126 
127  def alarm_disarm(self, code: str | None = None) -> None:
128  """Send disarm command."""
129  if code:
130  self._client_client.send(f"{code!s}1")
131 
132  def alarm_arm_away(self, code: str | None = None) -> None:
133  """Send arm away command."""
134  self._client_client.arm_away(
135  code=code,
136  code_arm_required=self._attr_code_arm_required_attr_code_arm_required,
137  auto_bypass=self._auto_bypass_auto_bypass,
138  )
139 
140  def alarm_arm_home(self, code: str | None = None) -> None:
141  """Send arm home command."""
142  self._client_client.arm_home(
143  code=code,
144  code_arm_required=self._attr_code_arm_required_attr_code_arm_required,
145  auto_bypass=self._auto_bypass_auto_bypass,
146  )
147 
148  def alarm_arm_night(self, code: str | None = None) -> None:
149  """Send arm night command."""
150  self._client_client.arm_night(
151  code=code,
152  code_arm_required=self._attr_code_arm_required_attr_code_arm_required,
153  alt_night_mode=self._alt_night_mode_alt_night_mode,
154  auto_bypass=self._auto_bypass_auto_bypass,
155  )
156 
157  def alarm_toggle_chime(self, code=None):
158  """Send toggle chime command."""
159  if code:
160  self._client_client.send(f"{code!s}9")
161 
162  def alarm_keypress(self, keypress):
163  """Send custom keypresses."""
164  if keypress:
165  self._client_client.send(keypress)
def __init__(self, client, auto_bypass, code_arm_required, alt_night_mode)
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
None schedule_update_ha_state(self, bool force_refresh=False)
Definition: entity.py:1244
None async_setup_entry(HomeAssistant hass, AlarmDecoderConfigEntry entry, AddEntitiesCallback async_add_entities)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103