mijiaAPI 2.0.0__tar.gz → 2.0.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: 2.0.0
3
+ Version: 2.0.1
4
4
  Summary: A Python API for Xiaomi Mijia
5
5
  License: GPLv3
6
6
  Author: Do1e
@@ -133,7 +133,7 @@ def init_api(auth_path: str) -> mijiaAPI:
133
133
  auth = json.load(f)
134
134
  api = mijiaAPI(auth_data=auth)
135
135
  if not api.available:
136
- raise ValueError("Saved auth is no longer valid")
136
+ raise ValueError("认证信息已过期")
137
137
  except (json.JSONDecodeError, ValueError):
138
138
  api = mijiaLogin(save_path=auth_path)
139
139
  auth = api.QRlogin()
@@ -147,7 +147,7 @@ def init_api(auth_path: str) -> mijiaAPI:
147
147
  def get_devices_list(api: mijiaAPI, verbose: bool = True) -> dict:
148
148
  devices = api.get_devices_list()
149
149
  if verbose:
150
- print("Devices:")
150
+ print("设备列表:")
151
151
  for device in devices:
152
152
  print(f" - {device['name']}\n"
153
153
  f" did: {device['did']}\n"
@@ -162,14 +162,14 @@ def get_homes_list(api: mijiaAPI, verbose: bool = True, device_mapping: Optional
162
162
  device_mapping = get_devices_list(api, verbose=False)
163
163
  homes = api.get_homes_list()
164
164
  if verbose:
165
- print("Homes:")
165
+ print("家庭列表:")
166
166
  for home in homes:
167
167
  print(f" - {home['name']}\n"
168
- f" id: {home['id']}\n"
169
- f" address: {home['address']}\n"
170
- f" room count: {len(home['roomlist'])}\n"
171
- f" create time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(home['create_time']))}")
172
- print(" Rooms:")
168
+ f" ID: {home['id']}\n"
169
+ f" 地址: {home['address']}\n"
170
+ f" 房间数量: {len(home['roomlist'])}\n"
171
+ f" 创建时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(home['create_time']))}")
172
+ print( " 房间列表:")
173
173
  for room in home['roomlist']:
174
174
  devices_name = []
175
175
  if room['dids']:
@@ -180,9 +180,9 @@ def get_homes_list(api: mijiaAPI, verbose: bool = True, device_mapping: Optional
180
180
  devices_name.append(did)
181
181
  dids = ', '.join(devices_name)
182
182
  print(f" - {room['name']}\n"
183
- f" id: {room['id']}\n"
184
- f" devices: {dids}\n"
185
- f" create time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(room['create_time']))}")
183
+ f" ID: {room['id']}\n"
184
+ f" 设备列表: {dids}\n"
185
+ f" 创建时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(room['create_time']))}")
186
186
  home_mapping = {home['id']: home for home in homes}
187
187
  return home_mapping
188
188
 
@@ -193,11 +193,11 @@ def get_scenes_list(api: mijiaAPI, verbose: bool = True, home_mapping: Optional[
193
193
  for home_id, home in home_mapping.items():
194
194
  scenes = api.get_scenes_list(home_id)
195
195
  if scenes and verbose:
196
- print(f"Scenes in {home['name']} ({home_id}):")
196
+ print(f"{home['name']} ({home_id}) 中的场景:")
197
197
  for scene in scenes:
198
198
  print(f" - {scene['name']}\n"
199
- f" id: {scene['scene_id']}\n"
200
- f" create time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(scene['create_time'])))}\n"
199
+ f" ID: {scene['scene_id']}\n"
200
+ f" 创建时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(scene['create_time'])))}\n"
201
201
  f" update time: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(scene['update_time'])))}")
202
202
  scene_mapping.update({scene['scene_id']: scene for scene in scenes})
203
203
  return scene_mapping
@@ -207,11 +207,11 @@ def get_consumable_items(api: mijiaAPI, home_mapping: Optional[dict] = None):
207
207
  home_mapping = get_homes_list(api, verbose=False)
208
208
  for home_id, home in home_mapping.items():
209
209
  items = api.get_consumable_items(home_id, home['uid'])
210
- print(f"Consumable items in {home['name']} ({home_id}):")
210
+ print(f"{home['name']} ({home_id}) 中的耗材:")
211
211
  for item in items:
212
212
  for consumes_data in item['consumes_data']:
213
- print(f" - {consumes_data['details'][0]['description']} in {consumes_data['name']}({consumes_data['did']})\n"
214
- f" value: {consumes_data['details'][0]['value']}")
213
+ print(f" - {consumes_data['details'][0]['description']} {consumes_data['name']}({consumes_data['did']})\n"
214
+ f" 值: {consumes_data['details'][0]['value']}")
215
215
 
216
216
  def run_scene(api: mijiaAPI, scene_id: str, scene_mapping: Optional[dict] = None) -> bool:
217
217
  if scene_mapping is None:
@@ -225,15 +225,15 @@ def run_scene(api: mijiaAPI, scene_id: str, scene_mapping: Optional[dict] = None
225
225
  found = True
226
226
  break
227
227
  if not found:
228
- print(f"Scene {scene_name_to_find} not found")
228
+ print(f"场景 {scene_name_to_find} 未找到")
229
229
  return False
230
230
  scene_name = scene_mapping[scene_id]['name']
231
231
  ret = api.run_scene(scene_id)
232
232
  if ret:
233
- print(f"Scene {scene_name}({scene_id}) run successfully")
233
+ print(f"场景 {scene_name}({scene_id}) 运行成功")
234
234
  return True
235
235
  else:
236
- print(f"Failed to run scene {scene_name}({scene_id})")
236
+ print(f"运行场景 {scene_name}({scene_id}) 失败")
237
237
  return False
238
238
 
239
239
  def get(args):
@@ -241,7 +241,7 @@ def get(args):
241
241
  device = mijiaDevice(api, dev_name=args.dev_name)
242
242
  value = device.get(args.prop_name)
243
243
  unit = device.prop_list[args.prop_name].unit
244
- print(f"The {args.prop_name} of {args.dev_name} is {value} {unit if unit else ''}")
244
+ print(f"{args.dev_name} {args.prop_name} 值为 {value} {unit if unit else ''}")
245
245
 
246
246
  def set(args):
247
247
  api = init_api(args.auth_path)
@@ -249,9 +249,9 @@ def set(args):
249
249
  ret = device.set(args.prop_name, args.value)
250
250
  unit = device.prop_list[args.prop_name].unit
251
251
  if ret:
252
- print(f"The {args.prop_name} of {args.dev_name} is set to {args.value} {unit if unit else ''}")
252
+ print(f"{args.dev_name} {args.prop_name} 值已设置为 {args.value} {unit if unit else ''}")
253
253
  else:
254
- print(f"Failed to set the {args.prop_name} of {args.dev_name} to {args.value}")
254
+ print(f"设置 {args.dev_name} {args.prop_name} 值为 {args.value} 失败")
255
255
 
256
256
 
257
257
  def main(args):
@@ -295,7 +295,7 @@ def main(args):
295
295
  wifispeaker = mijiaDevice(api, dev_name=device['name'])
296
296
  break
297
297
  if wifispeaker is None:
298
- raise ValueError("No wifispeaker found")
298
+ raise ValueError("未找到小爱音箱设备")
299
299
  else:
300
300
  wifispeaker = mijiaDevice(api, dev_name=args.wifispeaker_name)
301
301
  wifispeaker.run_action('execute-text-directive', _in=[args.run, args.quiet])
@@ -4,7 +4,8 @@ from typing import Union, Optional
4
4
  import requests
5
5
  import requests.cookies
6
6
 
7
- from .utils import defaultUA, post_data, PostDataError
7
+ from .consts import defaultUA
8
+ from .utils import post_data
8
9
 
9
10
 
10
11
  class mijiaAPI(object):
@@ -19,7 +20,7 @@ class mijiaAPI(object):
19
20
  Exception: 当授权数据不完整时抛出异常。
20
21
  """
21
22
  if any(k not in auth_data for k in ['userId', 'deviceId', 'ssecurity', 'serviceToken']):
22
- raise Exception('Invalid authorize data')
23
+ raise Exception('授权数据无效')
23
24
  self.userId = auth_data['userId']
24
25
  self.ssecurity = auth_data['ssecurity']
25
26
  self.session = requests.Session()
@@ -35,7 +36,7 @@ class mijiaAPI(object):
35
36
  @staticmethod
36
37
  def _post_process(data: dict) -> Union[list, bool]:
37
38
  if data['code'] != 0:
38
- raise Exception(f'Failed to get data, {data["message"]}')
39
+ raise Exception(f'获取数据失败, {data["message"]}')
39
40
  return data['result']
40
41
 
41
42
  @property
@@ -64,18 +65,26 @@ class mijiaAPI(object):
64
65
  home_list = self.get_homes_list()
65
66
  devices = []
66
67
  for home in home_list:
67
- data = {
68
- "home_owner": home['uid'],
69
- "home_id": int(home['id']),
70
- "limit": 200,
71
- "get_split_device": True,
72
- "support_smart_home": True,
73
- "get_cariot_device": True,
74
- "get_third_device": True
75
- }
76
- ret = self._post_process(post_data(self.session, self.ssecurity, uri, data))
77
- if ret and ret.get('device_info'):
78
- devices.extend(ret['device_info'])
68
+ start_did = ''
69
+ has_more = True
70
+ while has_more:
71
+ data = {
72
+ "home_owner": home['uid'],
73
+ "home_id": int(home['id']),
74
+ "limit": 200,
75
+ "start_did": start_did,
76
+ "get_split_device": True,
77
+ "support_smart_home": True,
78
+ "get_cariot_device": True,
79
+ "get_third_device": True
80
+ }
81
+ ret = self._post_process(post_data(self.session, self.ssecurity, uri, data))
82
+ if ret and ret.get('device_info'):
83
+ devices.extend(ret['device_info'])
84
+ start_did = ret.get('max_did', '')
85
+ has_more = ret.get('has_more', False) and start_did != ''
86
+ else:
87
+ has_more = False
79
88
  return devices
80
89
 
81
90
  def get_homes_list(self) -> list:
@@ -5,3 +5,5 @@ qrURL = 'https://account.xiaomi.com/longPolling/loginUrl'
5
5
  apiURL = 'https://api.io.mi.com/app'
6
6
  deviceURL = 'https://home.miot-spec.com/spec/'
7
7
  accountURL = 'https://account.xiaomi.com/pass2/profile/home?bizFlag=&userId='
8
+
9
+ defaultUA = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36 Edg/126.0.0.0'
@@ -6,7 +6,7 @@ import requests
6
6
  from time import sleep
7
7
  from .apis import mijiaAPI
8
8
  from .code import ERROR_CODE
9
- from .urls import deviceURL
9
+ from .consts import deviceURL
10
10
  from .logger import get_logger
11
11
 
12
12
  logger = get_logger(__name__)
@@ -26,7 +26,7 @@ class DevProp(object):
26
26
  self.desc = prop_dict['description']
27
27
  self.type = prop_dict['type']
28
28
  if self.type not in ['bool', 'int', 'uint', 'float', 'string']:
29
- raise ValueError(f'Unsupported type: {self.type}, available types: bool, int, uint, float, string')
29
+ raise ValueError(f'不支持的类型: {self.type}, 可选类型: bool, int, uint, float, string')
30
30
  self.rw = prop_dict['rw']
31
31
  self.unit = prop_dict['unit']
32
32
  self.range = prop_dict['range']
@@ -106,18 +106,18 @@ class mijiaDevice(object):
106
106
  - 如果只提供了dev_info,则直接使用该信息。
107
107
  """
108
108
  if dev_info is None and dev_name is None:
109
- raise RuntimeError("Either 'dev_info' or 'dev_name' must be provided.")
109
+ raise RuntimeError("必须提供 'dev_info' 'dev_name' 中的一个参数。")
110
110
  if dev_info is not None and dev_name is not None:
111
- logger.warning("Both 'dev_info' and 'dev_name' provided. Using 'dev_info' for initialization.")
111
+ logger.warning("同时提供了 'dev_info' 'dev_name'。将使用 'dev_info' 进行初始化。")
112
112
 
113
113
  self.api = api
114
114
  if dev_info is None:
115
115
  devices_list = self.api.get_devices_list()
116
116
  matches = [device for device in devices_list if device['name'] == dev_name]
117
117
  if not matches:
118
- raise ValueError(f"Device {dev_name} not found")
118
+ raise ValueError(f"未找到设备 {dev_name}")
119
119
  elif len(matches) > 1:
120
- raise ValueError(f"Multiple devices named {dev_name} found")
120
+ raise ValueError(f"找到多个名为 {dev_name} 的设备")
121
121
  else:
122
122
  dev_info = get_device_info(matches[0]['model'])
123
123
  did = matches[0]['did']
@@ -171,15 +171,15 @@ class mijiaDevice(object):
171
171
  if did is None:
172
172
  did = self.did
173
173
  if did is None:
174
- raise ValueError('Please specify the did')
174
+ raise ValueError('请指定设备ID (did)')
175
175
  if name not in self.prop_list:
176
- raise ValueError(f'Unsupported property: {name}, available properties: {list(self.prop_list.keys())}')
176
+ raise ValueError(f'不支持的属性: {name}, 可用属性: {list(self.prop_list.keys())}')
177
177
  prop = self.prop_list[name]
178
178
  if 'w' not in prop.rw:
179
- raise ValueError(f'Property {name} can not be written')
179
+ raise ValueError(f'属性 {name} 不可写入')
180
180
  if prop.value_list:
181
181
  if value not in [item['value'] for item in prop.value_list]:
182
- raise ValueError(f'Invalid value: {value}, should be in {prop.value_list}')
182
+ raise ValueError(f'无效值: {value}, 请使用 {prop.value_list}')
183
183
  if prop.type == 'bool':
184
184
  if isinstance(value, str):
185
185
  if value.lower() == 'true':
@@ -189,51 +189,51 @@ class mijiaDevice(object):
189
189
  elif value in ['0', '1']:
190
190
  value = bool(int(value))
191
191
  else:
192
- raise ValueError(f'Invalid value for bool: {value}, should be True or False')
192
+ raise ValueError(f'无效布尔值: {value}')
193
193
  elif isinstance(value, int):
194
194
  if value == 0:
195
195
  value = False
196
196
  elif value == 1:
197
197
  value = True
198
198
  else:
199
- raise ValueError(f'Invalid value for bool: {value}, should be True or False')
199
+ raise ValueError(f'无效布尔值: {value}')
200
200
  elif not isinstance(value, bool):
201
- raise ValueError(f'Invalid value for bool: {value}, should be True or False')
201
+ raise ValueError(f'无效布尔值: {value}')
202
202
  elif prop.type in ['int', 'uint']:
203
203
  value = int(value)
204
204
  if prop.range:
205
205
  if value < prop.range[0] or value > prop.range[1]:
206
- raise ValueError(f'Value out of range: {value}, should be in range {prop.range[:2]}')
206
+ raise ValueError(f'{value} 超出数值范围, 应该在 {prop.range[:2]} 之间')
207
207
  if len(prop.range) >= 3 and prop.range[2] != 1:
208
208
  if (value - prop.range[0]) % prop.range[2] != 0:
209
209
  raise ValueError(
210
- f'Invalid value: {value}, should be in range {prop.range[:2]} with step {prop.range[2]}')
210
+ f'无效的值: {value}, 应该在范围 {prop.range[:2]} 内且步长为 {prop.range[2]}')
211
211
  elif prop.type == 'float':
212
212
  value = float(value)
213
213
  if prop.range:
214
214
  if value < prop.range[0] or value > prop.range[1]:
215
- raise ValueError(f'Value out of range: {value}, should be in range {prop.range[:2]}')
215
+ raise ValueError(f'{value} 超出数值范围, 应该在 {prop.range[:2]} 之间')
216
216
  if len(prop.range) >= 3 and isinstance(prop.range[2], int):
217
217
  if int(value - prop.range[0]) % prop.range[2] != 0:
218
218
  raise ValueError(
219
- f'Invalid value: {value}, should be in range {prop.range[:2]} with step {prop.range[2]}')
219
+ f'无效的值: {value}, 应该在范围 {prop.range[:2]} 内且步长为 {prop.range[2]}')
220
220
  elif prop.type == 'string':
221
221
  if not isinstance(value, str):
222
- raise ValueError(f'Invalid value for string: {value}, should be a string')
222
+ raise ValueError(f'无效字符串值: {value}')
223
223
  else:
224
- raise ValueError(f'Unsupported type: {prop.type}, available types: bool, int, uint, float, string')
224
+ raise ValueError(f'不支持的类型: {prop.type}, 可用类型: bool, int, uint, float, string')
225
225
  method = prop.method.copy()
226
226
  method['did'] = did
227
227
  method['value'] = value
228
228
  result = self.api.set_devices_prop([method])[0]
229
229
  if result['code'] != 0:
230
230
  raise RuntimeError(
231
- f"Failed to set property: {name}, "
232
- f"code: {result['code']}, "
233
- f"message: {ERROR_CODE.get(str(result['code']), 'Unknown error')}"
231
+ f"设置属性 {name} 失败, "
232
+ f"错误码: {result['code']}, "
233
+ f"错误信息: {ERROR_CODE.get(str(result['code']), '未知错误')}"
234
234
  )
235
235
  sleep(self.sleep_time)
236
- logger.debug(f"Set property: {self.name} -> {name}, value: {value}, result: {result}")
236
+ logger.debug(f"设置属性: {self.name} -> {name}, 值: {value}, 结果: {result}")
237
237
  return result['code'] == 0
238
238
 
239
239
  def get(self, name: str, did: Optional[str] = None) -> Union[bool, int, float, str]:
@@ -254,23 +254,23 @@ class mijiaDevice(object):
254
254
  if did is None:
255
255
  did = self.did
256
256
  if did is None:
257
- raise ValueError('Please specify the did')
257
+ raise ValueError('请指定设备ID (did)')
258
258
  if name not in self.prop_list:
259
- raise ValueError(f'Unsupported property: {name}, available properties: {list(self.prop_list.keys())}')
259
+ raise ValueError(f'不支持的属性: {name}, 可用属性: {list(self.prop_list.keys())}')
260
260
  prop = self.prop_list[name]
261
261
  if 'r' not in prop.rw:
262
- raise ValueError(f'Property {name} can not be read')
262
+ raise ValueError(f'属性 {name} 不可读取')
263
263
  method = prop.method.copy()
264
264
  method['did'] = did
265
265
  result = self.api.get_devices_prop([method])[0]
266
266
  if result['code'] != 0:
267
267
  raise RuntimeError(
268
- f"Failed to get property: {name}, "
269
- f"code: {result['code']}, "
270
- f"message: {ERROR_CODE.get(str(result['code']), 'Unknown error')}"
268
+ f"获取属性 {name} 失败, "
269
+ f"错误码: {result['code']}, "
270
+ f"错误信息: {ERROR_CODE.get(str(result['code']), '未知错误')}"
271
271
  )
272
272
  sleep(self.sleep_time)
273
- logger.debug(f"Get property: {self.name} -> {name}, result: {result}")
273
+ logger.debug(f"获取属性: {self.name} -> {name}, 结果: {result}")
274
274
  return result['value']
275
275
 
276
276
  def __setattr__(self, name: str, value: Union[bool, int, float, str]) -> None:
@@ -286,7 +286,7 @@ class mijiaDevice(object):
286
286
  """
287
287
  if 'prop_list' in self.__dict__ and name in self.prop_list:
288
288
  if not self.set(name, value):
289
- raise RuntimeError(f'Failed to set property: {name}')
289
+ raise RuntimeError(f'设置属性 {name} 失败')
290
290
  else:
291
291
  super().__setattr__(name, value)
292
292
 
@@ -331,9 +331,9 @@ class mijiaDevice(object):
331
331
  if did is None:
332
332
  did = self.did
333
333
  if did is None:
334
- raise ValueError('Please specify the did')
334
+ raise ValueError('请指定设备ID (did)')
335
335
  if name not in self.action_list:
336
- raise ValueError(f'Unsupported action: {name}, available actions: {list(self.action_list.keys())}')
336
+ raise ValueError(f'不支持的动作: {name}, 可用动作: {list(self.action_list.keys())}')
337
337
  act = self.action_list[name]
338
338
  method = act.method.copy()
339
339
  method['did'] = did
@@ -344,17 +344,17 @@ class mijiaDevice(object):
344
344
  if k.startswith("_"):
345
345
  k = k[1:]
346
346
  if k in method:
347
- raise ValueError(f'Invalid argument: {k}. Do not use arguments in ({", ".join(method.keys())})')
347
+ raise ValueError(f'无效的参数: {k}. 请勿使用以下参数 ({", ".join(method.keys())})')
348
348
  method[k] = v
349
349
  result = self.api.run_action(method)
350
350
  if result['code'] != 0:
351
351
  raise RuntimeError(
352
- f"Failed to run action: {name}, "
353
- f"code: {result['code']}, "
354
- f"message: {ERROR_CODE.get(str(result['code']), 'Unknown error')}"
352
+ f"执行动作 {name} 失败, "
353
+ f"错误码: {result['code']}, "
354
+ f"错误信息: {ERROR_CODE.get(str(result['code']), '未知错误')}"
355
355
  )
356
356
  sleep(self.sleep_time)
357
- logger.debug(f"Run action: {self.name} -> {name}, result: {result}")
357
+ logger.debug(f"执行动作: {self.name} -> {name}, 结果: {result}")
358
358
  return result['code'] == 0
359
359
 
360
360
 
@@ -379,10 +379,10 @@ def get_device_info(device_model: str, cache_path: Optional[str] = os.path.join(
379
379
  return json.load(f)
380
380
  response = requests.get(deviceURL + device_model)
381
381
  if response.status_code != 200:
382
- raise RuntimeError(f'Failed to get device info')
382
+ raise RuntimeError(f'获取设备信息失败')
383
383
  content = re.search(r'data-page="(.*?)">', response.text)
384
384
  if content is None:
385
- raise RuntimeError(f'Failed to get device info')
385
+ raise RuntimeError(f'获取设备信息失败')
386
386
  content = content.group(1)
387
387
  content = json.loads(content.replace('&quot;', '"'))
388
388
 
@@ -13,8 +13,7 @@ import requests
13
13
  from qrcode import QRCode
14
14
 
15
15
  from .logger import get_logger
16
- from .urls import msgURL, loginURL, qrURL, accountURL
17
- from .utils import defaultUA
16
+ from .consts import msgURL, loginURL, qrURL, accountURL, defaultUA
18
17
 
19
18
  logger = get_logger(__name__)
20
19
 
@@ -65,7 +64,7 @@ class mijiaLogin(object):
65
64
  """
66
65
  ret = self.session.get(msgURL)
67
66
  if ret.status_code != 200:
68
- raise LoginError(ret.status_code, f'Failed to get index page, {ret.text}')
67
+ raise LoginError(ret.status_code, f'获取索引页失败, {ret.text}')
69
68
  ret_data = json.loads(ret.text[11:])
70
69
  data = {'deviceId': self.deviceId}
71
70
  data.update({
@@ -90,7 +89,7 @@ class mijiaLogin(object):
90
89
  try:
91
90
  ret = self.session.get(accountURL + str(user_id))
92
91
  if ret.status_code != 200:
93
- raise LoginError(ret.status_code, f'Failed to get account page, {ret.text}')
92
+ raise LoginError(ret.status_code, f'获取账户页面失败, {ret.text}')
94
93
  data = json.loads(ret.text[11:])['data']
95
94
  except (KeyError, json.JSONDecodeError) as e:
96
95
  data = {}
@@ -117,7 +116,7 @@ class mijiaLogin(object):
117
116
  ]
118
117
 
119
118
  if not gmt_time_keys:
120
- raise LoginError(-1, 'No GMT time keys found in the data')
119
+ raise LoginError(-1, '在cookie中未找到GMT时间键')
121
120
  parsed_times = [datetime.strptime(k, '%d-%b-%Y %H:%M:%S GMT') for k in gmt_time_keys]
122
121
  latest_utc_time = max(parsed_times)
123
122
  china_time = latest_utc_time + timedelta(hours=8)
@@ -136,14 +135,14 @@ class mijiaLogin(object):
136
135
  if not os.path.isabs(self.save_path):
137
136
  self.save_path = os.path.abspath(self.save_path)
138
137
  if os.path.exists(self.save_path) and not os.path.isfile(self.save_path):
139
- raise ValueError(f'Path [{self.save_path}] is not a file')
138
+ raise ValueError(f'[{self.save_path}] 不是文件')
140
139
  if not os.path.exists(os.path.dirname(self.save_path)):
141
140
  os.makedirs(os.path.dirname(self.save_path))
142
141
  with open(self.save_path, 'w') as f:
143
142
  json.dump(self.auth_data, f, indent=2)
144
- logger.info(f'Auth data saved to [{self.save_path}]')
143
+ logger.info(f'认证文件已保存到 [{self.save_path}]')
145
144
  else:
146
- logger.info('Auth data not saved')
145
+ logger.info('认证文件未保存')
147
146
 
148
147
  def login(self, username: str, password: str) -> dict:
149
148
  """
@@ -159,7 +158,7 @@ class mijiaLogin(object):
159
158
  Raises:
160
159
  LoginError: 登录失败时抛出。
161
160
  """
162
- logger.warning('There is a high probability of verification code with account and password. Please try `QRlogin` method.')
161
+ logger.warning('使用账号密码登录很可能需要验证码。请尝试使用 `QRlogin` 方法。')
163
162
  data = self._get_index()
164
163
  post_data = {
165
164
  'qs': data['qs'],
@@ -172,17 +171,17 @@ class mijiaLogin(object):
172
171
  }
173
172
  ret = self.session.post(loginURL, data=post_data)
174
173
  if ret.status_code != 200:
175
- raise LoginError(ret.status_code, f'Failed to post login page, {ret.text}')
174
+ raise LoginError(ret.status_code, f'登录页面提交失败, {ret.text}')
176
175
  ret_data = json.loads(ret.text[11:])
177
176
  if ret_data['code'] != 0:
178
177
  raise LoginError(ret_data['code'], ret_data['desc'])
179
178
  if 'location' not in ret_data:
180
- raise LoginError(-1, 'Failed to get location')
179
+ raise LoginError(-1, '获取跳转位置失败')
181
180
  if 'notificationUrl' in ret_data:
182
- raise LoginError(-1, 'Verification code required, please try `QRlogin` method')
181
+ raise LoginError(-1, '需要验证码,请尝试使用 `QRlogin` 方法')
183
182
  ret = self.session.get(ret_data['location'])
184
183
  if ret.status_code != 200:
185
- raise LoginError(ret.status_code, f'Failed to get location, {ret.text}')
184
+ raise LoginError(ret.status_code, f'获取跳转位置失败, {ret.text}')
186
185
  cookies = self.session.cookies.get_dict()
187
186
 
188
187
  self.auth_data = {
@@ -207,7 +206,7 @@ class mijiaLogin(object):
207
206
  loginurl (str): 包含登录信息的URL。
208
207
  box_size (int, optional): 二维码大小。默认为10。
209
208
  """
210
- logger.info('Scan the QR code below with Mi Home app')
209
+ logger.info('请使用米家APP扫描下方二维码')
211
210
  qr = QRCode(border=1, box_size=box_size)
212
211
  qr.add_data(loginurl)
213
212
  qr.make_image().save('qr.png')
@@ -215,10 +214,10 @@ class mijiaLogin(object):
215
214
  qr.print_ascii(invert=True, tty=True)
216
215
  except OSError:
217
216
  qr.print_ascii(invert=True, tty=False)
218
- logger.info('If the QR code can not be scanned, '
219
- 'please change the font of the terminal, '
220
- 'such as "Maple Mono", "Fira Code", etc.\n'
221
- 'Or just use the qr.png file in the current directory.')
217
+ logger.info('如果无法扫描二维码,'
218
+ '请更改终端字体,'
219
+ '"Maple Mono""Fira Code"等。\n'
220
+ '或者直接使用当前目录下的qr.png文件。')
222
221
 
223
222
  def QRlogin(self) -> dict:
224
223
  """
@@ -251,7 +250,7 @@ class mijiaLogin(object):
251
250
  url = qrURL + '?' + parse.urlencode(params)
252
251
  ret = self.session.get(url)
253
252
  if ret.status_code != 200:
254
- raise LoginError(ret.status_code, f'Failed to get QR code URL, {ret.text}')
253
+ raise LoginError(ret.status_code, f'获取二维码URL失败, {ret.text}')
255
254
  ret_data = json.loads(ret.text[11:])
256
255
  if ret_data['code'] != 0:
257
256
  raise LoginError(ret_data['code'], ret_data['desc'])
@@ -260,15 +259,15 @@ class mijiaLogin(object):
260
259
  try:
261
260
  ret = self.session.get(ret_data['lp'], timeout=60, headers={'Connection': 'keep-alive'})
262
261
  except requests.exceptions.Timeout:
263
- raise LoginError(-1, 'Timeout, please try again')
262
+ raise LoginError(-1, '超时,请重试')
264
263
  if ret.status_code != 200:
265
- raise LoginError(ret.status_code, f'Failed to wait for login, {ret.text}')
264
+ raise LoginError(ret.status_code, f'等待登录失败, {ret.text}')
266
265
  ret_data = json.loads(ret.text[11:])
267
266
  if ret_data['code'] != 0:
268
267
  raise LoginError(ret_data['code'], ret_data['desc'])
269
268
  ret = self.session.get(ret_data['location'])
270
269
  if ret.status_code != 200:
271
- raise LoginError(ret.status_code, f'Failed to get location, {ret.text}')
270
+ raise LoginError(ret.status_code, f'获取跳转位置失败, {ret.text}')
272
271
  cookies = self.session.cookies.get_dict()
273
272
 
274
273
  self.auth_data = {
@@ -6,9 +6,8 @@ import string
6
6
 
7
7
  import requests
8
8
 
9
- from .urls import apiURL
9
+ from .consts import apiURL
10
10
 
11
- defaultUA = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Mobile Safari/537.36 Edg/126.0.0.0'
12
11
 
13
12
  class PostDataError(Exception):
14
13
  def __init__(self, code: int, message: str):
@@ -38,6 +37,6 @@ def post_data(session: requests.Session, ssecurity: str, uri: str, data: dict) -
38
37
  post_data = {'_nonce': nonce, 'data': data, 'signature': signature}
39
38
  ret = session.post(apiURL + uri, data=post_data)
40
39
  if ret.status_code != 200:
41
- raise PostDataError(ret.status_code, f'Failed to post data, {ret.text}')
40
+ raise PostDataError(ret.status_code, f'发送数据失败, {ret.text}')
42
41
  ret_data = ret.json()
43
42
  return ret_data
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mijiaAPI"
3
- version = "2.0.0"
3
+ version = "2.0.1"
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 = "2.0.0"
18
+ version = "2.0.1"
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