From a7e6e81d40b2393132010ee43c2714120e7c4bb0 Mon Sep 17 00:00:00 2001 From: shred86 Date: Sun, 15 Mar 2020 21:30:56 -0700 Subject: [PATCH 1/8] Add callback for abode connection status --- abodepy/event_controller.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/abodepy/event_controller.py b/abodepy/event_controller.py index 873e222..27985f1 100644 --- a/abodepy/event_controller.py +++ b/abodepy/event_controller.py @@ -20,8 +20,10 @@ def __init__(self, abode, url=CONST.SOCKETIO_URL): self._abode = abode self._thread = None self._running = False + self._is_connected = False # Setup callback dicts + self._abode_status_callback = [] self._device_callbacks = collections.defaultdict(list) self._event_callbacks = collections.defaultdict(list) self._timeline_callbacks = collections.defaultdict(list) @@ -33,6 +35,7 @@ def __init__(self, abode, url=CONST.SOCKETIO_URL): # Setup SocketIO Callbacks self._socketio.on(sio.STARTED, self._on_socket_started) self._socketio.on(sio.CONNECTED, self._on_socket_connected) + self._socketio.on(sio.DISCONNECTED, self._on_socket_disconnected) self._socketio.on(CONST.DEVICE_UPDATE_EVENT, self._on_device_update) self._socketio.on(CONST.GATEWAY_MODE_EVENT, self._on_mode_change) self._socketio.on(CONST.TIMELINE_EVENT, self._on_timeline_update) @@ -46,6 +49,12 @@ def stop(self): """Tell the subscription thread to terminate - will block.""" self._socketio.stop() + def add_connection_status_callback(self, callback): + """Add an Abode server connection status callback.""" + self._abode_status_callback.append(callback) + + return True + def add_device_callback(self, devices, callback): """Register a device callback.""" if not devices: @@ -142,6 +151,11 @@ def add_timeline_callback(self, timeline_events, callback): return True + @property + def is_connected(self): + """Get the Abode connection status.""" + return self._is_connected + @property def socketio(self): """Get the SocketIO instance.""" @@ -158,8 +172,20 @@ def _on_socket_started(self): def _on_socket_connected(self): """Socket IO connected callback.""" + self._is_connected = True + self._abode.refresh() + for callback in self._abode_status_callback: + _execute_callback(callback) + + def _on_socket_disconnected(self): + """Socket IO disconnected callback.""" + self._is_connected = False + + for callback in self._abode_status_callback: + _execute_callback(callback) + def _on_device_update(self, devid): """Device callback from Abode SocketIO server.""" if isinstance(devid, (tuple, list)): From 53a40d8689747891952948cab75481929c479492 Mon Sep 17 00:00:00 2001 From: shred86 Date: Sun, 15 Mar 2020 22:15:06 -0700 Subject: [PATCH 2/8] Minor naming changes --- abodepy/event_controller.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/abodepy/event_controller.py b/abodepy/event_controller.py index 27985f1..b898218 100644 --- a/abodepy/event_controller.py +++ b/abodepy/event_controller.py @@ -23,7 +23,7 @@ def __init__(self, abode, url=CONST.SOCKETIO_URL): self._is_connected = False # Setup callback dicts - self._abode_status_callback = [] + self._connection_status_callbacks = [] self._device_callbacks = collections.defaultdict(list) self._event_callbacks = collections.defaultdict(list) self._timeline_callbacks = collections.defaultdict(list) @@ -51,7 +51,7 @@ def stop(self): def add_connection_status_callback(self, callback): """Add an Abode server connection status callback.""" - self._abode_status_callback.append(callback) + self._connection_status_callbacks.append(callback) return True @@ -176,14 +176,14 @@ def _on_socket_connected(self): self._abode.refresh() - for callback in self._abode_status_callback: + for callback in self._connection_status_callbacks: _execute_callback(callback) def _on_socket_disconnected(self): """Socket IO disconnected callback.""" self._is_connected = False - for callback in self._abode_status_callback: + for callback in self._connection_status_callbacks: _execute_callback(callback) def _on_device_update(self, devid): From 1c751f55f69b5d572b314c21747c4dd487790bc2 Mon Sep 17 00:00:00 2001 From: shred86 Date: Mon, 16 Mar 2020 19:12:02 -0700 Subject: [PATCH 3/8] Minor updates and added some notes --- abodepy/event_controller.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/abodepy/event_controller.py b/abodepy/event_controller.py index b898218..794659d 100644 --- a/abodepy/event_controller.py +++ b/abodepy/event_controller.py @@ -20,7 +20,7 @@ def __init__(self, abode, url=CONST.SOCKETIO_URL): self._abode = abode self._thread = None self._running = False - self._is_connected = False + self._connected = False # Setup callback dicts self._connection_status_callbacks = [] @@ -50,7 +50,9 @@ def stop(self): self._socketio.stop() def add_connection_status_callback(self, callback): - """Add an Abode server connection status callback.""" + """Register callback for Abode server connection status.""" + # All callback in the list `_connection_status_callbacks` are + # called when the web socket is connected or disconnected self._connection_status_callbacks.append(callback) return True @@ -152,9 +154,9 @@ def add_timeline_callback(self, timeline_events, callback): return True @property - def is_connected(self): + def connected(self): """Get the Abode connection status.""" - return self._is_connected + return self._connected @property def socketio(self): @@ -172,7 +174,7 @@ def _on_socket_started(self): def _on_socket_connected(self): """Socket IO connected callback.""" - self._is_connected = True + self._connected = True self._abode.refresh() @@ -181,7 +183,7 @@ def _on_socket_connected(self): def _on_socket_disconnected(self): """Socket IO disconnected callback.""" - self._is_connected = False + self._connected = False for callback in self._connection_status_callbacks: _execute_callback(callback) From 08da1a1f45f10df3ce6cf2d071d50595ce8997b0 Mon Sep 17 00:00:00 2001 From: shred86 Date: Mon, 16 Mar 2020 20:46:09 -0700 Subject: [PATCH 4/8] Add removal of callbacks and updates --- abodepy/event_controller.py | 39 ++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/abodepy/event_controller.py b/abodepy/event_controller.py index 794659d..24ee223 100644 --- a/abodepy/event_controller.py +++ b/abodepy/event_controller.py @@ -23,7 +23,7 @@ def __init__(self, abode, url=CONST.SOCKETIO_URL): self._connected = False # Setup callback dicts - self._connection_status_callbacks = [] + self._connection_status_callbacks = collections.defaultdict(list) self._device_callbacks = collections.defaultdict(list) self._event_callbacks = collections.defaultdict(list) self._timeline_callbacks = collections.defaultdict(list) @@ -49,11 +49,27 @@ def stop(self): """Tell the subscription thread to terminate - will block.""" self._socketio.stop() - def add_connection_status_callback(self, callback): + def add_connection_status_callback(self, devices, callback): """Register callback for Abode server connection status.""" - # All callback in the list `_connection_status_callbacks` are - # called when the web socket is connected or disconnected - self._connection_status_callbacks.append(callback) + if not devices: + return False + + if not isinstance(devices, (tuple, list)): + devices = [devices] + + for device in devices: + device_id = device + + if isinstance(device, AbodeDevice): + device_id = device.device_id + + if not self._abode.get_device(device_id): + raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) + + _LOGGER.debug( + "Subscribing to Abode connection updates for device_id: %s", device_id) + + self._connection_status_callbacks[device_id].append((callback)) return True @@ -109,6 +125,8 @@ def remove_all_device_callbacks(self, devices): self._device_callbacks[device_id].clear() + self._connection_status_callbacks[device_id].clear() + return True def add_event_callback(self, event_groups, callback): @@ -178,15 +196,18 @@ def _on_socket_connected(self): self._abode.refresh() - for callback in self._connection_status_callbacks: - _execute_callback(callback) + for callback in self._connection_status_callbacks.items(): + _execute_callback(callback[1][0]) def _on_socket_disconnected(self): """Socket IO disconnected callback.""" self._connected = False - for callback in self._connection_status_callbacks: - _execute_callback(callback) + for callback in self._connection_status_callbacks.items(): + # Checks if list is empty for when remove_all_device_callbacks + # is called before _on_socket_disconnected. + if callback[1]: + _execute_callback(callback[1][0]) def _on_device_update(self, devid): """Device callback from Abode SocketIO server.""" From 3b0c45e9c7bd8fc02b6a67849d18ac9abcb8d935 Mon Sep 17 00:00:00 2001 From: shred86 Date: Tue, 17 Mar 2020 19:47:09 -0700 Subject: [PATCH 5/8] Fix for multiple callbacks in a list --- abodepy/event_controller.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/abodepy/event_controller.py b/abodepy/event_controller.py index 24ee223..98f7115 100644 --- a/abodepy/event_controller.py +++ b/abodepy/event_controller.py @@ -2,6 +2,7 @@ import collections import logging +from abodepy.automation import AbodeAutomation from abodepy.devices import AbodeDevice from abodepy.exceptions import AbodeException import abodepy.helpers.constants as CONST @@ -60,11 +61,17 @@ def add_connection_status_callback(self, devices, callback): for device in devices: device_id = device - if isinstance(device, AbodeDevice): + if isinstance(device, (AbodeDevice)): device_id = device.device_id - if not self._abode.get_device(device_id): - raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) + if not self._abode.get_device(device_id): + raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) + + if isinstance(device, (AbodeAutomation)): + device_id = device.automation_id + + if not self._abode.get_automation(device_id): + raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) _LOGGER.debug( "Subscribing to Abode connection updates for device_id: %s", device_id) @@ -196,18 +203,21 @@ def _on_socket_connected(self): self._abode.refresh() - for callback in self._connection_status_callbacks.items(): - _execute_callback(callback[1][0]) + for callbacks in self._connection_status_callbacks.items(): + for callback in callbacks[1]: + _execute_callback(callback) def _on_socket_disconnected(self): """Socket IO disconnected callback.""" self._connected = False - for callback in self._connection_status_callbacks.items(): - # Checks if list is empty for when remove_all_device_callbacks + for callbacks in self._connection_status_callbacks.items(): + # Check if list is not empty. + # Applicable when remove_all_device_callbacks # is called before _on_socket_disconnected. - if callback[1]: - _execute_callback(callback[1][0]) + if callbacks[1]: + for callback in callbacks[1]: + _execute_callback(callback) def _on_device_update(self, devid): """Device callback from Abode SocketIO server.""" From 8c09890933e4de89c82e14208ea9c8f5f20cac4a Mon Sep 17 00:00:00 2001 From: shred86 Date: Tue, 17 Mar 2020 19:50:57 -0700 Subject: [PATCH 6/8] Minor clean up --- abodepy/event_controller.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/abodepy/event_controller.py b/abodepy/event_controller.py index 98f7115..e36105b 100644 --- a/abodepy/event_controller.py +++ b/abodepy/event_controller.py @@ -61,13 +61,13 @@ def add_connection_status_callback(self, devices, callback): for device in devices: device_id = device - if isinstance(device, (AbodeDevice)): + if isinstance(device, AbodeDevice): device_id = device.device_id if not self._abode.get_device(device_id): raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) - if isinstance(device, (AbodeAutomation)): + if isinstance(device, AbodeAutomation): device_id = device.automation_id if not self._abode.get_automation(device_id): From 388f2dc021f76c1a257bb4120dc491e6f8cdafd7 Mon Sep 17 00:00:00 2001 From: shred86 Date: Wed, 18 Mar 2020 19:24:44 -0700 Subject: [PATCH 7/8] Add method to remove connection status callback --- abodepy/event_controller.py | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/abodepy/event_controller.py b/abodepy/event_controller.py index e36105b..4162557 100644 --- a/abodepy/event_controller.py +++ b/abodepy/event_controller.py @@ -74,12 +74,45 @@ def add_connection_status_callback(self, devices, callback): raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) _LOGGER.debug( - "Subscribing to Abode connection updates for device_id: %s", device_id) + "Subscribing to Abode connection updates for: %s", device_id) self._connection_status_callbacks[device_id].append((callback)) return True + def remove_connection_status_callback(self, devices): + """Unregister connection status callbacks.""" + if not devices: + return False + + if not isinstance(devices, (tuple, list)): + devices = [devices] + + for device in devices: + device_id = device + + if isinstance(device, AbodeDevice): + device_id = device.device_id + + if not self._abode.get_device(device_id): + raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) + + if isinstance(device, AbodeAutomation): + device_id = device.automation_id + + if not self._abode.get_automation(device_id): + raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) + + if device_id not in self._connection_status_callbacks: + return False + + _LOGGER.debug( + "Unsubscribing from Abode connection updates for : %s", device_id) + + self._connection_status_callbacks[device_id].clear() + + return True + def add_device_callback(self, devices, callback): """Register a device callback.""" if not devices: @@ -132,8 +165,6 @@ def remove_all_device_callbacks(self, devices): self._device_callbacks[device_id].clear() - self._connection_status_callbacks[device_id].clear() - return True def add_event_callback(self, event_groups, callback): From 0c617cc81491329c06c894a15fb3c389afffb427 Mon Sep 17 00:00:00 2001 From: shred86 Date: Fri, 27 Mar 2020 20:43:40 -0700 Subject: [PATCH 8/8] Fix for multi sensor --- abodepy/event_controller.py | 59 +++++++------------------------------ 1 file changed, 10 insertions(+), 49 deletions(-) diff --git a/abodepy/event_controller.py b/abodepy/event_controller.py index 4162557..c753513 100644 --- a/abodepy/event_controller.py +++ b/abodepy/event_controller.py @@ -50,66 +50,27 @@ def stop(self): """Tell the subscription thread to terminate - will block.""" self._socketio.stop() - def add_connection_status_callback(self, devices, callback): + def add_connection_status_callback(self, unique_id, callback): """Register callback for Abode server connection status.""" - if not devices: + if not unique_id: return False - if not isinstance(devices, (tuple, list)): - devices = [devices] - - for device in devices: - device_id = device + _LOGGER.debug( + "Subscribing to Abode connection updates for: %s", unique_id) - if isinstance(device, AbodeDevice): - device_id = device.device_id - - if not self._abode.get_device(device_id): - raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) - - if isinstance(device, AbodeAutomation): - device_id = device.automation_id - - if not self._abode.get_automation(device_id): - raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) - - _LOGGER.debug( - "Subscribing to Abode connection updates for: %s", device_id) - - self._connection_status_callbacks[device_id].append((callback)) + self._connection_status_callbacks[unique_id].append((callback)) return True - def remove_connection_status_callback(self, devices): + def remove_connection_status_callback(self, unique_id): """Unregister connection status callbacks.""" - if not devices: + if not unique_id: return False - if not isinstance(devices, (tuple, list)): - devices = [devices] - - for device in devices: - device_id = device - - if isinstance(device, AbodeDevice): - device_id = device.device_id - - if not self._abode.get_device(device_id): - raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) - - if isinstance(device, AbodeAutomation): - device_id = device.automation_id - - if not self._abode.get_automation(device_id): - raise AbodeException((ERROR.EVENT_DEVICE_INVALID)) - - if device_id not in self._connection_status_callbacks: - return False - - _LOGGER.debug( - "Unsubscribing from Abode connection updates for : %s", device_id) + _LOGGER.debug( + "Unsubscribing from Abode connection updates for : %s", unique_id) - self._connection_status_callbacks[device_id].clear() + self._connection_status_callbacks[unique_id].clear() return True