mijiaAPI 1.1.0__tar.gz → 1.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.
- mijiaapi-1.2.0/.gitignore +8 -0
- mijiaapi-1.2.0/.vscode/launch.json +40 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/PKG-INFO +13 -4
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/README.md +12 -3
- mijiaapi-1.2.0/demos/dev_info_example/miaomiaoce.sensor_ht.t1.json +42 -0
- mijiaapi-1.2.0/demos/dev_info_example/yeelink.light.lamp4.json +125 -0
- mijiaapi-1.2.0/demos/test_QRlogin.py +13 -0
- mijiaapi-1.2.0/demos/test_apis.py +66 -0
- mijiaapi-1.2.0/demos/test_available.py +10 -0
- mijiaapi-1.2.0/demos/test_devices_airconditioner.py +96 -0
- mijiaapi-1.2.0/demos/test_devices_light.py +43 -0
- mijiaapi-1.2.0/demos/test_devices_sensor.py +20 -0
- mijiaapi-1.2.0/demos/test_devices_v2_light.py +43 -0
- mijiaapi-1.2.0/demos/test_login.py +15 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI/__version__.py +1 -1
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI/apis.py +12 -1
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI/devices.py +34 -4
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI.egg-info/PKG-INFO +13 -4
- mijiaapi-1.2.0/mijiaAPI.egg-info/SOURCES.txt +28 -0
- mijiaapi-1.2.0/requirements.txt +2 -0
- mijiaAPI-1.1.0/mijiaAPI.egg-info/SOURCES.txt +0 -15
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/LICENSE +0 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI/__init__.py +0 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI/login.py +0 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI/urls.py +0 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI/utils.py +0 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI.egg-info/dependency_links.txt +0 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI.egg-info/requires.txt +0 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/mijiaAPI.egg-info/top_level.txt +0 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/setup.cfg +0 -0
- {mijiaAPI-1.1.0 → mijiaapi-1.2.0}/setup.py +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
// 使用 IntelliSense 了解相关属性。
|
|
3
|
+
// 悬停以查看现有属性的描述。
|
|
4
|
+
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"name": "current file",
|
|
9
|
+
"type": "debugpy",
|
|
10
|
+
"request": "launch",
|
|
11
|
+
"program": "${file}",
|
|
12
|
+
"console": "integratedTerminal"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "test_login",
|
|
16
|
+
"type": "debugpy",
|
|
17
|
+
"request": "launch",
|
|
18
|
+
"program": "demos/test_login.py",
|
|
19
|
+
"console": "integratedTerminal",
|
|
20
|
+
"env": {
|
|
21
|
+
"XIAOMI_USERNAME": "xxxx",
|
|
22
|
+
"XIAOMI_PASSWORD": "xxxx"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "test_QRlogin",
|
|
27
|
+
"type": "debugpy",
|
|
28
|
+
"request": "launch",
|
|
29
|
+
"program": "demos/test_QRlogin.py",
|
|
30
|
+
"console": "integratedTerminal"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "test_apis",
|
|
34
|
+
"type": "debugpy",
|
|
35
|
+
"request": "launch",
|
|
36
|
+
"program": "demos/test_apis.py",
|
|
37
|
+
"console": "integratedTerminal"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mijiaAPI
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: A Python API for Xiaomi Mijia
|
|
5
5
|
Home-page: https://github.com/Do1e/mijia-api
|
|
6
6
|
Author: Do1e
|
|
@@ -29,24 +29,33 @@ pip install mijiaAPI
|
|
|
29
29
|
## 使用
|
|
30
30
|
使用实例可以参考`demos`文件夹下的示例代码,以下是简单的使用说明
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
有三个类分别用于登录和API调用
|
|
33
33
|
|
|
34
34
|
* `mijiaLogin`:登录小米账号,获取控制设备必须的`userId`, `ssecurity`, `deviceId`, `serviceToken`,方法列表
|
|
35
35
|
* `login(username: str, password: str) -> dict`:账号密码登录,返回上述信息
|
|
36
36
|
* `QRlogin() -> dict`:扫描二维码登录,返回上述信息(会在支持tty的终端打印二维码,若打印识别可查看当前文件夹下的`qr.png`)
|
|
37
37
|
|
|
38
38
|
* `mijiaAPI`:API的实现,使用`mijiaLogin`登录后返回的信息进行初始化
|
|
39
|
-
* `__init__(
|
|
39
|
+
* `__init__(auth_data: dict)`:初始化
|
|
40
|
+
* `available -> bool`:传入的`auth_data`是否有效
|
|
40
41
|
* `get_devices_list() -> list`:获取设备列表
|
|
41
42
|
* `get_homes_list() -> list`:获取家庭列表,家庭字典中包含房间列表
|
|
42
43
|
* `get_scenes_list(home_id: str) -> list`:获取手动场景列表,在 *米家->添加->手动控制* 中设置
|
|
43
44
|
* `run_scene(scene_id: str) -> bool`:运行手动场景
|
|
44
|
-
* `get_consumable_items(
|
|
45
|
+
* `get_consumable_items(home_id: str) -> list`:获取设备的耗材信息
|
|
45
46
|
* `get_devices_prop(data: list) -> list`:获取设备的属性
|
|
46
47
|
* `set_devices_prop(data: list) -> list`:设置设备的属性
|
|
47
48
|
* `data`为一个字典的列表,字典需要包含`did`, `siid`, `piid`,后面两个键可从 *https://home.miot-spec.com/spec/{model}* 中获取,其中`model`为设备的model,在设备列表中获取,如[米家台灯 1S](https://home.miot-spec.com/spec/yeelink.light.lamp4)。
|
|
48
49
|
* 网站上的方法并非全部可用,需要自行测试
|
|
49
50
|
|
|
51
|
+
|
|
52
|
+
* `mijiaDevices`:使用`mijiaAPI`和设备属性字典初始化,以便更方便地调用设备属性
|
|
53
|
+
* `__init__(api: mijiaAPI, dev_info: dict. did: str = None, sleep_time: float = 0.5)`:初始化,`dev_info`为设备属性,参考[demos/dev_info_example](demos/dev_info_example),`sleep_time`为每次调用设备属性的间隔时间(注:设置属性后立刻获取属性会不符合预期,需要延迟一段时间)
|
|
54
|
+
* `set(name: str, did: str, value: Union[bool, int]) -> Union[bool, int]`:设置设备属性
|
|
55
|
+
* `get(name: str, did: str) -> Union[bool, int]`:获取设备属性
|
|
56
|
+
* v1.2.0 新增直接通过名称设置/获取属性,需要在初始化时传入`did`,详见[demos/test_devices_v2_light.py](demos/test_devices_v2_light.py)。名称中包含`-`的属性需要替换为`_`。
|
|
57
|
+
* **欢迎大家把自己编写的设备属性字典分享到Issues中,方便大家使用**
|
|
58
|
+
|
|
50
59
|
## 致谢
|
|
51
60
|
* [janzlan/mijia-api](https://gitee.com/janzlan/mijia-api/tree/master)
|
|
52
61
|
|
|
@@ -13,24 +13,33 @@ pip install mijiaAPI
|
|
|
13
13
|
## 使用
|
|
14
14
|
使用实例可以参考`demos`文件夹下的示例代码,以下是简单的使用说明
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
有三个类分别用于登录和API调用
|
|
17
17
|
|
|
18
18
|
* `mijiaLogin`:登录小米账号,获取控制设备必须的`userId`, `ssecurity`, `deviceId`, `serviceToken`,方法列表
|
|
19
19
|
* `login(username: str, password: str) -> dict`:账号密码登录,返回上述信息
|
|
20
20
|
* `QRlogin() -> dict`:扫描二维码登录,返回上述信息(会在支持tty的终端打印二维码,若打印识别可查看当前文件夹下的`qr.png`)
|
|
21
21
|
|
|
22
22
|
* `mijiaAPI`:API的实现,使用`mijiaLogin`登录后返回的信息进行初始化
|
|
23
|
-
* `__init__(
|
|
23
|
+
* `__init__(auth_data: dict)`:初始化
|
|
24
|
+
* `available -> bool`:传入的`auth_data`是否有效
|
|
24
25
|
* `get_devices_list() -> list`:获取设备列表
|
|
25
26
|
* `get_homes_list() -> list`:获取家庭列表,家庭字典中包含房间列表
|
|
26
27
|
* `get_scenes_list(home_id: str) -> list`:获取手动场景列表,在 *米家->添加->手动控制* 中设置
|
|
27
28
|
* `run_scene(scene_id: str) -> bool`:运行手动场景
|
|
28
|
-
* `get_consumable_items(
|
|
29
|
+
* `get_consumable_items(home_id: str) -> list`:获取设备的耗材信息
|
|
29
30
|
* `get_devices_prop(data: list) -> list`:获取设备的属性
|
|
30
31
|
* `set_devices_prop(data: list) -> list`:设置设备的属性
|
|
31
32
|
* `data`为一个字典的列表,字典需要包含`did`, `siid`, `piid`,后面两个键可从 *https://home.miot-spec.com/spec/{model}* 中获取,其中`model`为设备的model,在设备列表中获取,如[米家台灯 1S](https://home.miot-spec.com/spec/yeelink.light.lamp4)。
|
|
32
33
|
* 网站上的方法并非全部可用,需要自行测试
|
|
33
34
|
|
|
35
|
+
|
|
36
|
+
* `mijiaDevices`:使用`mijiaAPI`和设备属性字典初始化,以便更方便地调用设备属性
|
|
37
|
+
* `__init__(api: mijiaAPI, dev_info: dict. did: str = None, sleep_time: float = 0.5)`:初始化,`dev_info`为设备属性,参考[demos/dev_info_example](demos/dev_info_example),`sleep_time`为每次调用设备属性的间隔时间(注:设置属性后立刻获取属性会不符合预期,需要延迟一段时间)
|
|
38
|
+
* `set(name: str, did: str, value: Union[bool, int]) -> Union[bool, int]`:设置设备属性
|
|
39
|
+
* `get(name: str, did: str) -> Union[bool, int]`:获取设备属性
|
|
40
|
+
* v1.2.0 新增直接通过名称设置/获取属性,需要在初始化时传入`did`,详见[demos/test_devices_v2_light.py](demos/test_devices_v2_light.py)。名称中包含`-`的属性需要替换为`_`。
|
|
41
|
+
* **欢迎大家把自己编写的设备属性字典分享到Issues中,方便大家使用**
|
|
42
|
+
|
|
34
43
|
## 致谢
|
|
35
44
|
* [janzlan/mijia-api](https://gitee.com/janzlan/mijia-api/tree/master)
|
|
36
45
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "小米米家电子温湿度计Pro",
|
|
3
|
+
"model": "miaomiaoce.sensor_ht.t1",
|
|
4
|
+
"properties": [
|
|
5
|
+
{
|
|
6
|
+
"name": "temperature",
|
|
7
|
+
"description": "温度",
|
|
8
|
+
"type": "float",
|
|
9
|
+
"rw": "r",
|
|
10
|
+
"unit": "celsius",
|
|
11
|
+
"range": [-30, 100],
|
|
12
|
+
"method": {
|
|
13
|
+
"siid": 2,
|
|
14
|
+
"piid": 1
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "relative-humidity",
|
|
19
|
+
"description": "相对湿度",
|
|
20
|
+
"type": "float",
|
|
21
|
+
"rw": "r",
|
|
22
|
+
"unit": "percentage",
|
|
23
|
+
"range": [0, 100],
|
|
24
|
+
"method": {
|
|
25
|
+
"siid": 2,
|
|
26
|
+
"piid": 2
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "battery-level",
|
|
31
|
+
"description": "电池电量",
|
|
32
|
+
"type": "uint",
|
|
33
|
+
"rw": "r",
|
|
34
|
+
"unit": "percentage",
|
|
35
|
+
"range": [0, 100],
|
|
36
|
+
"method": {
|
|
37
|
+
"siid": 3,
|
|
38
|
+
"piid": 1
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "米家台灯 1S",
|
|
3
|
+
"model": "yeelink.light.lamp4",
|
|
4
|
+
"properties": [
|
|
5
|
+
{
|
|
6
|
+
"name": "on",
|
|
7
|
+
"description": "开关",
|
|
8
|
+
"type": "bool",
|
|
9
|
+
"rw": "rw",
|
|
10
|
+
"unit": null,
|
|
11
|
+
"range": null,
|
|
12
|
+
"method": {
|
|
13
|
+
"siid": 2,
|
|
14
|
+
"piid": 1
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "brightness",
|
|
19
|
+
"description": "亮度",
|
|
20
|
+
"type": "uint",
|
|
21
|
+
"rw": "rw",
|
|
22
|
+
"unit": "percentage",
|
|
23
|
+
"range": [
|
|
24
|
+
1,
|
|
25
|
+
100
|
|
26
|
+
],
|
|
27
|
+
"method": {
|
|
28
|
+
"siid": 2,
|
|
29
|
+
"piid": 2
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "color-temperature",
|
|
34
|
+
"description": "色温",
|
|
35
|
+
"type": "uint",
|
|
36
|
+
"rw": "rw",
|
|
37
|
+
"unit": "kelvin",
|
|
38
|
+
"range": [
|
|
39
|
+
2600,
|
|
40
|
+
5000
|
|
41
|
+
],
|
|
42
|
+
"method": {
|
|
43
|
+
"siid": 2,
|
|
44
|
+
"piid": 3
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "mode",
|
|
49
|
+
"description": "模式,0-6分别为[Reading, Computer, Night Reading, Anti-blue, Effective Work, Candle, Twinkle]",
|
|
50
|
+
"type": "uint",
|
|
51
|
+
"rw": "w",
|
|
52
|
+
"unit": null,
|
|
53
|
+
"range": [
|
|
54
|
+
0,
|
|
55
|
+
6
|
|
56
|
+
],
|
|
57
|
+
"method": {
|
|
58
|
+
"siid": 2,
|
|
59
|
+
"piid": 4
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "brightness-delta",
|
|
64
|
+
"description": "百分比调节亮度",
|
|
65
|
+
"type": "int",
|
|
66
|
+
"rw": "w",
|
|
67
|
+
"unit": "percentage",
|
|
68
|
+
"range": [
|
|
69
|
+
-100,
|
|
70
|
+
100
|
|
71
|
+
],
|
|
72
|
+
"method": {
|
|
73
|
+
"siid": 3,
|
|
74
|
+
"piid": 1
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"name": "ct-delta",
|
|
79
|
+
"description": "百分比调节色温",
|
|
80
|
+
"type": "int",
|
|
81
|
+
"rw": "w",
|
|
82
|
+
"unit": "percentage",
|
|
83
|
+
"range": [
|
|
84
|
+
-100,
|
|
85
|
+
100
|
|
86
|
+
],
|
|
87
|
+
"method": {
|
|
88
|
+
"siid": 3,
|
|
89
|
+
"piid": 2
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"name": "ct-adjust-alexa-increase",
|
|
94
|
+
"description": "色温增加",
|
|
95
|
+
"type": "uint",
|
|
96
|
+
"rw": "w",
|
|
97
|
+
"unit": null,
|
|
98
|
+
"range": [
|
|
99
|
+
1,
|
|
100
|
+
1
|
|
101
|
+
],
|
|
102
|
+
"method": {
|
|
103
|
+
"siid": 3,
|
|
104
|
+
"piid": 3,
|
|
105
|
+
"value": 1
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "ct-adjust-alexa-decrease",
|
|
110
|
+
"description": "色温减少",
|
|
111
|
+
"type": "uint",
|
|
112
|
+
"rw": "w",
|
|
113
|
+
"unit": null,
|
|
114
|
+
"range": [
|
|
115
|
+
2,
|
|
116
|
+
2
|
|
117
|
+
],
|
|
118
|
+
"method": {
|
|
119
|
+
"siid": 3,
|
|
120
|
+
"piid": 3,
|
|
121
|
+
"value": 2
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
sys.path.extend(['.', '..'])
|
|
5
|
+
from mijiaAPI import mijiaLogin
|
|
6
|
+
|
|
7
|
+
if not os.path.exists('jsons'):
|
|
8
|
+
os.mkdir('jsons')
|
|
9
|
+
|
|
10
|
+
api = mijiaLogin()
|
|
11
|
+
auth = api.QRlogin()
|
|
12
|
+
with open('jsons/auth.json', 'w') as f:
|
|
13
|
+
json.dump(auth, f, indent=2)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import time
|
|
3
|
+
import sys
|
|
4
|
+
sys.path.extend(['.', '..'])
|
|
5
|
+
from mijiaAPI import mijiaAPI
|
|
6
|
+
|
|
7
|
+
with open('jsons/auth.json') as f:
|
|
8
|
+
auth = json.load(f)
|
|
9
|
+
api = mijiaAPI(auth)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# ---------------------- get devices list ----------------------
|
|
13
|
+
devices = api.get_devices_list()['list']
|
|
14
|
+
with open('jsons/devices.json', 'w') as f:
|
|
15
|
+
json.dump(devices, f, indent=2, ensure_ascii=False)
|
|
16
|
+
time.sleep(2)
|
|
17
|
+
|
|
18
|
+
# ---------------------- get homes list ------------------------
|
|
19
|
+
homes = api.get_homes_list()['homelist']
|
|
20
|
+
with open('jsons/homes.json', 'w') as f:
|
|
21
|
+
json.dump(homes, f, indent=2, ensure_ascii=False)
|
|
22
|
+
time.sleep(2)
|
|
23
|
+
|
|
24
|
+
# ---------------------- get scenes list -----------------------
|
|
25
|
+
home_id = homes[0]['id']
|
|
26
|
+
scenes = api.get_scenes_list(home_id)['scene_info_list']
|
|
27
|
+
with open('jsons/scenes.json', 'w') as f:
|
|
28
|
+
json.dump(scenes, f, indent=2, ensure_ascii=False)
|
|
29
|
+
time.sleep(2)
|
|
30
|
+
|
|
31
|
+
# ---------------------- run scene -----------------------------
|
|
32
|
+
scence_id = scenes[0]['scene_id']
|
|
33
|
+
scence_name = scenes[0]['name']
|
|
34
|
+
ret = api.run_scene(scence_id)
|
|
35
|
+
print(f'Run scene {scence_name}: {ret}')
|
|
36
|
+
time.sleep(2)
|
|
37
|
+
|
|
38
|
+
# ---------------------- get consumable items ------------------
|
|
39
|
+
consumable_items = api.get_consumable_items(home_id)['items']
|
|
40
|
+
with open('jsons/consumable_items.json', 'w') as f:
|
|
41
|
+
json.dump(consumable_items, f, indent=2, ensure_ascii=False)
|
|
42
|
+
time.sleep(2)
|
|
43
|
+
|
|
44
|
+
# ---------------------- get/set device properties -------------
|
|
45
|
+
# look for did and model in devices.json
|
|
46
|
+
# look for siid and piid in https://home.miot-spec.com/spec/{model}
|
|
47
|
+
# or it's feasible to use `run_scene`` to set the device properties
|
|
48
|
+
did = devices[0]['did']
|
|
49
|
+
name = devices[0]['name']
|
|
50
|
+
ret = api.get_devices_prop([
|
|
51
|
+
{"did": did, "siid": 2, "piid": 2},
|
|
52
|
+
{"did": did, "siid": 2, "piid": 3},
|
|
53
|
+
])
|
|
54
|
+
brightness = ret[0]['value']
|
|
55
|
+
color_temperature = ret[1]['value']
|
|
56
|
+
print(f'Get device {name} properties:\nBrightness: {brightness}%\n'
|
|
57
|
+
f'Color temperature: {color_temperature}K')
|
|
58
|
+
time.sleep(2)
|
|
59
|
+
|
|
60
|
+
ret = api.set_devices_prop([
|
|
61
|
+
{"did": did, "siid": 2, "piid": 2, "value": 50},
|
|
62
|
+
{"did": did, "siid": 2, "piid": 3, "value": 2700},
|
|
63
|
+
])
|
|
64
|
+
print(f'Set device {name} properties:\n'
|
|
65
|
+
f'Brightness: {"Success" if ret[0]["code"] == 0 else "Failed"}\n'
|
|
66
|
+
f'Color temperature: {"Success" if ret[1]["code"] == 0 else "Failed"}')
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import sys
|
|
3
|
+
sys.path.extend(['.', '..'])
|
|
4
|
+
from mijiaAPI import mijiaDevices, mijiaAPI
|
|
5
|
+
|
|
6
|
+
with open('jsons/auth.json') as f:
|
|
7
|
+
auth = json.load(f)
|
|
8
|
+
api = mijiaAPI(auth)
|
|
9
|
+
|
|
10
|
+
with open('jsons/devices.json') as f:
|
|
11
|
+
devices = json.load(f)
|
|
12
|
+
did = devices[2]['did']
|
|
13
|
+
dev_info = {
|
|
14
|
+
"name": "米家空调伴侣Pro 万能遥控版",
|
|
15
|
+
"model": "lumi.acpartner.mcn04",
|
|
16
|
+
"properties": [
|
|
17
|
+
{
|
|
18
|
+
"name": "on",
|
|
19
|
+
"description": "开关",
|
|
20
|
+
"type": "bool",
|
|
21
|
+
"rw": "rw",
|
|
22
|
+
"unit": None,
|
|
23
|
+
"range": None,
|
|
24
|
+
"method": {
|
|
25
|
+
"siid": 3,
|
|
26
|
+
"piid": 1
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "mode",
|
|
31
|
+
"description": "空调模式,0-4分别是制冷、制热、自动、送风、除湿",
|
|
32
|
+
"type": "uint",
|
|
33
|
+
"rw": "rw",
|
|
34
|
+
"unit": None,
|
|
35
|
+
"range": [0, 4],
|
|
36
|
+
"method": {
|
|
37
|
+
"siid": 3,
|
|
38
|
+
"piid": 2
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "target-temperature",
|
|
43
|
+
"description": "目标温度",
|
|
44
|
+
"type": "uint",
|
|
45
|
+
"rw": "rw",
|
|
46
|
+
"unit": "celsius",
|
|
47
|
+
"range": [16, 30],
|
|
48
|
+
"method": {
|
|
49
|
+
"siid": 3,
|
|
50
|
+
"piid": 4
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "power-consumption",
|
|
55
|
+
"description": "耗电量",
|
|
56
|
+
"type": "float",
|
|
57
|
+
"rw": "r",
|
|
58
|
+
"unit": None,
|
|
59
|
+
"range": [0, 3.4e38],
|
|
60
|
+
"method": {
|
|
61
|
+
"siid": 7,
|
|
62
|
+
"piid": 1
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "electric-power",
|
|
67
|
+
"description": "功率",
|
|
68
|
+
"type": "float",
|
|
69
|
+
"rw": "r",
|
|
70
|
+
"unit": "watt",
|
|
71
|
+
"range": [0, 3.4e38],
|
|
72
|
+
"method": {
|
|
73
|
+
"siid": 7,
|
|
74
|
+
"piid": 2
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# sleep_time is optional, default is 0.5
|
|
81
|
+
# get after set shuold be delayed for a while, or the result may be incorrect
|
|
82
|
+
device = mijiaDevices(api, dev_info, sleep_time=2)
|
|
83
|
+
print(device)
|
|
84
|
+
print('---------------------')
|
|
85
|
+
print(device.get('on', did))
|
|
86
|
+
print(device.set('on', did, True))
|
|
87
|
+
print(device.get('on', did))
|
|
88
|
+
print('---------------------')
|
|
89
|
+
print(device.get('mode', did))
|
|
90
|
+
print('---------------------')
|
|
91
|
+
print(device.get('target-temperature', did))
|
|
92
|
+
print(device.set('target-temperature', did, 26))
|
|
93
|
+
print(device.get('target-temperature', did))
|
|
94
|
+
print('---------------------')
|
|
95
|
+
print(device.get('power-consumption', did))
|
|
96
|
+
print(device.get('electric-power', did))
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import sys
|
|
3
|
+
sys.path.extend(['.', '..'])
|
|
4
|
+
from mijiaAPI import mijiaDevices, mijiaAPI
|
|
5
|
+
|
|
6
|
+
with open('jsons/auth.json') as f:
|
|
7
|
+
auth = json.load(f)
|
|
8
|
+
api = mijiaAPI(auth)
|
|
9
|
+
|
|
10
|
+
with open('demos/dev_info_example/yeelink.light.lamp4.json', encoding='utf-8') as f:
|
|
11
|
+
dev_info = json.load(f)
|
|
12
|
+
with open('jsons/devices.json') as f:
|
|
13
|
+
devices = json.load(f)
|
|
14
|
+
did = devices[0]['did']
|
|
15
|
+
# sleep_time is optional, default is 0.5
|
|
16
|
+
# get after set shuold be delayed for a while, or the result may be incorrect
|
|
17
|
+
device = mijiaDevices(api, dev_info, sleep_time=2)
|
|
18
|
+
print(device)
|
|
19
|
+
print('---------------------')
|
|
20
|
+
print(device.get('on', did))
|
|
21
|
+
print(device.set('on', did, True))
|
|
22
|
+
print('---------------------')
|
|
23
|
+
print(f"{device.get('brightness', did)} {device.prop_list['brightness'].unit}")
|
|
24
|
+
print(device.set('brightness', did, 60))
|
|
25
|
+
print(f"{device.get('brightness', did)} {device.prop_list['brightness'].unit}")
|
|
26
|
+
print('---------------------')
|
|
27
|
+
print(f"{device.get('color-temperature', did)} {device.prop_list['color-temperature'].unit}")
|
|
28
|
+
print(device.set('color-temperature', did, 5000))
|
|
29
|
+
print(f"{device.get('color-temperature', did)} {device.prop_list['color-temperature'].unit}")
|
|
30
|
+
print('---------------------')
|
|
31
|
+
print(device.set('mode', did, 0))
|
|
32
|
+
print('---------------------')
|
|
33
|
+
print(f"{device.get('brightness', did)} {device.prop_list['brightness'].unit}")
|
|
34
|
+
print(device.set('brightness-delta', did, -10))
|
|
35
|
+
print(f"{device.get('brightness', did)} {device.prop_list['brightness'].unit}")
|
|
36
|
+
print('---------------------')
|
|
37
|
+
print(f"{device.get('color-temperature', did)} {device.prop_list['color-temperature'].unit}")
|
|
38
|
+
print(device.set('ct-delta', did, -10))
|
|
39
|
+
print(f"{device.get('color-temperature', did)} {device.prop_list['color-temperature'].unit}")
|
|
40
|
+
print(device.set('ct-adjust-alexa-increase', did, 1))
|
|
41
|
+
print(f"{device.get('color-temperature', did)} {device.prop_list['color-temperature'].unit}")
|
|
42
|
+
print(device.set('ct-adjust-alexa-decrease', did, 2))
|
|
43
|
+
print(f"{device.get('color-temperature', did)} {device.prop_list['color-temperature'].unit}")
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import sys
|
|
3
|
+
sys.path.extend(['.', '..'])
|
|
4
|
+
from mijiaAPI import mijiaDevices, mijiaAPI
|
|
5
|
+
|
|
6
|
+
with open('jsons/auth.json') as f:
|
|
7
|
+
auth = json.load(f)
|
|
8
|
+
api = mijiaAPI(auth)
|
|
9
|
+
|
|
10
|
+
with open('demos/dev_info_example/miaomiaoce.sensor_ht.t1.json', encoding='utf-8') as f:
|
|
11
|
+
dev_info = json.load(f)
|
|
12
|
+
with open('jsons/devices.json') as f:
|
|
13
|
+
devices = json.load(f)
|
|
14
|
+
did = devices[5]['did']
|
|
15
|
+
device = mijiaDevices(api, dev_info)
|
|
16
|
+
print(device)
|
|
17
|
+
print('---------------------')
|
|
18
|
+
print(device.get('temperature', did))
|
|
19
|
+
print(device.get('relative-humidity', did))
|
|
20
|
+
print(device.get('battery-level', did))
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import sys
|
|
3
|
+
sys.path.extend(['.', '..'])
|
|
4
|
+
from mijiaAPI import mijiaDevices, mijiaAPI
|
|
5
|
+
|
|
6
|
+
with open('jsons/auth.json') as f:
|
|
7
|
+
auth = json.load(f)
|
|
8
|
+
api = mijiaAPI(auth)
|
|
9
|
+
|
|
10
|
+
with open('demos/dev_info_example/yeelink.light.lamp4.json', encoding='utf-8') as f:
|
|
11
|
+
dev_info = json.load(f)
|
|
12
|
+
with open('jsons/devices.json') as f:
|
|
13
|
+
devices = json.load(f)
|
|
14
|
+
did = devices[0]['did']
|
|
15
|
+
# sleep_time is optional, default is 0.5
|
|
16
|
+
# get after set shuold be delayed for a while, or the result may be incorrect
|
|
17
|
+
device = mijiaDevices(api, dev_info, did=did, sleep_time=2)
|
|
18
|
+
print(device)
|
|
19
|
+
print('---------------------')
|
|
20
|
+
print(device.on)
|
|
21
|
+
device.on = True
|
|
22
|
+
print('---------------------')
|
|
23
|
+
print(f"{device.brightness} {device.prop_list['brightness'].unit}")
|
|
24
|
+
device.brightness = 60
|
|
25
|
+
print(f"{device.brightness} {device.prop_list['brightness'].unit}")
|
|
26
|
+
print('---------------------')
|
|
27
|
+
print(f"{device.color_temperature} {device.prop_list['color-temperature'].unit}")
|
|
28
|
+
device.color_temperature = 5000
|
|
29
|
+
print(f"{device.color_temperature} {device.prop_list['color-temperature'].unit}")
|
|
30
|
+
print('---------------------')
|
|
31
|
+
device.mode = 0
|
|
32
|
+
print('---------------------')
|
|
33
|
+
print(f"{device.brightness} {device.prop_list['brightness'].unit}")
|
|
34
|
+
device.brightness_delta = -10
|
|
35
|
+
print(f"{device.brightness} {device.prop_list['brightness'].unit}")
|
|
36
|
+
print('---------------------')
|
|
37
|
+
print(f"{device.color_temperature} {device.prop_list['color-temperature'].unit}")
|
|
38
|
+
device.ct_delta = -10
|
|
39
|
+
print(f"{device.color_temperature} {device.prop_list['color-temperature'].unit}")
|
|
40
|
+
device.ct_adjust_alexa_increase = 1
|
|
41
|
+
print(f"{device.color_temperature} {device.prop_list['color-temperature'].unit}")
|
|
42
|
+
device.ct_adjust_alexa_decrease = 2
|
|
43
|
+
print(f"{device.color_temperature} {device.prop_list['color-temperature'].unit}")
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
sys.path.extend(['.', '..'])
|
|
5
|
+
from mijiaAPI import mijiaLogin
|
|
6
|
+
|
|
7
|
+
if not os.path.exists('jsons'):
|
|
8
|
+
os.mkdir('jsons')
|
|
9
|
+
|
|
10
|
+
username = os.getenv('XIAOMI_USERNAME')
|
|
11
|
+
password = os.getenv('XIAOMI_PASSWORD')
|
|
12
|
+
api = mijiaLogin()
|
|
13
|
+
auth = api.login(username, password)
|
|
14
|
+
with open('jsons/auth.json', 'w') as f:
|
|
15
|
+
json.dump(auth, f, indent=2)
|
|
@@ -2,7 +2,7 @@ from typing import Union
|
|
|
2
2
|
import requests
|
|
3
3
|
import requests.cookies
|
|
4
4
|
|
|
5
|
-
from .utils import defaultUA, post_data
|
|
5
|
+
from .utils import defaultUA, post_data, PostDataError
|
|
6
6
|
|
|
7
7
|
class mijiaAPI(object):
|
|
8
8
|
def __init__(self, auth_data: dict):
|
|
@@ -25,6 +25,17 @@ class mijiaAPI(object):
|
|
|
25
25
|
raise Exception(f'Failed to get data, {data["message"]}')
|
|
26
26
|
return data['result']
|
|
27
27
|
|
|
28
|
+
@property
|
|
29
|
+
def available(self) -> bool:
|
|
30
|
+
"""check if the API is available"""
|
|
31
|
+
uri = '/home/device_list'
|
|
32
|
+
data = {"getVirtualModel": False, "getHuamiDevices": 0}
|
|
33
|
+
try:
|
|
34
|
+
post_data(self.session, self.ssecurity, uri, data)
|
|
35
|
+
return True
|
|
36
|
+
except PostDataError:
|
|
37
|
+
return False
|
|
38
|
+
|
|
28
39
|
def get_devices_list(self) -> list:
|
|
29
40
|
"""get devices list
|
|
30
41
|
mijiaAPI.get_devices_list() -> list
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Union
|
|
1
|
+
from typing import Union, Optional
|
|
2
2
|
from time import sleep
|
|
3
3
|
from .apis import mijiaAPI
|
|
4
4
|
|
|
@@ -19,16 +19,21 @@ class DevProp(object):
|
|
|
19
19
|
f' valuetype: {self.type}, rw: {self.rw}, unit: {self.unit}, range: {self.range}'
|
|
20
20
|
|
|
21
21
|
class mijiaDevices(object):
|
|
22
|
-
def __init__(self, api: mijiaAPI, dev_info: dict,
|
|
22
|
+
def __init__(self, api: mijiaAPI, dev_info: dict,
|
|
23
|
+
did: Optional[str] = None,
|
|
24
|
+
sleep_time: Optional[Union[int, float]] = 0.5):
|
|
23
25
|
self.api = api
|
|
24
26
|
self.name = dev_info['name']
|
|
25
27
|
self.model = dev_info['model']
|
|
26
28
|
self.prop_list = {prop['name']: DevProp(prop) for prop in dev_info['properties']}
|
|
29
|
+
self.prop_list.update({prop['name'].replace('-', '_'): DevProp(prop) for prop in dev_info['properties'] if '-' in prop['name']})
|
|
30
|
+
self.did = did
|
|
27
31
|
self.sleep_time = sleep_time
|
|
28
32
|
|
|
29
33
|
def __str__(self):
|
|
34
|
+
prop_list = [str(v) for k, v in self.prop_list.items() if '_' not in k]
|
|
30
35
|
return f'{self.name} ({self.model})\n' \
|
|
31
|
-
f'Properties:\n' + '\n'.join(
|
|
36
|
+
f'Properties:\n' + '\n'.join(prop_list)
|
|
32
37
|
|
|
33
38
|
def set(self, name: str, did: str, value: Union[bool, int]) -> Union[bool, int]:
|
|
34
39
|
if name not in self.prop_list:
|
|
@@ -67,7 +72,19 @@ class mijiaDevices(object):
|
|
|
67
72
|
sleep(self.sleep_time)
|
|
68
73
|
return ret
|
|
69
74
|
|
|
70
|
-
def
|
|
75
|
+
def set_v2(self, name: str, value: Union[bool, int], did: Optional[str] = None) -> Union[bool, int]:
|
|
76
|
+
if did is not None:
|
|
77
|
+
return self.set(name, did, value)
|
|
78
|
+
elif self.did is not None:
|
|
79
|
+
return self.set(name, self.did, value)
|
|
80
|
+
else:
|
|
81
|
+
raise ValueError('Please specify the did')
|
|
82
|
+
|
|
83
|
+
def get(self, name: str, did: Optional[str] = None) -> Union[bool, int]:
|
|
84
|
+
if did is None:
|
|
85
|
+
did = self.did
|
|
86
|
+
if did is None:
|
|
87
|
+
raise ValueError('Please specify the did')
|
|
71
88
|
if name not in self.prop_list:
|
|
72
89
|
raise ValueError(f'Unsupported property: {name}, available properties: {list(self.prop_list.keys())}')
|
|
73
90
|
prop = self.prop_list[name]
|
|
@@ -78,3 +95,16 @@ class mijiaDevices(object):
|
|
|
78
95
|
ret = self.api.get_devices_prop([method])[0]['value']
|
|
79
96
|
sleep(self.sleep_time)
|
|
80
97
|
return ret
|
|
98
|
+
|
|
99
|
+
def __setattr__(self, name: str, value: Union[bool, int]) -> None:
|
|
100
|
+
if 'prop_list' in self.__dict__ and name in self.prop_list:
|
|
101
|
+
if not self.set_v2(name, value):
|
|
102
|
+
raise RuntimeError(f'Failed to set property: {name}')
|
|
103
|
+
else:
|
|
104
|
+
super().__setattr__(name, value)
|
|
105
|
+
|
|
106
|
+
def __getattr__(self, name: str) -> Union[bool, int]:
|
|
107
|
+
if 'prop_list' in self.__dict__ and name in self.prop_list:
|
|
108
|
+
return self.get(name)
|
|
109
|
+
else:
|
|
110
|
+
return super().__getattr__(name)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mijiaAPI
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: A Python API for Xiaomi Mijia
|
|
5
5
|
Home-page: https://github.com/Do1e/mijia-api
|
|
6
6
|
Author: Do1e
|
|
@@ -29,24 +29,33 @@ pip install mijiaAPI
|
|
|
29
29
|
## 使用
|
|
30
30
|
使用实例可以参考`demos`文件夹下的示例代码,以下是简单的使用说明
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
有三个类分别用于登录和API调用
|
|
33
33
|
|
|
34
34
|
* `mijiaLogin`:登录小米账号,获取控制设备必须的`userId`, `ssecurity`, `deviceId`, `serviceToken`,方法列表
|
|
35
35
|
* `login(username: str, password: str) -> dict`:账号密码登录,返回上述信息
|
|
36
36
|
* `QRlogin() -> dict`:扫描二维码登录,返回上述信息(会在支持tty的终端打印二维码,若打印识别可查看当前文件夹下的`qr.png`)
|
|
37
37
|
|
|
38
38
|
* `mijiaAPI`:API的实现,使用`mijiaLogin`登录后返回的信息进行初始化
|
|
39
|
-
* `__init__(
|
|
39
|
+
* `__init__(auth_data: dict)`:初始化
|
|
40
|
+
* `available -> bool`:传入的`auth_data`是否有效
|
|
40
41
|
* `get_devices_list() -> list`:获取设备列表
|
|
41
42
|
* `get_homes_list() -> list`:获取家庭列表,家庭字典中包含房间列表
|
|
42
43
|
* `get_scenes_list(home_id: str) -> list`:获取手动场景列表,在 *米家->添加->手动控制* 中设置
|
|
43
44
|
* `run_scene(scene_id: str) -> bool`:运行手动场景
|
|
44
|
-
* `get_consumable_items(
|
|
45
|
+
* `get_consumable_items(home_id: str) -> list`:获取设备的耗材信息
|
|
45
46
|
* `get_devices_prop(data: list) -> list`:获取设备的属性
|
|
46
47
|
* `set_devices_prop(data: list) -> list`:设置设备的属性
|
|
47
48
|
* `data`为一个字典的列表,字典需要包含`did`, `siid`, `piid`,后面两个键可从 *https://home.miot-spec.com/spec/{model}* 中获取,其中`model`为设备的model,在设备列表中获取,如[米家台灯 1S](https://home.miot-spec.com/spec/yeelink.light.lamp4)。
|
|
48
49
|
* 网站上的方法并非全部可用,需要自行测试
|
|
49
50
|
|
|
51
|
+
|
|
52
|
+
* `mijiaDevices`:使用`mijiaAPI`和设备属性字典初始化,以便更方便地调用设备属性
|
|
53
|
+
* `__init__(api: mijiaAPI, dev_info: dict. did: str = None, sleep_time: float = 0.5)`:初始化,`dev_info`为设备属性,参考[demos/dev_info_example](demos/dev_info_example),`sleep_time`为每次调用设备属性的间隔时间(注:设置属性后立刻获取属性会不符合预期,需要延迟一段时间)
|
|
54
|
+
* `set(name: str, did: str, value: Union[bool, int]) -> Union[bool, int]`:设置设备属性
|
|
55
|
+
* `get(name: str, did: str) -> Union[bool, int]`:获取设备属性
|
|
56
|
+
* v1.2.0 新增直接通过名称设置/获取属性,需要在初始化时传入`did`,详见[demos/test_devices_v2_light.py](demos/test_devices_v2_light.py)。名称中包含`-`的属性需要替换为`_`。
|
|
57
|
+
* **欢迎大家把自己编写的设备属性字典分享到Issues中,方便大家使用**
|
|
58
|
+
|
|
50
59
|
## 致谢
|
|
51
60
|
* [janzlan/mijia-api](https://gitee.com/janzlan/mijia-api/tree/master)
|
|
52
61
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
.gitignore
|
|
2
|
+
LICENSE
|
|
3
|
+
README.md
|
|
4
|
+
requirements.txt
|
|
5
|
+
setup.py
|
|
6
|
+
.vscode/launch.json
|
|
7
|
+
demos/test_QRlogin.py
|
|
8
|
+
demos/test_apis.py
|
|
9
|
+
demos/test_available.py
|
|
10
|
+
demos/test_devices_airconditioner.py
|
|
11
|
+
demos/test_devices_light.py
|
|
12
|
+
demos/test_devices_sensor.py
|
|
13
|
+
demos/test_devices_v2_light.py
|
|
14
|
+
demos/test_login.py
|
|
15
|
+
demos/dev_info_example/miaomiaoce.sensor_ht.t1.json
|
|
16
|
+
demos/dev_info_example/yeelink.light.lamp4.json
|
|
17
|
+
mijiaAPI/__init__.py
|
|
18
|
+
mijiaAPI/__version__.py
|
|
19
|
+
mijiaAPI/apis.py
|
|
20
|
+
mijiaAPI/devices.py
|
|
21
|
+
mijiaAPI/login.py
|
|
22
|
+
mijiaAPI/urls.py
|
|
23
|
+
mijiaAPI/utils.py
|
|
24
|
+
mijiaAPI.egg-info/PKG-INFO
|
|
25
|
+
mijiaAPI.egg-info/SOURCES.txt
|
|
26
|
+
mijiaAPI.egg-info/dependency_links.txt
|
|
27
|
+
mijiaAPI.egg-info/requires.txt
|
|
28
|
+
mijiaAPI.egg-info/top_level.txt
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
LICENSE
|
|
2
|
-
README.md
|
|
3
|
-
setup.py
|
|
4
|
-
mijiaAPI/__init__.py
|
|
5
|
-
mijiaAPI/__version__.py
|
|
6
|
-
mijiaAPI/apis.py
|
|
7
|
-
mijiaAPI/devices.py
|
|
8
|
-
mijiaAPI/login.py
|
|
9
|
-
mijiaAPI/urls.py
|
|
10
|
-
mijiaAPI/utils.py
|
|
11
|
-
mijiaAPI.egg-info/PKG-INFO
|
|
12
|
-
mijiaAPI.egg-info/SOURCES.txt
|
|
13
|
-
mijiaAPI.egg-info/dependency_links.txt
|
|
14
|
-
mijiaAPI.egg-info/requires.txt
|
|
15
|
-
mijiaAPI.egg-info/top_level.txt
|
|
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
|