From 1f73840aab53e89d06c8a4c02acb28df2f2c9130 Mon Sep 17 00:00:00 2001
From: Dom <domwillcode@gmail.com>
Date: Fri, 7 Sep 2018 11:22:10 +0100
Subject: [PATCH] Add Yale Smart Alarm component (#16377)

* Add Smart Alarm Component

* Lint fixes

* Update coverage

* Update coverage with the correct file name

* PR Fixes. Update client version (to include timeouts). Cleaned up clien tcreation and improved authentication failure error. Added state map to replace nasty if blocks.

* PR Fixes. Update client version (to include timeouts). Cleaned up clien tcreation and improved authentication failure error. Added state map to replace nasty if blocks.

* Remove test file added in error.

* PR Fixes
---
 .coveragerc                                   |  1 +
 .../alarm_control_panel/yale_smart_alarm.py   | 98 +++++++++++++++++++
 requirements_all.txt                          |  3 +
 3 files changed, 102 insertions(+)
 create mode 100755 homeassistant/components/alarm_control_panel/yale_smart_alarm.py

diff --git a/.coveragerc b/.coveragerc
index c1a0d0d967c..85ed4e1fcf4 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -377,6 +377,7 @@ omit =
     homeassistant/components/alarm_control_panel/nx584.py
     homeassistant/components/alarm_control_panel/simplisafe.py
     homeassistant/components/alarm_control_panel/totalconnect.py
+    homeassistant/components/alarm_control_panel/yale_smart_alarm.py
     homeassistant/components/apiai.py
     homeassistant/components/binary_sensor/arest.py
     homeassistant/components/binary_sensor/concord232.py
diff --git a/homeassistant/components/alarm_control_panel/yale_smart_alarm.py b/homeassistant/components/alarm_control_panel/yale_smart_alarm.py
new file mode 100755
index 00000000000..e512d15fcdd
--- /dev/null
+++ b/homeassistant/components/alarm_control_panel/yale_smart_alarm.py
@@ -0,0 +1,98 @@
+"""
+Yale Smart Alarm client for interacting with the Yale Smart Alarm System API.
+
+For more details about this platform, please refer to the documentation at
+https://www.home-assistant.io/components/alarm_control_panel.yale_smart_alarm
+"""
+import logging
+
+import voluptuous as vol
+
+from homeassistant.components.alarm_control_panel import (
+    AlarmControlPanel, PLATFORM_SCHEMA)
+from homeassistant.const import (
+    CONF_PASSWORD, CONF_USERNAME, CONF_NAME,
+    STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED)
+import homeassistant.helpers.config_validation as cv
+
+REQUIREMENTS = ['yalesmartalarmclient==0.1.4']
+
+CONF_AREA_ID = 'area_id'
+
+DEFAULT_NAME = 'Yale Smart Alarm'
+
+DEFAULT_AREA_ID = '1'
+
+_LOGGER = logging.getLogger(__name__)
+
+PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
+    vol.Required(CONF_USERNAME): cv.string,
+    vol.Required(CONF_PASSWORD): cv.string,
+    vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
+    vol.Optional(CONF_AREA_ID, default=DEFAULT_AREA_ID): cv.string,
+})
+
+
+def setup_platform(hass, config, add_entities, discovery_info=None):
+    """Set up the alarm platform."""
+    name = config[CONF_NAME]
+    username = config[CONF_USERNAME]
+    password = config[CONF_PASSWORD]
+    area_id = config[CONF_AREA_ID]
+
+    from yalesmartalarmclient.client import (
+        YaleSmartAlarmClient, AuthenticationError)
+    try:
+        client = YaleSmartAlarmClient(username, password, area_id)
+    except AuthenticationError:
+        _LOGGER.error("Authentication failed. Check credentials")
+        return
+
+    add_entities([YaleAlarmDevice(name, client)], True)
+
+
+class YaleAlarmDevice(AlarmControlPanel):
+    """Represent a Yale Smart Alarm."""
+
+    def __init__(self, name, client):
+        """Initialize the Yale Alarm Device."""
+        self._name = name
+        self._client = client
+        self._state = None
+
+        from yalesmartalarmclient.client import (YALE_STATE_DISARM,
+                                                 YALE_STATE_ARM_PARTIAL,
+                                                 YALE_STATE_ARM_FULL)
+        self._state_map = {
+            YALE_STATE_DISARM: STATE_ALARM_DISARMED,
+            YALE_STATE_ARM_PARTIAL: STATE_ALARM_ARMED_HOME,
+            YALE_STATE_ARM_FULL: STATE_ALARM_ARMED_AWAY
+        }
+
+    @property
+    def name(self):
+        """Return the name of the device."""
+        return self._name
+
+    @property
+    def state(self):
+        """Return the state of the device."""
+        return self._state
+
+    def update(self):
+        """Return the state of the device."""
+        armed_status = self._client.get_armed_status()
+
+        self._state = self._state_map.get(armed_status)
+
+    def alarm_disarm(self, code=None):
+        """Send disarm command."""
+        self._client.disarm()
+
+    def alarm_arm_home(self, code=None):
+        """Send arm home command."""
+        self._client.arm_partial()
+
+    def alarm_arm_away(self, code=None):
+        """Send arm away command."""
+        self._client.arm_full()
diff --git a/requirements_all.txt b/requirements_all.txt
index bc81da03660..d280fa14f15 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -1508,6 +1508,9 @@ yahoo-finance==1.4.0
 # homeassistant.components.weather.yweather
 yahooweather==0.10
 
+# homeassistant.components.alarm_control_panel.yale_smart_alarm
+yalesmartalarmclient==0.1.4
+
 # homeassistant.components.light.yeelight
 yeelight==0.4.0
 
-- 
GitLab