pyvesync 3.0.0b6__tar.gz → 3.0.0b8__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.
Files changed (58) hide show
  1. {pyvesync-3.0.0b6/src/pyvesync.egg-info → pyvesync-3.0.0b8}/PKG-INFO +11 -2
  2. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/README.md +9 -1
  3. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/pyproject.toml +2 -1
  4. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/devices/vesyncbulb.py +14 -15
  5. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/devices/vesyncfan.py +0 -2
  6. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/devices/vesyncpurifier.py +9 -2
  7. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/bulb_models.py +2 -2
  8. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/fan_models.py +0 -2
  9. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/utils/errors.py +1 -1
  10. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/vesync.py +3 -4
  11. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8/src/pyvesync.egg-info}/PKG-INFO +11 -2
  12. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/LICENSE +0 -0
  13. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/MANIFEST.in +0 -0
  14. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/requirements.txt +0 -0
  15. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/setup.cfg +0 -0
  16. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/setup.py +0 -0
  17. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/__init__.py +0 -0
  18. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/base_devices/__init__.py +0 -0
  19. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/base_devices/bulb_base.py +0 -0
  20. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/base_devices/fan_base.py +0 -0
  21. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/base_devices/fryer_base.py +0 -0
  22. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/base_devices/humidifier_base.py +0 -0
  23. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/base_devices/outlet_base.py +0 -0
  24. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/base_devices/purifier_base.py +0 -0
  25. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/base_devices/switch_base.py +0 -0
  26. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/base_devices/thermostat_base.py +0 -0
  27. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/base_devices/vesyncbasedevice.py +0 -0
  28. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/const.py +0 -0
  29. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/device_container.py +0 -0
  30. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/device_map.py +0 -0
  31. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/devices/__init__.py +0 -0
  32. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/devices/vesynchumidifier.py +0 -0
  33. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/devices/vesynckitchen.py +0 -0
  34. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/devices/vesyncoutlet.py +0 -0
  35. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/devices/vesyncswitch.py +0 -0
  36. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/devices/vesyncthermostat.py +0 -0
  37. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/__init__.py +0 -0
  38. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/base_models.py +0 -0
  39. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/bypass_models.py +0 -0
  40. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/fryer_models.py +0 -0
  41. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/home_models.py +0 -0
  42. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/humidifier_models.py +0 -0
  43. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/outlet_models.py +0 -0
  44. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/purifier_models.py +0 -0
  45. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/switch_models.py +0 -0
  46. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/thermostat_models.py +0 -0
  47. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/models/vesync_models.py +0 -0
  48. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/utils/__init__.py +0 -0
  49. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/utils/colors.py +0 -0
  50. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/utils/device_mixins.py +0 -0
  51. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/utils/enum_utils.py +0 -0
  52. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/utils/helpers.py +0 -0
  53. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/utils/logs.py +0 -0
  54. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync/vesynchome.py +0 -0
  55. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync.egg-info/SOURCES.txt +0 -0
  56. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync.egg-info/dependency_links.txt +0 -0
  57. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync.egg-info/requires.txt +0 -0
  58. {pyvesync-3.0.0b6 → pyvesync-3.0.0b8}/src/pyvesync.egg-info/top_level.txt +0 -0
@@ -1,11 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyvesync
3
- Version: 3.0.0b6
3
+ Version: 3.0.0b8
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
  Author: Mark Perdue
6
6
  Author-email: Joe Trabulsy <webdjoe@gmail.com>
7
7
  License: MIT
8
8
  Project-URL: Home Page, https://github.com/webdjoe/pyvesync
9
+ Project-URL: Documentation, https://webdjoe.github.io/pyvesync/latest/
9
10
  Keywords: iot,vesync,levoit,etekcity,cosori,valceno
10
11
  Classifier: License :: OSI Approved :: MIT License
11
12
  Classifier: Intended Audience :: Developers
@@ -80,7 +81,15 @@ import aiohttp
80
81
  from pyvesync.vesync import VeSync
81
82
 
82
83
  async def main():
83
- async with VeSync("user", "password") as manager:
84
+ async with VeSync(
85
+ username="user",
86
+ password="password",
87
+ country_code="US", # Optional - country Code to select correct server
88
+ session=session, # Optional - aiohttp.ClientSession
89
+ time_zone="America/New_York", # Optional - Timezone, defaults to America/New_York
90
+ debug=False, # Optional - Debug output
91
+ redact=True # Optional - Redact sensitive information from logs
92
+ ) as manager:
84
93
 
85
94
  # To enable debug mode - prints request and response content for
86
95
  # api calls that return an error code
@@ -49,7 +49,15 @@ import aiohttp
49
49
  from pyvesync.vesync import VeSync
50
50
 
51
51
  async def main():
52
- async with VeSync("user", "password") as manager:
52
+ async with VeSync(
53
+ username="user",
54
+ password="password",
55
+ country_code="US", # Optional - country Code to select correct server
56
+ session=session, # Optional - aiohttp.ClientSession
57
+ time_zone="America/New_York", # Optional - Timezone, defaults to America/New_York
58
+ debug=False, # Optional - Debug output
59
+ redact=True # Optional - Redact sensitive information from logs
60
+ ) as manager:
53
61
 
54
62
  # To enable debug mode - prints request and response content for
55
63
  # api calls that return an error code
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyvesync"
7
- version = "3.0.0b6"
7
+ version = "3.0.0b8"
8
8
  description = "pyvesync is a library to manage Etekcity Devices, Cosori Air Fryers, and Levoit Air Purifiers run on the VeSync app."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -28,6 +28,7 @@ dependencies = [
28
28
 
29
29
  [project.urls]
30
30
  "Home Page" = "https://github.com/webdjoe/pyvesync"
31
+ "Documentation" = "https://webdjoe.github.io/pyvesync/latest/"
31
32
 
32
33
  [project.optional-dependencies]
33
34
  dev = [
@@ -176,7 +176,7 @@ class VeSyncBulbESL100MC(VeSyncBulb):
176
176
  )
177
177
 
178
178
  result_model = process_bypassv2_result(
179
- self, logger, "get_details", r_dict, bulb_models.ResponseESL100MCStatus
179
+ self, logger, "get_details", r_dict, bulb_models.ResponseESL100MCResult
180
180
  )
181
181
  if result_model is None:
182
182
  return
@@ -184,15 +184,14 @@ class VeSyncBulbESL100MC(VeSyncBulb):
184
184
  return
185
185
 
186
186
  def _set_state(
187
- self, response: bulb_models.ResponseESL100MCStatus) -> None:
187
+ self, response: bulb_models.ResponseESL100MCResult) -> None:
188
188
  """Build detail dictionary from response."""
189
- result = response.result.result
190
- self.state.brightness = result.brightness
191
- self.state.color_mode = result.colorMode
189
+ self.state.brightness = response.brightness
190
+ self.state.color_mode = response.colorMode
192
191
  self.set_state("color", Color.from_rgb(
193
- red=result.red,
194
- green=result.green,
195
- blue=result.blue
192
+ red=response.red,
193
+ green=response.green,
194
+ blue=response.blue
196
195
  ))
197
196
 
198
197
  async def set_brightness(self, brightness: int) -> bool:
@@ -397,15 +396,15 @@ class VeSyncBulbESL100(BypassV1Mixin, VeSyncBulb):
397
396
  'deviceDetail'
398
397
  )
399
398
  model = process_bypassv1_result(
400
- self, logger, "get_details", r_dict, bulb_models.ResponseESL100Detail
399
+ self, logger, "get_details", r_dict, bulb_models.ResponseESL100DetailResult
401
400
  )
402
401
 
403
402
  if model is None:
404
403
  self.state.connection_status = ConnectionStatus.OFFLINE
405
404
  return
406
- self.state.brightness = model.result.brightness
407
- self.state.device_status = model.result.deviceStatus
408
- self.state.connection_status = model.result.connectionStatus
405
+ self.state.brightness = model.brightness
406
+ self.state.device_status = model.deviceStatus
407
+ self.state.connection_status = model.connectionStatus
409
408
 
410
409
  @deprecated(
411
410
  "toggle() is deprecated, use toggle_switch(toggle: bool | None = None) instead"
@@ -613,7 +612,7 @@ class VeSyncBulbESL100CW(BypassV1Mixin, VeSyncBulb):
613
612
  )
614
613
 
615
614
  light_resp = process_bypassv1_result(
616
- self, logger, "get_details", r_dict, bulb_models.ResponseESL100CWDetail
615
+ self, logger, "get_details", r_dict, bulb_models.ResponseESL100CWDetailResult
617
616
  )
618
617
  if light_resp is None:
619
618
  self.state.connection_status = ConnectionStatus.OFFLINE
@@ -621,9 +620,9 @@ class VeSyncBulbESL100CW(BypassV1Mixin, VeSyncBulb):
621
620
  self._interpret_apicall_result(light_resp)
622
621
 
623
622
  def _interpret_apicall_result(
624
- self, response: bulb_models.ResponseESL100CWDetail) -> None:
623
+ self, response: bulb_models.ResponseESL100CWDetailResult) -> None:
625
624
  self.state.connection_status = ConnectionStatus.ONLINE
626
- result = response.result.light
625
+ result = response.light
627
626
  self.state.device_status = result.action
628
627
  self.state.brightness = result.brightness
629
628
  self.state.color_temp = result.colorTempe
@@ -38,9 +38,7 @@ class VeSyncTowerFan(BypassV2Mixin, VeSyncFanBase):
38
38
  self.state.mode = res.workMode
39
39
  self.state.fan_level = res.fanSpeedLevel
40
40
  self.state.fan_set_level = res.manualSpeedLevel
41
- self.state.humidity = res.humidity
42
41
  self.state.temperature = res.temperature
43
- self.state.thermal_comfort = res.thermalComfort
44
42
 
45
43
  self.state.mute_status = DeviceStatus.from_int(res.muteState)
46
44
  self.state.mute_set_status = DeviceStatus.from_int(res.muteSwitch)
@@ -528,6 +528,10 @@ class VeSyncAirBaseV2(VeSyncAirBypass):
528
528
 
529
529
  async def toggle_light_detection(self, toggle: bool | None = None) -> bool:
530
530
  """Enable/Disable Light Detection Feature."""
531
+ if bool(self.state.light_detection_status) == toggle:
532
+ _LOGGER.debug('Light detection is already %s', self.state.light_detection_status)
533
+ return True
534
+
531
535
  if toggle is None:
532
536
  toggle = not bool(self.state.light_detection_status)
533
537
  payload_data = {"lightDetectionSwitch": int(toggle)}
@@ -536,8 +540,7 @@ class VeSyncAirBaseV2(VeSyncAirBypass):
536
540
  if r is None:
537
541
  return False
538
542
 
539
- self.state.light_detection_switch = DeviceStatus.ON if toggle \
540
- else DeviceStatus.OFF
543
+ self.state.light_detection_switch = DeviceStatus.from_bool(toggle)
541
544
  self.state.connection_status = ConnectionStatus.ONLINE
542
545
  return True
543
546
 
@@ -587,6 +590,10 @@ class VeSyncAirBaseV2(VeSyncAirBypass):
587
590
  return True
588
591
 
589
592
  async def toggle_display(self, mode: bool) -> bool:
593
+ if bool(self.state.light_detection_status):
594
+ _LOGGER.error('Cannot set display when light detection is enabled')
595
+ return False
596
+
590
597
  if bool(self.state.display_set_status) == mode:
591
598
  _LOGGER.debug('Display is already %s', mode)
592
599
  return True
@@ -10,7 +10,7 @@ from typing import Self, TypedDict
10
10
  from mashumaro import field_options
11
11
  from mashumaro.config import BaseConfig
12
12
  from mashumaro.mixins.orjson import DataClassORJSONMixin
13
- from pyvesync.models.bypass_models import RequestBypassV1
13
+ from pyvesync.models.bypass_models import RequestBypassV1, BypassV2InnerResult
14
14
  from pyvesync.models.base_models import ResponseCodeModel, ResponseBaseModel
15
15
 
16
16
 
@@ -126,7 +126,7 @@ class ResponseESL100MCOuterResult:
126
126
 
127
127
 
128
128
  @dataclass
129
- class ResponseESL100MCResult:
129
+ class ResponseESL100MCResult(BypassV2InnerResult):
130
130
  """ESL100MC Multi-Color Bulb Status Response."""
131
131
  colorMode: str
132
132
  action: str
@@ -28,8 +28,6 @@ class TowerFanResult(BypassV2InnerResult):
28
28
  muteState: int
29
29
  timerRemain: int
30
30
  temperature: int
31
- humidity: int
32
- thermalComfort: int
33
31
  errorCode: int
34
32
  scheduleCount: int
35
33
  displayingType: int | None = None
@@ -847,7 +847,7 @@ def raise_api_errors(error_info: ResponseInfo) -> None:
847
847
 
848
848
  Raises:
849
849
  VeSyncRateLimitError: Rate limit error
850
- VesyncLoginError: Authentication error
850
+ VeSyncLoginError: Authentication error
851
851
  VeSyncTokenError: Token error
852
852
  VeSyncServerError: Server error
853
853
  """
@@ -307,7 +307,7 @@ class VeSync: # pylint: disable=function-redefined
307
307
 
308
308
  return proc_return
309
309
 
310
- async def login(self) -> bool: # pylint: disable=W9006 # pylint mult docstring raises
310
+ async def login(self) -> None: # pylint: disable=W9006 # pylint mult docstring raises
311
311
  """Log into VeSync server.
312
312
 
313
313
  Username and password are provided when class is instantiated.
@@ -364,7 +364,7 @@ class VeSync: # pylint: disable=function-redefined
364
364
  self,
365
365
  auth_code: str | None = None,
366
366
  region_change_token: str | None = None,
367
- ) -> bool: # pylint: disable=W9006 # pylint mult docstring raises
367
+ ) -> None: # pylint: disable=W9006 # pylint mult docstring raises
368
368
  """Exchanges the authorization code for a token.
369
369
 
370
370
  This completes the login process. If the initial call fails with
@@ -407,7 +407,7 @@ class VeSync: # pylint: disable=function-redefined
407
407
  if error_info.error_type == ErrorTypes.CROSS_REGION: # cross region error
408
408
  result = response_model.result
409
409
  self.country_code = result.countryCode
410
- await self._login_token(region_change_token=result.bizToken)
410
+ return await self._login_token(region_change_token=result.bizToken)
411
411
  resp_message = resp_dict.get('msg')
412
412
  if resp_message is not None:
413
413
  error_info.message = f'{error_info.message} ({resp_message})'
@@ -433,7 +433,6 @@ class VeSync: # pylint: disable=function-redefined
433
433
  raise VeSyncAPIResponseError(
434
434
  'Error receiving response to login request'
435
435
  ) from exc
436
- return True
437
436
 
438
437
  async def update(self) -> None:
439
438
  """Fetch updated information about devices and new device list.
@@ -1,11 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyvesync
3
- Version: 3.0.0b6
3
+ Version: 3.0.0b8
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
  Author: Mark Perdue
6
6
  Author-email: Joe Trabulsy <webdjoe@gmail.com>
7
7
  License: MIT
8
8
  Project-URL: Home Page, https://github.com/webdjoe/pyvesync
9
+ Project-URL: Documentation, https://webdjoe.github.io/pyvesync/latest/
9
10
  Keywords: iot,vesync,levoit,etekcity,cosori,valceno
10
11
  Classifier: License :: OSI Approved :: MIT License
11
12
  Classifier: Intended Audience :: Developers
@@ -80,7 +81,15 @@ import aiohttp
80
81
  from pyvesync.vesync import VeSync
81
82
 
82
83
  async def main():
83
- async with VeSync("user", "password") as manager:
84
+ async with VeSync(
85
+ username="user",
86
+ password="password",
87
+ country_code="US", # Optional - country Code to select correct server
88
+ session=session, # Optional - aiohttp.ClientSession
89
+ time_zone="America/New_York", # Optional - Timezone, defaults to America/New_York
90
+ debug=False, # Optional - Debug output
91
+ redact=True # Optional - Redact sensitive information from logs
92
+ ) as manager:
84
93
 
85
94
  # To enable debug mode - prints request and response content for
86
95
  # api calls that return an error code
File without changes
File without changes
File without changes
File without changes
File without changes