pyvesync 2.1.9__tar.gz → 2.1.11__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.
- {pyvesync-2.1.9 → pyvesync-2.1.11}/MANIFEST.in +2 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/PKG-INFO +36 -10
- pyvesync-2.1.9/src/pyvesync.egg-info/PKG-INFO → pyvesync-2.1.11/README.md +29 -27
- {pyvesync-2.1.9 → pyvesync-2.1.11}/setup.py +38 -39
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync/helpers.py +38 -62
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync/vesync.py +55 -4
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync/vesyncfan.py +931 -67
- pyvesync-2.1.9/README.md → pyvesync-2.1.11/src/pyvesync.egg-info/PKG-INFO +53 -8
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync.egg-info/SOURCES.txt +1 -3
- pyvesync-2.1.9/src/pyvesync.egg-info/not-zip-safe +0 -1
- pyvesync-2.1.9/test/test.py +0 -82
- {pyvesync-2.1.9 → pyvesync-2.1.11}/LICENSE +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/requirements.txt +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/setup.cfg +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync/__init__.py +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync/vesyncbasedevice.py +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync/vesyncbulb.py +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync/vesynckitchen.py +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync/vesyncoutlet.py +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync/vesyncswitch.py +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync.egg-info/dependency_links.txt +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync.egg-info/requires.txt +0 -0
- {pyvesync-2.1.9 → pyvesync-2.1.11}/src/pyvesync.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyvesync
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.11
|
|
4
4
|
Summary: pyvesync is a library to manage Etekcity Devices, Cosori Air Fryers and Levoit Air Purifiers run on the VeSync app.
|
|
5
5
|
Home-page: https://github.com/webdjoe/pyvesync
|
|
6
6
|
Author: Mark Perdue, Joe Trabulsy
|
|
@@ -14,8 +14,13 @@ Classifier: Natural Language :: English
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.8
|
|
15
15
|
Requires-Python: >=3.8
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
|
-
Provides-Extra: dev
|
|
18
17
|
License-File: LICENSE
|
|
18
|
+
Requires-Dist: requests>=2.20.0
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: pytest; extra == "dev"
|
|
21
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
22
|
+
Requires-Dist: yaml; extra == "dev"
|
|
23
|
+
Requires-Dist: tox; extra == "dev"
|
|
19
24
|
|
|
20
25
|
# pyvesync [](https://pypi.python.org/pypi/pyvesync) [](https://dev.azure.com/webdjoe/pyvesync/_build/latest?definitionId=4&branchName=master) [](https://github.com/Naereen/badges/) [](https://pypi.python.org/pypi/ansicolortags/) <!-- omit in toc -->
|
|
21
26
|
|
|
@@ -48,9 +53,9 @@ pyvesync is a library to manage VeSync compatible [smart home devices](#supporte
|
|
|
48
53
|
- [Standard Air Purifier Properties \& Methods](#standard-air-purifier-properties--methods)
|
|
49
54
|
- [Air Purifier Properties](#air-purifier-properties)
|
|
50
55
|
- [Air Purifier Methods](#air-purifier-methods)
|
|
51
|
-
- [Levoit Purifier Core200S/300S/400S and Vital 100S/200S Properties](#levoit-purifier-core200s300s400s-
|
|
52
|
-
- [Levoit Purifier Core200S/300S/400S
|
|
53
|
-
- [Levoit Vital 100S/200S Properties and Methods](#levoit-vital-100s200s-properties-and-methods)
|
|
56
|
+
- [Levoit Purifier Core200S/300S/400S and Vital 100S/200S Properties](#levoit-purifier-core200s300s400s-vital-100s200s--everest-air-properties)
|
|
57
|
+
- [Levoit Purifier Core200S/300S/400S, Vital 100S/200S & Everest Air Methods](#levoit-purifier-core200s300s400s-vital-100s200s--everest-air-methods)
|
|
58
|
+
- [Levoit Vital 100S/200S Properties and Methods](#levoit-vital-100s200s--everest-air-properties-and-methods)
|
|
54
59
|
- [Lights API Methods \& Properties](#lights-api-methods--properties)
|
|
55
60
|
- [Brightness Light Bulb Method and Properties](#brightness-light-bulb-method-and-properties)
|
|
56
61
|
- [Light Bulb Color Temperature Methods and Properties](#light-bulb-color-temperature-methods-and-properties)
|
|
@@ -113,6 +118,7 @@ pip install pyvesync
|
|
|
113
118
|
5. Core 600S
|
|
114
119
|
6. Vital 100S
|
|
115
120
|
7. Vital 200S
|
|
121
|
+
8. Everest Air
|
|
116
122
|
|
|
117
123
|
### Etekcity Bulbs
|
|
118
124
|
|
|
@@ -130,6 +136,7 @@ pip install pyvesync
|
|
|
130
136
|
3. LUH-D301S-WEU Dual (200S)
|
|
131
137
|
4. LV600S
|
|
132
138
|
5. OasisMist LUS-O415S-WUS
|
|
139
|
+
6. OasisMist LUH-M101S-WUS
|
|
133
140
|
|
|
134
141
|
Cosori Air Fryer
|
|
135
142
|
|
|
@@ -348,13 +355,13 @@ Compatible levels for each model:
|
|
|
348
355
|
- PUR131S [1, 2, 3]
|
|
349
356
|
- Vital 100S/200S [1, 2, 3, 4]
|
|
350
357
|
|
|
351
|
-
#### Levoit Purifier Core200S/300S/400S
|
|
358
|
+
#### Levoit Purifier Core200S/300S/400S, Vital 100S/200S & Everest Air Properties
|
|
352
359
|
|
|
353
360
|
`VeSyncFan.child_lock` - Return the state of the child lock (True=On/False=off)
|
|
354
361
|
|
|
355
362
|
`VeSyncAir.night_light` - Return the state of the night light (on/dim/off) **Not available on Vital 100S/200S**
|
|
356
363
|
|
|
357
|
-
#### Levoit Purifier Core200S/300S/400S
|
|
364
|
+
#### Levoit Purifier Core200S/300S/400S, Vital 100S/200S & Everest Air Methods
|
|
358
365
|
|
|
359
366
|
`VeSyncFan.child_lock_on()` Enable child lock
|
|
360
367
|
|
|
@@ -366,13 +373,15 @@ Compatible levels for each model:
|
|
|
366
373
|
|
|
367
374
|
`VeSyncFan.set_night_light('on'|'dim'|'off')` - Set night light brightness
|
|
368
375
|
|
|
369
|
-
`VeSyncFan.get_timer()` - Get any running timers, stores Timer DataClass in `VeSyncFan.timer
|
|
376
|
+
`VeSyncFan.get_timer()` - Get any running timers, stores Timer DataClass in `VeSyncFan.timer`. See [Timer Dataclass](#timer-dataclass)
|
|
370
377
|
|
|
371
378
|
`VeSyncFan.set_timer(timer_duration=3000)` - Set a timer for the device, only turns device off. Timer DataClass stored in `VeSyncFan.timer`
|
|
372
379
|
|
|
373
380
|
`VeSyncFan.clear_timer()` - Cancel any running timer
|
|
374
381
|
|
|
375
|
-
|
|
382
|
+
`VeSyncFan.reset_filter()` - Reset filter to 100% **NOTE: Only available on Core200S**
|
|
383
|
+
|
|
384
|
+
#### Levoit Vital 100S/200S & Everest Air Properties and Methods
|
|
376
385
|
|
|
377
386
|
The Levoit Vital 100S/200S has additional features not available on other models.
|
|
378
387
|
|
|
@@ -392,6 +401,23 @@ The Levoit Vital 100S/200S has additional features not available on other models
|
|
|
392
401
|
|
|
393
402
|
`VeSyncFan.set_light_detection_off()` - Turn off light detection mode
|
|
394
403
|
|
|
404
|
+
#### Levoit Everest Air Properties & Methods
|
|
405
|
+
|
|
406
|
+
`VeSyncFan.turbo_mode()` - Set turbo mode
|
|
407
|
+
|
|
408
|
+
Additional properties in the `VeSyncFan['details']` dictionary:
|
|
409
|
+
|
|
410
|
+
```python
|
|
411
|
+
VeSyncFan['Details'] = {
|
|
412
|
+
'pm1': 0, # air quality reading of particulates 1.0 microns
|
|
413
|
+
'pm10': 10, # air quality reading of particulates 10 microns
|
|
414
|
+
'fan_rotate_angle': 45, # angle of fan vents
|
|
415
|
+
'aq_percent': 45, # Air Quality percentage reading
|
|
416
|
+
'filter_open_state': False # returns bool of filter open
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
```
|
|
420
|
+
|
|
395
421
|
### Lights API Methods & Properties
|
|
396
422
|
|
|
397
423
|
#### Brightness Light Bulb Method and Properties
|
|
@@ -1045,7 +1071,7 @@ After:
|
|
|
1045
1071
|
}
|
|
1046
1072
|
```
|
|
1047
1073
|
|
|
1048
|
-
|
|
1074
|
+
## Contributing
|
|
1049
1075
|
|
|
1050
1076
|
All [contributions](CONTRIBUTING.md) are welcome.
|
|
1051
1077
|
|
|
@@ -1,22 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: pyvesync
|
|
3
|
-
Version: 2.1.9
|
|
4
|
-
Summary: pyvesync is a library to manage Etekcity Devices, Cosori Air Fryers and Levoit Air Purifiers run on the VeSync app.
|
|
5
|
-
Home-page: https://github.com/webdjoe/pyvesync
|
|
6
|
-
Author: Mark Perdue, Joe Trabulsy
|
|
7
|
-
Author-email: webdjoe@gmail.com
|
|
8
|
-
License: MIT
|
|
9
|
-
Keywords: iot,vesync,levoit,etekcity,cosori,valceno
|
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
-
Classifier: Intended Audience :: Developers
|
|
12
|
-
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
-
Classifier: Natural Language :: English
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
15
|
-
Requires-Python: >=3.8
|
|
16
|
-
Description-Content-Type: text/markdown
|
|
17
|
-
Provides-Extra: dev
|
|
18
|
-
License-File: LICENSE
|
|
19
|
-
|
|
20
1
|
# pyvesync [](https://pypi.python.org/pypi/pyvesync) [](https://dev.azure.com/webdjoe/pyvesync/_build/latest?definitionId=4&branchName=master) [](https://github.com/Naereen/badges/) [](https://pypi.python.org/pypi/ansicolortags/) <!-- omit in toc -->
|
|
21
2
|
|
|
22
3
|
pyvesync is a library to manage VeSync compatible [smart home devices](#supported-devices)
|
|
@@ -48,9 +29,9 @@ pyvesync is a library to manage VeSync compatible [smart home devices](#supporte
|
|
|
48
29
|
- [Standard Air Purifier Properties \& Methods](#standard-air-purifier-properties--methods)
|
|
49
30
|
- [Air Purifier Properties](#air-purifier-properties)
|
|
50
31
|
- [Air Purifier Methods](#air-purifier-methods)
|
|
51
|
-
- [Levoit Purifier Core200S/300S/400S and Vital 100S/200S Properties](#levoit-purifier-core200s300s400s-
|
|
52
|
-
- [Levoit Purifier Core200S/300S/400S
|
|
53
|
-
- [Levoit Vital 100S/200S Properties and Methods](#levoit-vital-100s200s-properties-and-methods)
|
|
32
|
+
- [Levoit Purifier Core200S/300S/400S and Vital 100S/200S Properties](#levoit-purifier-core200s300s400s-vital-100s200s--everest-air-properties)
|
|
33
|
+
- [Levoit Purifier Core200S/300S/400S, Vital 100S/200S & Everest Air Methods](#levoit-purifier-core200s300s400s-vital-100s200s--everest-air-methods)
|
|
34
|
+
- [Levoit Vital 100S/200S Properties and Methods](#levoit-vital-100s200s--everest-air-properties-and-methods)
|
|
54
35
|
- [Lights API Methods \& Properties](#lights-api-methods--properties)
|
|
55
36
|
- [Brightness Light Bulb Method and Properties](#brightness-light-bulb-method-and-properties)
|
|
56
37
|
- [Light Bulb Color Temperature Methods and Properties](#light-bulb-color-temperature-methods-and-properties)
|
|
@@ -113,6 +94,7 @@ pip install pyvesync
|
|
|
113
94
|
5. Core 600S
|
|
114
95
|
6. Vital 100S
|
|
115
96
|
7. Vital 200S
|
|
97
|
+
8. Everest Air
|
|
116
98
|
|
|
117
99
|
### Etekcity Bulbs
|
|
118
100
|
|
|
@@ -130,6 +112,7 @@ pip install pyvesync
|
|
|
130
112
|
3. LUH-D301S-WEU Dual (200S)
|
|
131
113
|
4. LV600S
|
|
132
114
|
5. OasisMist LUS-O415S-WUS
|
|
115
|
+
6. OasisMist LUH-M101S-WUS
|
|
133
116
|
|
|
134
117
|
Cosori Air Fryer
|
|
135
118
|
|
|
@@ -348,13 +331,13 @@ Compatible levels for each model:
|
|
|
348
331
|
- PUR131S [1, 2, 3]
|
|
349
332
|
- Vital 100S/200S [1, 2, 3, 4]
|
|
350
333
|
|
|
351
|
-
#### Levoit Purifier Core200S/300S/400S
|
|
334
|
+
#### Levoit Purifier Core200S/300S/400S, Vital 100S/200S & Everest Air Properties
|
|
352
335
|
|
|
353
336
|
`VeSyncFan.child_lock` - Return the state of the child lock (True=On/False=off)
|
|
354
337
|
|
|
355
338
|
`VeSyncAir.night_light` - Return the state of the night light (on/dim/off) **Not available on Vital 100S/200S**
|
|
356
339
|
|
|
357
|
-
#### Levoit Purifier Core200S/300S/400S
|
|
340
|
+
#### Levoit Purifier Core200S/300S/400S, Vital 100S/200S & Everest Air Methods
|
|
358
341
|
|
|
359
342
|
`VeSyncFan.child_lock_on()` Enable child lock
|
|
360
343
|
|
|
@@ -366,13 +349,15 @@ Compatible levels for each model:
|
|
|
366
349
|
|
|
367
350
|
`VeSyncFan.set_night_light('on'|'dim'|'off')` - Set night light brightness
|
|
368
351
|
|
|
369
|
-
`VeSyncFan.get_timer()` - Get any running timers, stores Timer DataClass in `VeSyncFan.timer
|
|
352
|
+
`VeSyncFan.get_timer()` - Get any running timers, stores Timer DataClass in `VeSyncFan.timer`. See [Timer Dataclass](#timer-dataclass)
|
|
370
353
|
|
|
371
354
|
`VeSyncFan.set_timer(timer_duration=3000)` - Set a timer for the device, only turns device off. Timer DataClass stored in `VeSyncFan.timer`
|
|
372
355
|
|
|
373
356
|
`VeSyncFan.clear_timer()` - Cancel any running timer
|
|
374
357
|
|
|
375
|
-
|
|
358
|
+
`VeSyncFan.reset_filter()` - Reset filter to 100% **NOTE: Only available on Core200S**
|
|
359
|
+
|
|
360
|
+
#### Levoit Vital 100S/200S & Everest Air Properties and Methods
|
|
376
361
|
|
|
377
362
|
The Levoit Vital 100S/200S has additional features not available on other models.
|
|
378
363
|
|
|
@@ -392,6 +377,23 @@ The Levoit Vital 100S/200S has additional features not available on other models
|
|
|
392
377
|
|
|
393
378
|
`VeSyncFan.set_light_detection_off()` - Turn off light detection mode
|
|
394
379
|
|
|
380
|
+
#### Levoit Everest Air Properties & Methods
|
|
381
|
+
|
|
382
|
+
`VeSyncFan.turbo_mode()` - Set turbo mode
|
|
383
|
+
|
|
384
|
+
Additional properties in the `VeSyncFan['details']` dictionary:
|
|
385
|
+
|
|
386
|
+
```python
|
|
387
|
+
VeSyncFan['Details'] = {
|
|
388
|
+
'pm1': 0, # air quality reading of particulates 1.0 microns
|
|
389
|
+
'pm10': 10, # air quality reading of particulates 10 microns
|
|
390
|
+
'fan_rotate_angle': 45, # angle of fan vents
|
|
391
|
+
'aq_percent': 45, # Air Quality percentage reading
|
|
392
|
+
'filter_open_state': False # returns bool of filter open
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
```
|
|
396
|
+
|
|
395
397
|
### Lights API Methods & Properties
|
|
396
398
|
|
|
397
399
|
#### Brightness Light Bulb Method and Properties
|
|
@@ -1045,7 +1047,7 @@ After:
|
|
|
1045
1047
|
}
|
|
1046
1048
|
```
|
|
1047
1049
|
|
|
1048
|
-
|
|
1050
|
+
## Contributing
|
|
1049
1051
|
|
|
1050
1052
|
All [contributions](CONTRIBUTING.md) are welcome.
|
|
1051
1053
|
|
|
@@ -1,39 +1,38 @@
|
|
|
1
|
-
"""pyvesync setup script."""
|
|
2
|
-
|
|
3
|
-
from os import path
|
|
4
|
-
from setuptools import setup, find_packages
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
this_directory = path.abspath(path.dirname(__file__))
|
|
8
|
-
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
|
|
9
|
-
long_description = f.read()
|
|
10
|
-
|
|
11
|
-
setup(
|
|
12
|
-
name='pyvesync',
|
|
13
|
-
version='2.1.
|
|
14
|
-
description='pyvesync is a library to manage Etekcity\
|
|
15
|
-
Devices, Cosori Air Fryers and Levoit Air \
|
|
16
|
-
Purifiers run on the VeSync app.',
|
|
17
|
-
long_description=long_description,
|
|
18
|
-
long_description_content_type='text/markdown',
|
|
19
|
-
url='https://github.com/webdjoe/pyvesync',
|
|
20
|
-
author='Mark Perdue, Joe Trabulsy',
|
|
21
|
-
author_email='webdjoe@gmail.com',
|
|
22
|
-
license='MIT',
|
|
23
|
-
classifiers=[
|
|
24
|
-
'License :: OSI Approved :: MIT License',
|
|
25
|
-
'Intended Audience :: Developers',
|
|
26
|
-
'Intended Audience :: End Users/Desktop',
|
|
27
|
-
'Natural Language :: English',
|
|
28
|
-
'Programming Language :: Python :: 3.8',
|
|
29
|
-
],
|
|
30
|
-
keywords=['iot', 'vesync', 'levoit', 'etekcity', 'cosori', 'valceno'],
|
|
31
|
-
packages=find_packages('src', exclude=['tests', '
|
|
32
|
-
package_dir={'': 'src'},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
1
|
+
"""pyvesync setup script."""
|
|
2
|
+
|
|
3
|
+
from os import path
|
|
4
|
+
from setuptools import setup, find_packages
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
this_directory = path.abspath(path.dirname(__file__))
|
|
8
|
+
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
|
|
9
|
+
long_description = f.read()
|
|
10
|
+
|
|
11
|
+
setup(
|
|
12
|
+
name='pyvesync',
|
|
13
|
+
version='2.1.11',
|
|
14
|
+
description='pyvesync is a library to manage Etekcity\
|
|
15
|
+
Devices, Cosori Air Fryers and Levoit Air \
|
|
16
|
+
Purifiers run on the VeSync app.',
|
|
17
|
+
long_description=long_description,
|
|
18
|
+
long_description_content_type='text/markdown',
|
|
19
|
+
url='https://github.com/webdjoe/pyvesync',
|
|
20
|
+
author='Mark Perdue, Joe Trabulsy',
|
|
21
|
+
author_email='webdjoe@gmail.com',
|
|
22
|
+
license='MIT',
|
|
23
|
+
classifiers=[
|
|
24
|
+
'License :: OSI Approved :: MIT License',
|
|
25
|
+
'Intended Audience :: Developers',
|
|
26
|
+
'Intended Audience :: End Users/Desktop',
|
|
27
|
+
'Natural Language :: English',
|
|
28
|
+
'Programming Language :: Python :: 3.8',
|
|
29
|
+
],
|
|
30
|
+
keywords=['iot', 'vesync', 'levoit', 'etekcity', 'cosori', 'valceno'],
|
|
31
|
+
packages=find_packages('src', exclude=['tests', 'test*']),
|
|
32
|
+
package_dir={'': 'src'},
|
|
33
|
+
install_requires=['requests>=2.20.0'],
|
|
34
|
+
extras_require={
|
|
35
|
+
'dev': ['pytest', 'pytest-cov', 'yaml', 'tox']
|
|
36
|
+
},
|
|
37
|
+
python_requires='>=3.8',
|
|
38
|
+
)
|
|
@@ -6,7 +6,7 @@ import time
|
|
|
6
6
|
import json
|
|
7
7
|
import colorsys
|
|
8
8
|
from dataclasses import dataclass, field, InitVar
|
|
9
|
-
from typing import NamedTuple, Optional, Union
|
|
9
|
+
from typing import Any, Dict, NamedTuple, Optional, Union
|
|
10
10
|
import re
|
|
11
11
|
import requests
|
|
12
12
|
|
|
@@ -38,7 +38,7 @@ class Helpers:
|
|
|
38
38
|
"""VeSync Helper Functions."""
|
|
39
39
|
|
|
40
40
|
@staticmethod
|
|
41
|
-
def req_headers(manager) ->
|
|
41
|
+
def req_headers(manager) -> Dict[str, str]:
|
|
42
42
|
"""Build header for api requests."""
|
|
43
43
|
headers = {
|
|
44
44
|
'accept-language': 'en',
|
|
@@ -51,7 +51,7 @@ class Helpers:
|
|
|
51
51
|
return headers
|
|
52
52
|
|
|
53
53
|
@staticmethod
|
|
54
|
-
def req_header_bypass() ->
|
|
54
|
+
def req_header_bypass() -> Dict[str, str]:
|
|
55
55
|
"""Build header for api requests on 'bypass' endpoint."""
|
|
56
56
|
return {
|
|
57
57
|
'Content-Type': 'application/json; charset=UTF-8',
|
|
@@ -59,17 +59,17 @@ class Helpers:
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
@staticmethod
|
|
62
|
-
def req_body_base(manager) ->
|
|
62
|
+
def req_body_base(manager) -> Dict[str, str]:
|
|
63
63
|
"""Return universal keys for body of api requests."""
|
|
64
64
|
return {'timeZone': manager.time_zone, 'acceptLanguage': 'en'}
|
|
65
65
|
|
|
66
66
|
@staticmethod
|
|
67
|
-
def req_body_auth(manager) ->
|
|
67
|
+
def req_body_auth(manager) -> Dict[str, str]:
|
|
68
68
|
"""Keys for authenticating api requests."""
|
|
69
69
|
return {'accountID': manager.account_id, 'token': manager.token}
|
|
70
70
|
|
|
71
71
|
@staticmethod
|
|
72
|
-
def req_body_details() ->
|
|
72
|
+
def req_body_details() -> Dict[str, str]:
|
|
73
73
|
"""Detail keys for api requests."""
|
|
74
74
|
return {
|
|
75
75
|
'appVersion': APP_VERSION,
|
|
@@ -79,83 +79,57 @@ class Helpers:
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
@classmethod
|
|
82
|
-
def req_body(cls, manager, type_) ->
|
|
82
|
+
def req_body(cls, manager, type_) -> Dict[str, Any]:
|
|
83
83
|
"""Builder for body of api requests."""
|
|
84
|
-
body =
|
|
84
|
+
body = cls.req_body_base(manager)
|
|
85
85
|
|
|
86
86
|
if type_ == 'login':
|
|
87
|
-
body
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
body
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
body
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
**cls.req_body_auth(manager),
|
|
106
|
-
**cls.req_body_details(),
|
|
107
|
-
}
|
|
87
|
+
body |= cls.req_body_details() # type: ignore
|
|
88
|
+
body |= {
|
|
89
|
+
'email': manager.username,
|
|
90
|
+
'password': cls.hash_password(manager.password),
|
|
91
|
+
'devToken': '',
|
|
92
|
+
'userType': USER_TYPE,
|
|
93
|
+
'method': 'login'
|
|
94
|
+
} # type: ignore
|
|
95
|
+
return body
|
|
96
|
+
|
|
97
|
+
body |= cls.req_body_auth(manager) # type: ignore
|
|
98
|
+
|
|
99
|
+
if type_ == 'devicestatus':
|
|
100
|
+
return body
|
|
101
|
+
|
|
102
|
+
body |= cls.req_body_details() # type: ignore
|
|
103
|
+
|
|
104
|
+
if type_ == 'devicelist':
|
|
108
105
|
body['method'] = 'devices'
|
|
109
106
|
body['pageNo'] = '1'
|
|
110
107
|
body['pageSize'] = '100'
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
108
|
+
|
|
109
|
+
elif type_ == 'devicedetail':
|
|
110
|
+
body['method'] = 'devicedetail'
|
|
111
|
+
body['mobileId'] = MOBILE_ID
|
|
112
|
+
|
|
114
113
|
elif type_ == 'energy_week':
|
|
115
|
-
body = {
|
|
116
|
-
**cls.req_body_base(manager),
|
|
117
|
-
**cls.req_body_auth(manager),
|
|
118
|
-
**cls.req_body_details(),
|
|
119
|
-
}
|
|
120
114
|
body['method'] = 'energyweek'
|
|
121
115
|
body['mobileId'] = MOBILE_ID
|
|
116
|
+
|
|
122
117
|
elif type_ == 'energy_month':
|
|
123
|
-
body = {
|
|
124
|
-
**cls.req_body_base(manager),
|
|
125
|
-
**cls.req_body_auth(manager),
|
|
126
|
-
**cls.req_body_details(),
|
|
127
|
-
}
|
|
128
118
|
body['method'] = 'energymonth'
|
|
129
119
|
body['mobileId'] = MOBILE_ID
|
|
120
|
+
|
|
130
121
|
elif type_ == 'energy_year':
|
|
131
|
-
body = {
|
|
132
|
-
**cls.req_body_base(manager),
|
|
133
|
-
**cls.req_body_auth(manager),
|
|
134
|
-
**cls.req_body_details(),
|
|
135
|
-
}
|
|
136
122
|
body['method'] = 'energyyear'
|
|
137
123
|
body['mobileId'] = MOBILE_ID
|
|
124
|
+
|
|
138
125
|
elif type_ == 'bypass':
|
|
139
|
-
body = {
|
|
140
|
-
**cls.req_body_base(manager),
|
|
141
|
-
**cls.req_body_auth(manager),
|
|
142
|
-
**cls.req_body_details(),
|
|
143
|
-
}
|
|
144
126
|
body['method'] = 'bypass'
|
|
127
|
+
|
|
145
128
|
elif type_ == 'bypassV2':
|
|
146
|
-
body = {
|
|
147
|
-
**cls.req_body_base(manager),
|
|
148
|
-
**cls.req_body_auth(manager),
|
|
149
|
-
**cls.req_body_details(),
|
|
150
|
-
}
|
|
151
129
|
body['deviceRegion'] = DEFAULT_REGION
|
|
152
130
|
body['method'] = 'bypassV2'
|
|
131
|
+
|
|
153
132
|
elif type_ == 'bypass_config':
|
|
154
|
-
body = {
|
|
155
|
-
**cls.req_body_base(manager),
|
|
156
|
-
**cls.req_body_auth(manager),
|
|
157
|
-
**cls.req_body_details(),
|
|
158
|
-
}
|
|
159
133
|
body['method'] = 'firmwareUpdateInfo'
|
|
160
134
|
|
|
161
135
|
return body
|
|
@@ -237,6 +211,8 @@ class Helpers:
|
|
|
237
211
|
API_BASE_URL + api, json=json_object, headers=headers,
|
|
238
212
|
timeout=API_TIMEOUT
|
|
239
213
|
)
|
|
214
|
+
else:
|
|
215
|
+
raise NameError(f'Invalid method {method}')
|
|
240
216
|
except requests.exceptions.RequestException as e:
|
|
241
217
|
logger.debug(e)
|
|
242
218
|
except Exception as e: # pylint: disable=broad-except
|
|
@@ -74,11 +74,45 @@ def object_factory(dev_type, config, manager) -> Tuple[str, VeSyncBaseDevice]:
|
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
class VeSync: # pylint: disable=function-redefined
|
|
77
|
-
"""VeSync
|
|
77
|
+
"""VeSync Manager Class."""
|
|
78
78
|
|
|
79
79
|
def __init__(self, username, password, time_zone=DEFAULT_TZ,
|
|
80
80
|
debug=False, redact=True):
|
|
81
|
-
"""Initialize VeSync
|
|
81
|
+
"""Initialize VeSync Manager.
|
|
82
|
+
|
|
83
|
+
This class is used as the manager for all VeSync objects, all methods and
|
|
84
|
+
API calls are performed from this class. Time zone, debug and redact are
|
|
85
|
+
optional. Time zone must be a string of an IANA time zone format. Once
|
|
86
|
+
class is instantiated, call `manager.login()` to log in to VeSync servers,
|
|
87
|
+
which returns `True` if successful. Once logged in, call `manager.update()`
|
|
88
|
+
to retrieve devices and update device details.
|
|
89
|
+
|
|
90
|
+
Parameters:
|
|
91
|
+
-----------
|
|
92
|
+
username : str
|
|
93
|
+
VeSync account username (usually email address)
|
|
94
|
+
password : str
|
|
95
|
+
VeSync account password
|
|
96
|
+
time_zone : str, optional
|
|
97
|
+
Time zone for device from IANA database, by default DEFAULT_TZ
|
|
98
|
+
debug : bool, optional
|
|
99
|
+
Enable debug logging, by default False
|
|
100
|
+
redact : bool, optional
|
|
101
|
+
Redact sensitive information in logs, by default True
|
|
102
|
+
|
|
103
|
+
Attributes
|
|
104
|
+
----------
|
|
105
|
+
fans : list
|
|
106
|
+
List of VeSyncFan objects for humidifiers and air purifiers
|
|
107
|
+
outlets : list
|
|
108
|
+
List of VeSyncOutlet objects for smart plugs
|
|
109
|
+
switches : list
|
|
110
|
+
List of VeSyncSwitch objects for wall switches
|
|
111
|
+
bulbs : list
|
|
112
|
+
List of VeSyncBulb objects for smart bulbs
|
|
113
|
+
kitchen : list
|
|
114
|
+
List of VeSyncKitchen objects for smart kitchen appliances
|
|
115
|
+
"""
|
|
82
116
|
self.debug = debug
|
|
83
117
|
if debug: # pragma: no cover
|
|
84
118
|
logger.setLevel(logging.DEBUG)
|
|
@@ -308,7 +342,15 @@ class VeSync: # pylint: disable=function-redefined
|
|
|
308
342
|
return proc_return
|
|
309
343
|
|
|
310
344
|
def login(self) -> bool:
|
|
311
|
-
"""
|
|
345
|
+
"""Log into VeSync server.
|
|
346
|
+
|
|
347
|
+
Username and password are provided when class is instantiated.
|
|
348
|
+
|
|
349
|
+
Returns
|
|
350
|
+
-------
|
|
351
|
+
bool
|
|
352
|
+
True if login successful, False if not
|
|
353
|
+
"""
|
|
312
354
|
user_check = isinstance(self.username, str) and len(self.username) > 0
|
|
313
355
|
pass_check = isinstance(self.password, str) and len(self.password) > 0
|
|
314
356
|
if user_check is False:
|
|
@@ -346,7 +388,16 @@ class VeSync: # pylint: disable=function-redefined
|
|
|
346
388
|
return False
|
|
347
389
|
|
|
348
390
|
def update(self) -> None:
|
|
349
|
-
"""Fetch updated information about devices.
|
|
391
|
+
"""Fetch updated information about devices.
|
|
392
|
+
|
|
393
|
+
Pulls devices list from VeSync and instantiates any new devices. Devices
|
|
394
|
+
are stored in the instance attributes `outlets`, `switches`, `fans`, and
|
|
395
|
+
`bulbs`. The `_device_list` attribute is a dictionary of these attributes.
|
|
396
|
+
|
|
397
|
+
Returns
|
|
398
|
+
-------
|
|
399
|
+
None
|
|
400
|
+
"""
|
|
350
401
|
if self.device_time_check():
|
|
351
402
|
|
|
352
403
|
if not self.enabled:
|