mijiaAPI 3.0.5__tar.gz → 3.2.0__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.
Files changed (28) hide show
  1. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/CHANGELOG.md +12 -0
  2. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/PKG-INFO +30 -20
  3. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/README.md +29 -19
  4. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI/__main__.py +43 -21
  5. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI/devices.py +65 -55
  6. mijiaapi-3.2.0/mijiaAPI/version.py +1 -0
  7. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI.egg-info/PKG-INFO +30 -20
  8. mijiaapi-3.0.5/mijiaAPI/version.py +0 -1
  9. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  10. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/.gitignore +0 -0
  11. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/FAQ.md +0 -0
  12. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/LICENSE +0 -0
  13. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/demos/test_apis.py +0 -0
  14. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/demos/test_get_statistics.py +0 -0
  15. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/demos/test_login.py +0 -0
  16. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI/__init__.py +0 -0
  17. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI/apis.py +0 -0
  18. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI/errors.py +0 -0
  19. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI/logger.py +0 -0
  20. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI/miutils.py +0 -0
  21. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI.egg-info/SOURCES.txt +0 -0
  22. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI.egg-info/dependency_links.txt +0 -0
  23. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI.egg-info/entry_points.txt +0 -0
  24. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI.egg-info/requires.txt +0 -0
  25. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/mijiaAPI.egg-info/top_level.txt +0 -0
  26. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/pyproject.toml +0 -0
  27. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/setup.cfg +0 -0
  28. {mijiaapi-3.0.5 → mijiaapi-3.2.0}/uv.lock +0 -0
@@ -2,6 +2,18 @@
2
2
 
3
3
  本文档记录了项目的v1.3.7以来的重要变更。
4
4
 
5
+ ## [3.2.0](https://github.com/Do1e/mijia-api/compare/v3.1.0...v3.2.0) - 2026-06-09
6
+ ### improvement
7
+ * 将 `--run` 参数重构为独立的 `run` 子命令,提升 CLI 结构一致性
8
+ * 保留 `--run` 作为隐藏的废弃参数,并显示迁移提示
9
+
10
+ ## [3.1.0](https://github.com/Do1e/mijia-api/compare/v3.0.5...v3.1.0) - 2026-05-27
11
+ ### new feature
12
+ * 删除设备属性的单位`unit`属性,因为 home.miot-spec.com 上已废弃
13
+ ### bugfix
14
+ * 适配 home.miot-spec.com 新的规格页格式
15
+ * 修复 execute-text-directive 中 quiet 参数的类型转换
16
+
5
17
  ## [3.0.5](https://github.com/Do1e/mijia-api/compare/v3.0.4...v3.0.5) - 2026-01-24
6
18
  ### bugfix
7
19
  * 蓝牙设备控制返回 code 为 1 时表示网关已经接收指令,视为成功。
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mijiaAPI
3
- Version: 3.0.5
3
+ Version: 3.2.0
4
4
  Summary: A Python API for Xiaomi Mijia
5
5
  Author-email: Do1e <i@do1e.cn>
6
6
  License-Expression: GPL-3.0-or-later
@@ -26,12 +26,6 @@ Dynamic: license-file
26
26
  [![PyPI](https://img.shields.io/badge/PyPI-mijiaAPI-blue)](https://pypi.org/project/mijiaAPI/)
27
27
  [![License: GPL-3.0](https://img.shields.io/badge/License-GPL--3.0-green.svg)](https://opensource.org/licenses/GPL-3.0)
28
28
 
29
- ## ⚠️ 重要提醒
30
-
31
- **v1.5.0 和 v3.0.0包含多项破坏性变更!**
32
-
33
- 如果您正在从旧版本升级,请务必查看 [CHANGELOG.md](CHANGELOG.md) 以了解详细的变更内容和迁移指南。
34
-
35
29
  常见问题见 [FAQ.md](FAQ.md)。
36
30
 
37
31
  ## 安装
@@ -365,14 +359,17 @@ MIJIA_LOG_LEVEL=WARNING mijiaAPI get --dev_name "卧室台灯" --prop_name "brig
365
359
  完整的命令行参数说明:
366
360
 
367
361
  ```
368
- usage: mijiaAPI [-h] [-p AUTH_PATH] [--list_homes] [-l] [--list_scenes]
369
- [--list_consumable_items] [--run_scene SCENE_ID/SCENE_NAME ...]
370
- [--get_device_info DEVICE_MODEL] [--run PROMPT]
371
- [--wifispeaker_name WIFISPEAKER_NAME] [--quiet]
372
- {get,set} ...
362
+ usage: mijiaAPI [-h] [-v] [-p AUTH_PATH] [--list_homes] [-l]
363
+ [--list_scenes] [--list_consumable_items]
364
+ [--run_scene SCENE_ID/SCENE_NAME [SCENE_ID/SCENE_NAME ...]]
365
+ [--get_device_info DEVICE_MODEL]
366
+ {run,get,set} ...
367
+
368
+ Mijia API CLI (v3.1.0)
373
369
 
374
370
  positional arguments:
375
- {get,set}
371
+ {run,get,set}
372
+ run 使用自然语言描述你的需求,如果你有小爱音箱的话
376
373
  get 获取设备属性
377
374
  set 设置设备属性
378
375
 
@@ -390,10 +387,6 @@ options:
390
387
  运行场景,指定场景ID或名称
391
388
  --get_device_info DEVICE_MODEL
392
389
  获取设备信息,指定设备model,先使用 --list_devices 获取
393
- --run PROMPT 使用自然语言描述你的需求,如果你有小爱音箱的话
394
- --wifispeaker_name WIFISPEAKER_NAME
395
- 指定小爱音箱名称,默认是获取到的第一个小爱音箱
396
- --quiet 小爱音箱静默执行
397
390
  ```
398
391
 
399
392
  ```
@@ -423,6 +416,23 @@ options:
423
416
  --value VALUE 需要设定的属性值
424
417
  ```
425
418
 
419
+ ```
420
+ usage: mijiaAPI run [-h] [-p AUTH_PATH]
421
+ [--wifispeaker_name WIFISPEAKER_NAME] [--quiet]
422
+ PROMPT
423
+
424
+ positional arguments:
425
+ PROMPT 使用自然语言描述你的需求
426
+
427
+ options:
428
+ -h, --help show this help message and exit
429
+ -p, --auth_path AUTH_PATH
430
+ 认证文件保存路径,默认保存在 ~/.config/mijia-api/auth.json
431
+ --wifispeaker_name WIFISPEAKER_NAME
432
+ 指定小爱音箱名称,默认是获取到的第一个小爱音箱
433
+ --quiet 小爱音箱静默执行
434
+ ```
435
+
426
436
  #### 获取设备属性
427
437
 
428
438
  ```bash
@@ -471,9 +481,9 @@ mijiaAPI --get_device_info yeelink.light.lamp4
471
481
  mijiaAPI --list_consumable_items
472
482
 
473
483
  # 使用小爱音箱执行自然语言命令
474
- mijiaAPI --run "打开卧室台灯"
475
- mijiaAPI --run "把亮度调到50%" --wifispeaker_name "卧室小爱"
476
- mijiaAPI --run "关闭所有灯" --quiet
484
+ mijiaAPI run "打开卧室台灯"
485
+ mijiaAPI run "把亮度调到50%" --wifispeaker_name "卧室小爱"
486
+ mijiaAPI run "关闭所有灯" --quiet
477
487
  ```
478
488
 
479
489
  #### 直接使用 uvx(无需安装)
@@ -6,12 +6,6 @@
6
6
  [![PyPI](https://img.shields.io/badge/PyPI-mijiaAPI-blue)](https://pypi.org/project/mijiaAPI/)
7
7
  [![License: GPL-3.0](https://img.shields.io/badge/License-GPL--3.0-green.svg)](https://opensource.org/licenses/GPL-3.0)
8
8
 
9
- ## ⚠️ 重要提醒
10
-
11
- **v1.5.0 和 v3.0.0包含多项破坏性变更!**
12
-
13
- 如果您正在从旧版本升级,请务必查看 [CHANGELOG.md](CHANGELOG.md) 以了解详细的变更内容和迁移指南。
14
-
15
9
  常见问题见 [FAQ.md](FAQ.md)。
16
10
 
17
11
  ## 安装
@@ -345,14 +339,17 @@ MIJIA_LOG_LEVEL=WARNING mijiaAPI get --dev_name "卧室台灯" --prop_name "brig
345
339
  完整的命令行参数说明:
346
340
 
347
341
  ```
348
- usage: mijiaAPI [-h] [-p AUTH_PATH] [--list_homes] [-l] [--list_scenes]
349
- [--list_consumable_items] [--run_scene SCENE_ID/SCENE_NAME ...]
350
- [--get_device_info DEVICE_MODEL] [--run PROMPT]
351
- [--wifispeaker_name WIFISPEAKER_NAME] [--quiet]
352
- {get,set} ...
342
+ usage: mijiaAPI [-h] [-v] [-p AUTH_PATH] [--list_homes] [-l]
343
+ [--list_scenes] [--list_consumable_items]
344
+ [--run_scene SCENE_ID/SCENE_NAME [SCENE_ID/SCENE_NAME ...]]
345
+ [--get_device_info DEVICE_MODEL]
346
+ {run,get,set} ...
347
+
348
+ Mijia API CLI (v3.1.0)
353
349
 
354
350
  positional arguments:
355
- {get,set}
351
+ {run,get,set}
352
+ run 使用自然语言描述你的需求,如果你有小爱音箱的话
356
353
  get 获取设备属性
357
354
  set 设置设备属性
358
355
 
@@ -370,10 +367,6 @@ options:
370
367
  运行场景,指定场景ID或名称
371
368
  --get_device_info DEVICE_MODEL
372
369
  获取设备信息,指定设备model,先使用 --list_devices 获取
373
- --run PROMPT 使用自然语言描述你的需求,如果你有小爱音箱的话
374
- --wifispeaker_name WIFISPEAKER_NAME
375
- 指定小爱音箱名称,默认是获取到的第一个小爱音箱
376
- --quiet 小爱音箱静默执行
377
370
  ```
378
371
 
379
372
  ```
@@ -403,6 +396,23 @@ options:
403
396
  --value VALUE 需要设定的属性值
404
397
  ```
405
398
 
399
+ ```
400
+ usage: mijiaAPI run [-h] [-p AUTH_PATH]
401
+ [--wifispeaker_name WIFISPEAKER_NAME] [--quiet]
402
+ PROMPT
403
+
404
+ positional arguments:
405
+ PROMPT 使用自然语言描述你的需求
406
+
407
+ options:
408
+ -h, --help show this help message and exit
409
+ -p, --auth_path AUTH_PATH
410
+ 认证文件保存路径,默认保存在 ~/.config/mijia-api/auth.json
411
+ --wifispeaker_name WIFISPEAKER_NAME
412
+ 指定小爱音箱名称,默认是获取到的第一个小爱音箱
413
+ --quiet 小爱音箱静默执行
414
+ ```
415
+
406
416
  #### 获取设备属性
407
417
 
408
418
  ```bash
@@ -451,9 +461,9 @@ mijiaAPI --get_device_info yeelink.light.lamp4
451
461
  mijiaAPI --list_consumable_items
452
462
 
453
463
  # 使用小爱音箱执行自然语言命令
454
- mijiaAPI --run "打开卧室台灯"
455
- mijiaAPI --run "把亮度调到50%" --wifispeaker_name "卧室小爱"
456
- mijiaAPI --run "关闭所有灯" --quiet
464
+ mijiaAPI run "打开卧室台灯"
465
+ mijiaAPI run "把亮度调到50%" --wifispeaker_name "卧室小爱"
466
+ mijiaAPI run "关闭所有灯" --quiet
457
467
  ```
458
468
 
459
469
  #### 直接使用 uvx(无需安装)
@@ -69,16 +69,36 @@ def parse_args(args):
69
69
  parser.add_argument(
70
70
  '--run',
71
71
  type=str,
72
+ help=argparse.SUPPRESS,
73
+ nargs='?',
74
+ default=None,
75
+ metavar='PROMPT',
76
+ )
77
+
78
+ run = subparsers.add_parser(
79
+ 'run',
72
80
  help="使用自然语言描述你的需求,如果你有小爱音箱的话",
81
+ )
82
+ run.set_defaults(func='run')
83
+ run.add_argument(
84
+ '-p', '--auth_path',
85
+ type=Path,
86
+ default=Path.home() / ".config" / "mijia-api" / "auth.json",
87
+ help="认证文件保存路径,默认保存在 ~/.config/mijia-api/auth.json",
88
+ )
89
+ run.add_argument(
90
+ 'prompt',
91
+ type=str,
92
+ help="使用自然语言描述你的需求",
73
93
  metavar='PROMPT',
74
94
  )
75
- parser.add_argument(
95
+ run.add_argument(
76
96
  '--wifispeaker_name',
77
97
  type=str,
78
98
  help="指定小爱音箱名称,默认是获取到的第一个小爱音箱",
79
99
  default=None,
80
100
  )
81
- parser.add_argument(
101
+ run.add_argument(
82
102
  '--quiet',
83
103
  action='store_true',
84
104
  help="小爱音箱静默执行",
@@ -265,8 +285,7 @@ def get(args):
265
285
  api = init_api(args.auth_path)
266
286
  device = mijiaDevice(api, did=args.did, dev_name=args.dev_name)
267
287
  value = device.get(args.prop_name)
268
- unit = device.prop_list[args.prop_name].unit
269
- print(f"{device.name} ({device.did}) 的 {args.prop_name} 值为 {value} {unit if unit else ''}")
288
+ print(f"{device.name} ({device.did}) 的 {args.prop_name} 值为 {value}")
270
289
 
271
290
  def set(args):
272
291
  api = init_api(args.auth_path)
@@ -276,12 +295,16 @@ def set(args):
276
295
  except Exception as e:
277
296
  print(f"设置 {args.dev_name} 的 {args.prop_name} 值为 {args.value} 失败: {e}")
278
297
  return
279
- unit = device.prop_list[args.prop_name].unit
280
- print(f"{device.name} ({device.did}) 的 {args.prop_name} 值已设置为 {args.value} {unit if unit else ''}")
298
+ print(f"{device.name} ({device.did}) 的 {args.prop_name} 值已设置为 {args.value}")
281
299
 
282
300
  def main(args):
283
301
  args = parse_args(args)
284
302
 
303
+ if args.run is not None:
304
+ print("错误: '--run' 参数已弃用,请使用 'run' 子命令代替。")
305
+ print(f"新用法: mijiaAPI run \"{args.run}\"")
306
+ sys.exit(1)
307
+
285
308
  if args.get_device_info:
286
309
  device_info = get_device_info(args.get_device_info)
287
310
  print(json.dumps(device_info, indent=2, ensure_ascii=False))
@@ -290,7 +313,6 @@ def main(args):
290
313
  args.list_scenes or
291
314
  args.list_consumable_items or
292
315
  args.run_scene or
293
- args.run or
294
316
  hasattr(args, 'func') and args.func is not None):
295
317
  return
296
318
 
@@ -310,25 +332,25 @@ def main(args):
310
332
  if args.run_scene:
311
333
  for scene_id in args.run_scene:
312
334
  run_scene(api, scene_id, scene_mapping=scenes_mapping)
313
- if args.run:
314
- if device_mapping is None:
315
- device_mapping = get_devices_list(api, verbose=False)
316
- if args.wifispeaker_name is None:
317
- wifispeaker = None
318
- for device in device_mapping.values():
319
- if 'xiaomi.wifispeaker' in device['model']:
320
- wifispeaker = mijiaDevice(api, dev_name=device['name'])
321
- break
322
- if wifispeaker is None:
323
- raise ValueError("未找到小爱音箱设备")
324
- else:
325
- wifispeaker = mijiaDevice(api, dev_name=args.wifispeaker_name)
326
- wifispeaker.run_action('execute-text-directive', _in=[args.run, args.quiet])
327
335
  if hasattr(args, 'func') and args.func is not None:
328
336
  if args.func == 'get':
329
337
  get(args)
330
338
  if args.func == 'set':
331
339
  set(args)
340
+ if args.func == 'run':
341
+ if device_mapping is None:
342
+ device_mapping = get_devices_list(api, verbose=False)
343
+ if args.wifispeaker_name is None:
344
+ wifispeaker = None
345
+ for device in device_mapping.values():
346
+ if 'xiaomi.wifispeaker' in device['model']:
347
+ wifispeaker = mijiaDevice(api, dev_name=device['name'])
348
+ break
349
+ if wifispeaker is None:
350
+ raise ValueError("未找到小爱音箱设备")
351
+ else:
352
+ wifispeaker = mijiaDevice(api, dev_name=args.wifispeaker_name)
353
+ wifispeaker.run_action('execute-text-directive', _in=[args.prompt, 1 if args.quiet else 0])
332
354
 
333
355
  def cli():
334
356
  main(sys.argv[1:])
@@ -30,7 +30,6 @@ class DevProp():
30
30
  if self.type not in ["bool", "int", "uint", "float", "string"]:
31
31
  raise ValueError(f"不支持的类型: {self.type}, 可选类型: bool, int, uint, float, string")
32
32
  self.rw = prop_dict["rw"]
33
- self.unit = prop_dict["unit"]
34
33
  self.range = prop_dict["range"]
35
34
  self.value_list = prop_dict.get("value-list", None)
36
35
  self.method = prop_dict["method"]
@@ -38,7 +37,7 @@ class DevProp():
38
37
  def __str__(self):
39
38
  lines = [
40
39
  f" {self.name}: {self.desc}",
41
- f" valuetype: {self.type}, rw: {self.rw}, unit: {self.unit}, range: {self.range}"
40
+ f" valuetype: {self.type}, rw: {self.rw}, range: {self.range}"
42
41
  ]
43
42
 
44
43
  if self.value_list:
@@ -260,7 +259,6 @@ def get_device_info(device_model: str, cache_path: Optional[Union[str, Path]] =
260
259
  - description (str): 属性描述
261
260
  - type (str): 属性数据类型(int、uint、float、bool、string)
262
261
  - rw (str): 读写权限('r' 可读,'w' 可写,'rw' 可读写)
263
- - unit (str): 属性单位
264
262
  - range (list): 属性值范围 [min, max, step]
265
263
  - value-list (list): 枚举值列表
266
264
  - method (dict): API 调用方法参数
@@ -288,72 +286,84 @@ def get_device_info(device_model: str, cache_path: Optional[Union[str, Path]] =
288
286
  })
289
287
  if response.status_code != 200:
290
288
  raise GetDeviceInfoError(device_model)
291
- content = re.search(r"data-page=\"(.*?)\">", response.text)
289
+ content = re.search(r"<script data-page=\"app\" type=\"application/json\">(.*?)</script>", response.text)
292
290
  if content is None:
293
291
  raise GetDeviceInfoError(device_model)
294
292
  content = content.group(1)
295
- content = json.loads(content.replace("&quot;", "\""))
296
-
297
- if content["props"]["product"]:
298
- name = content["props"]["product"]["name"]
299
- model = content["props"]["product"]["model"]
300
- else:
301
- name = content["props"]["spec"]["name"]
302
- model = device_model
293
+ content = json.loads(content)
294
+
295
+ product = content["props"]["product"]
296
+ name = product["name"]
297
+ model = product["model"]
298
+ i18n_zh = content["props"]["i18n"]["zh_cn"]
303
299
  result = {
304
300
  "name": name,
305
301
  "model": model,
306
302
  "properties": [],
307
303
  "actions": []
308
304
  }
309
- services = content["props"]["spec"]["services"]
305
+ services = content["props"]["tree"]["services"]
310
306
 
311
307
  properties_name = []
312
308
  actions_name = []
313
- for siid in services:
314
- if "properties" in services[siid]:
315
- for piid in services[siid]["properties"]:
316
- prop = services[siid]["properties"][piid]
317
- if prop["format"].startswith("int"):
318
- prop_type = "int"
319
- elif prop["format"].startswith("uint"):
320
- prop_type = "uint"
321
- else:
322
- prop_type = prop["format"]
323
- item = {
324
- "name": prop["name"],
325
- "description": f"{prop.get('description', '')} / {prop.get('desc_zh_cn', '')}",
326
- "type": prop_type,
327
- "rw": "".join([
328
- "r" if "read" in prop["access"] else "",
329
- "w" if "write" in prop["access"] else ""
330
- ]),
331
- "unit": prop.get("unit", None),
332
- "range": prop.get("value-range", None),
333
- "value-list": prop.get("value-list", None),
334
- "method": {
335
- "siid": int(siid),
336
- "piid": int(piid)
337
- }
309
+ for svc in services:
310
+ siid = svc["iid"]
311
+ svc_type = svc["type"]
312
+ for prop in svc.get("properties", []):
313
+ piid = prop["iid"]
314
+ if prop["format"].startswith("int"):
315
+ prop_type = "int"
316
+ elif prop["format"].startswith("uint"):
317
+ prop_type = "uint"
318
+ else:
319
+ prop_type = prop["format"]
320
+ access_str = "".join([
321
+ "r" if "read" in prop["access"] else "",
322
+ "w" if "write" in prop["access"] else ""
323
+ ])
324
+ zh_cn = i18n_zh.get(f"service:{siid:03d}:property:{piid:03d}", "")
325
+ item = {
326
+ "name": prop["type"],
327
+ "description": f"{prop['description']} / {zh_cn}".rstrip(" / "),
328
+ "type": prop_type,
329
+ "rw": access_str,
330
+ "range": prop.get("valueRange", None),
331
+ "value-list": None,
332
+ "method": {
333
+ "siid": siid,
334
+ "piid": piid
338
335
  }
339
- if item["name"] in properties_name:
340
- item["name"] = f"{services[siid]['name']}-{item['name']}"
341
- properties_name.append(item["name"])
342
- result["properties"].append({k: None if v == "none" else v for k, v in item.items()})
343
- if "actions" in services[siid]:
344
- for aiid in services[siid]["actions"]:
345
- act = services[siid]["actions"][aiid]
346
- if act["name"] in actions_name:
347
- act["name"] = f"{services[siid]['name']}-{act['name']}"
348
- actions_name.append(act["name"])
349
- result["actions"].append({
350
- "name": act["name"],
351
- "description": f"{act.get('description', '')} / {act.get('desc_zh_cn', '')}",
352
- "method": {
353
- "siid": int(siid),
354
- "aiid": int(aiid)
336
+ }
337
+ if prop.get("valueList"):
338
+ item["value-list"] = []
339
+ for vl_item in prop["valueList"]:
340
+ vl_zh = i18n_zh.get(vl_item.get("i18nKey", ""), "")
341
+ vl_entry = {
342
+ "value": vl_item["value"],
343
+ "description": vl_item["description"]
355
344
  }
356
- })
345
+ if vl_zh:
346
+ vl_entry["desc_zh_cn"] = vl_zh
347
+ item["value-list"].append(vl_entry)
348
+ if item["name"] in properties_name:
349
+ item["name"] = f"{svc_type}-{item['name']}"
350
+ properties_name.append(item["name"])
351
+ result["properties"].append(item)
352
+ for act in svc.get("actions", []):
353
+ aiid = act["iid"]
354
+ zh_cn = i18n_zh.get(f"service:{siid:03d}:action:{aiid:03d}", "")
355
+ act_item = {
356
+ "name": act["type"],
357
+ "description": f"{act['description']} / {zh_cn}".rstrip(" / "),
358
+ "method": {
359
+ "siid": siid,
360
+ "aiid": aiid
361
+ }
362
+ }
363
+ if act_item["name"] in actions_name:
364
+ act_item["name"] = f"{svc_type}-{act_item['name']}"
365
+ actions_name.append(act_item["name"])
366
+ result["actions"].append(act_item)
357
367
 
358
368
  if cache_path is not None:
359
369
  cache_path = Path(cache_path)
@@ -0,0 +1 @@
1
+ version = "3.2.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mijiaAPI
3
- Version: 3.0.5
3
+ Version: 3.2.0
4
4
  Summary: A Python API for Xiaomi Mijia
5
5
  Author-email: Do1e <i@do1e.cn>
6
6
  License-Expression: GPL-3.0-or-later
@@ -26,12 +26,6 @@ Dynamic: license-file
26
26
  [![PyPI](https://img.shields.io/badge/PyPI-mijiaAPI-blue)](https://pypi.org/project/mijiaAPI/)
27
27
  [![License: GPL-3.0](https://img.shields.io/badge/License-GPL--3.0-green.svg)](https://opensource.org/licenses/GPL-3.0)
28
28
 
29
- ## ⚠️ 重要提醒
30
-
31
- **v1.5.0 和 v3.0.0包含多项破坏性变更!**
32
-
33
- 如果您正在从旧版本升级,请务必查看 [CHANGELOG.md](CHANGELOG.md) 以了解详细的变更内容和迁移指南。
34
-
35
29
  常见问题见 [FAQ.md](FAQ.md)。
36
30
 
37
31
  ## 安装
@@ -365,14 +359,17 @@ MIJIA_LOG_LEVEL=WARNING mijiaAPI get --dev_name "卧室台灯" --prop_name "brig
365
359
  完整的命令行参数说明:
366
360
 
367
361
  ```
368
- usage: mijiaAPI [-h] [-p AUTH_PATH] [--list_homes] [-l] [--list_scenes]
369
- [--list_consumable_items] [--run_scene SCENE_ID/SCENE_NAME ...]
370
- [--get_device_info DEVICE_MODEL] [--run PROMPT]
371
- [--wifispeaker_name WIFISPEAKER_NAME] [--quiet]
372
- {get,set} ...
362
+ usage: mijiaAPI [-h] [-v] [-p AUTH_PATH] [--list_homes] [-l]
363
+ [--list_scenes] [--list_consumable_items]
364
+ [--run_scene SCENE_ID/SCENE_NAME [SCENE_ID/SCENE_NAME ...]]
365
+ [--get_device_info DEVICE_MODEL]
366
+ {run,get,set} ...
367
+
368
+ Mijia API CLI (v3.1.0)
373
369
 
374
370
  positional arguments:
375
- {get,set}
371
+ {run,get,set}
372
+ run 使用自然语言描述你的需求,如果你有小爱音箱的话
376
373
  get 获取设备属性
377
374
  set 设置设备属性
378
375
 
@@ -390,10 +387,6 @@ options:
390
387
  运行场景,指定场景ID或名称
391
388
  --get_device_info DEVICE_MODEL
392
389
  获取设备信息,指定设备model,先使用 --list_devices 获取
393
- --run PROMPT 使用自然语言描述你的需求,如果你有小爱音箱的话
394
- --wifispeaker_name WIFISPEAKER_NAME
395
- 指定小爱音箱名称,默认是获取到的第一个小爱音箱
396
- --quiet 小爱音箱静默执行
397
390
  ```
398
391
 
399
392
  ```
@@ -423,6 +416,23 @@ options:
423
416
  --value VALUE 需要设定的属性值
424
417
  ```
425
418
 
419
+ ```
420
+ usage: mijiaAPI run [-h] [-p AUTH_PATH]
421
+ [--wifispeaker_name WIFISPEAKER_NAME] [--quiet]
422
+ PROMPT
423
+
424
+ positional arguments:
425
+ PROMPT 使用自然语言描述你的需求
426
+
427
+ options:
428
+ -h, --help show this help message and exit
429
+ -p, --auth_path AUTH_PATH
430
+ 认证文件保存路径,默认保存在 ~/.config/mijia-api/auth.json
431
+ --wifispeaker_name WIFISPEAKER_NAME
432
+ 指定小爱音箱名称,默认是获取到的第一个小爱音箱
433
+ --quiet 小爱音箱静默执行
434
+ ```
435
+
426
436
  #### 获取设备属性
427
437
 
428
438
  ```bash
@@ -471,9 +481,9 @@ mijiaAPI --get_device_info yeelink.light.lamp4
471
481
  mijiaAPI --list_consumable_items
472
482
 
473
483
  # 使用小爱音箱执行自然语言命令
474
- mijiaAPI --run "打开卧室台灯"
475
- mijiaAPI --run "把亮度调到50%" --wifispeaker_name "卧室小爱"
476
- mijiaAPI --run "关闭所有灯" --quiet
484
+ mijiaAPI run "打开卧室台灯"
485
+ mijiaAPI run "把亮度调到50%" --wifispeaker_name "卧室小爱"
486
+ mijiaAPI run "关闭所有灯" --quiet
477
487
  ```
478
488
 
479
489
  #### 直接使用 uvx(无需安装)
@@ -1 +0,0 @@
1
- version = "3.0.5"
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
File without changes
File without changes