python-aidot 0.3.54b1__tar.gz → 0.3.54b3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/PKG-INFO +1 -1
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/aidot/aes_utils.py +19 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/aidot/client.py +5 -1
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/aidot/device_client.py +71 -97
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/aidot/discover.py +16 -32
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/python_aidot.egg-info/PKG-INFO +1 -1
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/setup.py +1 -1
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/LICENSE +0 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/README.md +0 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/aidot/__init__.py +0 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/aidot/const.py +0 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/aidot/exceptions.py +0 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/aidot/login_const.py +0 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/python_aidot.egg-info/SOURCES.txt +0 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/python_aidot.egg-info/dependency_links.txt +0 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/python_aidot.egg-info/requires.txt +0 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/python_aidot.egg-info/top_level.txt +0 -0
- {python_aidot-0.3.54b1 → python_aidot-0.3.54b3}/setup.cfg +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
|
|
2
2
|
from cryptography.hazmat.backends import default_backend
|
|
3
3
|
from cryptography.hazmat.primitives import padding
|
|
4
|
+
import json
|
|
5
|
+
from typing import Any, Optional
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
def aes_encrypt(plaintext, key):
|
|
@@ -25,3 +27,20 @@ def aes_decrypt(ciphertext, key):
|
|
|
25
27
|
plaintext = unpadder.update(decrypted_data) + unpadder.finalize()
|
|
26
28
|
|
|
27
29
|
return plaintext.decode()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def aes_decrypt_to_json(ciphertext: bytes, key: Optional[bytes] = None) -> dict[str, Any]:
|
|
33
|
+
"""Decrypt AES encrypted data and parse to JSON.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
ciphertext: AES encrypted data
|
|
37
|
+
key: AES key (optional, if None, assumes data is already decrypted)
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
Parsed JSON dict
|
|
41
|
+
"""
|
|
42
|
+
if key:
|
|
43
|
+
decrypted_data = aes_decrypt(ciphertext, key)
|
|
44
|
+
else:
|
|
45
|
+
decrypted_data = ciphertext.decode() if isinstance(ciphertext, bytes) else ciphertext
|
|
46
|
+
return json.loads(decrypted_data)
|
|
@@ -36,6 +36,8 @@ from .const import (
|
|
|
36
36
|
SUPPORTED_COUNTRYS,
|
|
37
37
|
DEFAULT_COUNTRY_CODE,
|
|
38
38
|
CONF_IS_OWNER,
|
|
39
|
+
CONF_TYPE,
|
|
40
|
+
CONF_AES_KEY,
|
|
39
41
|
ServerErrorCode,
|
|
40
42
|
)
|
|
41
43
|
|
|
@@ -77,7 +79,7 @@ class AidotClient:
|
|
|
77
79
|
password: str | None = None,
|
|
78
80
|
token: dict | None = None,
|
|
79
81
|
) -> None:
|
|
80
|
-
_LOGGER.info("Client Version: v0.3.
|
|
82
|
+
_LOGGER.info("Client Version: v0.3.54b3")
|
|
81
83
|
self.session = session
|
|
82
84
|
self.username = username
|
|
83
85
|
self.password = password
|
|
@@ -258,6 +260,7 @@ class AidotClient:
|
|
|
258
260
|
for device in final_device_list:
|
|
259
261
|
if device[CONF_PRODUCT_ID] == product[CONF_ID]:
|
|
260
262
|
device[CONF_PRODUCT] = product
|
|
263
|
+
|
|
261
264
|
except Exception as e:
|
|
262
265
|
raise e
|
|
263
266
|
return {CONF_DEVICE_LIST: final_device_list}
|
|
@@ -286,6 +289,7 @@ class AidotClient:
|
|
|
286
289
|
if self._discover is not None:
|
|
287
290
|
return
|
|
288
291
|
|
|
292
|
+
_LOGGER.warning(f"setup_discover")
|
|
289
293
|
def _discover_callback(dev_id, event: dict[str, str]) -> None:
|
|
290
294
|
device_ip = event[CONF_IPADDRESS]
|
|
291
295
|
device_client: DeviceClient = self._device_clients.get(dev_id)
|
|
@@ -11,7 +11,8 @@ from datetime import datetime
|
|
|
11
11
|
from typing import Any
|
|
12
12
|
|
|
13
13
|
from .exceptions import AidotNotLogin
|
|
14
|
-
from .aes_utils import aes_encrypt,
|
|
14
|
+
from .aes_utils import aes_encrypt, aes_decrypt_to_json
|
|
15
|
+
from .models.device_client_model import PingRequest, LoginRequest, LoginPayload, DeviceResponse, DeviceAttr, DeviceActionRequest
|
|
15
16
|
from .const import (
|
|
16
17
|
CONF_AES_KEY,
|
|
17
18
|
CONF_ASCNUMBER,
|
|
@@ -51,15 +52,16 @@ class DeviceStatusData:
|
|
|
51
52
|
cct: int = 2700
|
|
52
53
|
dimming: int = 100
|
|
53
54
|
|
|
54
|
-
def update(self, attr:
|
|
55
|
+
def update(self, attr: DeviceAttr) -> None:
|
|
56
|
+
"""Update status from DeviceAttr model."""
|
|
55
57
|
if attr is None:
|
|
56
58
|
return
|
|
57
|
-
if attr.
|
|
58
|
-
self.on = attr.
|
|
59
|
-
if attr.
|
|
60
|
-
self.dimming = int(attr.
|
|
61
|
-
if attr.
|
|
62
|
-
rgbw_value = attr.
|
|
59
|
+
if attr.OnOff is not None:
|
|
60
|
+
self.on = attr.OnOff
|
|
61
|
+
if attr.Dimming is not None:
|
|
62
|
+
self.dimming = int(attr.Dimming * 255 / 100)
|
|
63
|
+
if attr.RGBW is not None:
|
|
64
|
+
rgbw_value = attr.RGBW
|
|
63
65
|
# If RGBW is 0, set default red color (255, 0, 0, 0)
|
|
64
66
|
if rgbw_value == 0:
|
|
65
67
|
self.rgdb = 0xFF000000 # Red in int: 4278190080
|
|
@@ -72,8 +74,8 @@ class DeviceStatusData:
|
|
|
72
74
|
b = (rgbw >> 8) & 0xFF
|
|
73
75
|
w = rgbw & 0xFF
|
|
74
76
|
self.rgbw = (r, g, b, w)
|
|
75
|
-
if attr.
|
|
76
|
-
self.cct = attr.
|
|
77
|
+
if attr.CCT is not None:
|
|
78
|
+
self.cct = attr.CCT
|
|
77
79
|
|
|
78
80
|
|
|
79
81
|
class DeviceInformation:
|
|
@@ -123,6 +125,8 @@ class DeviceClient(object):
|
|
|
123
125
|
writer: Any = None
|
|
124
126
|
reader: Any = None
|
|
125
127
|
syncProperties = [CONF_ON_OFF, CONF_DIMMING, CONF_RGBW, CONF_CCT]
|
|
128
|
+
heart_time = 30
|
|
129
|
+
ping_data = PingRequest().to_dict()
|
|
126
130
|
_TAG: str = "DeviceClient"
|
|
127
131
|
@property
|
|
128
132
|
def connect_and_login(self) -> bool:
|
|
@@ -148,7 +152,11 @@ class DeviceClient(object):
|
|
|
148
152
|
self.password = device.get(CONF_PASSWORD)
|
|
149
153
|
self.device_id = device.get(CONF_ID)
|
|
150
154
|
self._simpleVersion = device.get("simpleVersion")
|
|
151
|
-
self._TAG = f"{self.device_id}"
|
|
155
|
+
self._TAG = f"{self.device_id}"
|
|
156
|
+
if self.info.model_id == 'lk.WIFI-RGBWLight-D0006':
|
|
157
|
+
self.ping_data = None
|
|
158
|
+
self.heart_time = 10
|
|
159
|
+
|
|
152
160
|
_LOGGER.warning(f"{self._TAG}:{device}")
|
|
153
161
|
|
|
154
162
|
async def connect(self, ip_address) -> None:
|
|
@@ -204,38 +212,36 @@ class DeviceClient(object):
|
|
|
204
212
|
async def login(self) -> None:
|
|
205
213
|
login_seq = str(int(time.time() * 1000) + self._login_uuid)[-9:]
|
|
206
214
|
self._login_uuid += 1
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
"ascNumber": 1,
|
|
219
|
-
},
|
|
220
|
-
}
|
|
215
|
+
|
|
216
|
+
login_request = LoginRequest(
|
|
217
|
+
seq=login_seq,
|
|
218
|
+
srcAddr=self.user_id,
|
|
219
|
+
deviceId=self.device_id,
|
|
220
|
+
payload=LoginPayload(
|
|
221
|
+
userId=self.user_id,
|
|
222
|
+
password=self.password,
|
|
223
|
+
),
|
|
224
|
+
)
|
|
225
|
+
message = login_request.to_dict()
|
|
221
226
|
try:
|
|
222
227
|
self.writer.write(self.get_send_packet(json.dumps(message).encode(), 1))
|
|
223
228
|
await self.writer.drain()
|
|
224
229
|
header = await self.reader.readexactly(8)
|
|
225
230
|
magic, msgtype, bodysize = struct.unpack(">HHI", header)
|
|
226
231
|
body = await self.reader.readexactly(bodysize)
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if code != 200:
|
|
232
|
+
json_data = aes_decrypt_to_json(body, self.aes_key)
|
|
233
|
+
_LOGGER.warning(f"{self._TAG}:login result: {json_data}")
|
|
234
|
+
|
|
235
|
+
response = DeviceResponse.from_json(json_data)
|
|
236
|
+
if response.ack.code != 200:
|
|
232
237
|
# 登录失败
|
|
233
|
-
_LOGGER.error(f"{self._TAG}:login error, code: {code}")
|
|
238
|
+
_LOGGER.error(f"{self._TAG}:login error, code: {response.ack.code}")
|
|
234
239
|
await self.reset()
|
|
235
240
|
return
|
|
236
241
|
|
|
237
|
-
self.ascNumber =
|
|
242
|
+
self.ascNumber = response.payload.ascNumber + 1
|
|
238
243
|
self.status.online = True
|
|
244
|
+
self._notify_status_update()
|
|
239
245
|
self._receive_task = asyncio.create_task(
|
|
240
246
|
self.receive_data(),
|
|
241
247
|
name=f"aidot_receive_{self.device_id}"
|
|
@@ -259,8 +265,7 @@ class DeviceClient(object):
|
|
|
259
265
|
magic, msgtype, bodysize = struct.unpack(">HHI", header)
|
|
260
266
|
self.ping_count = 0 #有读到数据就把ping清零
|
|
261
267
|
body = await self.reader.readexactly(bodysize)
|
|
262
|
-
|
|
263
|
-
json_data = json.loads(decrypted_data)
|
|
268
|
+
json_data = aes_decrypt_to_json(body, self.aes_key)
|
|
264
269
|
_LOGGER.warning(f"{self._TAG}:reveive_data : {json_data}")
|
|
265
270
|
except asyncio.CancelledError:
|
|
266
271
|
_LOGGER.debug(f"{self._TAG}:Receive task cancelled")
|
|
@@ -273,24 +278,23 @@ class DeviceClient(object):
|
|
|
273
278
|
return
|
|
274
279
|
except Exception as e:
|
|
275
280
|
_LOGGER.error(f"{self._TAG}:recv error: {e}")
|
|
276
|
-
self.ping_count = 0
|
|
277
281
|
continue
|
|
278
282
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
283
|
+
response = DeviceResponse.from_json(json_data)
|
|
284
|
+
if response.service == "test":
|
|
285
|
+
continue
|
|
286
|
+
|
|
287
|
+
if response.payload:
|
|
288
|
+
if response.payload.ascNumber:
|
|
289
|
+
self.ascNumber = response.payload.ascNumber
|
|
290
|
+
if response.payload.attr:
|
|
291
|
+
self.status.update(response.payload.attr)
|
|
292
|
+
self._notify_status_update()
|
|
289
293
|
|
|
290
294
|
def _schedule_ping(self):
|
|
291
295
|
loop = asyncio.get_running_loop()
|
|
292
296
|
loop.create_task(self.send_ping_action())
|
|
293
|
-
self._ping_timer = loop.call_later(
|
|
297
|
+
self._ping_timer = loop.call_later(self.heart_time, self._schedule_ping)
|
|
294
298
|
|
|
295
299
|
async def send_dev_attr(self, dev_attr) -> None:
|
|
296
300
|
if not self._connect_and_login:
|
|
@@ -318,42 +322,19 @@ class DeviceClient(object):
|
|
|
318
322
|
await self.send_dev_attr({CONF_CCT: cct})
|
|
319
323
|
|
|
320
324
|
async def send_action(self, attr, method) -> None:
|
|
321
|
-
current_timestamp_milliseconds = int(time.time() * 1000)
|
|
322
325
|
self.seq_num += 1
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
"userId": self.user_id,
|
|
336
|
-
"password": self.password,
|
|
337
|
-
"attr": attr,
|
|
338
|
-
"channel": "tcp",
|
|
339
|
-
"ascNumber": self.ascNumber,
|
|
340
|
-
},
|
|
341
|
-
"tst": current_timestamp_milliseconds,
|
|
342
|
-
"deviceId": self.device_id,
|
|
343
|
-
}
|
|
344
|
-
else:
|
|
345
|
-
action = {
|
|
346
|
-
"method": method,
|
|
347
|
-
"service": "device",
|
|
348
|
-
"seq": "" + seq,
|
|
349
|
-
"srcAddr": "0." + self.user_id,
|
|
350
|
-
CONF_PAYLOAD: {
|
|
351
|
-
"attr": attr,
|
|
352
|
-
"ascNumber": self.ascNumber,
|
|
353
|
-
},
|
|
354
|
-
"tst": current_timestamp_milliseconds,
|
|
355
|
-
"deviceId": self.device_id,
|
|
356
|
-
}
|
|
326
|
+
action_request = DeviceActionRequest.from_params(
|
|
327
|
+
method=method,
|
|
328
|
+
user_id=self.user_id,
|
|
329
|
+
device_id=self.device_id,
|
|
330
|
+
password=self.password,
|
|
331
|
+
ascNumber=self.ascNumber,
|
|
332
|
+
attr=attr,
|
|
333
|
+
seq="ha93" + str(self.seq_num).zfill(5),
|
|
334
|
+
simpleVersion=self._simpleVersion,
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
action = action_request.to_dict()
|
|
357
338
|
_LOGGER.warning(f"{self.device_id} send_action {action}")
|
|
358
339
|
try:
|
|
359
340
|
self.writer.write(self.get_send_packet(json.dumps(action).encode(), 1))
|
|
@@ -367,14 +348,6 @@ class DeviceClient(object):
|
|
|
367
348
|
async def send_ping_action(self) -> int:
|
|
368
349
|
if self._is_close:
|
|
369
350
|
return -1
|
|
370
|
-
ping = {
|
|
371
|
-
"service": "test",
|
|
372
|
-
"method": "pingreq",
|
|
373
|
-
"seq": "123456",
|
|
374
|
-
"srcAddr": "123456",
|
|
375
|
-
CONF_PAYLOAD: {},
|
|
376
|
-
}
|
|
377
|
-
_LOGGER.warning(f"{self.device_id} send_ping_action {ping}")
|
|
378
351
|
try:
|
|
379
352
|
if self.ping_count >= 3:
|
|
380
353
|
_LOGGER.error(
|
|
@@ -384,10 +357,15 @@ class DeviceClient(object):
|
|
|
384
357
|
return -1
|
|
385
358
|
if self._connect_and_login is False:
|
|
386
359
|
return -1
|
|
387
|
-
|
|
388
|
-
await self.writer.drain()
|
|
360
|
+
|
|
389
361
|
self.ping_count += 1
|
|
390
|
-
|
|
362
|
+
if self.ping_data is not None:
|
|
363
|
+
_LOGGER.warning(f"{self.device_id} send_ping {self.ping_data}")
|
|
364
|
+
self.writer.write(self.get_send_packet(json.dumps(self.ping_data).encode(), 2))
|
|
365
|
+
await self.writer.drain()
|
|
366
|
+
else:
|
|
367
|
+
_LOGGER.warning(f"{self.device_id} send_ping {self.syncProperties}")
|
|
368
|
+
await self.send_action(self.syncProperties, CONF_GET_DEV_ATTR_REQ)
|
|
391
369
|
return 1
|
|
392
370
|
except Exception as e:
|
|
393
371
|
_LOGGER.error(f"{self.device_id} ping error {e}")
|
|
@@ -414,7 +392,7 @@ class DeviceClient(object):
|
|
|
414
392
|
await self.writer.wait_closed()
|
|
415
393
|
except Exception as e:
|
|
416
394
|
_LOGGER.error(f"{self.device_id} writer/reader close error {e}")
|
|
417
|
-
self.writer = self.reader = None
|
|
395
|
+
self.writer = self.reader = None
|
|
418
396
|
|
|
419
397
|
self._connect_and_login = False
|
|
420
398
|
self.status.online = False
|
|
@@ -433,9 +411,5 @@ class DeviceClient(object):
|
|
|
433
411
|
"""延迟重连"""
|
|
434
412
|
_LOGGER.info(f"{self.device_id} _schedule_reconnect")
|
|
435
413
|
loop = asyncio.get_running_loop()
|
|
436
|
-
# self._reconnect_handle = loop.call_later(
|
|
437
|
-
# 10, # 10秒后重连
|
|
438
|
-
# lambda: asyncio.create_task(self.async_login())
|
|
439
|
-
# )
|
|
440
414
|
self._reconnect_handle = loop.call_later(60, self._schedule_reconnect)
|
|
441
415
|
self._login_task = asyncio.create_task(self.async_login())
|
|
@@ -8,10 +8,9 @@ from typing import Any
|
|
|
8
8
|
from .aes_utils import aes_encrypt, aes_decrypt
|
|
9
9
|
from .const import CONF_ID, CONF_IPADDRESS
|
|
10
10
|
from .exceptions import AidotOSError
|
|
11
|
+
from aidot.models.discover_model import DiscoverResponse, DiscoverRequest
|
|
11
12
|
|
|
12
13
|
_LOGGER = logging.getLogger(__name__)
|
|
13
|
-
# _DISCOVER_TIME = 15
|
|
14
|
-
|
|
15
14
|
_DISCOVER_FAST = 6 # 启动时快速发现
|
|
16
15
|
_DISCOVER_SLOW = 120 # 稳定后慢速维持
|
|
17
16
|
|
|
@@ -19,10 +18,7 @@ class BroadcastProtocol:
|
|
|
19
18
|
_is_closed = False
|
|
20
19
|
|
|
21
20
|
def __init__(self, callback, user_id) -> None:
|
|
22
|
-
self.aes_key = bytearray(32)
|
|
23
|
-
key_string = "T54uednca587"
|
|
24
|
-
key_bytes = key_string.encode()
|
|
25
|
-
self.aes_key[: len(key_bytes)] = key_bytes
|
|
21
|
+
self.aes_key = bytearray(b"T54uednca587".ljust(32, b'\x00'))
|
|
26
22
|
|
|
27
23
|
self._discover_cb = callback
|
|
28
24
|
self.user_id = user_id
|
|
@@ -36,37 +32,25 @@ class BroadcastProtocol:
|
|
|
36
32
|
if self._is_closed is True:
|
|
37
33
|
_LOGGER.error(f"{self.user_id}:Connection is closed")
|
|
38
34
|
return
|
|
39
|
-
current_timestamp_milliseconds = int(time.time() * 1000)
|
|
40
|
-
seq = str(current_timestamp_milliseconds + 1)[-9:]
|
|
41
|
-
message = {
|
|
42
|
-
"protocolVer": "2.0.0",
|
|
43
|
-
"service": "device",
|
|
44
|
-
"method": "devDiscoveryReq",
|
|
45
|
-
"seq": seq,
|
|
46
|
-
"srcAddr": f"0.{self.user_id}]",
|
|
47
|
-
"tst": current_timestamp_milliseconds,
|
|
48
|
-
"payload": {
|
|
49
|
-
"extends": {},
|
|
50
|
-
"localCtrFlag": 1,
|
|
51
|
-
"timestamp": str(current_timestamp_milliseconds),
|
|
52
|
-
},
|
|
53
|
-
}
|
|
54
|
-
_LOGGER.info(f"send_broadcast {message}")
|
|
55
|
-
send_data = aes_encrypt(json.dumps(message).encode(), self.aes_key)
|
|
56
35
|
try:
|
|
36
|
+
request = DiscoverRequest.from_params(userId=self.user_id)
|
|
37
|
+
message = request.to_dict()
|
|
38
|
+
_LOGGER.info(f"send_broadcast {message}")
|
|
39
|
+
send_data = aes_encrypt(json.dumps(message).encode(), self.aes_key)
|
|
57
40
|
self.transport.sendto(send_data, ("255.255.255.255", 6666))
|
|
58
41
|
except Exception as error:
|
|
59
42
|
_LOGGER.error(f"{self.user_id}:Connection lost due to error: {error}")
|
|
60
43
|
|
|
61
44
|
def datagram_received(self, data, addr) -> None:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
45
|
+
try:
|
|
46
|
+
data_str = aes_decrypt(data, self.aes_key)
|
|
47
|
+
data_json = json.loads(data_str)
|
|
48
|
+
response = DiscoverResponse.from_json(data=data_json)
|
|
49
|
+
_LOGGER.info(f"datagram_received {data_json}")
|
|
50
|
+
if response.payload and response.payload.devId and self._discover_cb:
|
|
51
|
+
self._discover_cb(response.payload.devId, {CONF_IPADDRESS: addr[0]})
|
|
52
|
+
except Exception as error:
|
|
53
|
+
_LOGGER.error(f"datagram_received error: {error}")
|
|
70
54
|
|
|
71
55
|
def error_received(self, exc) -> None:
|
|
72
56
|
_LOGGER.error(f"{self.user_id}:Error occurred: {exc}")
|
|
@@ -115,7 +99,7 @@ class Discover:
|
|
|
115
99
|
self._schedule_broadcast()
|
|
116
100
|
|
|
117
101
|
def _schedule_broadcast(self) -> None:
|
|
118
|
-
_LOGGER.
|
|
102
|
+
_LOGGER.warning(f"_schedule_broadcast")
|
|
119
103
|
# 前几次快速发现,之后慢速
|
|
120
104
|
if self._fast_discover_count > 0:
|
|
121
105
|
interval = _DISCOVER_FAST
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|