python-aidot 0.3.53__tar.gz → 0.3.54b2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-aidot
3
- Version: 0.3.53
3
+ Version: 0.3.54b2
4
4
  Summary: aidot control wifi lights
5
5
  Home-page: https://github.com/Aidot-Development-Team/python-aidot
6
6
  Author: aidotdev2024
@@ -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 = None
48
- rgbw: tuple[int, int, int, int] = None
49
- cct: int = None
50
- dimming: int = None
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
- self.rgdb = attr.get(CONF_RGBW)
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,9 @@ 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]
126
+ heart_time = 10
127
+ # syncProperties = []
117
128
  _TAG: str = "DeviceClient"
118
129
  @property
119
130
  def connect_and_login(self) -> bool:
@@ -139,7 +150,10 @@ class DeviceClient(object):
139
150
  self.password = device.get(CONF_PASSWORD)
140
151
  self.device_id = device.get(CONF_ID)
141
152
  self._simpleVersion = device.get("simpleVersion")
142
- self._TAG = f"{self.device_id}";
153
+ self._TAG = f"{self.device_id}"
154
+ # if self.info.model_id == 'lk.WIFI-RGBWLight-D0006':
155
+ # self.syncProperties = [CONF_ON_OFF, CONF_DIMMING, CONF_RGBW, CONF_CCT]
156
+
143
157
  _LOGGER.warning(f"{self._TAG}:{device}")
144
158
 
145
159
  async def connect(self, ip_address) -> None:
@@ -227,6 +241,7 @@ class DeviceClient(object):
227
241
 
228
242
  self.ascNumber = json_data[CONF_PAYLOAD][CONF_ASCNUMBER] + 1
229
243
  self.status.online = True
244
+ self._notify_status_update()
230
245
  self._receive_task = asyncio.create_task(
231
246
  self.receive_data(),
232
247
  name=f"aidot_receive_{self.device_id}"
@@ -238,7 +253,7 @@ class DeviceClient(object):
238
253
  self._reconnect_handle = None
239
254
  self._schedule_ping()
240
255
  _LOGGER.warning(f"{self._TAG}:connect success: {self._ip_address}")
241
- await self.send_action({}, "getDevAttrReq")
256
+ await self.send_action(self.syncProperties, CONF_GET_DEV_ATTR_REQ)
242
257
  except (BrokenPipeError, ConnectionResetError, Exception) as e:
243
258
  _LOGGER.error(f"{self.device_id} login read status error {e}")
244
259
 
@@ -281,12 +296,15 @@ class DeviceClient(object):
281
296
  def _schedule_ping(self):
282
297
  loop = asyncio.get_running_loop()
283
298
  loop.create_task(self.send_ping_action())
284
- self._ping_timer = loop.call_later(30, self._schedule_ping)
299
+ self._ping_timer = loop.call_later(self.heart_time, self._schedule_ping)
285
300
 
286
301
  async def send_dev_attr(self, dev_attr) -> None:
287
302
  if not self._connect_and_login:
288
303
  raise ConnectionError('Device offline')
289
- await self.send_action(dev_attr, "setDevAttrReq")
304
+ if not self.status.on and not CONF_ON_OFF in dev_attr:
305
+ self.status.on = True
306
+ attr[CONF_ON_OFF] = 1
307
+ await self.send_action(dev_attr, CONF_SET_DEV_ATTR_REQ)
290
308
 
291
309
  async def async_turn_off(self) -> None:
292
310
  await self.send_dev_attr({CONF_ON_OFF: 0})
@@ -309,9 +327,6 @@ class DeviceClient(object):
309
327
  current_timestamp_milliseconds = int(time.time() * 1000)
310
328
  self.seq_num += 1
311
329
  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
330
 
316
331
  if self._simpleVersion is not None:
317
332
  action = {
@@ -320,7 +335,7 @@ class DeviceClient(object):
320
335
  "clientId": "ha-" + self.user_id,
321
336
  "srcAddr": "0." + self.user_id,
322
337
  "seq": "" + seq,
323
- "payload": {
338
+ CONF_PAYLOAD: {
324
339
  "devId": self.device_id,
325
340
  "parentId": self.device_id,
326
341
  "userId": self.user_id,
@@ -338,14 +353,14 @@ class DeviceClient(object):
338
353
  "service": "device",
339
354
  "seq": "" + seq,
340
355
  "srcAddr": "0." + self.user_id,
341
- "payload": {
356
+ CONF_PAYLOAD: {
342
357
  "attr": attr,
343
358
  "ascNumber": self.ascNumber,
344
359
  },
345
360
  "tst": current_timestamp_milliseconds,
346
361
  "deviceId": self.device_id,
347
362
  }
348
-
363
+ _LOGGER.warning(f"{self.device_id} send_action {action}")
349
364
  try:
350
365
  self.writer.write(self.get_send_packet(json.dumps(action).encode(), 1))
351
366
  await self.writer.drain()
@@ -362,10 +377,10 @@ class DeviceClient(object):
362
377
  "service": "test",
363
378
  "method": "pingreq",
364
379
  "seq": "123456",
365
- "srcAddr": "x.xxxxxxx",
380
+ "srcAddr": "123456",
366
381
  CONF_PAYLOAD: {},
367
382
  }
368
- _LOGGER.info(f"{self.device_id} send_ping_action {ping}")
383
+ _LOGGER.warning(f"{self.device_id} send_ping_action {ping}")
369
384
  try:
370
385
  if self.ping_count >= 3:
371
386
  _LOGGER.error(
@@ -375,9 +390,10 @@ class DeviceClient(object):
375
390
  return -1
376
391
  if self._connect_and_login is False:
377
392
  return -1
378
- self.writer.write(self.get_send_packet(json.dumps(ping).encode(), 2))
379
- await self.writer.drain()
393
+ # self.writer.write(self.get_send_packet(json.dumps(ping).encode(), 2))
394
+ # await self.writer.drain()
380
395
  self.ping_count += 1
396
+ await self.send_action(self.syncProperties, CONF_GET_DEV_ATTR_REQ)
381
397
  return 1
382
398
  except Exception as e:
383
399
  _LOGGER.error(f"{self.device_id} ping error {e}")
@@ -423,9 +439,5 @@ class DeviceClient(object):
423
439
  """延迟重连"""
424
440
  _LOGGER.info(f"{self.device_id} _schedule_reconnect")
425
441
  loop = asyncio.get_running_loop()
426
- # self._reconnect_handle = loop.call_later(
427
- # 10, # 10秒后重连
428
- # lambda: asyncio.create_task(self.async_login())
429
- # )
430
442
  self._reconnect_handle = loop.call_later(60, self._schedule_reconnect)
431
443
  self._login_task = asyncio.create_task(self.async_login())
@@ -12,7 +12,7 @@ from .exceptions import AidotOSError
12
12
  _LOGGER = logging.getLogger(__name__)
13
13
  # _DISCOVER_TIME = 15
14
14
 
15
- _DISCOVER_FAST = 10 # 启动时快速发现
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 = 3 # 前三次快速
114
+ self._fast_discover_count = 5 # 前5次快速
115
115
  self._schedule_broadcast()
116
116
 
117
117
  def _schedule_broadcast(self) -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-aidot
3
- Version: 0.3.53
3
+ Version: 0.3.54b2
4
4
  Summary: aidot control wifi lights
5
5
  Home-page: https://github.com/Aidot-Development-Team/python-aidot
6
6
  Author: aidotdev2024
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="python-aidot",
8
- version="0.3.53",
8
+ version="0.3.54b2",
9
9
  author="aidotdev2024",
10
10
  url='https://github.com/Aidot-Development-Team/python-aidot',
11
11
  description="aidot control wifi lights",
File without changes
File without changes
File without changes