77import logging
88import secrets
99import time
10+ from abc import ABC , abstractmethod
1011from typing import Any
1112
1213from .containers import (
2122 RoborockMessage ,
2223)
2324from .roborock_typing import RoborockCommand
24- from .util import RoborockLoggerAdapter , get_next_int , get_running_loop_or_create_one
25+ from .util import get_next_int , get_running_loop_or_create_one
2526
2627_LOGGER = logging .getLogger (__name__ )
2728KEEPALIVE = 60
2829
2930
30- class RoborockClient :
31- def __init__ (self , endpoint : str , device_info : DeviceData , queue_timeout : int = 4 ) -> None :
31+ class RoborockClient (ABC ):
32+ """Roborock client base class."""
33+
34+ _logger : logging .LoggerAdapter
35+
36+ def __init__ (self , device_info : DeviceData , queue_timeout : int = 4 ) -> None :
37+ """Initialize RoborockClient."""
3238 self .event_loop = get_running_loop_or_create_one ()
3339 self .device_info = device_info
34- self ._endpoint = endpoint
3540 self ._nonce = secrets .token_bytes (16 )
3641 self ._waiting_queue : dict [int , RoborockFuture ] = {}
3742 self ._last_device_msg_in = time .monotonic ()
@@ -40,7 +45,6 @@ def __init__(self, endpoint: str, device_info: DeviceData, queue_timeout: int =
4045 self ._diagnostic_data : dict [str , dict [str , Any ]] = {
4146 "misc_info" : {"Nonce" : base64 .b64encode (self ._nonce ).decode ("utf-8" )}
4247 }
43- self ._logger = RoborockLoggerAdapter (device_info .device .name , _LOGGER )
4448 self .is_available : bool = True
4549 self .queue_timeout = queue_timeout
4650
@@ -57,17 +61,21 @@ async def async_release(self) -> None:
5761 def diagnostic_data (self ) -> dict :
5862 return self ._diagnostic_data
5963
64+ @abstractmethod
6065 async def async_connect (self ):
61- raise NotImplementedError
66+ """Connect to the Roborock device."""
6267
68+ @abstractmethod
6369 def sync_disconnect (self ) -> Any :
64- raise NotImplementedError
70+ """Disconnect from the Roborock device."""
6571
72+ @abstractmethod
6673 async def async_disconnect (self ) -> Any :
67- raise NotImplementedError
74+ """Disconnect from the Roborock device."""
6875
76+ @abstractmethod
6977 def on_message_received (self , messages : list [RoborockMessage ]) -> None :
70- raise NotImplementedError
78+ """Handle received incoming messages from the device."""
7179
7280 def on_connection_lost (self , exc : Exception | None ) -> None :
7381 self ._last_disconnection = time .monotonic ()
@@ -102,7 +110,7 @@ def _async_response(self, request_id: int, protocol_id: int = 0) -> Any:
102110 queue = RoborockFuture (protocol_id )
103111 if request_id in self ._waiting_queue :
104112 new_id = get_next_int (10000 , 32767 )
105- _LOGGER .warning (
113+ self . _logger .warning (
106114 "Attempting to create a future with an existing id %s (%s)... New id is %s. "
107115 "Code may not function properly." ,
108116 request_id ,
@@ -113,12 +121,14 @@ def _async_response(self, request_id: int, protocol_id: int = 0) -> Any:
113121 self ._waiting_queue [request_id ] = queue
114122 return asyncio .ensure_future (self ._wait_response (request_id , queue ))
115123
124+ @abstractmethod
116125 async def send_message (self , roborock_message : RoborockMessage ):
117- raise NotImplementedError
126+ """Send a message to the Roborock device."""
118127
128+ @abstractmethod
119129 async def _send_command (
120130 self ,
121131 method : RoborockCommand | str ,
122132 params : list | dict | int | None = None ,
123133 ):
124- raise NotImplementedError
134+ """Send a command to the Roborock device."""
0 commit comments