Skip to content
25 changes: 16 additions & 9 deletions roborock/cloud_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
from typing import Any

import paho.mqtt.client as mqtt
from paho.mqtt.reasoncodes import ReasonCodes

from .api import KEEPALIVE, RoborockClient
from .containers import DeviceData, UserData
from .exceptions import RoborockException, VacuumError
from .exceptions import RoborockException, RoborockInvalidUserData, VacuumError
from .protocol import (
Decoder,
Encoder,
Expand Down Expand Up @@ -78,21 +79,27 @@ def __init__(self, user_data: UserData, device_info: DeviceData) -> None:
self._encoder: Encoder = create_mqtt_encoder(device_info.device.local_key)

def _mqtt_on_connect(self, *args, **kwargs):
_, __, ___, rc, ____ = args
rc: ReasonCodes = args[3]
Comment thread
Lash-L marked this conversation as resolved.
Outdated
connection_queue = self._waiting_queue.get(CONNECT_REQUEST_ID)
if rc != mqtt.MQTT_ERR_SUCCESS:
message = f"Failed to connect ({mqtt.error_string(rc)})"
if rc != 0:
Comment thread
Lash-L marked this conversation as resolved.
Outdated
message = f"Failed to connect ({str(rc)})"
Comment thread
Lash-L marked this conversation as resolved.
Outdated
self._logger.error(message)
if connection_queue:
connection_queue.set_exception(VacuumError(message))
# These are the ReasonCodes relating to authorization issues.
Comment thread
allenporter marked this conversation as resolved.
Outdated
if rc.value in {24, 25, 133, 134, 135, 144}:
connection_queue.set_exception(
RoborockInvalidUserData("Failed to connect to mqtt. Invalid user data. Re-auth is needed.")
)
else:
connection_queue.set_exception(VacuumError(message))
else:
self._logger.debug("Failed to notify connect future, not in queue")
return
self._logger.info(f"Connected to mqtt {self._mqtt_host}:{self._mqtt_port}")
topic = f"rr/m/o/{self._mqtt_user}/{self._hashed_user}/{self.device_info.device.duid}"
(result, mid) = self._mqtt_client.subscribe(topic)
if result != 0:
message = f"Failed to subscribe ({mqtt.error_string(rc)})"
message = f"Failed to subscribe ({str(rc)})"
self._logger.error(message)
if connection_queue:
connection_queue.set_exception(VacuumError(message))
Expand All @@ -112,7 +119,7 @@ def _mqtt_on_message(self, *args, **kwargs):
def _mqtt_on_disconnect(self, *args, **kwargs):
_, __, rc, ___ = args
try:
exc = RoborockException(mqtt.error_string(rc)) if rc != mqtt.MQTT_ERR_SUCCESS else None
exc = RoborockException(str(rc)) if rc != mqtt.MQTT_ERR_SUCCESS else None
super().on_connection_lost(exc)
connection_queue = self._waiting_queue.get(DISCONNECT_REQUEST_ID)
if connection_queue:
Expand All @@ -138,7 +145,7 @@ def _sync_disconnect(self) -> Any:

if rc != mqtt.MQTT_ERR_SUCCESS:
disconnected_future.cancel()
raise RoborockException(f"Failed to disconnect ({mqtt.error_string(rc)})")
raise RoborockException(f"Failed to disconnect ({str(rc)})")

return disconnected_future

Expand Down Expand Up @@ -177,4 +184,4 @@ def _send_msg_raw(self, msg: bytes) -> None:
f"rr/m/i/{self._mqtt_user}/{self._hashed_user}/{self.device_info.device.duid}", msg
)
if info.rc != mqtt.MQTT_ERR_SUCCESS:
raise RoborockException(f"Failed to publish ({mqtt.error_string(info.rc)})")
raise RoborockException(f"Failed to publish ({str(info.rc)})")
5 changes: 5 additions & 0 deletions roborock/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Roborock exceptions."""

from __future__ import annotations


Expand Down Expand Up @@ -76,3 +77,7 @@ class RoborockTooManyRequest(RoborockException):

class RoborockRateLimit(RoborockException):
"""Class for our rate limits exceptions."""


class RoborockInvalidUserData(RoborockException):
"""Class to state the user data is invalid (expired or manipulated)."""
6 changes: 3 additions & 3 deletions roborock/roborock_future.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import async_timeout

from .exceptions import VacuumError
from .exceptions import RoborockInvalidUserData, VacuumError


class RoborockFuture:
Expand All @@ -21,11 +21,11 @@ def _set_result(self, item: Any) -> None:
def set_result(self, item: Any) -> None:
self.loop.call_soon_threadsafe(self._set_result, item)

def _set_exception(self, exc: VacuumError) -> None:
def _set_exception(self, exc: VacuumError | RoborockInvalidUserData) -> None:
if not self.fut.cancelled():
self.fut.set_exception(exc)

def set_exception(self, exc: VacuumError) -> None:
def set_exception(self, exc: VacuumError | RoborockInvalidUserData) -> None:
self.loop.call_soon_threadsafe(self._set_exception, exc)

async def async_get(self, timeout: float | int) -> tuple[Any, VacuumError | None]:
Expand Down