From 460d0df3661e78c11295b059b979dcf16d42921d Mon Sep 17 00:00:00 2001 From: Alberto Geniola Date: Sat, 20 Jun 2020 19:07:15 +0200 Subject: [PATCH] Implemented connection check --- .version | 2 +- meross_iot/controller/device.py | 2 +- meross_iot/manager.py | 20 ++++++++++++++++++-- meross_iot/model/enums.py | 5 +++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/.version b/.version index f164ddb5..9d977110 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.4.0.0rc12 \ No newline at end of file +0.4.0.0rc13 \ No newline at end of file diff --git a/meross_iot/controller/device.py b/meross_iot/controller/device.py index c2f5cc7f..ebf18bca 100644 --- a/meross_iot/controller/device.py +++ b/meross_iot/controller/device.py @@ -4,7 +4,7 @@ import logging from typing import List, Union, Optional, Iterable, Coroutine, Callable, Any, Awaitable -from meross_iot.model.enums import OnlineStatus, Namespace +from meross_iot.model.enums import OnlineStatus, Namespace, ConnectionEvent from meross_iot.model.http.device import HttpDeviceInfo from datetime import datetime diff --git a/meross_iot/manager.py b/meross_iot/manager.py index d780ed2e..943555a7 100644 --- a/meross_iot/manager.py +++ b/meross_iot/manager.py @@ -16,7 +16,7 @@ from meross_iot.controller.device import BaseDevice, HubDevice, GenericSubDevice from meross_iot.device_factory import build_meross_device, build_meross_subdevice from meross_iot.http_api import MerossHttpClient -from meross_iot.model.enums import Namespace, OnlineStatus +from meross_iot.model.enums import Namespace, OnlineStatus, ConnectionEvent from meross_iot.model.exception import CommandTimeoutError, CommandError from meross_iot.model.exception import UnconnectedError from meross_iot.model.http.device import HttpDeviceInfo @@ -319,6 +319,10 @@ def _on_disconnect(self, client, userdata, rc): _LOGGER.warning("Client has been disconnected, however auto_reconnect flag is set. " "Won't stop the looping thread, as it will retry to connect.") + # When a disconnection occurs, we need to set "unavailable" status. + asyncio.run_coroutine_threadsafe(self._notify_connection_event(ConnectionEvent.CONNECTION_DROP), + loop=self._loop) + def _on_unsubscribe(self): # NOTE! This method is called by the paho-mqtt thread, thus any invocation to the # asyncio platform must be scheduled via `self._loop.call_soon_threadsafe()` method. @@ -327,11 +331,14 @@ def _on_unsubscribe(self): def _on_subscribe(self, client, userdata, mid, granted_qos): # NOTE! This method is called by the paho-mqtt thread, thus any invocation to the # asyncio platform must be scheduled via `self._loop.call_soon_threadsafe()` method. - _LOGGER.debug("Succesfully subscribed to topics.") + _LOGGER.debug("Successfully subscribed to topics.") self._loop.call_soon_threadsafe( self._mqtt_connected_and_subscribed.set ) + asyncio.run_coroutine_threadsafe(self._notify_connection_event(ConnectionEvent.CONNECTION_ESTABLISHED), + loop=self._loop) + def _on_message(self, client, userdata, msg): # NOTE! This method is called by the paho-mqtt thread, thus any invocation to the # asyncio platform must be scheduled via `self._loop.call_soon_threadsafe()` method. @@ -528,6 +535,15 @@ async def _async_send_and_wait_ack(self, future: Future, target_device_uuid: str f"{target_device_uuid}. Timeout was: {timeout} seconds") raise CommandTimeoutError() + async def _notify_connection_event(self, status: ConnectionEvent): + for d in self._device_registry.find_all_by(): + payload = { + 'online': { + 'status': OnlineStatus.UNKNOWN.value + } + } + await d.async_handle_push_notification(namespace=Namespace.SYSTEM_ONLINE, data=payload) + def _build_mqtt_message(self, method: str, namespace: Namespace, payload: dict): """ Sends a message to the Meross MQTT broker, respecting the protocol payload. diff --git a/meross_iot/model/enums.py b/meross_iot/model/enums.py index 9ab65812..9366758f 100644 --- a/meross_iot/model/enums.py +++ b/meross_iot/model/enums.py @@ -6,6 +6,11 @@ _LOGGER = logging.getLogger(__name__) +class ConnectionEvent(Enum): + CONNECTION_DROP = 1 + CONNECTION_ESTABLISHED = 2 + + class OnlineStatus(Enum): ONLINE = 1 OFFLINE = 2