mijiaAPI 1.3.14__tar.gz → 1.4.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mijiaAPI
3
- Version: 1.3.14
3
+ Version: 1.4.1
4
4
  Summary: A Python API for Xiaomi Mijia
5
5
  License: GPLv3
6
6
  Author: Do1e
@@ -100,6 +100,19 @@ poetry install
100
100
 
101
101
  **注意**:并非所有米家产品库中列出的方法都可用,需要自行测试验证。
102
102
 
103
+ ### 设备信息获取
104
+
105
+ 使用 `get_device_info()` 函数可从米家规格平台在线获取设备属性字典:
106
+
107
+ ```python
108
+ from mijiaAPI import get_device_info
109
+
110
+ # 获取设备规格信息
111
+ device_info = get_device_info('yeelink.light.lamp4') # 米家台灯 1S 的 model
112
+ ```
113
+
114
+ 详细示例:[demos/test_get_device_info.py](demos/test_get_device_info.py)
115
+
103
116
  ### 设备控制封装
104
117
 
105
118
  `mijiaDevices`:基于 `mijiaAPI` 的高级封装,提供更简便的设备控制方式。
@@ -112,8 +125,14 @@ mijiaDevices(api: mijiaAPI, dev_info: dict = None, dev_name: str = None, did: st
112
125
 
113
126
  * `api`:已初始化的 `mijiaAPI` 对象
114
127
  * `dev_info`:设备属性字典(可选)
128
+ - 可通过 `get_device_info()` 函数获取
129
+ - **注意**:如果提供了 `dev_info`,则不需要提供 `dev_name`
115
130
  * `dev_name`:设备名称,用于自动查找设备(可选)
131
+ - 例如:`dev_name='台灯'`,会自动查找名称包含“台灯”的设备
132
+ - **注意**:如果提供了 `dev_name`,则不需要提供 `dev_info` 和 `did`
116
133
  * `did`:设备ID,便于直接通过属性名访问(可选)
134
+ - 如果初始化时未提供,无法使用属性样式访问,需要使用 `get()` 和 `set()` 方法指定 `did`
135
+ - 使用 `dev_name` 初始化时,`did` 会自动获取
117
136
  * `sleep_time`:属性操作间隔时间,单位秒(默认0.5秒)
118
137
  - **重要**:设置属性后立即获取可能不符合预期,需设置适当延迟
119
138
 
@@ -142,19 +161,92 @@ current_temp = device.color_temperature # 获取色温
142
161
  * 使用自然语言让小爱音箱执行:[demos/test_devices_wifispeaker.py](demos/test_devices_wifispeaker.py)
143
162
  * 通过属性直接控制台灯:[demos/test_devices_v2_light.py](demos/test_devices_v2_light.py)
144
163
 
145
- ### 设备信息获取
164
+ ### Mijia API CLI
165
+ `mijiaAPI` 还提供了一个命令行工具,可以直接在终端中使用。
146
166
 
147
- 使用 `get_device_info()` 函数可从米家规格平台在线获取设备属性字典:
167
+ ```
168
+ > python -m mijiaAPI --help
169
+ > mijiaAPI --help
170
+ usage: mijiaAPI [-h] [-p AUTH_PATH] [-l] [--list_homes] [--list_scenes] [--list_consumable_items]
171
+ [--run_scene SCENE_ID/SCENE_NAME [SCENE_ID/SCENE_NAME ...]] [--get_device_info DEVICE_MODEL] [--run PROMPT]
172
+ [--wifispeaker_name WIFISPEAKER_NAME] [--quiet]
173
+ {get,set} ...
174
+
175
+ Mijia API CLI
176
+
177
+ positional arguments:
178
+ {get,set}
179
+ get 获取设备属性
180
+ set 设置设备属性
181
+
182
+ options:
183
+ -h, --help show this help message and exit
184
+ -p AUTH_PATH, --auth_path AUTH_PATH
185
+ 认证文件保存路径,默认保存在~/.config/mijia-api-auth.json
186
+ -l, --list_devices 列出所有米家设备
187
+ --list_homes 列出家庭列表
188
+ --list_scenes 列出场景列表
189
+ --list_consumable_items
190
+ 列出耗材列表
191
+ --run_scene SCENE_ID/SCENE_NAME [SCENE_ID/SCENE_NAME ...]
192
+ 运行场景,指定场景ID或名称
193
+ --get_device_info DEVICE_MODEL
194
+ 获取设备信息,指定设备model,先使用 --list_devices 获取
195
+ --run PROMPT 使用自然语言描述你的需求,如果你有小爱音箱的话
196
+ --wifispeaker_name WIFISPEAKER_NAME
197
+ 指定小爱音箱名称,默认是获取到的第一个小爱音箱
198
+ --quiet 小爱音箱静默执行
199
+ ```
148
200
 
149
- ```python
150
- from mijiaAPI import get_device_info
201
+ ```
202
+ > python -m mijiaAPI get --help
203
+ > mijiaAPI get --help
204
+ usage: __main__.py get [-h] [-p AUTH_PATH] --dev_name DEV_NAME --prop_name PROP_NAME
205
+
206
+ options:
207
+ -h, --help show this help message and exit
208
+ -p AUTH_PATH, --auth_path AUTH_PATH
209
+ 认证文件保存路径,默认保存在~/.config/mijia-api-auth.json
210
+ --dev_name DEV_NAME 设备名称,指定为米家APP中设定的名称
211
+ --prop_name PROP_NAME
212
+ 属性名称,先使用 --get_device_info 获取
213
+ ```
151
214
 
152
- # 获取设备规格信息
153
- device_info = get_device_info('yeelink.light.lamp4') # 米家台灯 1S 的 model
215
+ ```
216
+ > python -m mijiaAPI set --help
217
+ > mijiaAPI set --help
218
+ usage: __main__.py set [-h] [-p AUTH_PATH] --dev_name DEV_NAME --prop_name PROP_NAME --value VALUE
219
+
220
+ options:
221
+ -h, --help show this help message and exit
222
+ -p AUTH_PATH, --auth_path AUTH_PATH
223
+ 认证文件保存路径,默认保存在~/.config/mijia-api-auth.json
224
+ --dev_name DEV_NAME 设备名称,指定为米家APP中设定的名称
225
+ --prop_name PROP_NAME
226
+ 属性名称,先使用 --get_device_info 获取
227
+ --value VALUE 需要设定的属性值
154
228
  ```
155
229
 
156
- 详细示例:[demos/test_get_device_info.py](demos/test_get_device_info.py)
230
+ 或者直接使用`uvx`忽略安装步骤:
231
+
232
+ ```bash
233
+ uvx mijiaAPI --help
234
+ ```
157
235
 
236
+ #### 示例:
237
+
238
+ ```bash
239
+ mijiaAPI -l # 列出所有米家设备
240
+ mijiaAPI --list_homes # 列出家庭列表
241
+ mijiaAPI --list_scenes # 列出场景列表
242
+ mijiaAPI --list_consumable_items # 列出耗材列表
243
+ mijiaAPI --run_scene SCENE_ID/SCENE_NAME # 运行场景,指定场景ID或名称
244
+ mijiaAPI --get_device_info DEVICE_MODEL # 获取设备信息,指定设备model,先使用 --list_devices 获取
245
+ mijiaAPI get --dev_name DEV_NAME --prop_name PROP_NAME # 获取设备属性
246
+ mijiaAPI set --dev_name DEV_NAME --prop_name PROP_NAME --value VALUE # 设置设备属性
247
+ mijiaAPI --run 明天天气如何
248
+ mijiaAPI --run 打开台灯并将亮度调至最大 --quiet
249
+ ```
158
250
 
159
251
  ## 致谢
160
252
 
@@ -76,6 +76,19 @@ poetry install
76
76
 
77
77
  **注意**:并非所有米家产品库中列出的方法都可用,需要自行测试验证。
78
78
 
79
+ ### 设备信息获取
80
+
81
+ 使用 `get_device_info()` 函数可从米家规格平台在线获取设备属性字典:
82
+
83
+ ```python
84
+ from mijiaAPI import get_device_info
85
+
86
+ # 获取设备规格信息
87
+ device_info = get_device_info('yeelink.light.lamp4') # 米家台灯 1S 的 model
88
+ ```
89
+
90
+ 详细示例:[demos/test_get_device_info.py](demos/test_get_device_info.py)
91
+
79
92
  ### 设备控制封装
80
93
 
81
94
  `mijiaDevices`:基于 `mijiaAPI` 的高级封装,提供更简便的设备控制方式。
@@ -88,8 +101,14 @@ mijiaDevices(api: mijiaAPI, dev_info: dict = None, dev_name: str = None, did: st
88
101
 
89
102
  * `api`:已初始化的 `mijiaAPI` 对象
90
103
  * `dev_info`:设备属性字典(可选)
104
+ - 可通过 `get_device_info()` 函数获取
105
+ - **注意**:如果提供了 `dev_info`,则不需要提供 `dev_name`
91
106
  * `dev_name`:设备名称,用于自动查找设备(可选)
107
+ - 例如:`dev_name='台灯'`,会自动查找名称包含“台灯”的设备
108
+ - **注意**:如果提供了 `dev_name`,则不需要提供 `dev_info` 和 `did`
92
109
  * `did`:设备ID,便于直接通过属性名访问(可选)
110
+ - 如果初始化时未提供,无法使用属性样式访问,需要使用 `get()` 和 `set()` 方法指定 `did`
111
+ - 使用 `dev_name` 初始化时,`did` 会自动获取
93
112
  * `sleep_time`:属性操作间隔时间,单位秒(默认0.5秒)
94
113
  - **重要**:设置属性后立即获取可能不符合预期,需设置适当延迟
95
114
 
@@ -118,19 +137,92 @@ current_temp = device.color_temperature # 获取色温
118
137
  * 使用自然语言让小爱音箱执行:[demos/test_devices_wifispeaker.py](demos/test_devices_wifispeaker.py)
119
138
  * 通过属性直接控制台灯:[demos/test_devices_v2_light.py](demos/test_devices_v2_light.py)
120
139
 
121
- ### 设备信息获取
140
+ ### Mijia API CLI
141
+ `mijiaAPI` 还提供了一个命令行工具,可以直接在终端中使用。
122
142
 
123
- 使用 `get_device_info()` 函数可从米家规格平台在线获取设备属性字典:
143
+ ```
144
+ > python -m mijiaAPI --help
145
+ > mijiaAPI --help
146
+ usage: mijiaAPI [-h] [-p AUTH_PATH] [-l] [--list_homes] [--list_scenes] [--list_consumable_items]
147
+ [--run_scene SCENE_ID/SCENE_NAME [SCENE_ID/SCENE_NAME ...]] [--get_device_info DEVICE_MODEL] [--run PROMPT]
148
+ [--wifispeaker_name WIFISPEAKER_NAME] [--quiet]
149
+ {get,set} ...
150
+
151
+ Mijia API CLI
152
+
153
+ positional arguments:
154
+ {get,set}
155
+ get 获取设备属性
156
+ set 设置设备属性
157
+
158
+ options:
159
+ -h, --help show this help message and exit
160
+ -p AUTH_PATH, --auth_path AUTH_PATH
161
+ 认证文件保存路径,默认保存在~/.config/mijia-api-auth.json
162
+ -l, --list_devices 列出所有米家设备
163
+ --list_homes 列出家庭列表
164
+ --list_scenes 列出场景列表
165
+ --list_consumable_items
166
+ 列出耗材列表
167
+ --run_scene SCENE_ID/SCENE_NAME [SCENE_ID/SCENE_NAME ...]
168
+ 运行场景,指定场景ID或名称
169
+ --get_device_info DEVICE_MODEL
170
+ 获取设备信息,指定设备model,先使用 --list_devices 获取
171
+ --run PROMPT 使用自然语言描述你的需求,如果你有小爱音箱的话
172
+ --wifispeaker_name WIFISPEAKER_NAME
173
+ 指定小爱音箱名称,默认是获取到的第一个小爱音箱
174
+ --quiet 小爱音箱静默执行
175
+ ```
124
176
 
125
- ```python
126
- from mijiaAPI import get_device_info
177
+ ```
178
+ > python -m mijiaAPI get --help
179
+ > mijiaAPI get --help
180
+ usage: __main__.py get [-h] [-p AUTH_PATH] --dev_name DEV_NAME --prop_name PROP_NAME
181
+
182
+ options:
183
+ -h, --help show this help message and exit
184
+ -p AUTH_PATH, --auth_path AUTH_PATH
185
+ 认证文件保存路径,默认保存在~/.config/mijia-api-auth.json
186
+ --dev_name DEV_NAME 设备名称,指定为米家APP中设定的名称
187
+ --prop_name PROP_NAME
188
+ 属性名称,先使用 --get_device_info 获取
189
+ ```
127
190
 
128
- # 获取设备规格信息
129
- device_info = get_device_info('yeelink.light.lamp4') # 米家台灯 1S 的 model
191
+ ```
192
+ > python -m mijiaAPI set --help
193
+ > mijiaAPI set --help
194
+ usage: __main__.py set [-h] [-p AUTH_PATH] --dev_name DEV_NAME --prop_name PROP_NAME --value VALUE
195
+
196
+ options:
197
+ -h, --help show this help message and exit
198
+ -p AUTH_PATH, --auth_path AUTH_PATH
199
+ 认证文件保存路径,默认保存在~/.config/mijia-api-auth.json
200
+ --dev_name DEV_NAME 设备名称,指定为米家APP中设定的名称
201
+ --prop_name PROP_NAME
202
+ 属性名称,先使用 --get_device_info 获取
203
+ --value VALUE 需要设定的属性值
130
204
  ```
131
205
 
132
- 详细示例:[demos/test_get_device_info.py](demos/test_get_device_info.py)
206
+ 或者直接使用`uvx`忽略安装步骤:
207
+
208
+ ```bash
209
+ uvx mijiaAPI --help
210
+ ```
133
211
 
212
+ #### 示例:
213
+
214
+ ```bash
215
+ mijiaAPI -l # 列出所有米家设备
216
+ mijiaAPI --list_homes # 列出家庭列表
217
+ mijiaAPI --list_scenes # 列出场景列表
218
+ mijiaAPI --list_consumable_items # 列出耗材列表
219
+ mijiaAPI --run_scene SCENE_ID/SCENE_NAME # 运行场景,指定场景ID或名称
220
+ mijiaAPI --get_device_info DEVICE_MODEL # 获取设备信息,指定设备model,先使用 --list_devices 获取
221
+ mijiaAPI get --dev_name DEV_NAME --prop_name PROP_NAME # 获取设备属性
222
+ mijiaAPI set --dev_name DEV_NAME --prop_name PROP_NAME --value VALUE # 设置设备属性
223
+ mijiaAPI --run 明天天气如何
224
+ mijiaAPI --run 打开台灯并将亮度调至最大 --quiet
225
+ ```
134
226
 
135
227
  ## 致谢
136
228
 
@@ -0,0 +1,317 @@
1
+ from typing import Optional
2
+ import argparse
3
+ import json
4
+ import os
5
+ import sys
6
+ import time
7
+
8
+ from .apis import mijiaAPI
9
+ from .devices import mijiaDevices, get_device_info
10
+ from .login import mijiaLogin
11
+
12
+ def parse_args(args):
13
+ parser = argparse.ArgumentParser(description="Mijia API CLI")
14
+ subparsers = parser.add_subparsers(dest='command')
15
+ parser.add_argument(
16
+ '-p', '--auth_path',
17
+ type=str,
18
+ default=os.path.join(os.path.expanduser("~"), ".config", "mijia-api-auth.json"),
19
+ help="认证文件保存路径,默认保存在~/.config/mijia-api-auth.json",
20
+ )
21
+ parser.add_argument(
22
+ '-l', '--list_devices',
23
+ action='store_true',
24
+ help="列出所有米家设备",
25
+ )
26
+ parser.add_argument(
27
+ '--list_homes',
28
+ action='store_true',
29
+ help="列出家庭列表",
30
+ )
31
+ parser.add_argument(
32
+ '--list_scenes',
33
+ action='store_true',
34
+ help="列出场景列表",
35
+ )
36
+ parser.add_argument(
37
+ '--list_consumable_items',
38
+ action='store_true',
39
+ help="列出耗材列表",
40
+ )
41
+ parser.add_argument(
42
+ '--run_scene',
43
+ type=str,
44
+ help="运行场景,指定场景ID或名称",
45
+ nargs='+',
46
+ metavar='SCENE_ID/SCENE_NAME',
47
+ )
48
+ parser.add_argument(
49
+ '--get_device_info',
50
+ type=str,
51
+ help="获取设备信息,指定设备model,先使用 --list_devices 获取",
52
+ metavar='DEVICE_MODEL',
53
+ )
54
+ parser.add_argument(
55
+ '--run',
56
+ type=str,
57
+ help="使用自然语言描述你的需求,如果你有小爱音箱的话",
58
+ metavar='PROMPT',
59
+ )
60
+ parser.add_argument(
61
+ '--wifispeaker_name',
62
+ type=str,
63
+ help="指定小爱音箱名称,默认是获取到的第一个小爱音箱",
64
+ default=None,
65
+ )
66
+ parser.add_argument(
67
+ '--quiet',
68
+ action='store_true',
69
+ help="小爱音箱静默执行",
70
+ )
71
+
72
+ get = subparsers.add_parser(
73
+ 'get',
74
+ help="获取设备属性",
75
+ )
76
+ get.set_defaults(func='get')
77
+ get.add_argument(
78
+ '-p', '--auth_path',
79
+ type=str,
80
+ default=os.path.join(os.path.expanduser("~"), ".config", "mijia-api-auth.json"),
81
+ help="认证文件保存路径,默认保存在~/.config/mijia-api-auth.json",
82
+ )
83
+ get.add_argument(
84
+ '--dev_name',
85
+ type=str,
86
+ help="设备名称,指定为米家APP中设定的名称",
87
+ required=True,
88
+ )
89
+ get.add_argument(
90
+ '--prop_name',
91
+ type=str,
92
+ help="属性名称,先使用 --get_device_info 获取",
93
+ required=True,
94
+ )
95
+
96
+ set = subparsers.add_parser(
97
+ 'set',
98
+ help="设置设备属性",
99
+ )
100
+ set.set_defaults(func='set')
101
+ set.add_argument(
102
+ '-p', '--auth_path',
103
+ type=str,
104
+ default=os.path.join(os.path.expanduser("~"), ".config", "mijia-api-auth.json"),
105
+ help="认证文件保存路径,默认保存在~/.config/mijia-api-auth.json",
106
+ )
107
+ set.add_argument(
108
+ '--dev_name',
109
+ type=str,
110
+ help="设备名称,指定为米家APP中设定的名称",
111
+ required=True,
112
+ )
113
+ set.add_argument(
114
+ '--prop_name',
115
+ type=str,
116
+ help="属性名称,先使用 --get_device_info 获取",
117
+ required=True,
118
+ )
119
+ set.add_argument(
120
+ '--value',
121
+ type=str,
122
+ help="需要设定的属性值",
123
+ required=True,
124
+ )
125
+ return parser.parse_args(args)
126
+
127
+ def init_api(auth_path: str) -> mijiaAPI:
128
+ if os.path.isdir(auth_path):
129
+ auth_path = os.path.join(auth_path, "mijia-api-auth.json")
130
+ if os.path.exists(auth_path):
131
+ try:
132
+ with open(auth_path, 'r') as f:
133
+ auth = json.load(f)
134
+ api = mijiaAPI(auth_data=auth)
135
+ if not api.available:
136
+ raise ValueError("Saved auth is no longer valid")
137
+ except (json.JSONDecodeError, ValueError):
138
+ api = mijiaLogin(save_path=auth_path)
139
+ auth = api.QRlogin()
140
+ api = mijiaAPI(auth_data=auth)
141
+ else:
142
+ api = mijiaLogin(save_path=auth_path)
143
+ auth = api.QRlogin()
144
+ api = mijiaAPI(auth_data=auth)
145
+ return api
146
+
147
+ def get_devices_list(api: mijiaAPI, verbose: bool = True) -> dict:
148
+ devices = api.get_devices_list()
149
+ if 'list' in devices:
150
+ devices = devices['list']
151
+ else:
152
+ devices = []
153
+ if verbose:
154
+ print("Devices:")
155
+ for device in devices:
156
+ print(f" - {device['name']}\n"
157
+ f" did: {device['did']}\n"
158
+ f" model: {device['model']}\n"
159
+ f" online: {device['isOnline']}")
160
+ device_mapping = {device['did']: device for device in devices}
161
+ return device_mapping
162
+
163
+ def get_homes_list(api: mijiaAPI, verbose: bool = True, device_mapping: Optional[dict] = None) -> dict:
164
+ if verbose:
165
+ if device_mapping is None:
166
+ device_mapping = get_devices_list(api, verbose=False)
167
+ homes = api.get_homes_list()
168
+ if 'homelist' in homes:
169
+ homes = homes['homelist']
170
+ else:
171
+ homes = []
172
+ if verbose:
173
+ print("Homes:")
174
+ for home in homes:
175
+ print(f" - {home['name']}\n"
176
+ f" id: {home['id']}\n"
177
+ f" address: {home['address']}\n"
178
+ f" room count: {len(home['roomlist'])}\n"
179
+ f" create time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(home['create_time']))}")
180
+ print(" Rooms:")
181
+ for room in home['roomlist']:
182
+ devices_name = []
183
+ if room['dids']:
184
+ for did in room['dids']:
185
+ if did in device_mapping:
186
+ devices_name.append(device_mapping[did]['name'])
187
+ else:
188
+ devices_name.append(did)
189
+ dids = ', '.join(devices_name)
190
+ print(f" - {room['name']}\n"
191
+ f" id: {room['id']}\n"
192
+ f" dids: {dids}\n"
193
+ f" create time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(room['create_time']))}")
194
+ home_mapping = {home['id']: home for home in homes}
195
+ return home_mapping
196
+
197
+ def get_scenes_list(api: mijiaAPI, verbose: bool = True, home_mapping: Optional[dict] = None) -> dict:
198
+ if home_mapping is None:
199
+ home_mapping = get_homes_list(api, verbose=False)
200
+ scene_mapping = {}
201
+ for home_id, home in home_mapping.items():
202
+ scenes = api.get_scenes_list(home_id)
203
+ if 'scene_info_list' in scenes:
204
+ scenes = scenes['scene_info_list']
205
+ else:
206
+ scenes = []
207
+ if scenes and verbose:
208
+ print(f"Scenes in {home['name']} ({home_id}):")
209
+ for scene in scenes:
210
+ print(f" - {scene['name']}\n"
211
+ f" id: {scene['scene_id']}\n"
212
+ f" create time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(scene['create_time'])))}\n"
213
+ f" update time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(scene['update_time'])))}")
214
+ scene_mapping.update({scene['scene_id']: scene for scene in scenes})
215
+ return scene_mapping
216
+
217
+ def get_consumable_items(api: mijiaAPI, home_mapping: Optional[dict] = None):
218
+ if home_mapping is None:
219
+ home_mapping = get_homes_list(api, verbose=False)
220
+ for home_id, home in home_mapping.items():
221
+ items = api.get_consumable_items(home_id)
222
+ if 'items' in items:
223
+ items = items['items'][0]['consumes_data']
224
+ else:
225
+ items = []
226
+ print(f"Consumable items in {home['name']} ({home_id}):")
227
+ for item in items:
228
+ print(f" - {item['details'][0]['description']} in {item['name']}({item['did']})\n"
229
+ f" value: {item['details'][0]['value']}")
230
+
231
+ def run_scene(api: mijiaAPI, scene_id: str, scene_mapping: Optional[dict] = None) -> bool:
232
+ if scene_mapping is None:
233
+ scene_mapping = get_scenes_list(api, verbose=False)
234
+ if scene_id not in scene_mapping:
235
+ scene_name_to_find = scene_id
236
+ found = False
237
+ for sid, scene in scene_mapping.items():
238
+ if scene['name'] == scene_name_to_find:
239
+ scene_id = sid
240
+ found = True
241
+ break
242
+ if not found:
243
+ print(f"Scene {scene_name_to_find} not found")
244
+ return False
245
+ scene_name = scene_mapping[scene_id]['name']
246
+ ret = api.run_scene(scene_id)
247
+ if ret:
248
+ print(f"Scene {scene_name}({scene_id}) run successfully")
249
+ return True
250
+ else:
251
+ print(f"Failed to run scene {scene_name}({scene_id})")
252
+ return False
253
+
254
+ def get(args):
255
+ api = init_api(args.auth_path)
256
+ device = mijiaDevices(api, dev_name=args.dev_name)
257
+ value = device.get(args.prop_name)
258
+ unit = device.prop_list[args.prop_name].unit
259
+ print(f"The {args.prop_name} of {args.dev_name} is {value} {unit if unit else ''}")
260
+
261
+ def set(args):
262
+ api = init_api(args.auth_path)
263
+ device = mijiaDevices(api, dev_name=args.dev_name)
264
+ ret = device.set_v2(args.prop_name, args.value)
265
+ unit = device.prop_list[args.prop_name].unit
266
+ if ret:
267
+ print(f"The {args.prop_name} of {args.dev_name} is set to {args.value} {unit if unit else ''}")
268
+ else:
269
+ print(f"Failed to set the {args.prop_name} of {args.dev_name} to {args.value}")
270
+
271
+
272
+ def main(args):
273
+ args = parse_args(args)
274
+ api = init_api(args.auth_path)
275
+ device_mapping = None
276
+ home_mapping = None
277
+ scenes_mapping = None
278
+
279
+ if args.list_devices:
280
+ device_mapping = get_devices_list(api)
281
+ if args.list_homes:
282
+ home_mapping = get_homes_list(api, device_mapping=device_mapping)
283
+ if args.list_scenes:
284
+ scenes_mapping = get_scenes_list(api, home_mapping=home_mapping)
285
+ if args.list_consumable_items:
286
+ get_consumable_items(api, home_mapping=home_mapping)
287
+ if args.run_scene:
288
+ for scene_id in args.run_scene:
289
+ 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
+ if args.run:
294
+ if device_mapping is None:
295
+ device_mapping = get_devices_list(api, verbose=False)
296
+ if args.wifispeaker_name is None:
297
+ wifispeaker = None
298
+ for device in device_mapping.values():
299
+ if 'xiaomi.wifispeaker' in device['model']:
300
+ wifispeaker = mijiaDevices(api, dev_name=device['name'])
301
+ break
302
+ if wifispeaker is None:
303
+ raise ValueError("No wifispeaker found")
304
+ else:
305
+ wifispeaker = mijiaDevices(api, dev_name=args.wifispeaker_name)
306
+ wifispeaker.run_action('execute-text-directive', _in=[args.run, args.quiet])
307
+ if hasattr(args, 'func') and args.func is not None:
308
+ if args.func == 'get':
309
+ get(args)
310
+ if args.func == 'set':
311
+ set(args)
312
+
313
+ def cli():
314
+ main(sys.argv[1:])
315
+
316
+ if __name__ == "__main__":
317
+ main(sys.argv[1:])
@@ -174,7 +174,23 @@ class mijiaDevices(object):
174
174
  if value not in [item['value'] for item in prop.value_list]:
175
175
  raise ValueError(f'Invalid value: {value}, should be in {prop.value_list}')
176
176
  if prop.type == 'bool':
177
- if not isinstance(value, bool):
177
+ if isinstance(value, str):
178
+ if value.lower() == 'true':
179
+ value = True
180
+ elif value.lower() == 'false':
181
+ value = False
182
+ elif value in ['0', '1']:
183
+ value = bool(int(value))
184
+ else:
185
+ raise ValueError(f'Invalid value for bool: {value}, should be True or False')
186
+ elif isinstance(value, int):
187
+ if value == 0:
188
+ value = False
189
+ elif value == 1:
190
+ value = True
191
+ else:
192
+ raise ValueError(f'Invalid value for bool: {value}, should be True or False')
193
+ elif not isinstance(value, bool):
178
194
  raise ValueError(f'Invalid value for bool: {value}, should be True or False')
179
195
  elif prop.type in ['int', 'uint']:
180
196
  value = int(value)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mijiaAPI"
3
- version = "1.3.14"
3
+ version = "1.4.1"
4
4
  description = "A Python API for Xiaomi Mijia"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9,<4.0"
@@ -10,9 +10,12 @@ dependencies = [
10
10
  "requests>=2.32.3,<3.0.0",
11
11
  ]
12
12
 
13
+ [project.scripts]
14
+ mijiaAPI = "mijiaAPI.__main__:cli"
15
+
13
16
  [tool.poetry]
14
17
  name = "mijiaAPI"
15
- version = "1.3.14"
18
+ version = "1.4.1"
16
19
  description = "A Python API for Xiaomi Mijia"
17
20
  authors = ["Do1e <dpj.email@qq.com>"]
18
21
  license = "GPLv3"
@@ -34,6 +37,9 @@ requests = "^2.32.3"
34
37
  qrcode = "^8.0"
35
38
  pillow = "^11.0.0"
36
39
 
40
+ [tool.poetry.scripts]
41
+ mijiaAPI = "mijiaAPI.__main__:cli"
42
+
37
43
  [tool.poetry-dynamic-versioning]
38
44
  enable = false
39
45
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes