1 """Component to interface with an alarm control panel."""
3 from __future__
import annotations
6 from datetime
import timedelta
7 from functools
import partial
9 from typing
import TYPE_CHECKING, Any, Final, final
11 from propcache
import cached_property
12 import voluptuous
as vol
18 SERVICE_ALARM_ARM_AWAY,
19 SERVICE_ALARM_ARM_CUSTOM_BYPASS,
20 SERVICE_ALARM_ARM_HOME,
21 SERVICE_ALARM_ARM_NIGHT,
22 SERVICE_ALARM_ARM_VACATION,
24 SERVICE_ALARM_TRIGGER,
31 all_with_deprecated_constants,
32 check_if_deprecated_constant,
33 dir_with_deprecated_constants,
43 _DEPRECATED_FORMAT_NUMBER,
44 _DEPRECATED_FORMAT_TEXT,
45 _DEPRECATED_SUPPORT_ALARM_ARM_AWAY,
46 _DEPRECATED_SUPPORT_ALARM_ARM_CUSTOM_BYPASS,
47 _DEPRECATED_SUPPORT_ALARM_ARM_HOME,
48 _DEPRECATED_SUPPORT_ALARM_ARM_NIGHT,
49 _DEPRECATED_SUPPORT_ALARM_ARM_VACATION,
50 _DEPRECATED_SUPPORT_ALARM_TRIGGER,
52 ATTR_CODE_ARM_REQUIRED,
54 AlarmControlPanelEntityFeature,
55 AlarmControlPanelState,
59 _LOGGER: Final = logging.getLogger(__name__)
61 DATA_COMPONENT: HassKey[EntityComponent[AlarmControlPanelEntity]] =
HassKey(DOMAIN)
62 ENTITY_ID_FORMAT: Final = DOMAIN +
".{}"
63 PLATFORM_SCHEMA: Final = cv.PLATFORM_SCHEMA
64 PLATFORM_SCHEMA_BASE: Final = cv.PLATFORM_SCHEMA_BASE
67 CONF_DEFAULT_CODE =
"default_code"
70 {vol.Optional(ATTR_CODE): cv.string}
77 async
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
78 """Track states and offer events for sensors."""
79 component = hass.data[DATA_COMPONENT] = EntityComponent[AlarmControlPanelEntity](
80 _LOGGER, DOMAIN, hass, SCAN_INTERVAL
83 await component.async_setup(config)
85 component.async_register_entity_service(
88 "async_handle_alarm_disarm",
90 component.async_register_entity_service(
91 SERVICE_ALARM_ARM_HOME,
93 "async_handle_alarm_arm_home",
94 [AlarmControlPanelEntityFeature.ARM_HOME],
96 component.async_register_entity_service(
97 SERVICE_ALARM_ARM_AWAY,
99 "async_handle_alarm_arm_away",
100 [AlarmControlPanelEntityFeature.ARM_AWAY],
102 component.async_register_entity_service(
103 SERVICE_ALARM_ARM_NIGHT,
104 ALARM_SERVICE_SCHEMA,
105 "async_handle_alarm_arm_night",
106 [AlarmControlPanelEntityFeature.ARM_NIGHT],
108 component.async_register_entity_service(
109 SERVICE_ALARM_ARM_VACATION,
110 ALARM_SERVICE_SCHEMA,
111 "async_handle_alarm_arm_vacation",
112 [AlarmControlPanelEntityFeature.ARM_VACATION],
114 component.async_register_entity_service(
115 SERVICE_ALARM_ARM_CUSTOM_BYPASS,
116 ALARM_SERVICE_SCHEMA,
117 "async_handle_alarm_arm_custom_bypass",
118 [AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS],
120 component.async_register_entity_service(
121 SERVICE_ALARM_TRIGGER,
122 ALARM_SERVICE_SCHEMA,
123 "async_alarm_trigger",
124 [AlarmControlPanelEntityFeature.TRIGGER],
131 """Set up a config entry."""
136 """Unload a config entry."""
141 """A class that describes alarm control panel entities."""
144 CACHED_PROPERTIES_WITH_ATTR_ = {
148 "supported_features",
154 """An abstract class for alarm control entities."""
156 entity_description: AlarmControlPanelEntityDescription
157 _attr_alarm_state: AlarmControlPanelState |
None =
None
158 _attr_changed_by: str |
None =
None
159 _attr_code_arm_required: bool =
True
160 _attr_code_format: CodeFormat |
None =
None
161 _attr_supported_features: AlarmControlPanelEntityFeature = (
164 _alarm_control_panel_option_default_code: str |
None =
None
166 __alarm_legacy_state: bool =
False
169 """Post initialisation processing."""
171 if any(method
in cls.__dict__
for method
in (
"_attr_state",
"state")):
179 Deprecation warning if setting '_attr_state' directly
180 unless already reported.
182 if name ==
"_attr_state":
190 platform: EntityPlatform,
191 parallel_updates: asyncio.Semaphore |
None,
193 """Start adding an entity to a platform."""
200 """Report on deprecated handling of alarm state.
202 Integrations should implement alarm_state instead of using state directly.
205 "is setting state directly."
206 f
" Entity {self.entity_id} ({type(self)}) should implement the 'alarm_state'"
207 " property and return its state using the AlarmControlPanelState enum",
208 core_integration_behavior=ReportBehavior.ERROR,
209 custom_integration_behavior=ReportBehavior.LOG,
210 breaks_in_ha_version=
"2025.11",
211 integration_domain=self.
platformplatform.platform_name
if self.
platformplatform
else None,
212 exclude_integrations={DOMAIN},
218 """Return the current state."""
219 if (alarm_state := self.
alarm_statealarm_state)
is not None:
221 if self._attr_state
is not None:
225 assert isinstance(self._attr_state, str)
226 return self._attr_state
231 """Return the current alarm control panel entity state.
233 Integrations should overwrite this or use the '_attr_alarm_state'
234 attribute to set the alarm status using the 'AlarmControlPanelState' enum.
236 return self._attr_alarm_state
241 """Return code to use for a service call.
243 If the passed in code is not None, it will be returned. Otherwise return the
244 default code, if set, or None if not set, is returned.
254 """Code format or None if no code is required."""
255 return self._attr_code_format
259 """Last change triggered by."""
260 return self._attr_changed_by
264 """Whether the code is required for arm actions."""
265 return self._attr_code_arm_required
270 """Check if arm code is required, raise if no code is given."""
273 translation_domain=DOMAIN,
274 translation_key=
"code_arm_required",
275 translation_placeholders={
283 """Add default code and disarm."""
287 """Send disarm command."""
288 raise NotImplementedError
291 """Send disarm command."""
292 await self.
hasshass.async_add_executor_job(self.
alarm_disarmalarm_disarm, code)
296 """Add default code and arm home."""
300 """Send arm home command."""
301 raise NotImplementedError
304 """Send arm home command."""
309 """Add default code and arm away."""
313 """Send arm away command."""
314 raise NotImplementedError
317 """Send arm away command."""
322 """Add default code and arm night."""
326 """Send arm night command."""
327 raise NotImplementedError
330 """Send arm night command."""
335 """Add default code and arm vacation."""
339 """Send arm vacation command."""
340 raise NotImplementedError
343 """Send arm vacation command."""
347 """Send alarm trigger command."""
348 raise NotImplementedError
351 """Send alarm trigger command."""
352 await self.
hasshass.async_add_executor_job(self.
alarm_triggeralarm_trigger, code)
356 self, code: str |
None =
None
358 """Add default code and arm custom bypass."""
362 """Send arm custom bypass command."""
363 raise NotImplementedError
366 """Send arm custom bypass command."""
371 """Return the list of supported features."""
372 features = self._attr_supported_features
373 if type(features)
is int:
382 """Return the state attributes."""
390 """Call when the alarm control panel entity is added to hass."""
398 """Run when the entity registry entry has been updated."""
403 """Read entity options from entity registry.
405 Called when the entity registry entry has been updated and before the
406 alarm control panel is added to the state machine.
409 if (alarm_options := self.
registry_entryregistry_entry.options.get(DOMAIN))
and (
410 default_code := alarm_options.get(CONF_DEFAULT_CODE)
420 __getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
422 dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
None alarm_disarm(self, str|None code=None)
None async_handle_alarm_disarm(self, str|None code=None)
bool code_arm_required(self)
CodeFormat|None code_format(self)
None alarm_arm_away(self, str|None code=None)
None async_handle_alarm_arm_custom_bypass(self, str|None code=None)
None async_alarm_arm_home(self, str|None code=None)
AlarmControlPanelEntityFeature supported_features(self)
None async_handle_alarm_arm_vacation(self, str|None code=None)
None async_alarm_arm_night(self, str|None code=None)
None alarm_arm_vacation(self, str|None code=None)
None async_handle_alarm_arm_night(self, str|None code=None)
str|None check_code_arm_required(self, str|None code)
None alarm_arm_night(self, str|None code=None)
None alarm_arm_custom_bypass(self, str|None code=None)
None async_internal_added_to_hass(self)
None add_to_platform_start(self, HomeAssistant hass, EntityPlatform platform, asyncio.Semaphore|None parallel_updates)
None alarm_arm_home(self, str|None code=None)
AlarmControlPanelState|None alarm_state(self)
None async_alarm_arm_away(self, str|None code=None)
AlarmControlPanelEntityFeature
None async_handle_alarm_arm_home(self, str|None code=None)
None alarm_trigger(self, str|None code=None)
None async_handle_alarm_arm_away(self, str|None code=None)
None async_registry_entry_updated(self)
None async_alarm_arm_vacation(self, str|None code=None)
None async_alarm_arm_custom_bypass(self, str|None code=None)
None _report_deprecated_alarm_state_handling(self)
None async_alarm_trigger(self, str|None code=None)
dict[str, Any]|None state_attributes(self)
str|None code_or_default_code(self, str|None code)
None __init_subclass__(cls, **Any kwargs)
None __setattr__(self, str name, Any value)
str|None changed_by(self)
None _async_read_entity_options(self)
None async_alarm_disarm(self, str|None code=None)
_alarm_control_panel_option_default_code
None _report_deprecated_supported_features_values(self, IntFlag replacement)
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
bool async_setup(HomeAssistant hass, ConfigType config)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
VolSchemaType make_entity_service_schema(dict|None schema, *int extra=vol.PREVENT_EXTRA)
list[str] all_with_deprecated_constants(dict[str, Any] module_globals)
None report_usage(str what, *str|None breaks_in_ha_version=None, ReportBehavior core_behavior=ReportBehavior.ERROR, ReportBehavior core_integration_behavior=ReportBehavior.LOG, ReportBehavior custom_integration_behavior=ReportBehavior.LOG, set[str]|None exclude_integrations=None, str|None integration_domain=None, int level=logging.WARNING)