diff --git a/abodepy/event_controller.py b/abodepy/event_controller.py index 873e222..c753513 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 @@ -20,8 +21,10 @@ def __init__(self, abode, url=CONST.SOCKETIO_URL): self._abode = abode self._thread = None self._running = False + self._connected = False # Setup callback dicts + 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) @@ -33,6 +36,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 +50,30 @@ def stop(self): """Tell the subscription thread to terminate - will block.""" self._socketio.stop() + def add_connection_status_callback(self, unique_id, callback): + """Register callback for Abode server connection status.""" + if not unique_id: + return False + + _LOGGER.debug( + "Subscribing to Abode connection updates for: %s", unique_id) + + self._connection_status_callbacks[unique_id].append((callback)) + + return True + + def remove_connection_status_callback(self, unique_id): + """Unregister connection status callbacks.""" + if not unique_id: + return False + + _LOGGER.debug( + "Unsubscribing from Abode connection updates for : %s", unique_id) + + self._connection_status_callbacks[unique_id].clear() + + return True + def add_device_callback(self, devices, callback): """Register a device callback.""" if not devices: @@ -142,6 +170,11 @@ def add_timeline_callback(self, timeline_events, callback): return True + @property + def connected(self): + """Get the Abode connection status.""" + return self._connected + @property def socketio(self): """Get the SocketIO instance.""" @@ -158,8 +191,26 @@ def _on_socket_started(self): def _on_socket_connected(self): """Socket IO connected callback.""" + self._connected = True + self._abode.refresh() + 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 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 callbacks[1]: + for callback in callbacks[1]: + _execute_callback(callback) + def _on_device_update(self, devid): """Device callback from Abode SocketIO server.""" if isinstance(devid, (tuple, list)):