Skip to content

Commit 691b04b

Browse files
feat: keep connection alive
1 parent dce399e commit 691b04b

File tree

4 files changed

+35
-13
lines changed

4 files changed

+35
-13
lines changed

roborock/api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ async def _async_response(self, request_id: int, protocol_id: int = 0) -> tuple[
191191
except (asyncio.TimeoutError, asyncio.CancelledError):
192192
raise RoborockTimeout(f"id={request_id} Timeout after {QUEUE_TIMEOUT} seconds") from None
193193
finally:
194-
del self._waiting_queue[request_id]
194+
self._waiting_queue.pop(request_id, None)
195195

196196
def _get_payload(
197197
self,

roborock/local_api.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def __init__(self, device_data: DeviceData):
3030
self.remaining = b""
3131
self.transport: Transport | None = None
3232
self._mutex = Lock()
33+
self.keep_alive_func()
3334

3435
def data_received(self, message):
3536
if self.remaining:
@@ -45,6 +46,13 @@ def connection_lost(self, exc: Optional[Exception]):
4546
def is_connected(self):
4647
return self.transport and self.transport.is_reading()
4748

49+
def keep_alive_func(self, _=None):
50+
keep_alive_task = asyncio.gather(
51+
asyncio.sleep(10),
52+
self.ping(),
53+
)
54+
keep_alive_task.add_done_callback(self.keep_alive_func)
55+
4856
async def async_connect(self) -> None:
4957
async with self._mutex:
5058
try:
@@ -87,7 +95,18 @@ def build_roborock_message(self, method: RoborockCommand, params: Optional[list
8795
)
8896

8997
async def ping(self):
90-
return await self.send_command(RoborockCommand.APP_WAKEUP_ROBOT)
98+
request_id = 2
99+
_LOGGER.debug(f"id={request_id} Requesting method ping with None")
100+
try:
101+
return await self.send_message(RoborockMessage(
102+
protocol=2,
103+
payload=None,
104+
seq=request_id,
105+
version=b'1.0',
106+
random=23
107+
))
108+
except Exception as e:
109+
_LOGGER.error(e)
91110

92111
async def send_command(self, method: RoborockCommand, params: Optional[list | dict] = None):
93112
roborock_message = self.build_roborock_message(method, params)
@@ -96,9 +115,9 @@ async def send_command(self, method: RoborockCommand, params: Optional[list | di
96115
async def async_local_response(self, roborock_message: RoborockMessage):
97116
method = roborock_message.get_method()
98117
request_id: int | None
99-
if method and not method.startswith("get"):
118+
if not method or not method.startswith("get"):
100119
request_id = roborock_message.seq
101-
response_protocol = 5
120+
response_protocol = request_id + 1
102121
else:
103122
request_id = roborock_message.get_request_id()
104123
response_protocol = 4
@@ -107,7 +126,8 @@ async def async_local_response(self, roborock_message: RoborockMessage):
107126
(response, err) = await self._async_response(request_id, response_protocol)
108127
if err:
109128
raise CommandVacuumError("", err) from err
110-
_LOGGER.debug(f"id={request_id} Response from {roborock_message.get_method()}: {response}")
129+
method = roborock_message.get_method() if roborock_message.protocol != 2 else "ping"
130+
_LOGGER.debug(f"id={request_id} Response from method {method}: {response}")
111131
return response
112132

113133
def _send_msg_raw(self, data: bytes):

roborock/protocol.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,19 +176,21 @@ def _parse(self, stream, context, path):
176176
subcon1 = Optional(Int16ub)
177177
length = subcon1.parse_stream(stream, **context)
178178
if not length:
179-
subcon1.parse_stream(stream, **context) # seek 2
179+
if length == 0:
180+
subcon1.parse_stream(stream, **context) # seek 2
180181
return None
181182
subcon2 = Bytes(length)
182183
obj = subcon2.parse_stream(stream, **context)
183184
return self._decode(obj, context, path)
184185

185186
def _build(self, obj, stream, context, path):
186-
obj2 = self._encode(obj, context, path)
187-
subcon1 = Int16ub
188-
length = len(obj2)
189-
subcon1.build_stream(length, stream, **context)
190-
subcon2 = Bytes(length)
191-
subcon2.build_stream(obj2, stream, **context)
187+
if obj is not None:
188+
obj2 = self._encode(obj, context, path)
189+
subcon1 = Int16ub
190+
length = len(obj2)
191+
subcon1.build_stream(length, stream, **context)
192+
subcon2 = Bytes(length)
193+
subcon2.build_stream(obj2, stream, **context)
192194
return obj
193195

194196
def _encode(self, obj, context, _):

roborock/roborock_message.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
@dataclass
1313
class RoborockMessage:
1414
protocol: int
15-
payload: bytes
15+
payload: bytes | None
1616
seq: int = randint(100000, 999999)
1717
version: bytes = b"1.0"
1818
random: int = randint(10000, 99999)

0 commit comments

Comments
 (0)