"""Alarm control panel entities for MB-Secure.""" from __future__ import annotations from homeassistant.components.alarm_control_panel import ( AlarmControlPanelEntity, AlarmControlPanelEntityFeature, AlarmControlPanelState, ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .coordinator import MBSecureCoordinator from .entity import MBSecureEntity, async_setup_dynamic_entities async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry[MBSecureCoordinator], async_add_entities: AddEntitiesCallback, ) -> None: """Set up capability-reported area alarm entities.""" coordinator = entry.runtime_data assert coordinator.info is not None and coordinator.info.bridge_id is not None bridge_id = coordinator.info.bridge_id async_setup_dynamic_entities( entry, async_add_entities, collection_name="areas", capability=frozenset({"arm_away", "disarm"}), factory=lambda object_id: MBSecureAlarmEntity( coordinator, bridge_id, object_id ), ) class MBSecureAlarmEntity(MBSecureEntity, AlarmControlPanelEntity): """Represent one normalized security area.""" _attr_code_arm_required = False def __init__( self, coordinator: MBSecureCoordinator, bridge_id: str, object_id: str ) -> None: """Initialize an area alarm entity.""" super().__init__(coordinator, bridge_id, "areas", object_id) @property def alarm_state(self) -> AlarmControlPanelState | None: """Return the normalized area state.""" item = self.bridge_object if item is None: return None try: return AlarmControlPanelState(item.state) except ValueError: return None @property def supported_features(self) -> AlarmControlPanelEntityFeature: """Expose only explicitly reported arm capabilities.""" item = self.bridge_object if item is None: return AlarmControlPanelEntityFeature(0) features = AlarmControlPanelEntityFeature(0) if "arm_away" in item.capabilities: features |= AlarmControlPanelEntityFeature.ARM_AWAY return features async def async_alarm_arm_away(self, code: str | None = None) -> None: """Arm this area in away mode.""" item = self.bridge_object if item is None or "arm_away" not in item.capabilities: raise NotImplementedError("arm away capability is not available") await self.coordinator.client.async_arm_area(self._object_id, "away") await self.coordinator.async_request_refresh() async def async_alarm_disarm(self, code: str | None = None) -> None: """Disarm this area when the capability is available.""" item = self.bridge_object if item is None or "disarm" not in item.capabilities: raise NotImplementedError("disarm capability is not available") await self.coordinator.client.async_disarm_area(self._object_id) await self.coordinator.async_request_refresh()