From fd8d32ec82cf84e319380d15baf5ce185336c14e Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Feb 2017 00:17:56 -0500 Subject: [PATCH 1/5] updated pylintrc --- pylintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylintrc b/pylintrc index 4c0b1523..34f9568c 100644 --- a/pylintrc +++ b/pylintrc @@ -35,4 +35,4 @@ disable= abstract-method [EXCEPTIONS] -overgeneral-exceptions=Exception,HomeAssistantError +overgeneral-exceptions=Exception From b9222e632456ea3a3420590055a23510e718de65 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Feb 2017 00:58:59 -0500 Subject: [PATCH 2/5] Added has_subscription and check if device is online/offline --- ring_doorbell/__init__.py | 103 +++++++++++++++++++++++++++++++------- 1 file changed, 86 insertions(+), 17 deletions(-) diff --git a/ring_doorbell/__init__.py b/ring_doorbell/__init__.py index f59ca7c7..10d2163c 100644 --- a/ring_doorbell/__init__.py +++ b/ring_doorbell/__init__.py @@ -104,6 +104,14 @@ def _query(self, url, attempts=RETRY_TOKEN, _LOGGER.error(GENERIC_FAIL) return response + @property + def has_subscription(self): + """Return if account has subscription""" + try: + return self.features.get('subscriptions_enabled') + except AttributeError: + return NOT_FOUND + @property def devices(self): """Return all devices.""" @@ -121,20 +129,49 @@ def __devices(self): @property def chimes(self): """Return list of chimes by name.""" - req = self.__devices.get('chimes') - return list((obj['description'] for obj in req)) + try: + req = self.__devices.get('chimes') + return list((obj['description'] for obj in req)) + except AttributeError: + return NOT_FOUND def chime_id(self, name): """Return chime ID.""" - return self.chime_attributes(name).get('id') + try: + return self.chime_attributes(name).get('id') + except AttributeError: + return NOT_FOUND def chime_attributes(self, name): """Return chime attributes.""" - lst = self.__devices.get('chimes') - index = _locator(lst, 'description', name) - if index == NOT_FOUND: - return None - return lst[index] + try: + lst = self.__devices.get('chimes') + index = _locator(lst, 'description', name) + if index == NOT_FOUND: + return NOT_FOUND + return lst[index] + except AttributeError: + return NOT_FOUND + + def is_chime_online(self, name): + """Return if chime is online""" + try: + result = self.chime_attributes(name).get('subscribed') + if result is None: + return False + except AttributeError: + return NOT_FOUND + return True + + def is_chime_subscribed_motions(self, name): + """Return if chime is subscribed_motions""" + try: + result = self.chime_attributes(name).get('subscribed_motions') + if result is None: + return False + except AttributeError: + return NOT_FOUND + return True def chime_tree(self, name): """Return doorbell data linked to chime.""" @@ -145,24 +182,56 @@ def chime_tree(self, name): @property def doorbells(self): """Return list of doorbells by name.""" - req = self.__devices.get('doorbots') - return list((obj['description'] for obj in req)) + try: + req = self.__devices.get('doorbots') + return list((obj['description'] for obj in req)) + except AttributeError: + return NOT_FOUND def doorbell_attributes(self, name): """Return doorbell attributes.""" - lst = self.__devices.get('doorbots') - index = _locator(lst, 'description', name) - if index == NOT_FOUND: - return None - return lst[index] + try: + lst = self.__devices.get('doorbots') + index = _locator(lst, 'description', name) + if index == NOT_FOUND: + return NOT_FOUND + return lst[index] + except AttributeError: + return NOT_FOUND def doorbell_id(self, name): """Return doorbell ID.""" - return self.doorbell_attributes(name).get('id') + try: + return self.doorbell_attributes(name).get('id') + except AttributeError: + return NOT_FOUND + + def is_doorbell_online(self, name): + """Return state for doorbell is online""" + try: + result = self.doorbell_attributes(name).get('subscribed') + if result is None: + return False + except AttributeError: + return NOT_FOUND + return True + + def is_doorbell_subscribed_motions(self, name): + """Return if doorbell is subscribed""" + try: + result = self.doorbell_attributes(name).get('subscribed_motions') + if result is None: + return False + except AttributeError: + return NOT_FOUND + return True def doorbell_battery_life(self, name): """Return doorbell battery life.""" - return self.doorbell_attributes(name).get('battery_life') + try: + return self.doorbell_attributes(name).get('battery_life') + except AttributeError: + return NOT_FOUND def __live_streaming_create_session(self, name): """Initiate session live streaming URL.""" From b068e6a8f4bafa1961294532bf96cc4a08104394 Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Feb 2017 01:00:33 -0500 Subject: [PATCH 3/5] Makes lint happy --- ring_doorbell/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ring_doorbell/__init__.py b/ring_doorbell/__init__.py index 10d2163c..0b15acee 100644 --- a/ring_doorbell/__init__.py +++ b/ring_doorbell/__init__.py @@ -106,7 +106,7 @@ def _query(self, url, attempts=RETRY_TOKEN, @property def has_subscription(self): - """Return if account has subscription""" + """Return if account has subscription.""" try: return self.features.get('subscriptions_enabled') except AttributeError: @@ -154,7 +154,7 @@ def chime_attributes(self, name): return NOT_FOUND def is_chime_online(self, name): - """Return if chime is online""" + """Return if chime is online.""" try: result = self.chime_attributes(name).get('subscribed') if result is None: @@ -164,7 +164,7 @@ def is_chime_online(self, name): return True def is_chime_subscribed_motions(self, name): - """Return if chime is subscribed_motions""" + """Return if chime is subscribed_motions.""" try: result = self.chime_attributes(name).get('subscribed_motions') if result is None: @@ -207,7 +207,7 @@ def doorbell_id(self, name): return NOT_FOUND def is_doorbell_online(self, name): - """Return state for doorbell is online""" + """Return state for doorbell is online.""" try: result = self.doorbell_attributes(name).get('subscribed') if result is None: @@ -217,7 +217,7 @@ def is_doorbell_online(self, name): return True def is_doorbell_subscribed_motions(self, name): - """Return if doorbell is subscribed""" + """Return if doorbell is subscribed.""" try: result = self.doorbell_attributes(name).get('subscribed_motions') if result is None: From 75a819daee7fda925e57f8ef2cd402a4866a2a2f Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Feb 2017 01:08:38 -0500 Subject: [PATCH 4/5] Show error only into debug mode --- ring_doorbell/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ring_doorbell/__init__.py b/ring_doorbell/__init__.py index 0b15acee..525d93ab 100644 --- a/ring_doorbell/__init__.py +++ b/ring_doorbell/__init__.py @@ -100,8 +100,8 @@ def _query(self, url, attempts=RETRY_TOKEN, break - if response is None: - _LOGGER.error(GENERIC_FAIL) + if response is None and self.debug: + _LOGGER.debug(GENERIC_FAIL) return response @property From 6a3f8d43a16f255a88583b249578501abf1f2b9b Mon Sep 17 00:00:00 2001 From: Marcelo Moreira de Mello Date: Sun, 12 Feb 2017 02:46:06 -0500 Subject: [PATCH 5/5] Fixed bug to refresh authentication token when having multiple connections. This patch will try to use the old token and if fails a new one will be placed at self._params. It also allows users to pass extra parameters to the given connection too. In [5]: myring.history(limit=1) params ==> %s {'api_version': '9', 'auth_token': '3pJyU1nuxctB56sHWg9W', 'limit': '2'} self._params ==> %s {'api_version': '9', 'auth_token': '3pJyU1nuxctB56sHWg9W', 'limit': '2'} .... REFRESHING auth_token because the older has expired .... params ==> %s {'api_version': '9', 'auth_token': 'SYDCAsQzAzGF1JBZJG82', 'limit': '2'} self._params ==> %s {'api_version': '9', 'auth_token': 'SYDCAsQzAzGF1JBZJG82', 'limit': '2'} Out[5]: [{'answered': False, 'created_at': '2017-02-12T00:42:05.000Z', 'doorbot': {'description': 'Front Door', 'id': 1572563}, 'events': [], 'favorite': False, 'id': 1234567, 'kind': 'motion', 'recording': {'status': 'ready'}, 'snapshot_url': ''}] --- ring_doorbell/__init__.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/ring_doorbell/__init__.py b/ring_doorbell/__init__.py index 525d93ab..04f6e9ff 100644 --- a/ring_doorbell/__init__.py +++ b/ring_doorbell/__init__.py @@ -57,18 +57,14 @@ def _authenticate(self, attempts=RETRY_TOKEN): self.token = data.get('authentication_token') self._params = {'api_version': API_VERSION, 'auth_token': self.token} - return + return True self.is_connected = False req.raise_for_status() def _query(self, url, attempts=RETRY_TOKEN, - raw=False, params=None): + raw=False, extra_params=None): """Query data from Ring API.""" - # allow to override params - if params is None: - params = self._params - if self.debug: _LOGGER.debug("Querying %s", url) @@ -79,6 +75,15 @@ def _query(self, url, attempts=RETRY_TOKEN, response = None loop = 0 while loop <= attempts: + + # allow to override params when necessary + # and update self._params globally for the next connection + if extra_params: + params = self._params + params.update(extra_params) + else: + params = self._params + loop += 1 try: req = self.session.get((url), params=urlencode(params)) @@ -259,11 +264,10 @@ def check_activity(self): def history(self, limit=30): """Return history.""" # allow modify the items to return - params = self._params - params.update({'limit': str(limit)}) + params = {'limit': str(limit)} url = API_URI + URL_HISTORY - return self._query(url, params=params) + return self._query(url, extra_params=params) def doorbell_recording(self, recording_id): """Return recording in MP4 format."""