"""Support alarm_control_panel entity for Xiaomi Miot.""" import logging from homeassistant.components.alarm_control_panel import ( DOMAIN as ENTITY_DOMAIN, AlarmControlPanelEntity, AlarmControlPanelEntityFeature, # v2022.5 ) from . import ( DOMAIN, CONF_MODEL, XIAOMI_CONFIG_SCHEMA as PLATFORM_SCHEMA, # noqa: F401 HassEntry, MiotEntity, async_setup_config_entry, bind_services_to_entries, ) from .core.miot_spec import ( MiotSpec, MiotService, ) from .core.const import AlarmControlPanelState _LOGGER = logging.getLogger(__name__) DATA_KEY = f'{ENTITY_DOMAIN}.{DOMAIN}' SERVICE_TO_METHOD = {} async def async_setup_entry(hass, config_entry, async_add_entities): HassEntry.init(hass, config_entry).new_adder(ENTITY_DOMAIN, async_add_entities) await async_setup_config_entry(hass, config_entry, async_setup_platform, async_add_entities, ENTITY_DOMAIN) async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): hass.data.setdefault(DATA_KEY, {}) hass.data[DOMAIN]['add_entities'][ENTITY_DOMAIN] = async_add_entities config['hass'] = hass model = str(config.get(CONF_MODEL) or '') spec = hass.data[DOMAIN]['miot_specs'].get(model) entities = [] if isinstance(spec, MiotSpec): for srv in spec.get_services('arming'): if not srv.get_property('arming_mode'): continue entities.append(MiotAlarmEntity(config, srv)) for entity in entities: hass.data[DOMAIN]['entities'][entity.unique_id] = entity async_add_entities(entities, update_before_add=True) bind_services_to_entries(hass, SERVICE_TO_METHOD) class MiotAlarmEntity(MiotEntity, AlarmControlPanelEntity): def __init__(self, config, miot_service: MiotService): super().__init__(miot_service, config=config, logger=_LOGGER) self._attr_code_arm_required = False self._is_mgl03 = self.model == 'lumi.gateway.mgl03' self._prop_mode = miot_service.get_property('arming_mode') if self._prop_mode: if self._prop_mode.list_value('home_arming') is not None: self._supported_features |= AlarmControlPanelEntityFeature.ARM_HOME if self._prop_mode.list_value('away_arming') is not None: self._supported_features |= AlarmControlPanelEntityFeature.ARM_AWAY if self._prop_mode.list_value('sleep_arming') is not None: self._supported_features |= AlarmControlPanelEntityFeature.ARM_NIGHT if self._is_mgl03: self._supported_features |= AlarmControlPanelEntityFeature.TRIGGER async def async_update(self): await super().async_update() if not self._available: return self.update_state() def update_state(self): sta = None if self._prop_mode: val = self._prop_mode.from_device(self.device) des = self._prop_mode.list_description(val) if val is not None else None if des is not None: des = f'{des}'.lower() if 'basic' in des: sta = AlarmControlPanelState.DISARMED elif 'home' in des: sta = AlarmControlPanelState.ARMED_HOME elif 'away' in des: sta = AlarmControlPanelState.ARMED_AWAY elif 'sleep' in des: sta = AlarmControlPanelState.ARMED_NIGHT if self._is_mgl03: if self.device.props.get('arming.alarm'): sta = AlarmControlPanelState.TRIGGERED if hasattr(self, '_attr_alarm_state'): self._attr_alarm_state = sta else: self._attr_state = sta async def async_set_arm_mode(self, mode): ret = False val = self._prop_mode.list_value(mode) if val is not None: ret = await self.async_set_property(self._prop_mode, val) if ret: self.update_state() return ret async def async_alarm_disarm(self, code=None): """Send disarm command.""" return await self.async_set_arm_mode('basic_arming') async def async_alarm_arm_home(self, code=None): """Send arm home command.""" return await self.async_set_arm_mode('home_arming') async def async_alarm_arm_away(self, code=None): """Send arm away command.""" return await self.async_set_arm_mode('away_arming') async def async_alarm_arm_night(self, code=None): """Send arm night command.""" return await self.async_set_arm_mode('sleep_arming') def alarm_arm_vacation(self, code=None): """Send arm vacation command.""" raise NotImplementedError() async def async_alarm_trigger(self, code=None): """Send alarm trigger command.""" if self._is_mgl03: return await self.async_set_miot_property(3, 22, 1) raise NotImplementedError() def alarm_arm_custom_bypass(self, code=None): """Send arm custom bypass command.""" raise NotImplementedError()