From d3791fa45db0d56aec53424931d9f04aaa68b12a Mon Sep 17 00:00:00 2001
From: Tom Harris <tharris@harrisnj.net>
Date: Fri, 31 Aug 2018 17:56:26 -0400
Subject: [PATCH] Add Cover to the Insteon component (#16215)

* Create cover platform

* Create insteon cover platform

* Bump insteonplm to 0.13.0

* Change async_add_devices to async_add_entities

* Missing doc string

* Simplify open and set_position

* Flake8

* Bump insteonplm to 0.13.1

* Code review changes

* Flake8 updates
---
 homeassistant/components/cover/insteon.py    | 73 ++++++++++++++++++++
 homeassistant/components/insteon/__init__.py | 15 ++--
 requirements_all.txt                         |  2 +-
 3 files changed, 83 insertions(+), 7 deletions(-)
 create mode 100644 homeassistant/components/cover/insteon.py

diff --git a/homeassistant/components/cover/insteon.py b/homeassistant/components/cover/insteon.py
new file mode 100644
index 00000000000..f0cf93c13e9
--- /dev/null
+++ b/homeassistant/components/cover/insteon.py
@@ -0,0 +1,73 @@
+"""
+Support for Insteon covers via PowerLinc Modem.
+
+For more details about this component, please refer to the documentation at
+https://home-assistant.io/components/cover.insteon/
+"""
+import logging
+import math
+
+from homeassistant.components.insteon import InsteonEntity
+from homeassistant.components.cover import (CoverDevice, ATTR_POSITION,
+                                            SUPPORT_OPEN, SUPPORT_CLOSE,
+                                            SUPPORT_SET_POSITION)
+
+_LOGGER = logging.getLogger(__name__)
+
+DEPENDENCIES = ['insteon']
+SUPPORTED_FEATURES = SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_SET_POSITION
+
+
+async def async_setup_platform(hass, config, async_add_entities,
+                               discovery_info=None):
+    """Set up the Insteon platform."""
+    if not discovery_info:
+        return
+
+    insteon_modem = hass.data['insteon'].get('modem')
+
+    address = discovery_info['address']
+    device = insteon_modem.devices[address]
+    state_key = discovery_info['state_key']
+
+    _LOGGER.debug('Adding device %s entity %s to Cover platform',
+                  device.address.hex, device.states[state_key].name)
+
+    new_entity = InsteonCoverDevice(device, state_key)
+
+    async_add_entities([new_entity])
+
+
+class InsteonCoverDevice(InsteonEntity, CoverDevice):
+    """A Class for an Insteon device."""
+
+    @property
+    def current_cover_position(self):
+        """Return the current cover position."""
+        return int(math.ceil(self._insteon_device_state.value*100/255))
+
+    @property
+    def supported_features(self):
+        """Return the supported features for this entity."""
+        return SUPPORTED_FEATURES
+
+    @property
+    def is_closed(self):
+        """Return the boolean response if the node is on."""
+        return bool(self.current_cover_position)
+
+    async def async_open_cover(self, **kwargs):
+        """Open device."""
+        self._insteon_device_state.open()
+
+    async def async_close_cover(self, **kwargs):
+        """Close device."""
+        self._insteon_device_state.close()
+
+    async def async_set_cover_position(self, **kwargs):
+        """Set the cover position."""
+        position = int(kwargs[ATTR_POSITION]*255/100)
+        if position == 0:
+            self._insteon_device_state.close()
+        else:
+            self._insteon_device_state.set_position(position)
diff --git a/homeassistant/components/insteon/__init__.py b/homeassistant/components/insteon/__init__.py
index 212cdbac3b8..d79640b77ab 100644
--- a/homeassistant/components/insteon/__init__.py
+++ b/homeassistant/components/insteon/__init__.py
@@ -18,7 +18,7 @@ import homeassistant.helpers.config_validation as cv
 from homeassistant.helpers import discovery
 from homeassistant.helpers.entity import Entity
 
-REQUIREMENTS = ['insteonplm==0.12.3']
+REQUIREMENTS = ['insteonplm==0.13.1']
 
 _LOGGER = logging.getLogger(__name__)
 
@@ -358,6 +358,8 @@ class IPDB:
 
     def __init__(self):
         """Create the INSTEON Product Database (IPDB)."""
+        from insteonplm.states.cover import Cover
+
         from insteonplm.states.onOff import (OnOffSwitch,
                                              OnOffSwitch_OutletTop,
                                              OnOffSwitch_OutletBottom,
@@ -383,7 +385,9 @@ class IPDB:
                                            X10AllLightsOnSensor,
                                            X10AllLightsOffSensor)
 
-        self.states = [State(OnOffSwitch_OutletTop, 'switch'),
+        self.states = [State(Cover, 'cover'),
+
+                       State(OnOffSwitch_OutletTop, 'switch'),
                        State(OnOffSwitch_OutletBottom, 'switch'),
                        State(OpenClosedRelay, 'switch'),
                        State(OnOffSwitch, 'switch'),
@@ -470,11 +474,10 @@ class InsteonEntity(Entity):
         return attributes
 
     @callback
-    def async_entity_update(self, deviceid, statename, val):
+    def async_entity_update(self, deviceid, group, val):
         """Receive notification from transport that new data exists."""
-        _LOGGER.debug('Received update for device %s group %d statename %s',
-                      self.address, self.group,
-                      self._insteon_device_state.name)
+        _LOGGER.debug('Received update for device %s group %d value %s',
+                      deviceid.human, group, val)
         self.async_schedule_update_ha_state()
 
     @asyncio.coroutine
diff --git a/requirements_all.txt b/requirements_all.txt
index 7137c4b15d2..ff95a8fc2ad 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -482,7 +482,7 @@ ihcsdk==2.2.0
 influxdb==5.0.0
 
 # homeassistant.components.insteon
-insteonplm==0.12.3
+insteonplm==0.13.1
 
 # homeassistant.components.sensor.iperf3
 iperf3==0.1.10
-- 
GitLab