From 07e8202ec9ce26be1ae65c4df14cb9c6bb55f100 Mon Sep 17 00:00:00 2001 From: ArrayLabs Date: Tue, 16 Oct 2018 12:42:27 -0400 Subject: [PATCH 1/4] add scan interval, update to pymyq 0.0.16 - default SCAN_INTERVAL defined as 120 seconds not the standard 15 seconds - SCAN_INTERVAL (the default of 120 seconds) can be overridden in configuration.yaml with scan_interval on the component - Switch to 0.0.16 of the pymyq library which includes an endpoint change for get_status, its a more direct endpoint and the return is much smaller. Also retries 3 times for status update if server returns an error. - change init to check door status immediately and if fails fall back to None, better than waiting for the update to get the status after HA start/restart - Updates to close_cover and open_cover based on @ehendrix23 code with additional status check. Does two things, retries sending the open/close command if it initially fails the API call. Once API is successfull it queries status until it gets an open or close status or fails. Provides a quicker update of confirmed open/close than waiting for update to occur. - Change to update to check for False from pymyq and return either current status or None. --- homeassistant/components/cover/myq.py | 82 +++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/cover/myq.py b/homeassistant/components/cover/myq.py index 5ceb4260d0c3fb..b31b3d8b9601d3 100644 --- a/homeassistant/components/cover/myq.py +++ b/homeassistant/components/cover/myq.py @@ -5,7 +5,8 @@ https://home-assistant.io/components/cover.myq/ """ import logging - +from datetime import timedelta +from time import sleep import voluptuous as vol from homeassistant.components.cover import ( @@ -15,7 +16,7 @@ STATE_OPEN, STATE_OPENING) import homeassistant.helpers.config_validation as cv -REQUIREMENTS = ['pymyq==0.0.15'] +REQUIREMENTS = ['pymyq==0.0.16'] _LOGGER = logging.getLogger(__name__) @@ -37,6 +38,7 @@ vol.Required(CONF_PASSWORD): cv.string }) +SCAN_INTERVAL = timedelta(seconds=120) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the MyQ component.""" @@ -76,7 +78,11 @@ def __init__(self, myq, device): self.myq = myq self.device_id = device['deviceid'] self._name = device['name'] - self._status = None + + if (self.myq.get_status(self.device_id)): + self._status = self.myq.get_status(self.device_id) + else: + self._status = None @property def device_class(self): @@ -112,11 +118,71 @@ def is_opening(self): def close_cover(self, **kwargs): """Issue close command to cover.""" - self.myq.close_device(self.device_id) + iterations = 0 + while True: + if self.myq.close_device(self.device_id): + break + if iterations > 5: + _LOGGER.error( + "Failed to close %s " + "after 6 attempts", self._name) + break + iterations += 1 + sleep(10) + + if (iterations <= 5): + closed_confired_interations = 0 + while True: + self._status = self.myq.get_status(self.device_id) + if self._status == STATE_CLOSED: + break + if closed_confired_interations > 5: + _LOGGER.error( + "Failed to confirm closed status for %s " + "after 60 seconds", self._name) + self._status = None + break + closed_confired_interations += 1 + sleep(10) + + if (iterations <= 5 and closed_confired_interations <= 5): + return True + else: + return False def open_cover(self, **kwargs): """Issue open command to cover.""" - self.myq.open_device(self.device_id) + iterations = 0 + while True: + if self.myq.open_device(self.device_id): + break + if iterations > 5: + _LOGGER.error( + "Failed to open %s " + "after 6 attempts", self._name) + break + iterations += 1 + sleep(10) + + if (iterations <= 5): + open_confirmed_interations = 0 + while True: + self._status = self.myq.get_status(self.device_id) + if self._status == STATE_OPEN: + break + if open_confirmed_interations > 5: + _LOGGER.error( + "Failed to confirm open status for %s " + "after 60 seconds", self._name) + self._status = None + break + open_confirmed_interations += 1 + sleep(10) + + if (iterations <= 5 and open_confirmed_interations <= 5): + return True + else: + return False @property def supported_features(self): @@ -130,4 +196,8 @@ def unique_id(self): def update(self): """Update status of cover.""" - self._status = self.myq.get_status(self.device_id) + current = self.myq.get_status(self.device_id) + if current is not False: + self._status = current + else: + self._status = None From ac6d817409cdfad7bb9f65423cb58b52c108b2bd Mon Sep 17 00:00:00 2001 From: ArrayLabs Date: Tue, 16 Oct 2018 13:44:16 -0400 Subject: [PATCH 2/4] update pymyq from 0.0.15 to 0.0.16 --- requirements_all.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements_all.txt b/requirements_all.txt index 6f8bb03d5a9444..061953cf356b41 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -999,7 +999,7 @@ pymonoprice==0.3 pymusiccast==0.1.6 # homeassistant.components.cover.myq -pymyq==0.0.15 +pymyq==0.0.16 # homeassistant.components.mysensors pymysensors==0.17.0 From 5189fa0471ac1bf13039ef5f4ffd7548ef2b0c40 Mon Sep 17 00:00:00 2001 From: ArrayLabs Date: Tue, 16 Oct 2018 16:05:00 -0400 Subject: [PATCH 3/4] fix spacing for flake8 --- homeassistant/components/cover/myq.py | 1 + 1 file changed, 1 insertion(+) diff --git a/homeassistant/components/cover/myq.py b/homeassistant/components/cover/myq.py index b31b3d8b9601d3..bb6ac8f5ec3bc2 100644 --- a/homeassistant/components/cover/myq.py +++ b/homeassistant/components/cover/myq.py @@ -40,6 +40,7 @@ SCAN_INTERVAL = timedelta(seconds=120) + def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the MyQ component.""" from pymyq import MyQAPI as pymyq From 30b9d18c9a29449917b840422c6ab8c56fd1bdb5 Mon Sep 17 00:00:00 2001 From: ArrayLabs Date: Tue, 16 Oct 2018 16:09:25 -0400 Subject: [PATCH 4/4] fix parens, if statements for pylint --- homeassistant/components/cover/myq.py | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/cover/myq.py b/homeassistant/components/cover/myq.py index bb6ac8f5ec3bc2..a78ed6f622e859 100644 --- a/homeassistant/components/cover/myq.py +++ b/homeassistant/components/cover/myq.py @@ -80,7 +80,7 @@ def __init__(self, myq, device): self.device_id = device['deviceid'] self._name = device['name'] - if (self.myq.get_status(self.device_id)): + if self.myq.get_status(self.device_id): self._status = self.myq.get_status(self.device_id) else: self._status = None @@ -131,7 +131,7 @@ def close_cover(self, **kwargs): iterations += 1 sleep(10) - if (iterations <= 5): + if iterations <= 5: closed_confired_interations = 0 while True: self._status = self.myq.get_status(self.device_id) @@ -146,10 +146,7 @@ def close_cover(self, **kwargs): closed_confired_interations += 1 sleep(10) - if (iterations <= 5 and closed_confired_interations <= 5): - return True - else: - return False + return iterations <= 5 and closed_confired_interations <= 5 def open_cover(self, **kwargs): """Issue open command to cover.""" @@ -165,7 +162,7 @@ def open_cover(self, **kwargs): iterations += 1 sleep(10) - if (iterations <= 5): + if iterations <= 5: open_confirmed_interations = 0 while True: self._status = self.myq.get_status(self.device_id) @@ -180,10 +177,7 @@ def open_cover(self, **kwargs): open_confirmed_interations += 1 sleep(10) - if (iterations <= 5 and open_confirmed_interations <= 5): - return True - else: - return False + return iterations <= 5 and open_confirmed_interations <= 5 @property def supported_features(self):