mijiaAPI 1.4.2__tar.gz → 1.4.4__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.3
2
2
  Name: mijiaAPI
3
- Version: 1.4.2
3
+ Version: 1.4.4
4
4
  Summary: A Python API for Xiaomi Mijia
5
5
  License: GPLv3
6
6
  Author: Do1e
@@ -271,6 +271,19 @@ def set(args):
271
271
 
272
272
  def main(args):
273
273
  args = parse_args(args)
274
+
275
+ if args.get_device_info:
276
+ device_info = get_device_info(args.get_device_info)
277
+ print(json.dumps(device_info, indent=2, ensure_ascii=False))
278
+ if not (args.list_devices or
279
+ args.list_homes or
280
+ args.list_scenes or
281
+ args.list_consumable_items or
282
+ args.run_scene or
283
+ args.run or
284
+ hasattr(args, 'func') and args.func is not None):
285
+ return
286
+
274
287
  api = init_api(args.auth_path)
275
288
  device_mapping = None
276
289
  home_mapping = None
@@ -287,9 +300,6 @@ def main(args):
287
300
  if args.run_scene:
288
301
  for scene_id in args.run_scene:
289
302
  run_scene(api, scene_id, scene_mapping=scenes_mapping)
290
- if args.get_device_info:
291
- device_info = get_device_info(args.get_device_info)
292
- print(json.dumps(device_info, indent=2, ensure_ascii=False))
293
303
  if args.run:
294
304
  if device_mapping is None:
295
305
  device_mapping = get_devices_list(api, verbose=False)
@@ -7,7 +7,9 @@ from time import sleep
7
7
  from .apis import mijiaAPI
8
8
  from .code import ERROR_CODE
9
9
  from .urls import deviceURL
10
- from .logger import logger
10
+ from .logger import get_logger
11
+
12
+ logger = get_logger(__name__)
11
13
 
12
14
  class DevProp(object):
13
15
  def __init__(self, prop_dict: dict):
@@ -170,7 +172,7 @@ class mijiaDevices(object):
170
172
  raise ValueError(f'Unsupported property: {name}, available properties: {list(self.prop_list.keys())}')
171
173
  prop = self.prop_list[name]
172
174
  if 'w' not in prop.rw:
173
- raise ValueError(f'Property {name} is read-only')
175
+ raise ValueError(f'Property {name} can not be written')
174
176
  if prop.value_list:
175
177
  if value not in [item['value'] for item in prop.value_list]:
176
178
  raise ValueError(f'Invalid value: {value}, should be in {prop.value_list}')
@@ -227,6 +229,7 @@ class mijiaDevices(object):
227
229
  f"message: {ERROR_CODE.get(str(result['code']), 'Unknown error')}"
228
230
  )
229
231
  sleep(self.sleep_time)
232
+ logger.debug(f"Set property: {self.name} -> {name}, value: {value}, result: {result}")
230
233
  return result['code'] == 0
231
234
 
232
235
  def set_v2(self, name: str, value: Union[bool, int, float, str], did: Optional[str] = None) -> bool:
@@ -274,7 +277,7 @@ class mijiaDevices(object):
274
277
  raise ValueError(f'Unsupported property: {name}, available properties: {list(self.prop_list.keys())}')
275
278
  prop = self.prop_list[name]
276
279
  if 'r' not in prop.rw:
277
- raise ValueError(f'Property {name} is write-only')
280
+ raise ValueError(f'Property {name} can not be read')
278
281
  method = prop.method.copy()
279
282
  method['did'] = did
280
283
  result = self.api.get_devices_prop([method])[0]
@@ -285,6 +288,7 @@ class mijiaDevices(object):
285
288
  f"message: {ERROR_CODE.get(str(result['code']), 'Unknown error')}"
286
289
  )
287
290
  sleep(self.sleep_time)
291
+ logger.debug(f"Get property: {self.name} -> {name}, result: {result}")
288
292
  return result['value']
289
293
 
290
294
  def __setattr__(self, name: str, value: Union[bool, int, float, str]) -> None:
@@ -368,6 +372,7 @@ class mijiaDevices(object):
368
372
  f"message: {ERROR_CODE.get(str(result['code']), 'Unknown error')}"
369
373
  )
370
374
  sleep(self.sleep_time)
375
+ logger.debug(f"Run action: {self.name} -> {name}, result: {result}")
371
376
  return result['code'] == 0
372
377
 
373
378
 
@@ -399,9 +404,15 @@ def get_device_info(device_model: str, cache_path: Optional[str] = os.path.join(
399
404
  content = content.group(1)
400
405
  content = json.loads(content.replace('"', '"'))
401
406
 
407
+ if content['props']['product']:
408
+ name = content['props']['product']['name']
409
+ model = content['props']['product']['model']
410
+ else:
411
+ name = content['props']['spec']['name']
412
+ model = device_model
402
413
  result = {
403
- 'name': content['props']['product']['name'],
404
- 'model': content['props']['product']['model'],
414
+ 'name': name,
415
+ 'model': model,
405
416
  'properties': [],
406
417
  'actions': []
407
418
  }
@@ -421,7 +432,7 @@ def get_device_info(device_model: str, cache_path: Optional[str] = os.path.join(
421
432
  prop_type = prop['format']
422
433
  item = {
423
434
  'name': prop['name'],
424
- 'description': prop['description'],
435
+ 'description': f"{prop.get('description', '')} / {prop.get('desc_zh_cn', '')}",
425
436
  'type': prop_type,
426
437
  'rw': ''.join([
427
438
  'r' if 'read' in prop['access'] else '',
@@ -447,7 +458,7 @@ def get_device_info(device_model: str, cache_path: Optional[str] = os.path.join(
447
458
  actions_name.append(act['name'])
448
459
  result['actions'].append({
449
460
  'name': act['name'],
450
- 'description': act['description'],
461
+ 'description': f"{act.get('description', '')} / {act.get('desc_zh_cn', '')}",
451
462
  'method': {
452
463
  'siid': int(siid),
453
464
  'aiid': int(aiid)
@@ -22,16 +22,24 @@ class ColorFormatter(logging.Formatter):
22
22
  return f"{color_code}{log_message}{self.COLORS['RESET']}"
23
23
  return log_message
24
24
 
25
- logger = logging.getLogger('mijiaAPI')
26
- logger.setLevel(logging.INFO)
25
+ def get_logger(name: str) -> logging.Logger:
26
+ """
27
+ 获取指定名称的日志记录器。
27
28
 
28
- console_handler = logging.StreamHandler()
29
- console_handler.setLevel(logging.INFO)
29
+ Args:
30
+ name (str): 日志记录器的名称。
30
31
 
31
- formatter = ColorFormatter(
32
- '%(asctime)s - %(name)s - %(levelname)s: %(message)s',
33
- datefmt='%Y-%m-%d %H:%M:%S',
34
- )
35
- console_handler.setFormatter(formatter)
32
+ Returns:
33
+ logging.Logger: 日志记录器对象。
34
+ """
35
+ logger = logging.getLogger(name)
36
36
 
37
- logger.addHandler(console_handler)
37
+ console_handler = logging.StreamHandler()
38
+
39
+ formatter = ColorFormatter(
40
+ '%(asctime)s - %(name)s - %(levelname)s: %(message)s',
41
+ datefmt='%Y-%m-%d %H:%M:%S',
42
+ )
43
+ console_handler.setFormatter(formatter)
44
+ logger.addHandler(console_handler)
45
+ return logger
@@ -12,10 +12,11 @@ from urllib import parse
12
12
  import requests
13
13
  from qrcode import QRCode
14
14
 
15
- from .logger import logger
15
+ from .logger import get_logger
16
16
  from .urls import msgURL, loginURL, qrURL, accountURL
17
17
  from .utils import defaultUA
18
18
 
19
+ logger = get_logger(__name__)
19
20
 
20
21
  class LoginError(Exception):
21
22
  def __init__(self, code: int, message: str):
@@ -97,7 +98,7 @@ class mijiaLogin(object):
97
98
  return data
98
99
 
99
100
  @staticmethod
100
- def extract_latest_gmt_datetime(data: dict) -> datetime:
101
+ def _extract_latest_gmt_datetime(data: dict) -> datetime:
101
102
  """
102
103
  提取过期时间并转换为中国时区。
103
104
 
@@ -157,8 +158,7 @@ class mijiaLogin(object):
157
158
  Raises:
158
159
  LoginError: 登录失败时抛出。
159
160
  """
160
- logger.warning(
161
- 'There is a high probability of verification code with account and password. Please try other login methods')
161
+ logger.warning('There is a high probability of verification code with account and password. Please try `QRlogin` method.')
162
162
  data = self._get_index()
163
163
  post_data = {
164
164
  'qs': data['qs'],
@@ -178,7 +178,7 @@ class mijiaLogin(object):
178
178
  if 'location' not in ret_data:
179
179
  raise LoginError(-1, 'Failed to get location')
180
180
  if 'notificationUrl' in ret_data:
181
- raise LoginError(-1, 'Verification code required, please try other login methods')
181
+ raise LoginError(-1, 'Verification code required, please try `QRlogin` method')
182
182
  ret = self.session.get(ret_data['location'])
183
183
  if ret.status_code != 200:
184
184
  raise LoginError(ret.status_code, f'Failed to get location, {ret.text}')
@@ -189,7 +189,7 @@ class mijiaLogin(object):
189
189
  'ssecurity': ret_data['ssecurity'],
190
190
  'deviceId': data['deviceId'],
191
191
  'serviceToken': cookies['serviceToken'],
192
- 'expireTime': self.extract_latest_gmt_datetime(cookies).strftime('%Y-%m-%d %H:%M:%S'),
192
+ 'expireTime': self._extract_latest_gmt_datetime(cookies).strftime('%Y-%m-%d %H:%M:%S'),
193
193
  **self._get_account(ret_data['userId'])
194
194
  }
195
195
 
@@ -274,7 +274,7 @@ class mijiaLogin(object):
274
274
  'ssecurity': ret_data['ssecurity'],
275
275
  'deviceId': data['deviceId'],
276
276
  'serviceToken': cookies['serviceToken'],
277
- 'expireTime': self.extract_latest_gmt_datetime(cookies).strftime('%Y-%m-%d %H:%M:%S'),
277
+ 'expireTime': self._extract_latest_gmt_datetime(cookies).strftime('%Y-%m-%d %H:%M:%S'),
278
278
  **self._get_account(ret_data['userId'])
279
279
  }
280
280
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mijiaAPI"
3
- version = "1.4.2"
3
+ version = "1.4.4"
4
4
  description = "A Python API for Xiaomi Mijia"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9,<4.0"
@@ -15,7 +15,7 @@ mijiaAPI = "mijiaAPI.__main__:cli"
15
15
 
16
16
  [tool.poetry]
17
17
  name = "mijiaAPI"
18
- version = "1.4.2"
18
+ version = "1.4.4"
19
19
  description = "A Python API for Xiaomi Mijia"
20
20
  authors = ["Do1e <dpj.email@qq.com>"]
21
21
  license = "GPLv3"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes