python-aidot 0.3.52__tar.gz → 0.3.54b1__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.52 → python_aidot-0.3.54b1}/PKG-INFO +1 -1
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/aidot/client.py +6 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/aidot/const.py +3 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/aidot/device_client.py +25 -15
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/aidot/discover.py +2 -2
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/python_aidot.egg-info/PKG-INFO +1 -1
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/setup.py +1 -1
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/LICENSE +0 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/README.md +0 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/aidot/__init__.py +0 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/aidot/aes_utils.py +0 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/aidot/exceptions.py +0 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/aidot/login_const.py +0 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/python_aidot.egg-info/SOURCES.txt +0 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/python_aidot.egg-info/dependency_links.txt +0 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/python_aidot.egg-info/requires.txt +0 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/python_aidot.egg-info/top_level.txt +0 -0
- {python_aidot-0.3.52 → python_aidot-0.3.54b1}/setup.cfg +0 -0
|
@@ -90,6 +90,12 @@ class AidotClient:
|
|
|
90
90
|
self._base_url = API_URL_TEMPLATE.format(region=self._region)
|
|
91
91
|
break
|
|
92
92
|
if token is not None:
|
|
93
|
+
# ✅ 兼容性处理: v1.0.8 数据结构迁移到 v1.1.3
|
|
94
|
+
# 旧版本: config_entry.data[CONF_LOGIN_INFO]
|
|
95
|
+
# 新版本: config_entry.data
|
|
96
|
+
if token.get(CONF_ID) is None and token.get(CONF_LOGIN_INFO) is not None:
|
|
97
|
+
token = token.get(CONF_LOGIN_INFO)
|
|
98
|
+
|
|
93
99
|
self.login_info = token.copy()
|
|
94
100
|
self.username = token[CONF_USERNAME]
|
|
95
101
|
self.password = token[CONF_PASSWORD]
|
|
@@ -188,6 +188,7 @@ CONF_IS_DEFAULT = "isDefault"
|
|
|
188
188
|
CONF_TYPE = "type"
|
|
189
189
|
CONF_MODEL_ID = "modelId"
|
|
190
190
|
CONF_MAC = "mac"
|
|
191
|
+
CONF_LOGIN_INFO = "loginInfo"
|
|
191
192
|
CONF_AES_KEY = "aesKey"
|
|
192
193
|
CONF_MODEL_ID = "modelId"
|
|
193
194
|
CONF_HARDWARE_VERSION = "hardwareVersion"
|
|
@@ -207,6 +208,8 @@ CONF_RGBW = "RGBW"
|
|
|
207
208
|
CONF_CCT = "CCT"
|
|
208
209
|
CONF_ACK = "ack"
|
|
209
210
|
CONF_IS_OWNER = "isOwner"
|
|
211
|
+
CONF_GET_DEV_ATTR_REQ = "getDevAttrReq"
|
|
212
|
+
CONF_SET_DEV_ATTR_REQ = "setDevAttrReq"
|
|
210
213
|
|
|
211
214
|
|
|
212
215
|
class Identity(StrEnum):
|
|
@@ -35,6 +35,8 @@ from .const import (
|
|
|
35
35
|
CONF_SERVICE_MODULES,
|
|
36
36
|
CONF_ACK,
|
|
37
37
|
CONF_CODE,
|
|
38
|
+
CONF_GET_DEV_ATTR_REQ,
|
|
39
|
+
CONF_SET_DEV_ATTR_REQ,
|
|
38
40
|
Identity,
|
|
39
41
|
)
|
|
40
42
|
|
|
@@ -44,10 +46,10 @@ _LOGGER = logging.getLogger(__name__)
|
|
|
44
46
|
class DeviceStatusData:
|
|
45
47
|
online: bool = False
|
|
46
48
|
on: bool = False
|
|
47
|
-
rgdb: int =
|
|
48
|
-
rgbw: tuple[int, int, int, int] =
|
|
49
|
-
cct: int =
|
|
50
|
-
dimming: int =
|
|
49
|
+
rgdb: int = 0xFF000000
|
|
50
|
+
rgbw: tuple[int, int, int, int] = (255, 0, 0, 0)
|
|
51
|
+
cct: int = 2700
|
|
52
|
+
dimming: int = 100
|
|
51
53
|
|
|
52
54
|
def update(self, attr: dict[str, Any]) -> None:
|
|
53
55
|
if attr is None:
|
|
@@ -57,7 +59,13 @@ class DeviceStatusData:
|
|
|
57
59
|
if attr.get(CONF_DIMMING) is not None:
|
|
58
60
|
self.dimming = int(attr.get(CONF_DIMMING) * 255 / 100)
|
|
59
61
|
if attr.get(CONF_RGBW) is not None:
|
|
60
|
-
|
|
62
|
+
rgbw_value = attr.get(CONF_RGBW)
|
|
63
|
+
# If RGBW is 0, set default red color (255, 0, 0, 0)
|
|
64
|
+
if rgbw_value == 0:
|
|
65
|
+
self.rgdb = 0xFF000000 # Red in int: 4278190080
|
|
66
|
+
else:
|
|
67
|
+
self.rgdb = rgbw_value
|
|
68
|
+
|
|
61
69
|
rgbw = ctypes.c_uint32(self.rgdb).value
|
|
62
70
|
r = (rgbw >> 24) & 0xFF
|
|
63
71
|
g = (rgbw >> 16) & 0xFF
|
|
@@ -114,6 +122,7 @@ class DeviceClient(object):
|
|
|
114
122
|
_ping_timer: Any = None
|
|
115
123
|
writer: Any = None
|
|
116
124
|
reader: Any = None
|
|
125
|
+
syncProperties = [CONF_ON_OFF, CONF_DIMMING, CONF_RGBW, CONF_CCT]
|
|
117
126
|
_TAG: str = "DeviceClient"
|
|
118
127
|
@property
|
|
119
128
|
def connect_and_login(self) -> bool:
|
|
@@ -238,7 +247,7 @@ class DeviceClient(object):
|
|
|
238
247
|
self._reconnect_handle = None
|
|
239
248
|
self._schedule_ping()
|
|
240
249
|
_LOGGER.warning(f"{self._TAG}:connect success: {self._ip_address}")
|
|
241
|
-
await self.send_action(
|
|
250
|
+
await self.send_action(self.syncProperties, CONF_GET_DEV_ATTR_REQ)
|
|
242
251
|
except (BrokenPipeError, ConnectionResetError, Exception) as e:
|
|
243
252
|
_LOGGER.error(f"{self.device_id} login read status error {e}")
|
|
244
253
|
|
|
@@ -286,7 +295,10 @@ class DeviceClient(object):
|
|
|
286
295
|
async def send_dev_attr(self, dev_attr) -> None:
|
|
287
296
|
if not self._connect_and_login:
|
|
288
297
|
raise ConnectionError('Device offline')
|
|
289
|
-
|
|
298
|
+
if not self.status.on and not CONF_ON_OFF in dev_attr:
|
|
299
|
+
self.status.on = True
|
|
300
|
+
attr[CONF_ON_OFF] = 1
|
|
301
|
+
await self.send_action(dev_attr, CONF_SET_DEV_ATTR_REQ)
|
|
290
302
|
|
|
291
303
|
async def async_turn_off(self) -> None:
|
|
292
304
|
await self.send_dev_attr({CONF_ON_OFF: 0})
|
|
@@ -309,9 +321,6 @@ class DeviceClient(object):
|
|
|
309
321
|
current_timestamp_milliseconds = int(time.time() * 1000)
|
|
310
322
|
self.seq_num += 1
|
|
311
323
|
seq = "ha93" + str(self.seq_num).zfill(5)
|
|
312
|
-
if not self.status.on and not CONF_ON_OFF in attr:
|
|
313
|
-
self.status.on = True
|
|
314
|
-
attr[CONF_ON_OFF] = 1
|
|
315
324
|
|
|
316
325
|
if self._simpleVersion is not None:
|
|
317
326
|
action = {
|
|
@@ -320,7 +329,7 @@ class DeviceClient(object):
|
|
|
320
329
|
"clientId": "ha-" + self.user_id,
|
|
321
330
|
"srcAddr": "0." + self.user_id,
|
|
322
331
|
"seq": "" + seq,
|
|
323
|
-
|
|
332
|
+
CONF_PAYLOAD: {
|
|
324
333
|
"devId": self.device_id,
|
|
325
334
|
"parentId": self.device_id,
|
|
326
335
|
"userId": self.user_id,
|
|
@@ -338,14 +347,14 @@ class DeviceClient(object):
|
|
|
338
347
|
"service": "device",
|
|
339
348
|
"seq": "" + seq,
|
|
340
349
|
"srcAddr": "0." + self.user_id,
|
|
341
|
-
|
|
350
|
+
CONF_PAYLOAD: {
|
|
342
351
|
"attr": attr,
|
|
343
352
|
"ascNumber": self.ascNumber,
|
|
344
353
|
},
|
|
345
354
|
"tst": current_timestamp_milliseconds,
|
|
346
355
|
"deviceId": self.device_id,
|
|
347
356
|
}
|
|
348
|
-
|
|
357
|
+
_LOGGER.warning(f"{self.device_id} send_action {action}")
|
|
349
358
|
try:
|
|
350
359
|
self.writer.write(self.get_send_packet(json.dumps(action).encode(), 1))
|
|
351
360
|
await self.writer.drain()
|
|
@@ -362,10 +371,10 @@ class DeviceClient(object):
|
|
|
362
371
|
"service": "test",
|
|
363
372
|
"method": "pingreq",
|
|
364
373
|
"seq": "123456",
|
|
365
|
-
"srcAddr": "
|
|
374
|
+
"srcAddr": "123456",
|
|
366
375
|
CONF_PAYLOAD: {},
|
|
367
376
|
}
|
|
368
|
-
_LOGGER.
|
|
377
|
+
_LOGGER.warning(f"{self.device_id} send_ping_action {ping}")
|
|
369
378
|
try:
|
|
370
379
|
if self.ping_count >= 3:
|
|
371
380
|
_LOGGER.error(
|
|
@@ -378,6 +387,7 @@ class DeviceClient(object):
|
|
|
378
387
|
self.writer.write(self.get_send_packet(json.dumps(ping).encode(), 2))
|
|
379
388
|
await self.writer.drain()
|
|
380
389
|
self.ping_count += 1
|
|
390
|
+
await self.send_action(self.syncProperties, CONF_GET_DEV_ATTR_REQ)
|
|
381
391
|
return 1
|
|
382
392
|
except Exception as e:
|
|
383
393
|
_LOGGER.error(f"{self.device_id} ping error {e}")
|
|
@@ -12,7 +12,7 @@ from .exceptions import AidotOSError
|
|
|
12
12
|
_LOGGER = logging.getLogger(__name__)
|
|
13
13
|
# _DISCOVER_TIME = 15
|
|
14
14
|
|
|
15
|
-
_DISCOVER_FAST =
|
|
15
|
+
_DISCOVER_FAST = 6 # 启动时快速发现
|
|
16
16
|
_DISCOVER_SLOW = 120 # 稳定后慢速维持
|
|
17
17
|
|
|
18
18
|
class BroadcastProtocol:
|
|
@@ -111,7 +111,7 @@ class Discover:
|
|
|
111
111
|
|
|
112
112
|
def start_repeat_broadcast(self) -> None:
|
|
113
113
|
self._is_close = False
|
|
114
|
-
self._fast_discover_count =
|
|
114
|
+
self._fast_discover_count = 5 # 前5次快速
|
|
115
115
|
self._schedule_broadcast()
|
|
116
116
|
|
|
117
117
|
def _schedule_broadcast(self) -> None:
|
|
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
|