11from __future__ import annotations
22
3- import asyncio
43import binascii
54import gzip
65import hashlib
7- import json
86import logging
9- from asyncio import BaseTransport , Lock
107from collections .abc import Callable
118from urllib .parse import urlparse
129
3128from Crypto .Cipher import AES
3229from Crypto .Util .Padding import pad , unpad
3330
34- from roborock .containers import BroadcastMessage , RRiot
31+ from roborock .containers import RRiot
3532from roborock .exceptions import RoborockException
3633from roborock .mqtt .session import MqttParams
3734from roborock .roborock_message import RoborockMessage
4037SALT = b"TXdfu$jyZ#TZHsg4"
4138A01_HASH = "726f626f726f636b2d67a6d6da"
4239B01_HASH = "5wwh9ikChRjASpMU8cxg7o1d2E"
43- BROADCAST_TOKEN = b"qWKYcdQWrbm9hPqe"
4440AP_CONFIG = 1
4541SOCK_DISCOVERY = 2
4642
@@ -51,38 +47,6 @@ def md5hex(message: str) -> str:
5147 return md5 .hexdigest ()
5248
5349
54- class RoborockProtocol (asyncio .DatagramProtocol ):
55- def __init__ (self , timeout : int = 5 ):
56- self .timeout = timeout
57- self .transport : BaseTransport | None = None
58- self .devices_found : list [BroadcastMessage ] = []
59- self ._mutex = Lock ()
60-
61- def __del__ (self ):
62- self .close ()
63-
64- def datagram_received (self , data , _ ):
65- [broadcast_message ], _ = BroadcastParser .parse (data )
66- if broadcast_message .payload :
67- parsed_message = BroadcastMessage .from_dict (json .loads (broadcast_message .payload ))
68- _LOGGER .debug (f"Received broadcast: { parsed_message } " )
69- self .devices_found .append (parsed_message )
70-
71- async def discover (self ):
72- async with self ._mutex :
73- try :
74- loop = asyncio .get_event_loop ()
75- self .transport , _ = await loop .create_datagram_endpoint (lambda : self , local_addr = ("0.0.0.0" , 58866 ))
76- await asyncio .sleep (self .timeout )
77- return self .devices_found
78- finally :
79- self .close ()
80- self .devices_found = []
81-
82- def close (self ):
83- self .transport .close () if self .transport else None
84-
85-
8650class Utils :
8751 """Util class for protocol manipulation."""
8852
@@ -324,19 +288,6 @@ def _build(self, obj, stream, context, path):
324288 "remaining" / Optional (GreedyBytes ),
325289)
326290
327- _BroadcastMessage = Struct (
328- "message"
329- / RawCopy (
330- Struct (
331- "version" / Bytes (3 ),
332- "seq" / Int32ub ,
333- "protocol" / Int16ub ,
334- "payload" / EncryptionAdapter (lambda ctx : BROADCAST_TOKEN ),
335- )
336- ),
337- "checksum" / Checksum (Int32ub , Utils .crc , lambda ctx : ctx .message .data ),
338- )
339-
340291
341292class _Parser :
342293 def __init__ (self , con : Construct , required_local_key : bool ):
@@ -390,7 +341,6 @@ def build(
390341
391342
392343MessageParser : _Parser = _Parser (_Messages , True )
393- BroadcastParser : _Parser = _Parser (_BroadcastMessage , False )
394344
395345
396346def create_mqtt_params (rriot : RRiot ) -> MqttParams :
0 commit comments