mijiaAPI 4.1.3__tar.gz → 4.2.1__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.
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/PKG-INFO +1 -1
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/mijiaAPI/devices.py +27 -15
- mijiaapi-4.2.1/mijiaAPI/version.py +1 -0
- mijiaapi-4.1.3/mijiaAPI/version.py +0 -1
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/.gitignore +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/LICENSE +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/MANIFEST.in +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/README.md +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/mijiaAPI/__init__.py +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/mijiaAPI/__main__.py +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/mijiaAPI/apis.py +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/mijiaAPI/errors.py +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/mijiaAPI/logger.py +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/mijiaAPI/mcp_server.py +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/mijiaAPI/miutils.py +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/mijiaAPI.egg-info/SOURCES.txt +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/pyproject.toml +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/setup.cfg +0 -0
- {mijiaapi-4.1.3 → mijiaapi-4.2.1}/uv.lock +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import re
|
|
3
3
|
import time
|
|
4
|
+
from collections import Counter
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from typing import Optional, Union
|
|
6
7
|
|
|
@@ -20,6 +21,19 @@ from .version import version
|
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
device_url = "https://home.miot-spec.com/spec/"
|
|
24
|
+
device_info_version = 1
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _deduplicate_names(items: list[dict], iid_key: str) -> None:
|
|
28
|
+
name_counts = Counter(item["name"] for item in items)
|
|
29
|
+
for item in items:
|
|
30
|
+
if name_counts[item["name"]] > 1:
|
|
31
|
+
item["name"] = f"{item['name']}-{item['method']['siid']}"
|
|
32
|
+
|
|
33
|
+
name_counts = Counter(item["name"] for item in items)
|
|
34
|
+
for item in items:
|
|
35
|
+
if name_counts[item["name"]] > 1:
|
|
36
|
+
item["name"] = f"{item['name']}-{item['method'][iid_key]}"
|
|
23
37
|
|
|
24
38
|
|
|
25
39
|
class DevProp():
|
|
@@ -252,6 +266,7 @@ def get_device_info(device_model: str, cache_path: Optional[Union[str, Path]] =
|
|
|
252
266
|
|
|
253
267
|
返回值:
|
|
254
268
|
dict: 设备规格信息字典,包含以下字段:
|
|
269
|
+
- version (int): 设备信息缓存格式版本
|
|
255
270
|
- name (str): 设备名称
|
|
256
271
|
- model (str): 设备型号
|
|
257
272
|
- properties (list): 设备属性列表,每个属性包含以下字段:
|
|
@@ -275,12 +290,16 @@ def get_device_info(device_model: str, cache_path: Optional[Union[str, Path]] =
|
|
|
275
290
|
>>> print(info['name']) # 输出设备名称
|
|
276
291
|
>>> print(info['properties'][0]['name']) # 输出第一个属性的名称
|
|
277
292
|
"""
|
|
293
|
+
cache_file = None
|
|
278
294
|
if cache_path is not None:
|
|
279
295
|
cache_file = Path(cache_path) / f"{device_model}.json"
|
|
280
296
|
if cache_file.exists():
|
|
281
297
|
logger.debug(f"从缓存加载设备信息: {cache_file}")
|
|
282
298
|
with cache_file.open("r", encoding="utf-8") as f:
|
|
283
|
-
|
|
299
|
+
cached_result = json.load(f)
|
|
300
|
+
if cached_result.get("version") == device_info_version:
|
|
301
|
+
return cached_result
|
|
302
|
+
logger.debug(f"设备信息缓存版本不匹配,重新获取: {cache_file}")
|
|
284
303
|
response = requests.get(device_url + device_model, headers={
|
|
285
304
|
"User-Agent": f"mijiaAPI/{version}"
|
|
286
305
|
})
|
|
@@ -295,8 +314,9 @@ def get_device_info(device_model: str, cache_path: Optional[Union[str, Path]] =
|
|
|
295
314
|
product = content["props"]["product"]
|
|
296
315
|
name = product["name"]
|
|
297
316
|
model = product["model"]
|
|
298
|
-
i18n_zh = content["props"]
|
|
317
|
+
i18n_zh = content["props"].get("i18n", {}).get("zh_cn", {})
|
|
299
318
|
result = {
|
|
319
|
+
"version": device_info_version,
|
|
300
320
|
"name": name,
|
|
301
321
|
"model": model,
|
|
302
322
|
"properties": [],
|
|
@@ -304,11 +324,8 @@ def get_device_info(device_model: str, cache_path: Optional[Union[str, Path]] =
|
|
|
304
324
|
}
|
|
305
325
|
services = content["props"]["tree"]["services"]
|
|
306
326
|
|
|
307
|
-
properties_name = []
|
|
308
|
-
actions_name = []
|
|
309
327
|
for svc in services:
|
|
310
328
|
siid = svc["iid"]
|
|
311
|
-
svc_type = svc["type"]
|
|
312
329
|
for prop in svc.get("properties", []):
|
|
313
330
|
piid = prop["iid"]
|
|
314
331
|
if prop["format"].startswith("int"):
|
|
@@ -345,9 +362,6 @@ def get_device_info(device_model: str, cache_path: Optional[Union[str, Path]] =
|
|
|
345
362
|
if vl_zh:
|
|
346
363
|
vl_entry["desc_zh_cn"] = vl_zh
|
|
347
364
|
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
365
|
result["properties"].append(item)
|
|
352
366
|
for act in svc.get("actions", []):
|
|
353
367
|
aiid = act["iid"]
|
|
@@ -360,15 +374,13 @@ def get_device_info(device_model: str, cache_path: Optional[Union[str, Path]] =
|
|
|
360
374
|
"aiid": aiid
|
|
361
375
|
}
|
|
362
376
|
}
|
|
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
377
|
result["actions"].append(act_item)
|
|
367
378
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
379
|
+
_deduplicate_names(result["properties"], "piid")
|
|
380
|
+
_deduplicate_names(result["actions"], "aiid")
|
|
381
|
+
|
|
382
|
+
if cache_file is not None:
|
|
383
|
+
cache_file.parent.mkdir(parents=True, exist_ok=True)
|
|
372
384
|
logger.debug(f"缓存设备信息到: {cache_file}")
|
|
373
385
|
with cache_file.open("w", encoding="utf-8") as f:
|
|
374
386
|
json.dump(result, f, indent=2, ensure_ascii=False)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
version = "4.2.1"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
version = "4.1.3"
|
|
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
|
|
File without changes
|
|
File without changes
|