From a44181fd35d0c8107c1135fced4ca571df50ac8c Mon Sep 17 00:00:00 2001 From: Michael Irigoyen Date: Mon, 25 Dec 2017 05:34:07 -0500 Subject: [PATCH] Add Chime status and control to Alarm Decoder component (#11271) * Enable more alarm decoder attributes, including chime status and ready status * Expose chime service in the alarm decoder component * Fix line length linting issue * Fix spacing lint issue * Update PR based on reviewer requests * Update based on linting catches * Fix descriptions include from async to sync --- .../alarm_control_panel/alarmdecoder.py | 90 +++++++++++++++---- .../alarm_control_panel/services.yaml | 10 +++ 2 files changed, 81 insertions(+), 19 deletions(-) diff --git a/homeassistant/components/alarm_control_panel/alarmdecoder.py b/homeassistant/components/alarm_control_panel/alarmdecoder.py index d5fbbec599897..2e4255493d488 100644 --- a/homeassistant/components/alarm_control_panel/alarmdecoder.py +++ b/homeassistant/components/alarm_control_panel/alarmdecoder.py @@ -6,24 +6,46 @@ """ import asyncio import logging +from os import path + +import voluptuous as vol import homeassistant.components.alarm_control_panel as alarm +import homeassistant.helpers.config_validation as cv +from homeassistant.config import load_yaml_config_file from homeassistant.components.alarmdecoder import ( DATA_AD, SIGNAL_PANEL_MESSAGE) from homeassistant.const import ( - STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, - STATE_ALARM_TRIGGERED) + ATTR_CODE, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, + STATE_ALARM_DISARMED, STATE_ALARM_TRIGGERED) _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['alarmdecoder'] +SERVICE_ALARM_TOGGLE_CHIME = 'alarmdecoder_alarm_toggle_chime' +ALARM_TOGGLE_CHIME_SCHEMA = vol.Schema({ + vol.Required(ATTR_CODE): cv.string, +}) + def setup_platform(hass, config, add_devices, discovery_info=None): """Set up for AlarmDecoder alarm panels.""" - add_devices([AlarmDecoderAlarmPanel()]) + device = AlarmDecoderAlarmPanel() + add_devices([device]) + + def alarm_toggle_chime_handler(service): + """Register toggle chime handler.""" + code = service.data.get(ATTR_CODE) + device.alarm_toggle_chime(code) - return True + descriptions = load_yaml_config_file( + path.join(path.dirname(__file__), 'services.yaml')) + + hass.services.register( + alarm.DOMAIN, SERVICE_ALARM_TOGGLE_CHIME, alarm_toggle_chime_handler, + descriptions.get(SERVICE_ALARM_TOGGLE_CHIME), + schema=ALARM_TOGGLE_CHIME_SCHEMA) class AlarmDecoderAlarmPanel(alarm.AlarmControlPanel): @@ -34,6 +56,15 @@ def __init__(self): self._display = "" self._name = "Alarm Panel" self._state = None + self._ac_power = None + self._backlight_on = None + self._battery_low = None + self._check_zone = None + self._chime = None + self._entry_delay_off = None + self._programming_mode = None + self._ready = None + self._zone_bypassed = None @asyncio.coroutine def async_added_to_hass(self): @@ -43,21 +74,25 @@ def async_added_to_hass(self): def _message_callback(self, message): if message.alarm_sounding or message.fire_alarm: - if self._state != STATE_ALARM_TRIGGERED: - self._state = STATE_ALARM_TRIGGERED - self.schedule_update_ha_state() + self._state = STATE_ALARM_TRIGGERED elif message.armed_away: - if self._state != STATE_ALARM_ARMED_AWAY: - self._state = STATE_ALARM_ARMED_AWAY - self.schedule_update_ha_state() + self._state = STATE_ALARM_ARMED_AWAY elif message.armed_home: - if self._state != STATE_ALARM_ARMED_HOME: - self._state = STATE_ALARM_ARMED_HOME - self.schedule_update_ha_state() + self._state = STATE_ALARM_ARMED_HOME else: - if self._state != STATE_ALARM_DISARMED: - self._state = STATE_ALARM_DISARMED - self.schedule_update_ha_state() + self._state = STATE_ALARM_DISARMED + + self._ac_power = message.ac_power + self._backlight_on = message.backlight_on + self._battery_low = message.battery_low + self._check_zone = message.check_zone + self._chime = message.chime_on + self._entry_delay_off = message.entry_delay_off + self._programming_mode = message.programming_mode + self._ready = message.ready + self._zone_bypassed = message.zone_bypassed + + self.schedule_update_ha_state() @property def name(self): @@ -79,20 +114,37 @@ def state(self): """Return the state of the device.""" return self._state + @property + def device_state_attributes(self): + """Return the state attributes.""" + return { + 'ac_power': self._ac_power, + 'backlight_on': self._backlight_on, + 'battery_low': self._battery_low, + 'check_zone': self._check_zone, + 'chime': self._chime, + 'entry_delay_off': self._entry_delay_off, + 'programming_mode': self._programming_mode, + 'ready': self._ready, + 'zone_bypassed': self._zone_bypassed + } + def alarm_disarm(self, code=None): """Send disarm command.""" if code: - _LOGGER.debug("alarm_disarm: sending %s1", str(code)) self.hass.data[DATA_AD].send("{!s}1".format(code)) def alarm_arm_away(self, code=None): """Send arm away command.""" if code: - _LOGGER.debug("alarm_arm_away: sending %s2", str(code)) self.hass.data[DATA_AD].send("{!s}2".format(code)) def alarm_arm_home(self, code=None): """Send arm home command.""" if code: - _LOGGER.debug("alarm_arm_home: sending %s3", str(code)) self.hass.data[DATA_AD].send("{!s}3".format(code)) + + def alarm_toggle_chime(self, code=None): + """Send toggle chime command.""" + if code: + self.hass.data[DATA_AD].send("{!s}9".format(code)) diff --git a/homeassistant/components/alarm_control_panel/services.yaml b/homeassistant/components/alarm_control_panel/services.yaml index 21378876d9b5e..bfd38c902d0a1 100644 --- a/homeassistant/components/alarm_control_panel/services.yaml +++ b/homeassistant/components/alarm_control_panel/services.yaml @@ -59,3 +59,13 @@ envisalink_alarm_keypress: keypress: description: 'String to send to the alarm panel (1-6 characters).' example: '*71' + +alarmdecoder_alarm_toggle_chime: + description: Send the alarm the toggle chime command. + fields: + entity_id: + description: Name of the alarm control panel to trigger. + example: 'alarm_control_panel.downstairs' + code: + description: A required code to toggle the alarm control panel chime with. + example: 1234