From 3f53ed5d5cddfebd302a2d4fad45d271943533d6 Mon Sep 17 00:00:00 2001 From: Kostas Chatzikokolakis Date: Thu, 7 Jul 2022 21:31:03 +0300 Subject: [PATCH] Add trigger/arm_custom_bypass to Template Alarm Control Panel (#74629) --- .../template/alarm_control_panel.py | 40 +++++++++++++++++++ .../template/test_alarm_control_panel.py | 16 ++++++++ 2 files changed, 56 insertions(+) diff --git a/homeassistant/components/template/alarm_control_panel.py b/homeassistant/components/template/alarm_control_panel.py index 132e9fb0ca5..d7c117c9be7 100644 --- a/homeassistant/components/template/alarm_control_panel.py +++ b/homeassistant/components/template/alarm_control_panel.py @@ -19,6 +19,7 @@ from homeassistant.const import ( CONF_UNIQUE_ID, CONF_VALUE_TEMPLATE, STATE_ALARM_ARMED_AWAY, + STATE_ALARM_ARMED_CUSTOM_BYPASS, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_ARMED_VACATION, @@ -42,6 +43,7 @@ from .template_entity import TemplateEntity, rewrite_common_legacy_to_modern_con _LOGGER = logging.getLogger(__name__) _VALID_STATES = [ STATE_ALARM_ARMED_AWAY, + STATE_ALARM_ARMED_CUSTOM_BYPASS, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_ARMED_VACATION, @@ -53,10 +55,12 @@ _VALID_STATES = [ ] CONF_ARM_AWAY_ACTION = "arm_away" +CONF_ARM_CUSTOM_BYPASS_ACTION = "arm_custom_bypass" CONF_ARM_HOME_ACTION = "arm_home" CONF_ARM_NIGHT_ACTION = "arm_night" CONF_ARM_VACATION_ACTION = "arm_vacation" CONF_DISARM_ACTION = "disarm" +CONF_TRIGGER_ACTION = "trigger" CONF_ALARM_CONTROL_PANELS = "panels" CONF_CODE_ARM_REQUIRED = "code_arm_required" CONF_CODE_FORMAT = "code_format" @@ -75,9 +79,11 @@ ALARM_CONTROL_PANEL_SCHEMA = vol.Schema( vol.Optional(CONF_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_DISARM_ACTION): cv.SCRIPT_SCHEMA, vol.Optional(CONF_ARM_AWAY_ACTION): cv.SCRIPT_SCHEMA, + vol.Optional(CONF_ARM_CUSTOM_BYPASS_ACTION): cv.SCRIPT_SCHEMA, vol.Optional(CONF_ARM_HOME_ACTION): cv.SCRIPT_SCHEMA, vol.Optional(CONF_ARM_NIGHT_ACTION): cv.SCRIPT_SCHEMA, vol.Optional(CONF_ARM_VACATION_ACTION): cv.SCRIPT_SCHEMA, + vol.Optional(CONF_TRIGGER_ACTION): cv.SCRIPT_SCHEMA, vol.Optional(CONF_CODE_ARM_REQUIRED, default=True): cv.boolean, vol.Optional(CONF_CODE_FORMAT, default=TemplateCodeFormat.number.name): cv.enum( TemplateCodeFormat @@ -164,6 +170,16 @@ class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity): self._arm_vacation_script = None if (arm_vacation_action := config.get(CONF_ARM_VACATION_ACTION)) is not None: self._arm_vacation_script = Script(hass, arm_vacation_action, name, DOMAIN) + self._arm_custom_bypass_script = None + if ( + arm_custom_bypass_action := config.get(CONF_ARM_CUSTOM_BYPASS_ACTION) + ) is not None: + self._arm_custom_bypass_script = Script( + hass, arm_custom_bypass_action, name, DOMAIN + ) + self._trigger_script = None + if (trigger_action := config.get(CONF_TRIGGER_ACTION)) is not None: + self._trigger_script = Script(hass, trigger_action, name, DOMAIN) self._state: str | None = None @@ -196,6 +212,16 @@ class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity): supported_features | AlarmControlPanelEntityFeature.ARM_VACATION ) + if self._arm_custom_bypass_script is not None: + supported_features = ( + supported_features | AlarmControlPanelEntityFeature.ARM_CUSTOM_BYPASS + ) + + if self._trigger_script is not None: + supported_features = ( + supported_features | AlarmControlPanelEntityFeature.TRIGGER + ) + return supported_features @property @@ -275,8 +301,22 @@ class AlarmControlPanelTemplate(TemplateEntity, AlarmControlPanelEntity): STATE_ALARM_ARMED_VACATION, script=self._arm_vacation_script, code=code ) + async def async_alarm_arm_custom_bypass(self, code: str | None = None) -> None: + """Arm the panel to Custom Bypass.""" + await self._async_alarm_arm( + STATE_ALARM_ARMED_CUSTOM_BYPASS, + script=self._arm_custom_bypass_script, + code=code, + ) + async def async_alarm_disarm(self, code: str | None = None) -> None: """Disarm the panel.""" await self._async_alarm_arm( STATE_ALARM_DISARMED, script=self._disarm_script, code=code ) + + async def async_alarm_trigger(self, code: str | None = None) -> None: + """Trigger the panel.""" + await self._async_alarm_arm( + STATE_ALARM_TRIGGERED, script=self._trigger_script, code=code + ) diff --git a/tests/components/template/test_alarm_control_panel.py b/tests/components/template/test_alarm_control_panel.py index 9e51b48dcc6..7ae69b2d563 100644 --- a/tests/components/template/test_alarm_control_panel.py +++ b/tests/components/template/test_alarm_control_panel.py @@ -8,6 +8,7 @@ from homeassistant.const import ( ATTR_SERVICE_DATA, EVENT_CALL_SERVICE, STATE_ALARM_ARMED_AWAY, + STATE_ALARM_ARMED_CUSTOM_BYPASS, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_ARMED_VACATION, @@ -62,11 +63,21 @@ OPTIMISTIC_TEMPLATE_ALARM_CONFIG = { "entity_id": "alarm_control_panel.test", "data": {"code": "{{ this.entity_id }}"}, }, + "arm_custom_bypass": { + "service": "alarm_control_panel.alarm_arm_custom_bypass", + "entity_id": "alarm_control_panel.test", + "data": {"code": "{{ this.entity_id }}"}, + }, "disarm": { "service": "alarm_control_panel.alarm_disarm", "entity_id": "alarm_control_panel.test", "data": {"code": "{{ this.entity_id }}"}, }, + "trigger": { + "service": "alarm_control_panel.alarm_trigger", + "entity_id": "alarm_control_panel.test", + "data": {"code": "{{ this.entity_id }}"}, + }, } @@ -96,6 +107,7 @@ async def test_template_state_text(hass, start_ha): STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_NIGHT, STATE_ALARM_ARMED_VACATION, + STATE_ALARM_ARMED_CUSTOM_BYPASS, STATE_ALARM_ARMING, STATE_ALARM_DISARMED, STATE_ALARM_PENDING, @@ -136,7 +148,9 @@ async def test_optimistic_states(hass, start_ha): ("alarm_arm_home", STATE_ALARM_ARMED_HOME), ("alarm_arm_night", STATE_ALARM_ARMED_NIGHT), ("alarm_arm_vacation", STATE_ALARM_ARMED_VACATION), + ("alarm_arm_custom_bypass", STATE_ALARM_ARMED_CUSTOM_BYPASS), ("alarm_disarm", STATE_ALARM_DISARMED), + ("alarm_trigger", STATE_ALARM_TRIGGERED), ]: await hass.services.async_call( ALARM_DOMAIN, service, {"entity_id": TEMPLATE_NAME}, blocking=True @@ -259,7 +273,9 @@ async def test_name(hass, start_ha): "alarm_arm_away", "alarm_arm_night", "alarm_arm_vacation", + "alarm_arm_custom_bypass", "alarm_disarm", + "alarm_trigger", ], ) async def test_actions(hass, service, start_ha, service_calls):