From 1fde0d18ed25e90b35ecaa14f589761b31dae85a Mon Sep 17 00:00:00 2001 From: SukramJ Date: Tue, 26 Nov 2019 00:42:53 +0100 Subject: [PATCH] Add supported_features to Alarm Control Panel to limit device_actions (#29065) * Add supported_features to Alarm Control Panel * mark supported_features abstract * Add SF to async_register_entity_service * fix test * Add missing SF SUPPORT_ALARM_ARM_CUSTOM_BYPASS * isort * fix async_register_entity_service * Update alarm_control_panel.py --- .../components/abode/alarm_control_panel.py | 9 ++ .../alarm_control_panel/__init__.py | 45 ++++++++-- .../components/alarm_control_panel/const.py | 7 ++ .../alarm_control_panel/device_action.py | 88 ++++++++++++------- .../alarmdecoder/alarm_control_panel.py | 10 +++ .../alarmdotcom/alarm_control_panel.py | 9 ++ .../components/arlo/alarm_control_panel.py | 10 +++ .../components/blink/alarm_control_panel.py | 6 ++ .../components/canary/alarm_control_panel.py | 10 +++ .../concord232/alarm_control_panel.py | 9 ++ .../components/demo/alarm_control_panel.py | 7 +- .../components/egardia/alarm_control_panel.py | 9 ++ .../components/elkm1/alarm_control_panel.py | 10 +++ .../envisalink/alarm_control_panel.py | 16 ++++ .../homekit_controller/alarm_control_panel.py | 10 +++ .../homematicip_cloud/alarm_control_panel.py | 9 ++ .../components/ialarm/alarm_control_panel.py | 9 ++ .../components/ifttt/alarm_control_panel.py | 10 +++ .../components/lupusec/alarm_control_panel.py | 9 ++ .../components/manual/alarm_control_panel.py | 20 ++++- .../manual_mqtt/alarm_control_panel.py | 39 +++++--- .../components/mqtt/alarm_control_panel.py | 10 +++ .../ness_alarm/alarm_control_panel.py | 10 +++ .../components/nx584/alarm_control_panel.py | 9 ++ .../components/point/alarm_control_panel.py | 6 ++ .../satel_integra/alarm_control_panel.py | 13 ++- .../simplisafe/alarm_control_panel.py | 9 ++ .../components/spc/alarm_control_panel.py | 10 +++ .../totalconnect/alarm_control_panel.py | 14 ++- .../verisure/alarm_control_panel.py | 9 ++ .../components/wink/alarm_control_panel.py | 9 ++ .../yale_smart_alarm/alarm_control_panel.py | 13 ++- .../alarm_control_panel/test_device_action.py | 33 +++++++ .../components/device_automation/test_init.py | 3 + .../test/alarm_control_panel.py | 16 ++++ 35 files changed, 449 insertions(+), 66 deletions(-) create mode 100644 homeassistant/components/alarm_control_panel/const.py diff --git a/homeassistant/components/abode/alarm_control_panel.py b/homeassistant/components/abode/alarm_control_panel.py index f1ff08f3a0ac2e..88a072bd79cd51 100644 --- a/homeassistant/components/abode/alarm_control_panel.py +++ b/homeassistant/components/abode/alarm_control_panel.py @@ -2,6 +2,10 @@ import logging import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, @@ -51,6 +55,11 @@ def state(self): state = None return state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + def alarm_disarm(self, code=None): """Send disarm command.""" self._device.set_standby() diff --git a/homeassistant/components/alarm_control_panel/__init__.py b/homeassistant/components/alarm_control_panel/__init__.py index 6faad5dd51f194..36cb8650aced00 100644 --- a/homeassistant/components/alarm_control_panel/__init__.py +++ b/homeassistant/components/alarm_control_panel/__init__.py @@ -1,4 +1,5 @@ """Component to interface with an alarm control panel.""" +from abc import abstractmethod from datetime import timedelta import logging @@ -7,22 +8,30 @@ from homeassistant.const import ( ATTR_CODE, ATTR_CODE_FORMAT, - SERVICE_ALARM_TRIGGER, - SERVICE_ALARM_DISARM, - SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY, - SERVICE_ALARM_ARM_NIGHT, SERVICE_ALARM_ARM_CUSTOM_BYPASS, + SERVICE_ALARM_ARM_HOME, + SERVICE_ALARM_ARM_NIGHT, + SERVICE_ALARM_DISARM, + SERVICE_ALARM_TRIGGER, ) +import homeassistant.helpers.config_validation as cv from homeassistant.helpers.config_validation import ( # noqa: F401 ENTITY_SERVICE_SCHEMA, PLATFORM_SCHEMA, PLATFORM_SCHEMA_BASE, ) -import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_component import EntityComponent +from .const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_CUSTOM_BYPASS, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, + SUPPORT_ALARM_TRIGGER, +) + DOMAIN = "alarm_control_panel" SCAN_INTERVAL = timedelta(seconds=30) ATTR_CHANGED_BY = "changed_by" @@ -49,21 +58,34 @@ async def async_setup(hass, config): SERVICE_ALARM_DISARM, ALARM_SERVICE_SCHEMA, "async_alarm_disarm" ) component.async_register_entity_service( - SERVICE_ALARM_ARM_HOME, ALARM_SERVICE_SCHEMA, "async_alarm_arm_home" + SERVICE_ALARM_ARM_HOME, + ALARM_SERVICE_SCHEMA, + "async_alarm_arm_home", + [SUPPORT_ALARM_ARM_HOME], ) component.async_register_entity_service( - SERVICE_ALARM_ARM_AWAY, ALARM_SERVICE_SCHEMA, "async_alarm_arm_away" + SERVICE_ALARM_ARM_AWAY, + ALARM_SERVICE_SCHEMA, + "async_alarm_arm_away", + [SUPPORT_ALARM_ARM_AWAY], ) component.async_register_entity_service( - SERVICE_ALARM_ARM_NIGHT, ALARM_SERVICE_SCHEMA, "async_alarm_arm_night" + SERVICE_ALARM_ARM_NIGHT, + ALARM_SERVICE_SCHEMA, + "async_alarm_arm_night", + [SUPPORT_ALARM_ARM_NIGHT], ) component.async_register_entity_service( SERVICE_ALARM_ARM_CUSTOM_BYPASS, ALARM_SERVICE_SCHEMA, "async_alarm_arm_custom_bypass", + [SUPPORT_ALARM_ARM_CUSTOM_BYPASS], ) component.async_register_entity_service( - SERVICE_ALARM_TRIGGER, ALARM_SERVICE_SCHEMA, "async_alarm_trigger" + SERVICE_ALARM_TRIGGER, + ALARM_SERVICE_SCHEMA, + "async_alarm_trigger", + [SUPPORT_ALARM_TRIGGER], ) return True @@ -164,6 +186,11 @@ def async_alarm_arm_custom_bypass(self, code=None): """ return self.hass.async_add_executor_job(self.alarm_arm_custom_bypass, code) + @property + @abstractmethod + def supported_features(self) -> int: + """Return the list of supported features.""" + @property def state_attributes(self): """Return the state attributes.""" diff --git a/homeassistant/components/alarm_control_panel/const.py b/homeassistant/components/alarm_control_panel/const.py new file mode 100644 index 00000000000000..77f7846fc3476a --- /dev/null +++ b/homeassistant/components/alarm_control_panel/const.py @@ -0,0 +1,7 @@ +"""Provides the constants needed for component.""" + +SUPPORT_ALARM_ARM_HOME = 1 +SUPPORT_ALARM_ARM_AWAY = 2 +SUPPORT_ALARM_ARM_NIGHT = 4 +SUPPORT_ALARM_TRIGGER = 8 +SUPPORT_ALARM_ARM_CUSTOM_BYPASS = 16 diff --git a/homeassistant/components/alarm_control_panel/device_action.py b/homeassistant/components/alarm_control_panel/device_action.py index a3c2b4822611e5..81e444ae16f0cb 100644 --- a/homeassistant/components/alarm_control_panel/device_action.py +++ b/homeassistant/components/alarm_control_panel/device_action.py @@ -1,5 +1,6 @@ """Provides device automations for Alarm control panel.""" -from typing import Optional, List +from typing import List, Optional + import voluptuous as vol from homeassistant.const import ( @@ -16,10 +17,17 @@ SERVICE_ALARM_DISARM, SERVICE_ALARM_TRIGGER, ) -from homeassistant.core import HomeAssistant, Context +from homeassistant.core import Context, HomeAssistant from homeassistant.helpers import entity_registry import homeassistant.helpers.config_validation as cv + from . import ATTR_CODE_ARM_REQUIRED, DOMAIN +from .const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, + SUPPORT_ALARM_TRIGGER, +) ACTION_TYPES = {"arm_away", "arm_home", "arm_night", "disarm", "trigger"} @@ -42,31 +50,42 @@ async def async_get_actions(hass: HomeAssistant, device_id: str) -> List[dict]: if entry.domain != DOMAIN: continue + state = hass.states.get(entry.entity_id) + + # We need a state or else we can't populate the HVAC and preset modes. + if state is None: + continue + + supported_features = state.attributes["supported_features"] + # Add actions for each entity that belongs to this integration - actions.append( - { - CONF_DEVICE_ID: device_id, - CONF_DOMAIN: DOMAIN, - CONF_ENTITY_ID: entry.entity_id, - CONF_TYPE: "arm_away", - } - ) - actions.append( - { - CONF_DEVICE_ID: device_id, - CONF_DOMAIN: DOMAIN, - CONF_ENTITY_ID: entry.entity_id, - CONF_TYPE: "arm_home", - } - ) - actions.append( - { - CONF_DEVICE_ID: device_id, - CONF_DOMAIN: DOMAIN, - CONF_ENTITY_ID: entry.entity_id, - CONF_TYPE: "arm_night", - } - ) + if supported_features & SUPPORT_ALARM_ARM_AWAY: + actions.append( + { + CONF_DEVICE_ID: device_id, + CONF_DOMAIN: DOMAIN, + CONF_ENTITY_ID: entry.entity_id, + CONF_TYPE: "arm_away", + } + ) + if supported_features & SUPPORT_ALARM_ARM_HOME: + actions.append( + { + CONF_DEVICE_ID: device_id, + CONF_DOMAIN: DOMAIN, + CONF_ENTITY_ID: entry.entity_id, + CONF_TYPE: "arm_home", + } + ) + if supported_features & SUPPORT_ALARM_ARM_NIGHT: + actions.append( + { + CONF_DEVICE_ID: device_id, + CONF_DOMAIN: DOMAIN, + CONF_ENTITY_ID: entry.entity_id, + CONF_TYPE: "arm_night", + } + ) actions.append( { CONF_DEVICE_ID: device_id, @@ -75,14 +94,15 @@ async def async_get_actions(hass: HomeAssistant, device_id: str) -> List[dict]: CONF_TYPE: "disarm", } ) - actions.append( - { - CONF_DEVICE_ID: device_id, - CONF_DOMAIN: DOMAIN, - CONF_ENTITY_ID: entry.entity_id, - CONF_TYPE: "trigger", - } - ) + if supported_features & SUPPORT_ALARM_TRIGGER: + actions.append( + { + CONF_DEVICE_ID: device_id, + CONF_DOMAIN: DOMAIN, + CONF_ENTITY_ID: entry.entity_id, + CONF_TYPE: "trigger", + } + ) return actions diff --git a/homeassistant/components/alarmdecoder/alarm_control_panel.py b/homeassistant/components/alarmdecoder/alarm_control_panel.py index 288c1dfd1c75a8..f9bff3bfda7b62 100644 --- a/homeassistant/components/alarmdecoder/alarm_control_panel.py +++ b/homeassistant/components/alarmdecoder/alarm_control_panel.py @@ -4,6 +4,11 @@ import voluptuous as vol import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, +) from homeassistant.const import ( ATTR_CODE, STATE_ALARM_ARMED_AWAY, @@ -122,6 +127,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT + @property def device_state_attributes(self): """Return the state attributes.""" diff --git a/homeassistant/components/alarmdotcom/alarm_control_panel.py b/homeassistant/components/alarmdotcom/alarm_control_panel.py index 07d69960e0b738..dd6b1272223cea 100644 --- a/homeassistant/components/alarmdotcom/alarm_control_panel.py +++ b/homeassistant/components/alarmdotcom/alarm_control_panel.py @@ -7,6 +7,10 @@ import homeassistant.components.alarm_control_panel as alarm from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( CONF_CODE, CONF_NAME, @@ -95,6 +99,11 @@ def state(self): return STATE_ALARM_ARMED_AWAY return None + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + @property def device_state_attributes(self): """Return the state attributes.""" diff --git a/homeassistant/components/arlo/alarm_control_panel.py b/homeassistant/components/arlo/alarm_control_panel.py index a56b2a63372cfa..838f319abc1457 100644 --- a/homeassistant/components/arlo/alarm_control_panel.py +++ b/homeassistant/components/arlo/alarm_control_panel.py @@ -7,6 +7,11 @@ PLATFORM_SCHEMA, AlarmControlPanel, ) +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, +) from homeassistant.const import ( ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, @@ -91,6 +96,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT + def update(self): """Update the state of the device.""" _LOGGER.debug("Updating Arlo Alarm Control Panel %s", self.name) diff --git a/homeassistant/components/blink/alarm_control_panel.py b/homeassistant/components/blink/alarm_control_panel.py index b1c9f6a7ec07fd..9b23c1606d4381 100644 --- a/homeassistant/components/blink/alarm_control_panel.py +++ b/homeassistant/components/blink/alarm_control_panel.py @@ -2,6 +2,7 @@ import logging from homeassistant.components.alarm_control_panel import AlarmControlPanel +from homeassistant.components.alarm_control_panel.const import SUPPORT_ALARM_ARM_AWAY from homeassistant.const import ( ATTR_ATTRIBUTION, STATE_ALARM_ARMED_AWAY, @@ -52,6 +53,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_AWAY + @property def name(self): """Return the name of the panel.""" diff --git a/homeassistant/components/canary/alarm_control_panel.py b/homeassistant/components/canary/alarm_control_panel.py index 856ecb9f3a2559..cceb78743d3ee1 100644 --- a/homeassistant/components/canary/alarm_control_panel.py +++ b/homeassistant/components/canary/alarm_control_panel.py @@ -4,6 +4,11 @@ from canary.api import LOCATION_MODE_AWAY, LOCATION_MODE_HOME, LOCATION_MODE_NIGHT from homeassistant.components.alarm_control_panel import AlarmControlPanel +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, +) from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, @@ -59,6 +64,11 @@ def state(self): return STATE_ALARM_ARMED_NIGHT return None + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT + @property def device_state_attributes(self): """Return the state attributes.""" diff --git a/homeassistant/components/concord232/alarm_control_panel.py b/homeassistant/components/concord232/alarm_control_panel.py index 37bbf05283812c..81a54a182d46e0 100644 --- a/homeassistant/components/concord232/alarm_control_panel.py +++ b/homeassistant/components/concord232/alarm_control_panel.py @@ -8,6 +8,10 @@ import homeassistant.components.alarm_control_panel as alarm from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( CONF_CODE, CONF_HOST, @@ -85,6 +89,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + def update(self): """Update values from API.""" try: diff --git a/homeassistant/components/demo/alarm_control_panel.py b/homeassistant/components/demo/alarm_control_panel.py index d82edadf161497..0323b68b1b04a5 100644 --- a/homeassistant/components/demo/alarm_control_panel.py +++ b/homeassistant/components/demo/alarm_control_panel.py @@ -1,16 +1,17 @@ """Demo platform that has two fake alarm control panels.""" import datetime + from homeassistant.components.manual.alarm_control_panel import ManualAlarm from homeassistant.const import ( + CONF_DELAY_TIME, + CONF_PENDING_TIME, + CONF_TRIGGER_TIME, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_CUSTOM_BYPASS, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED, - CONF_DELAY_TIME, - CONF_PENDING_TIME, - CONF_TRIGGER_TIME, ) diff --git a/homeassistant/components/egardia/alarm_control_panel.py b/homeassistant/components/egardia/alarm_control_panel.py index 22a458ae9aabc5..2c18be47a1f817 100644 --- a/homeassistant/components/egardia/alarm_control_panel.py +++ b/homeassistant/components/egardia/alarm_control_panel.py @@ -4,6 +4,10 @@ import requests import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, @@ -79,6 +83,11 @@ def state(self): """Return the state of the device.""" return self._status + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + @property def should_poll(self): """Poll if no report server is enabled.""" diff --git a/homeassistant/components/elkm1/alarm_control_panel.py b/homeassistant/components/elkm1/alarm_control_panel.py index 38519ab5b3f77a..8c4db6e06a5f02 100644 --- a/homeassistant/components/elkm1/alarm_control_panel.py +++ b/homeassistant/components/elkm1/alarm_control_panel.py @@ -3,6 +3,11 @@ import voluptuous as vol import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, +) from homeassistant.const import ( ATTR_CODE, ATTR_ENTITY_ID, @@ -143,6 +148,11 @@ def state(self): """Return the state of the element.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT + @property def device_state_attributes(self): """Attributes of the area.""" diff --git a/homeassistant/components/envisalink/alarm_control_panel.py b/homeassistant/components/envisalink/alarm_control_panel.py index 663f19c8ed5806..19703297ccd6b0 100644 --- a/homeassistant/components/envisalink/alarm_control_panel.py +++ b/homeassistant/components/envisalink/alarm_control_panel.py @@ -4,6 +4,12 @@ import voluptuous as vol import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, + SUPPORT_ALARM_TRIGGER, +) from homeassistant.const import ( ATTR_ENTITY_ID, STATE_ALARM_ARMED_AWAY, @@ -141,6 +147,16 @@ def state(self): state = STATE_ALARM_DISARMED return state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return ( + SUPPORT_ALARM_ARM_HOME + | SUPPORT_ALARM_ARM_AWAY + | SUPPORT_ALARM_ARM_NIGHT + | SUPPORT_ALARM_TRIGGER + ) + async def async_alarm_disarm(self, code=None): """Send disarm command.""" if code: diff --git a/homeassistant/components/homekit_controller/alarm_control_panel.py b/homeassistant/components/homekit_controller/alarm_control_panel.py index bb45a6c33d93b0..8cdbe9b2f369de 100644 --- a/homeassistant/components/homekit_controller/alarm_control_panel.py +++ b/homeassistant/components/homekit_controller/alarm_control_panel.py @@ -4,6 +4,11 @@ from homekit.model.characteristics import CharacteristicsTypes from homeassistant.components.alarm_control_panel import AlarmControlPanel +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, +) from homeassistant.const import ( ATTR_BATTERY_LEVEL, STATE_ALARM_ARMED_AWAY, @@ -88,6 +93,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT + async def async_alarm_disarm(self, code=None): """Send disarm command.""" await self.set_alarm_state(STATE_ALARM_DISARMED, code) diff --git a/homeassistant/components/homematicip_cloud/alarm_control_panel.py b/homeassistant/components/homematicip_cloud/alarm_control_panel.py index f362133034f84a..f9a91203426476 100644 --- a/homeassistant/components/homematicip_cloud/alarm_control_panel.py +++ b/homeassistant/components/homematicip_cloud/alarm_control_panel.py @@ -5,6 +5,10 @@ from homematicip.functionalHomes import SecurityAndAlarmHome from homeassistant.components.alarm_control_panel import AlarmControlPanel +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, @@ -77,6 +81,11 @@ def state(self) -> str: def _security_and_alarm(self) -> SecurityAndAlarmHome: return self._home.get_functionalHome(SecurityAndAlarmHome) + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + async def async_alarm_disarm(self, code=None) -> None: """Send disarm command.""" await self._home.set_security_zones_activation(False, False) diff --git a/homeassistant/components/ialarm/alarm_control_panel.py b/homeassistant/components/ialarm/alarm_control_panel.py index 845c6b9021f1e2..c3bcf626f0ae93 100644 --- a/homeassistant/components/ialarm/alarm_control_panel.py +++ b/homeassistant/components/ialarm/alarm_control_panel.py @@ -6,6 +6,10 @@ import homeassistant.components.alarm_control_panel as alarm from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( CONF_CODE, CONF_HOST, @@ -91,6 +95,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + def update(self): """Return the state of the device.""" status = self._client.get_status() diff --git a/homeassistant/components/ifttt/alarm_control_panel.py b/homeassistant/components/ifttt/alarm_control_panel.py index e4d8b6ce654bd3..f740cc8ccc902f 100644 --- a/homeassistant/components/ifttt/alarm_control_panel.py +++ b/homeassistant/components/ifttt/alarm_control_panel.py @@ -6,6 +6,11 @@ import homeassistant.components.alarm_control_panel as alarm from homeassistant.components.alarm_control_panel import DOMAIN, PLATFORM_SCHEMA +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, +) from homeassistant.const import ( ATTR_ENTITY_ID, ATTR_STATE, @@ -127,6 +132,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT + @property def assumed_state(self): """Notify that this platform return an assumed state.""" diff --git a/homeassistant/components/lupusec/alarm_control_panel.py b/homeassistant/components/lupusec/alarm_control_panel.py index 245743d0f6537b..c6ad817bfbf6a1 100644 --- a/homeassistant/components/lupusec/alarm_control_panel.py +++ b/homeassistant/components/lupusec/alarm_control_panel.py @@ -2,6 +2,10 @@ from datetime import timedelta from homeassistant.components.alarm_control_panel import AlarmControlPanel +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, @@ -51,6 +55,11 @@ def state(self): state = None return state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + def alarm_arm_away(self, code=None): """Send arm away command.""" self._device.set_away() diff --git a/homeassistant/components/manual/alarm_control_panel.py b/homeassistant/components/manual/alarm_control_panel.py index ac234dc0ac9b5c..b41da2d51bdb24 100644 --- a/homeassistant/components/manual/alarm_control_panel.py +++ b/homeassistant/components/manual/alarm_control_panel.py @@ -7,6 +7,13 @@ import voluptuous as vol import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_CUSTOM_BYPASS, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, + SUPPORT_ALARM_TRIGGER, +) from homeassistant.const import ( CONF_CODE, CONF_DELAY_TIME, @@ -25,8 +32,8 @@ ) import homeassistant.helpers.config_validation as cv from homeassistant.helpers.event import track_point_in_time -import homeassistant.util.dt as dt_util from homeassistant.helpers.restore_state import RestoreEntity +import homeassistant.util.dt as dt_util _LOGGER = logging.getLogger(__name__) @@ -234,6 +241,17 @@ def state(self): return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return ( + SUPPORT_ALARM_ARM_HOME + | SUPPORT_ALARM_ARM_AWAY + | SUPPORT_ALARM_ARM_NIGHT + | SUPPORT_ALARM_TRIGGER + | SUPPORT_ALARM_ARM_CUSTOM_BYPASS + ) + @property def _active_state(self): """Get the current state.""" diff --git a/homeassistant/components/manual_mqtt/alarm_control_panel.py b/homeassistant/components/manual_mqtt/alarm_control_panel.py index c57fa275516f8e..f11dac357e615e 100644 --- a/homeassistant/components/manual_mqtt/alarm_control_panel.py +++ b/homeassistant/components/manual_mqtt/alarm_control_panel.py @@ -6,30 +6,33 @@ import voluptuous as vol +from homeassistant.components import mqtt import homeassistant.components.alarm_control_panel as alarm -import homeassistant.util.dt as dt_util +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, + SUPPORT_ALARM_TRIGGER, +) from homeassistant.const import ( + CONF_CODE, + CONF_DELAY_TIME, + CONF_DISARM_AFTER_TRIGGER, + CONF_NAME, + CONF_PENDING_TIME, + CONF_PLATFORM, + CONF_TRIGGER_TIME, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_DISARMED, STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, - CONF_PLATFORM, - CONF_NAME, - CONF_CODE, - CONF_DELAY_TIME, - CONF_PENDING_TIME, - CONF_TRIGGER_TIME, - CONF_DISARM_AFTER_TRIGGER, ) -from homeassistant.components import mqtt - -from homeassistant.helpers.event import async_track_state_change from homeassistant.core import callback - import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.event import track_point_in_time +from homeassistant.helpers.event import async_track_state_change, track_point_in_time +import homeassistant.util.dt as dt_util _LOGGER = logging.getLogger(__name__) @@ -278,6 +281,16 @@ def state(self): return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return ( + SUPPORT_ALARM_ARM_HOME + | SUPPORT_ALARM_ARM_AWAY + | SUPPORT_ALARM_ARM_NIGHT + | SUPPORT_ALARM_TRIGGER + ) + @property def _active_state(self): """Get the current state.""" diff --git a/homeassistant/components/mqtt/alarm_control_panel.py b/homeassistant/components/mqtt/alarm_control_panel.py index 7171a55b2709fd..43d0bb570a8e5a 100644 --- a/homeassistant/components/mqtt/alarm_control_panel.py +++ b/homeassistant/components/mqtt/alarm_control_panel.py @@ -6,6 +6,11 @@ from homeassistant.components import mqtt import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, +) from homeassistant.const import ( CONF_CODE, CONF_DEVICE, @@ -223,6 +228,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT + @property def code_format(self): """Return one or more digits/characters.""" diff --git a/homeassistant/components/ness_alarm/alarm_control_panel.py b/homeassistant/components/ness_alarm/alarm_control_panel.py index 1b45c52ab71098..d2feebfb64f4b9 100644 --- a/homeassistant/components/ness_alarm/alarm_control_panel.py +++ b/homeassistant/components/ness_alarm/alarm_control_panel.py @@ -3,6 +3,11 @@ import logging import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_TRIGGER, +) from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMING, @@ -62,6 +67,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_TRIGGER + async def async_alarm_disarm(self, code=None): """Send disarm command.""" await self._client.disarm(code) diff --git a/homeassistant/components/nx584/alarm_control_panel.py b/homeassistant/components/nx584/alarm_control_panel.py index d3d867ff378678..62bc7ae32bba34 100644 --- a/homeassistant/components/nx584/alarm_control_panel.py +++ b/homeassistant/components/nx584/alarm_control_panel.py @@ -6,6 +6,10 @@ import homeassistant.components.alarm_control_panel as alarm from homeassistant.components.alarm_control_panel import PLATFORM_SCHEMA +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( CONF_HOST, CONF_NAME, @@ -79,6 +83,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + def update(self): """Process new events from panel.""" try: diff --git a/homeassistant/components/point/alarm_control_panel.py b/homeassistant/components/point/alarm_control_panel.py index f9e725f6c8e5c7..e86b3dd42e8742 100644 --- a/homeassistant/components/point/alarm_control_panel.py +++ b/homeassistant/components/point/alarm_control_panel.py @@ -2,6 +2,7 @@ import logging from homeassistant.components.alarm_control_panel import DOMAIN, AlarmControlPanel +from homeassistant.components.alarm_control_panel.const import SUPPORT_ALARM_ARM_AWAY from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_DISARMED, @@ -88,6 +89,11 @@ def state(self): """Return state of the device.""" return EVENT_MAP.get(self._home["alarm_status"], STATE_ALARM_ARMED_AWAY) + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_AWAY + @property def changed_by(self): """Return the user the last change was triggered by.""" diff --git a/homeassistant/components/satel_integra/alarm_control_panel.py b/homeassistant/components/satel_integra/alarm_control_panel.py index 2f0e165f21f181..c4321673061a8a 100644 --- a/homeassistant/components/satel_integra/alarm_control_panel.py +++ b/homeassistant/components/satel_integra/alarm_control_panel.py @@ -1,9 +1,13 @@ """Support for Satel Integra alarm, using ETHM module.""" import asyncio -import logging from collections import OrderedDict +import logging import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, @@ -17,8 +21,8 @@ from . import ( CONF_ARM_HOME_MODE, CONF_DEVICE_PARTITIONS, - DATA_SATEL, CONF_ZONE_NAME, + DATA_SATEL, SIGNAL_PANEL_MESSAGE, ) @@ -131,6 +135,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + async def async_alarm_disarm(self, code=None): """Send disarm command.""" if not code: diff --git a/homeassistant/components/simplisafe/alarm_control_panel.py b/homeassistant/components/simplisafe/alarm_control_panel.py index a63a077ed15b8c..96f3fa05f6bc4e 100644 --- a/homeassistant/components/simplisafe/alarm_control_panel.py +++ b/homeassistant/components/simplisafe/alarm_control_panel.py @@ -10,6 +10,10 @@ FORMAT_TEXT, AlarmControlPanel, ) +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( CONF_CODE, STATE_ALARM_ARMED_AWAY, @@ -94,6 +98,11 @@ def state(self): """Return the state of the entity.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + def _validate_code(self, code, state): """Validate given code.""" check = self._code is None or code == self._code diff --git a/homeassistant/components/spc/alarm_control_panel.py b/homeassistant/components/spc/alarm_control_panel.py index 8eeccc06515cbd..fa9a9681fff041 100644 --- a/homeassistant/components/spc/alarm_control_panel.py +++ b/homeassistant/components/spc/alarm_control_panel.py @@ -2,6 +2,11 @@ import logging import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, +) from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, @@ -80,6 +85,11 @@ def state(self): """Return the state of the device.""" return _get_alarm_state(self._area) + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT + async def async_alarm_disarm(self, code=None): """Send disarm command.""" from pyspcwebgw.const import AreaMode diff --git a/homeassistant/components/totalconnect/alarm_control_panel.py b/homeassistant/components/totalconnect/alarm_control_panel.py index e5f0b0c8279350..b8b4236806f1ef 100644 --- a/homeassistant/components/totalconnect/alarm_control_panel.py +++ b/homeassistant/components/totalconnect/alarm_control_panel.py @@ -2,15 +2,20 @@ import logging import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_NIGHT, +) from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, + STATE_ALARM_ARMED_CUSTOM_BYPASS, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, - STATE_ALARM_DISARMED, STATE_ALARM_ARMING, + STATE_ALARM_DISARMED, STATE_ALARM_DISARMING, STATE_ALARM_TRIGGERED, - STATE_ALARM_ARMED_CUSTOM_BYPASS, ) from . import DOMAIN as TOTALCONNECT_DOMAIN @@ -55,6 +60,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT + @property def device_state_attributes(self): """Return the state attributes of the device.""" diff --git a/homeassistant/components/verisure/alarm_control_panel.py b/homeassistant/components/verisure/alarm_control_panel.py index 02f64b6fa9cd52..b7cc822bd43077 100644 --- a/homeassistant/components/verisure/alarm_control_panel.py +++ b/homeassistant/components/verisure/alarm_control_panel.py @@ -3,6 +3,10 @@ from time import sleep import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, @@ -64,6 +68,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + @property def code_format(self): """Return one or more digits/characters.""" diff --git a/homeassistant/components/wink/alarm_control_panel.py b/homeassistant/components/wink/alarm_control_panel.py index 654252f5ffea84..733022e91b1512 100644 --- a/homeassistant/components/wink/alarm_control_panel.py +++ b/homeassistant/components/wink/alarm_control_panel.py @@ -4,6 +4,10 @@ import pywink import homeassistant.components.alarm_control_panel as alarm +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, +) from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, @@ -52,6 +56,11 @@ def state(self): state = None return state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + def alarm_disarm(self, code=None): """Send disarm command.""" self.wink.set_mode("home") diff --git a/homeassistant/components/yale_smart_alarm/alarm_control_panel.py b/homeassistant/components/yale_smart_alarm/alarm_control_panel.py index c2d0ab01247226..7f2cbc2a33dddb 100644 --- a/homeassistant/components/yale_smart_alarm/alarm_control_panel.py +++ b/homeassistant/components/yale_smart_alarm/alarm_control_panel.py @@ -11,13 +11,17 @@ ) from homeassistant.components.alarm_control_panel import ( - AlarmControlPanel, PLATFORM_SCHEMA, + AlarmControlPanel, +) +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_HOME, ) from homeassistant.const import ( + CONF_NAME, CONF_PASSWORD, CONF_USERNAME, - CONF_NAME, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, @@ -83,6 +87,11 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY + def update(self): """Return the state of the device.""" armed_status = self._client.get_armed_status() diff --git a/tests/components/alarm_control_panel/test_device_action.py b/tests/components/alarm_control_panel/test_device_action.py index c2dfcbd78b985c..bc489dbe251172 100644 --- a/tests/components/alarm_control_panel/test_device_action.py +++ b/tests/components/alarm_control_panel/test_device_action.py @@ -46,6 +46,9 @@ async def test_get_actions(hass, device_reg, entity_reg): connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, ) entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id) + hass.states.async_set( + "alarm_control_panel.test_5678", "attributes", {"supported_features": 15} + ) expected_actions = [ { "domain": DOMAIN, @@ -82,6 +85,36 @@ async def test_get_actions(hass, device_reg, entity_reg): assert_lists_same(actions, expected_actions) +async def test_get_actions_arm_night_only(hass, device_reg, entity_reg): + """Test we get the expected actions from a alarm_control_panel.""" + config_entry = MockConfigEntry(domain="test", data={}) + config_entry.add_to_hass(hass) + device_entry = device_reg.async_get_or_create( + config_entry_id=config_entry.entry_id, + connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")}, + ) + entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id) + hass.states.async_set( + "alarm_control_panel.test_5678", "attributes", {"supported_features": 4} + ) + expected_actions = [ + { + "domain": DOMAIN, + "type": "arm_night", + "device_id": device_entry.id, + "entity_id": "alarm_control_panel.test_5678", + }, + { + "domain": DOMAIN, + "type": "disarm", + "device_id": device_entry.id, + "entity_id": "alarm_control_panel.test_5678", + }, + ] + actions = await async_get_device_automations(hass, "action", device_entry.id) + assert_lists_same(actions, expected_actions) + + async def test_get_action_capabilities(hass, device_reg, entity_reg): """Test we get the expected capabilities from a sensor trigger.""" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/device_automation/test_init.py b/tests/components/device_automation/test_init.py index 3c0e3b1eca7ad9..bddef3286ac877 100644 --- a/tests/components/device_automation/test_init.py +++ b/tests/components/device_automation/test_init.py @@ -184,6 +184,9 @@ async def test_websocket_get_action_capabilities( entity_reg.async_get_or_create( "alarm_control_panel", "test", "5678", device_id=device_entry.id ) + hass.states.async_set( + "alarm_control_panel.test_5678", "attributes", {"supported_features": 15} + ) expected_capabilities = { "arm_away": {"extra_fields": []}, "arm_home": {"extra_fields": []}, diff --git a/tests/testing_config/custom_components/test/alarm_control_panel.py b/tests/testing_config/custom_components/test/alarm_control_panel.py index 0e2842f869561a..1ffa52086e7bae 100644 --- a/tests/testing_config/custom_components/test/alarm_control_panel.py +++ b/tests/testing_config/custom_components/test/alarm_control_panel.py @@ -11,6 +11,12 @@ STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED, ) +from homeassistant.components.alarm_control_panel.const import ( + SUPPORT_ALARM_ARM_HOME, + SUPPORT_ALARM_ARM_AWAY, + SUPPORT_ALARM_ARM_NIGHT, + SUPPORT_ALARM_TRIGGER, +) from tests.common import MockEntity ENTITIES = {} @@ -64,6 +70,16 @@ def state(self): """Return the state of the device.""" return self._state + @property + def supported_features(self) -> int: + """Return the list of supported features.""" + return ( + SUPPORT_ALARM_ARM_HOME + | SUPPORT_ALARM_ARM_AWAY + | SUPPORT_ALARM_ARM_NIGHT + | SUPPORT_ALARM_TRIGGER + ) + def alarm_arm_away(self, code=None): """Send arm away command.""" self._state = STATE_ALARM_ARMED_AWAY