|
6 | 6 | import hashlib |
7 | 7 | import json |
8 | 8 | import logging |
9 | | -from asyncio import BaseTransport |
| 9 | +from asyncio import BaseTransport, Lock |
10 | 10 | from typing import Callable |
11 | 11 |
|
12 | 12 | from construct import ( |
@@ -43,20 +43,27 @@ class RoborockProtocol(asyncio.DatagramProtocol): |
43 | 43 | def __init__(self, timeout: int = 5): |
44 | 44 | self.timeout = timeout |
45 | 45 | self.transport: BaseTransport | None = None |
46 | | - self.devices_found: list[dict] = [] |
| 46 | + self.devices_found: dict = {} |
| 47 | + self._mutex = Lock() |
| 48 | + |
| 49 | + def __del__(self): |
| 50 | + self.close() |
47 | 51 |
|
48 | 52 | def datagram_received(self, data, _): |
49 | 53 | [broadcast_message], _ = BroadcastParser.parse(data) |
50 | | - self.devices_found.append(json.loads(broadcast_message.payload)) |
| 54 | + parsed_message = json.loads(broadcast_message.payload) |
| 55 | + self.devices_found[parsed_message.get("duid")] = parsed_message.get("ip") |
51 | 56 |
|
52 | 57 | async def discover(self): |
53 | | - loop = asyncio.get_event_loop() |
54 | | - self.transport, _ = await loop.create_datagram_endpoint(lambda: self, local_addr=("0.0.0.0", 58866)) |
55 | | - await asyncio.sleep(self.timeout) |
56 | | - self.transport.close() |
57 | | - devices_found = self.devices_found |
58 | | - self.devices_found = [] |
59 | | - return devices_found |
| 58 | + async with self._mutex: |
| 59 | + try: |
| 60 | + loop = asyncio.get_event_loop() |
| 61 | + self.transport, _ = await loop.create_datagram_endpoint(lambda: self, local_addr=("0.0.0.0", 58866)) |
| 62 | + await asyncio.sleep(self.timeout) |
| 63 | + return self.devices_found |
| 64 | + finally: |
| 65 | + self.close() |
| 66 | + self.devices_found = {} |
60 | 67 |
|
61 | 68 | def close(self): |
62 | 69 | self.transport.close() if self.transport else None |
|
0 commit comments