44import logging
55from collections .abc import Callable
66from dataclasses import dataclass
7- from json import JSONDecodeError
87
98from roborock .exceptions import RoborockConnectionException , RoborockException
109from roborock .protocol import Decoder , Encoder , create_local_decoder , create_local_encoder
1110from roborock .roborock_message import RoborockMessage
1211
1312from .channel import Channel
14- from .pending import PendingRpcs
1513
1614_LOGGER = logging .getLogger (__name__ )
1715_PORT = 58867
@@ -47,8 +45,6 @@ def __init__(self, host: str, local_key: str):
4745 self ._subscribers : list [Callable [[RoborockMessage ], None ]] = []
4846 self ._is_connected = False
4947
50- # RPC support
51- self ._pending_rpcs : PendingRpcs [int , RoborockMessage ] = PendingRpcs ()
5248 self ._decoder : Decoder = create_local_decoder (local_key )
5349 self ._encoder : Encoder = create_local_encoder (local_key )
5450
@@ -87,7 +83,6 @@ def _data_received(self, data: bytes) -> None:
8783 return
8884 for message in messages :
8985 _LOGGER .debug ("Received message: %s" , message )
90- asyncio .create_task (self ._resolve_future_with_lock (message ))
9186 for callback in self ._subscribers :
9287 try :
9388 callback (message )
@@ -109,37 +104,24 @@ def unsubscribe() -> None:
109104
110105 return unsubscribe
111106
112- async def _resolve_future_with_lock (self , message : RoborockMessage ) -> None :
113- """Resolve waiting future with proper locking."""
114- if (request_id := message .get_request_id ()) is None :
115- _LOGGER .debug ("Received message with no request_id" )
116- return
117- await self ._pending_rpcs .resolve (request_id , message )
107+ async def publish (self , message : RoborockMessage ) -> None :
108+ """Send a command message.
118109
119- async def send_message ( self , message : RoborockMessage , timeout : float = 10.0 ) -> RoborockMessage :
120- """Send a command message and wait for the response message."""
110+ The caller is responsible for associating the message with its response.
111+ """
121112 if not self ._transport or not self ._is_connected :
122113 raise RoborockConnectionException ("Not connected to device" )
123114
124- try :
125- if (request_id := message .get_request_id ()) is None :
126- raise RoborockException ("Message must have a request_id for RPC calls" )
127- except (ValueError , JSONDecodeError ) as err :
128- _LOGGER .exception ("Error getting request_id from message: %s" , err )
129- raise RoborockException (f"Invalid message format, Message must have a request_id: { err } " ) from err
130-
131- future : asyncio .Future [RoborockMessage ] = await self ._pending_rpcs .start (request_id )
132115 try :
133116 encoded_msg = self ._encoder (message )
117+ except Exception as err :
118+ _LOGGER .exception ("Error encoding MQTT message: %s" , err )
119+ raise RoborockException (f"Failed to encode MQTT message: { err } " ) from err
120+ try :
134121 self ._transport .write (encoded_msg )
135- return await asyncio .wait_for (future , timeout = timeout )
136- except asyncio .TimeoutError as ex :
137- await self ._pending_rpcs .pop (request_id )
138- raise RoborockException (f"Command timed out after { timeout } s" ) from ex
139- except Exception :
122+ except Exception as err :
140123 logging .exception ("Uncaught error sending command" )
141- await self ._pending_rpcs .pop (request_id )
142- raise
124+ raise RoborockException (f"Failed to send message: { message } " ) from err
143125
144126
145127# This module provides a factory function to create LocalChannel instances.
0 commit comments