pyvesync 3.0.0b8__tar.gz → 3.0.0rc2__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.0b8/src/pyvesync.egg-info → pyvesync-3.0.0rc2}/PKG-INFO +2 -1
  2. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/pyproject.toml +4 -4
  3. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/setup.cfg +1 -1
  4. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/base_devices/bulb_base.py +19 -35
  5. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/base_devices/fryer_base.py +1 -0
  6. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/base_devices/outlet_base.py +1 -1
  7. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/base_devices/purifier_base.py +18 -2
  8. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/base_devices/switch_base.py +5 -5
  9. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/base_devices/thermostat_base.py +11 -6
  10. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/base_devices/vesyncbasedevice.py +3 -1
  11. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/const.py +67 -9
  12. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/device_map.py +111 -32
  13. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/devices/vesyncbulb.py +52 -160
  14. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/devices/vesyncfan.py +1 -3
  15. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/devices/vesynchumidifier.py +3 -3
  16. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/devices/vesynckitchen.py +18 -22
  17. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/devices/vesyncoutlet.py +26 -23
  18. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/devices/vesyncpurifier.py +99 -7
  19. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/devices/vesyncswitch.py +1 -1
  20. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/devices/vesyncthermostat.py +6 -1
  21. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/base_models.py +5 -0
  22. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/bulb_models.py +19 -0
  23. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/bypass_models.py +21 -0
  24. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/fan_models.py +3 -2
  25. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/fryer_models.py +3 -0
  26. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/home_models.py +9 -0
  27. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/humidifier_models.py +12 -1
  28. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/outlet_models.py +24 -1
  29. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/purifier_models.py +57 -3
  30. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/switch_models.py +8 -0
  31. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/thermostat_models.py +12 -2
  32. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/vesync_models.py +108 -41
  33. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/utils/colors.py +14 -10
  34. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/utils/device_mixins.py +1 -0
  35. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/utils/helpers.py +4 -2
  36. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/utils/logs.py +4 -1
  37. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/vesync.py +17 -18
  38. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2/src/pyvesync.egg-info}/PKG-INFO +2 -1
  39. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync.egg-info/requires.txt +1 -0
  40. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/LICENSE +0 -0
  41. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/MANIFEST.in +0 -0
  42. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/README.md +0 -0
  43. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/requirements.txt +0 -0
  44. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/setup.py +0 -0
  45. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/__init__.py +0 -0
  46. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/base_devices/__init__.py +0 -0
  47. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/base_devices/fan_base.py +0 -0
  48. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/base_devices/humidifier_base.py +0 -0
  49. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/device_container.py +0 -0
  50. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/devices/__init__.py +0 -0
  51. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/models/__init__.py +0 -0
  52. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/utils/__init__.py +0 -0
  53. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/utils/enum_utils.py +0 -0
  54. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/utils/errors.py +0 -0
  55. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync/vesynchome.py +0 -0
  56. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync.egg-info/SOURCES.txt +0 -0
  57. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync.egg-info/dependency_links.txt +0 -0
  58. {pyvesync-3.0.0b8 → pyvesync-3.0.0rc2}/src/pyvesync.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyvesync
3
- Version: 3.0.0b8
3
+ Version: 3.0.0rc2
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>
@@ -23,6 +23,7 @@ Requires-Dist: pytest; extra == "dev"
23
23
  Requires-Dist: pytest-cov; extra == "dev"
24
24
  Requires-Dist: pyyaml; extra == "dev"
25
25
  Requires-Dist: tox; extra == "dev"
26
+ Requires-Dist: aiofiles; extra == "dev"
26
27
  Provides-Extra: docs
27
28
  Requires-Dist: mkdocstrings-python; extra == "docs"
28
29
  Requires-Dist: mkdocs; extra == "docs"
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyvesync"
7
- version = "3.0.0b8"
7
+ version = "3.0.0rc2"
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"
@@ -35,7 +35,8 @@ dev = [
35
35
  "pytest",
36
36
  "pytest-cov",
37
37
  "pyyaml",
38
- "tox"
38
+ "tox",
39
+ "aiofiles"
39
40
  ]
40
41
  docs = [
41
42
  "mkdocstrings-python",
@@ -49,11 +50,10 @@ where = ["src"]
49
50
  exclude = ["tests", "test*"]
50
51
 
51
52
  [tool.pytest.ini_options]
53
+ addopts = "--tb=short --color=yes"
52
54
  testpaths = ["src/tests"]
53
55
  norecursedirs = ["*.egg-info", ".git", ".tox", "dist", "build", "venv"]
54
56
  pythonpath = "src"
55
- log_level = "DEBUG"
56
- log_cli_level = "DEBUG"
57
57
  log_cli = true
58
58
 
59
59
  [tool.pylint.MAIN]
@@ -1,6 +1,6 @@
1
1
  [flake8]
2
2
  max-line-length = 90
3
- extend-ignore = D102
3
+ extend-ignore = D102,D401
4
4
 
5
5
  [pycodestyle]
6
6
  max-line-length = 90
@@ -6,7 +6,7 @@ from typing_extensions import deprecated
6
6
 
7
7
  from pyvesync.base_devices.vesyncbasedevice import VeSyncBaseToggleDevice, DeviceState
8
8
  from pyvesync.utils.colors import HSV, RGB, Color
9
- from pyvesync.utils.helpers import Converters, Validators, NUMERIC_STRICT
9
+ from pyvesync.utils.helpers import Converters, Validators
10
10
  from pyvesync.const import BulbFeatures
11
11
 
12
12
  if TYPE_CHECKING:
@@ -104,11 +104,12 @@ class BulbState(DeviceState):
104
104
  return None
105
105
 
106
106
  @hsv.setter
107
- def hsv(
108
- self, hue: NUMERIC_STRICT, saturation: NUMERIC_STRICT, value: NUMERIC_STRICT
109
- ) -> None:
107
+ def hsv(self, hsv_object: HSV | None) -> None:
110
108
  """Set color property with HSV values."""
111
- self._color = Color.from_hsv(hue, saturation, value)
109
+ if hsv_object is None:
110
+ self._color = None
111
+ return
112
+ self._color = Color(hsv_object)
112
113
 
113
114
  @property
114
115
  def rgb(self) -> RGB | None:
@@ -118,9 +119,12 @@ class BulbState(DeviceState):
118
119
  return None
119
120
 
120
121
  @rgb.setter
121
- def rgb(self, red: float, green: float, blue: float) -> None:
122
+ def rgb(self, rgb_object: RGB | None) -> None:
122
123
  """Set color property with RGB values."""
123
- self._color = Color.from_rgb(red, green, blue)
124
+ if rgb_object is None:
125
+ self._color = None
126
+ return
127
+ self._color = Color(rgb_object)
124
128
 
125
129
  @property
126
130
  def brightness(self) -> int | None:
@@ -240,14 +244,12 @@ class VeSyncBulb(VeSyncBaseToggleDevice[BulbState]):
240
244
  Returns:
241
245
  bool: True if successful, False otherwise.
242
246
  """
247
+ del hue, saturation, value
243
248
  if not self.supports_multicolor:
244
249
  logger.debug("Color mode is not supported on this bulb.")
245
- return False
246
- new_color = Color.from_hsv(hue, saturation, value)
247
- if new_color is None:
248
- logger.warning("Invalid color value")
249
- return False
250
- return await self.set_hsv(*new_color.rgb.to_tuple())
250
+ else:
251
+ logger.debug("set_hsv not configured for %s bulb", self.device_type)
252
+ return False
251
253
 
252
254
  async def set_rgb(self, red: float, green: float, blue: float) -> bool:
253
255
  """Set RGB if supported by bulb.
@@ -260,14 +262,12 @@ class VeSyncBulb(VeSyncBaseToggleDevice[BulbState]):
260
262
  Returns:
261
263
  bool: True if successful, False otherwise.
262
264
  """
265
+ del red, green, blue
263
266
  if not self.supports_multicolor:
264
267
  logger.debug("Color mode is not supported on this bulb.")
265
- return False
266
- new_color = Color.from_rgb(red, green, blue)
267
- if new_color is None:
268
- logger.warning("Invalid color value")
269
- return False
270
- return await self.set_hsv(*new_color.hsv.to_tuple())
268
+ else:
269
+ logger.debug("set_rgb not configured for %s bulb", self.device_type)
270
+ return False
271
271
 
272
272
  async def set_brightness(self, brightness: int) -> bool:
273
273
  """Set brightness if supported by bulb.
@@ -282,22 +282,6 @@ class VeSyncBulb(VeSyncBaseToggleDevice[BulbState]):
282
282
  logger.warning("Brightness not supported/configured by this bulb")
283
283
  return False
284
284
 
285
- @property
286
- @deprecated("Access state in `self.state` attribute, use `self.state.rgb`")
287
- def color_value_rgb(self) -> RGB | None:
288
- """DEPRECATED....use `self.state.rgb`."""
289
- if self.state.color is not None:
290
- return self.state.color.rgb
291
- return None
292
-
293
- @property
294
- @deprecated("Access state in `self.state` attribute, use `self.state.hsv`")
295
- def color_value_hsv(self) -> HSV | None:
296
- """DEPRECATED....use `self.state.hsv`."""
297
- if self.state.color is not None:
298
- return self.state.color.hsv
299
- return None
300
-
301
285
  async def set_color_temp(self, color_temp: int) -> bool:
302
286
  """Set color temperature if supported by bulb.
303
287
 
@@ -25,6 +25,7 @@ class FryerState(DeviceState):
25
25
  Note: This class is a placeholder for future functionality and does not currently
26
26
  implement any specific features or attributes.
27
27
  """
28
+
28
29
  __slots__ = ()
29
30
 
30
31
  def __init__(self,
@@ -185,7 +185,7 @@ class VeSyncOutlet(VeSyncBaseToggleDevice):
185
185
  return RequestEnergyHistory.from_dict(body)
186
186
 
187
187
  async def _get_energy_history(self, history_interval: str) -> None:
188
- """Internal function to pull energy history.
188
+ """Pull energy history from API.
189
189
 
190
190
  Args:
191
191
  history_interval (str): The interval for the energy history,
@@ -54,17 +54,24 @@ class PurifierState(DeviceState):
54
54
  light_detection_status (str): Light detection status of the purifier.
55
55
  nightlight_status (str): Nightlight status of the purifier.
56
56
  fan_rotate_angle (int): Fan rotate angle of the purifier.
57
+ temperature (int): Temperature value of the purifier.
58
+ humidity (int): Humidity value of the purifier.
59
+ voc (int): VOC value of the purifier.
60
+ co2 (int): CO2 value of the purifier.
61
+ nightlight_brightness (int): Nightlight brightness level of the purifier.
57
62
 
58
63
  Note:
59
64
  Not all attributes are supported by all models.
60
65
  """
61
66
 
62
67
  __slots__ = (
68
+
63
69
  "_air_quality_level",
64
70
  "aq_percent",
65
71
  "auto_preference_type",
66
72
  "auto_room_size",
67
73
  "child_lock",
74
+ "co2",
68
75
  "display_forever",
69
76
  "display_set_status",
70
77
  "display_status",
@@ -73,13 +80,17 @@ class PurifierState(DeviceState):
73
80
  "fan_set_level",
74
81
  "filter_life",
75
82
  "filter_open_state",
83
+ "humidity",
76
84
  "light_detection_status",
77
85
  "light_detection_switch",
78
86
  "mode",
87
+ "nightlight_brightness",
79
88
  "nightlight_status",
80
89
  "pm1",
81
90
  "pm10",
82
91
  "pm25",
92
+ "temperature",
93
+ "voc",
83
94
  )
84
95
 
85
96
  def __init__(
@@ -102,13 +113,18 @@ class PurifierState(DeviceState):
102
113
  self.display_status: str | None = None
103
114
  self.display_set_status: str | None = None
104
115
  self.display_forever: bool = False
116
+ self.humidity: int | None = None
117
+ self.temperature: int | None = None
105
118
  # Attributes not supported by all purifiers
106
119
  self.pm25: int | None = None
107
120
  self.pm1: int | None = None
108
121
  self.pm10: int | None = None
109
122
  self.aq_percent: int | None = None
123
+ self.voc: int | None = None
124
+ self.co2: int | None = None
110
125
  self.light_detection_switch: str | None = None
111
126
  self.light_detection_status: str | None = None
127
+ self.nightlight_brightness: int | None = None
112
128
  self.nightlight_status: str | None = None
113
129
  self.fan_rotate_angle: int | None = None
114
130
 
@@ -450,12 +466,12 @@ class VeSyncPurifier(VeSyncBaseToggleDevice):
450
466
 
451
467
  @deprecated("Use `set_fan_speed()` instead.")
452
468
  async def change_fan_speed(self, speed: int | None = None) -> bool:
453
- """Deprecated method for changing fan speed."""
469
+ """Deprecated - Set fan speed."""
454
470
  return await self.set_fan_speed(speed)
455
471
 
456
472
  @deprecated("Use `set_mode(mode: str)` instead.")
457
473
  async def change_mode(self, mode: str) -> bool:
458
- """Deprecated method for changing purifier mode."""
474
+ """Deprecated - Set purifier mode."""
459
475
  return await self.set_mode(mode)
460
476
 
461
477
  @deprecated("Use `toggle_child_lock()` instead.")
@@ -102,8 +102,8 @@ class VeSyncSwitch(VeSyncBaseToggleDevice):
102
102
  """Etekcity Switch Base Class.
103
103
 
104
104
  Abstract Base Class for Etekcity Switch Devices, inheriting from
105
- pyvesync.base_devices.vesyncbasedevice.VeSyncBaseDevice. Should not be instantiated directly,
106
- subclassed by VeSyncWallSwitch and VeSyncDimmerSwitch.
105
+ pyvesync.base_devices.vesyncbasedevice.VeSyncBaseDevice. Should not be
106
+ instantiated directly, subclassed by VeSyncWallSwitch and VeSyncDimmerSwitch.
107
107
 
108
108
  Attributes:
109
109
  state (SwitchState): Switch state object.
@@ -191,7 +191,7 @@ class VeSyncSwitch(VeSyncBaseToggleDevice):
191
191
  green: int | None = None,
192
192
  blue: int | None = None
193
193
  ) -> bool:
194
- """Sets the backlight status and optionally its color if supported by the device.
194
+ """Set the backlight status and optionally its color if supported by the device.
195
195
 
196
196
  Args:
197
197
  status (bool): Backlight status (True for ON, False for OFF).
@@ -261,10 +261,10 @@ class VeSyncSwitch(VeSyncBaseToggleDevice):
261
261
 
262
262
  @deprecated("Use `turn_on_indicator_light` instead.")
263
263
  async def turn_indicator_light_on(self) -> bool:
264
- """Deprecated, use turn_on_indicator_light."""
264
+ """Deprecated - use turn_on_indicator_light."""
265
265
  return await self.toggle_indicator_light(True)
266
266
 
267
267
  @deprecated("Use `turn_off_indicator_light` instead.")
268
268
  async def turn_indicator_light_off(self) -> bool:
269
- """Deprecated, use turn_off_indicator_light."""
269
+ """Deprecated - use turn_off_indicator_light."""
270
270
  return await self.toggle_indicator_light(False)
@@ -37,8 +37,10 @@ class ThermostatState(DeviceState):
37
37
  details (ResponseDeviceDetailsModel): The thermostat device details.
38
38
  feature_map (ThermostatMap): The thermostat feature map.
39
39
  """
40
+
40
41
  __slots__ = (
41
42
  "alert_status",
43
+ "battery_level",
42
44
  "configuration",
43
45
  "cool_to_temp",
44
46
  "deadband",
@@ -46,6 +48,7 @@ class ThermostatState(DeviceState):
46
48
  "eco_type",
47
49
  "fan_mode",
48
50
  "fan_status",
51
+ "filter_life",
49
52
  "heat_to_temp",
50
53
  "hold_end_time",
51
54
  "hold_option",
@@ -89,6 +92,8 @@ class ThermostatState(DeviceState):
89
92
  self.alert_status: int | None = None
90
93
  self.routines: list[ThermostatSimpleRoutine] = []
91
94
  self.routine_running_id: int | None = None
95
+ self.battery_level: int | None = None
96
+ self.filter_life: int | None = None
92
97
 
93
98
  @property
94
99
  def is_running(self) -> bool:
@@ -120,7 +125,7 @@ class VeSyncThermostat(VeSyncBaseDevice):
120
125
  feature_map (ThermostatMap): The thermostat feature map.
121
126
  """
122
127
 
123
- __slots__ = ("eco_types", "fan_modes", "hold_options", "work_modes")
128
+ __slots__ = ("eco_types", "fan_modes", "hold_options", "supported_work_modes")
124
129
 
125
130
  def __init__(
126
131
  self,
@@ -132,7 +137,7 @@ class VeSyncThermostat(VeSyncBaseDevice):
132
137
  super().__init__(details, manager, feature_map)
133
138
  self.state: ThermostatState = ThermostatState(self, details, feature_map)
134
139
  self.fan_modes = feature_map.fan_modes
135
- self.work_modes = feature_map.modes
140
+ self.supported_work_modes = feature_map.modes
136
141
  self.eco_types = feature_map.eco_types
137
142
  self.hold_options = feature_map.hold_options
138
143
 
@@ -185,22 +190,22 @@ class VeSyncThermostat(VeSyncBaseDevice):
185
190
  return await self.set_fan_mode(ThermostatConst.FanMode.ON)
186
191
 
187
192
  async def get_configuration(self) -> None:
188
- """Retrieves configuration from API."""
193
+ """Retrieve configuration from API."""
189
194
  _LOGGER.debug("get configuration not implemented for %s", self.device_type)
190
195
 
191
196
  async def set_temp_point(self, temperature: float) -> bool:
192
- """Sets the temperature point."""
197
+ """Set the temperature point."""
193
198
  del temperature
194
199
  _LOGGER.debug("set temp point not implemented for %s", self.device_type)
195
200
  return False
196
201
 
197
202
  async def cancel_hold(self) -> bool:
198
- """Cancels the scheduled hold."""
203
+ """Cancel the scheduled hold."""
199
204
  _LOGGER.debug("cancel hold not implemented for %s", self.device_type)
200
205
  return False
201
206
 
202
207
  async def set_cool_to_temp(self, temperature: float) -> bool:
203
- """Sets the cool to temperature.
208
+ """Set the cool to temperature.
204
209
 
205
210
  Args:
206
211
  temperature (float): The cool to temperature.
@@ -297,7 +297,9 @@ class VeSyncBaseDevice(ABC, Generic[VS_STATE_T]):
297
297
  self.state.display()
298
298
 
299
299
  @deprecated("Use to_json() instead")
300
- def displayJSON(self, state: bool = True, indent: bool = True) -> str: # pylint: disable=invalid-name
300
+ def displayJSON(
301
+ self, state: bool = True, indent: bool = True
302
+ ) -> str: # pylint: disable=invalid-name
301
303
  """Return JSON details for device. - Deprecated use to_json()."""
302
304
  return self.to_json(state, indent)
303
305
 
@@ -55,21 +55,38 @@ BYPASS_HEADER_UA = "okhttp/3.12.1"
55
55
  TERMINAL_ID = '2' + str(uuid4()).replace('-', '')
56
56
  CLIENT_TYPE = "vesyncApp"
57
57
 
58
+ STATUS_OK = 200
59
+
58
60
 
59
61
  # Generic Constants
60
62
 
63
+ KELVIN_MIN = 2700
64
+ KELVIN_MAX = 6500
65
+
66
+
67
+ class ProductLines(StrEnum):
68
+ """High level product line."""
69
+
70
+ WIFI_LIGHT = "wifi-light"
71
+ WIFI_AIR = "wifi-air"
72
+ WIFI_KITCHEN = "wifi-kitchen"
73
+ SWITCHES = "Switches"
74
+ WIFI_SWITCH = "wifi-switch"
75
+ THERMOSTAT = "thermostat"
76
+
61
77
 
62
78
  class ProductTypes(StrEnum):
63
79
  """General device types enum."""
64
- OUTLET = "Outlet"
65
- BULB = "Bulb"
66
- SWITCH = "Switch"
67
- PURIFIER = "Purifier"
68
- FAN = "Fan"
69
- HUMIDIFIER = "Humidifier"
70
- AIR_FRYER = "Air Fryer"
71
- KITCHEN_THERMOMETER = "Kitchen Thermometer"
72
- THERMOSTAT = "Thermostat"
80
+
81
+ OUTLET = "outlet"
82
+ BULB = "bulb"
83
+ SWITCH = "switch"
84
+ PURIFIER = "purifier"
85
+ FAN = "fan"
86
+ HUMIDIFIER = "humidifier"
87
+ AIR_FRYER = "air fryer"
88
+ KITCHEN_THERMOMETER = "kitchen thermometer"
89
+ THERMOSTAT = "thermostat"
73
90
 
74
91
 
75
92
  class IntFlag(IntEnum):
@@ -83,6 +100,7 @@ class IntFlag(IntEnum):
83
100
  Attributes:
84
101
  NOT_SUPPORTED: Device is not supported, -999
85
102
  """
103
+
86
104
  NOT_SUPPORTED = -999
87
105
 
88
106
  def __str__(self) -> str:
@@ -101,6 +119,7 @@ class StrFlag(StrEnum):
101
119
  Attributes:
102
120
  NOT_SUPPORTED: Device is not supported, "not_supported"
103
121
  """
122
+
104
123
  NOT_SUPPORTED = "not_supported"
105
124
 
106
125
 
@@ -125,6 +144,7 @@ class NightlightStatus(StrEnum):
125
144
  # True
126
145
  ```
127
146
  """
147
+
128
148
  ON = "on"
129
149
  OFF = "off"
130
150
  AUTO = "auto"
@@ -171,6 +191,7 @@ class DeviceStatus(StrEnum):
171
191
  # 'on'
172
192
  ```
173
193
  """
194
+
174
195
  ON = "on"
175
196
  OFF = "off"
176
197
  PAUSED = "paused"
@@ -246,6 +267,7 @@ class ConnectionStatus(StrEnum):
246
267
  # True
247
268
  ```
248
269
  """
270
+
249
271
  ONLINE = "online"
250
272
  OFFLINE = "offline"
251
273
  UNKNOWN = "unknown"
@@ -273,6 +295,7 @@ class NightlightModes(StrEnum):
273
295
  AUTO: Nightlight is in auto mode.
274
296
  UNKNOWN: Nightlight status is unknown.
275
297
  """
298
+
276
299
  ON = "on"
277
300
  OFF = "off"
278
301
  DIM = "dim"
@@ -298,6 +321,7 @@ class ColorMode(StrEnum):
298
321
  WHITE: White color mode.
299
322
  COLOR: Color mode.
300
323
  """
324
+
301
325
  RGB = "rgb"
302
326
  HSV = "hsv"
303
327
  WHITE = "white"
@@ -344,6 +368,7 @@ class AirQualityLevel(Enum):
344
368
  # "good"
345
369
  ```
346
370
  """
371
+
347
372
  EXCELLENT = 1
348
373
  GOOD = 2
349
374
  MODERATE = 3
@@ -400,6 +425,7 @@ class PurifierAutoPreference(StrEnum):
400
425
  QUIET: Quiet preference level.
401
426
  UNKNOWN: Unknown preference level.
402
427
  """
428
+
403
429
  DEFAULT = "default"
404
430
  EFFICIENT = "efficient"
405
431
  QUIET = "quiet"
@@ -419,6 +445,7 @@ class FanSleepPreference(StrEnum):
419
445
  QUIET: Quiet sleep mode.
420
446
  UNKNOWN: Unknown sleep mode.
421
447
  """
448
+
422
449
  DEFAULT = "default"
423
450
  ADVANCED = "advanced"
424
451
  TURBO = "turbo"
@@ -449,6 +476,7 @@ class HumidifierFeatures(Features):
449
476
  AUTO_STOP: Auto stop when target humidity is reached.
450
477
  Different from auto, which adjusts fan level to maintain humidity.
451
478
  """
479
+
452
480
  ONOFF = "onoff"
453
481
  CHILD_LOCK = "child_lock"
454
482
  NIGHTLIGHT = "night_light"
@@ -474,6 +502,7 @@ class PurifierFeatures(Features):
474
502
  AQPERCENT: Air quality percentage status.
475
503
  RESET_FILTER: Reset filter status.
476
504
  """
505
+
477
506
  RESET_FILTER = "reset_filter"
478
507
  CHILD_LOCK = "child_lock"
479
508
  NIGHTLIGHT = "night_light"
@@ -494,6 +523,7 @@ class PurifierStringLevels(Features):
494
523
  MEDIUM: Medium fan speed.
495
524
  HIGH: High fan speed.
496
525
  """
526
+
497
527
  LOW = "low"
498
528
  MEDIUM = "medium"
499
529
  HIGH = "high"
@@ -508,6 +538,7 @@ class BulbFeatures(Features):
508
538
  COLOR_TEMP: Color temperature status.
509
539
  MULTICOLOR: Multicolor status.
510
540
  """
541
+
511
542
  ONOFF = "onoff"
512
543
  DIMMABLE = "dimmable"
513
544
  COLOR_TEMP = "color_temp"
@@ -522,6 +553,7 @@ class OutletFeatures(Features):
522
553
  ENERGY_MONITOR: Energy monitor status.
523
554
  NIGHTLIGHT: Nightlight status.
524
555
  """
556
+
525
557
  ONOFF = "onoff"
526
558
  ENERGY_MONITOR = "energy_monitor"
527
559
  NIGHTLIGHT = "nightlight"
@@ -537,6 +569,7 @@ class SwitchFeatures(Features):
537
569
  BACKLIGHT: Backlight status.
538
570
  BACKLIGHT_RGB: RGB backlight status.
539
571
  """
572
+
540
573
  ONOFF = "onoff"
541
574
  DIMMABLE = "dimmable"
542
575
  INDICATOR_LIGHT = "indicator_light"
@@ -546,6 +579,7 @@ class SwitchFeatures(Features):
546
579
 
547
580
  class FanFeatures(Features):
548
581
  """VeSync fan features."""
582
+
549
583
  OSCILLATION = "oscillation"
550
584
  SOUND = "sound"
551
585
  DISPLAYING_TYPE = "displaying_type" # Unknown functionality
@@ -564,6 +598,7 @@ class PurifierModes(Features):
564
598
  PET: Pet mode.
565
599
  UNKNOWN: Unknown mode.
566
600
  """
601
+
567
602
  AUTO = "auto"
568
603
  MANUAL = "manual"
569
604
  SLEEP = "sleep"
@@ -585,6 +620,7 @@ class HumidifierModes(Features):
585
620
  UNKNOWN: Unknown mode.
586
621
  AUTOPRO: AutoPro mode.
587
622
  """
623
+
588
624
  AUTO = "auto"
589
625
  MANUAL = "manual"
590
626
  HUMIDITY = "humidity"
@@ -608,6 +644,7 @@ class FanModes(StrEnum):
608
644
  UNKNOWN: Unknown mode.
609
645
  ADVANCED_SLEEP: Advanced sleep mode.
610
646
  """
647
+
611
648
  AUTO = "auto"
612
649
  NORMAL = "normal"
613
650
  MANUAL = "normal"
@@ -643,6 +680,7 @@ class ThermostatWorkModes(IntEnum):
643
680
  EM_HEAT: Thermostat is in emergency heating mode (4).
644
681
  SMART_AUTO: Thermostat is in smart auto mode (5).
645
682
  """
683
+
646
684
  OFF = 0
647
685
  HEAT = 1
648
686
  COOL = 2
@@ -661,6 +699,7 @@ class ThermostatFanModes(IntEnum):
661
699
  ON: Fan is on (2).
662
700
  CIRCULATE: Fan is in circulate mode (3).
663
701
  """
702
+
664
703
  AUTO = 1
665
704
  ON = 2
666
705
  CIRCULATE = 3
@@ -675,6 +714,7 @@ class ThermostatHoldOptions(IntEnumMixin):
675
714
  FOUR_HOURS: Hold for four hours (4).
676
715
  PERMANENTLY: Hold permanently (5).
677
716
  """
717
+
678
718
  UNTIL_NEXT_SCHEDULED_ITEM = 2
679
719
  TWO_HOURS = 3
680
720
  FOUR_HOURS = 4
@@ -688,12 +728,14 @@ class ThermostatHoldStatus(IntEnumMixin):
688
728
  SET: Set the hold status (1).
689
729
  CANCEL: Cancel the hold status (0).
690
730
  """
731
+
691
732
  SET = 1
692
733
  CANCEL = 0
693
734
 
694
735
 
695
736
  class ThermostatScheduleOrHoldOptions(IntEnumMixin):
696
737
  """Schedule or hold options for VeSync Aura thermostats."""
738
+
697
739
  NOT_SCHEDULE_NOT_HOLD = 0
698
740
  ON_SCHEDULE = 1
699
741
  ON_HOLD = 2
@@ -702,6 +744,7 @@ class ThermostatScheduleOrHoldOptions(IntEnumMixin):
702
744
 
703
745
  class ThermostatEcoTypes(IntEnumMixin):
704
746
  """Eco types for VeSync Aura thermostats."""
747
+
705
748
  COMFORT_SECOND = 1
706
749
  COMFORT_FIRST = 2
707
750
  BALANCE = 3
@@ -711,6 +754,7 @@ class ThermostatEcoTypes(IntEnumMixin):
711
754
 
712
755
  class ThermostatRoutineTypes(IntEnumMixin):
713
756
  """Routine types for VeSync Aura thermostats."""
757
+
714
758
  HOME = 2
715
759
  AWAY = 1
716
760
  SLEEP = 3
@@ -719,6 +763,7 @@ class ThermostatRoutineTypes(IntEnumMixin):
719
763
 
720
764
  class ThermostatAlarmCodes(IntEnumMixin):
721
765
  """Alarm codes for VeSync Aura thermostats."""
766
+
722
767
  HEAT_COOL = 100
723
768
  ABOVE_SAFE_TEMP = 102
724
769
  HEAT_RUNNING_TIME_TOO_LONG = 104
@@ -726,12 +771,14 @@ class ThermostatAlarmCodes(IntEnumMixin):
726
771
 
727
772
  class ThermostatReminderCodes(IntEnumMixin):
728
773
  """Reminder codes for VeSync Aura thermostats."""
774
+
729
775
  FILTER = 150
730
776
  HVAC = 151
731
777
 
732
778
 
733
779
  class ThermostatWorkStatusCodes(IntEnumMixin):
734
780
  """Work status codes for VeSync Aura thermostats."""
781
+
735
782
  OFF = 0
736
783
  HEATING = 1
737
784
  COOLING = 2
@@ -740,12 +787,14 @@ class ThermostatWorkStatusCodes(IntEnumMixin):
740
787
 
741
788
  class ThermostatFanStatus(IntEnumMixin):
742
789
  """Fan Status Enum for Aura Thermostats."""
790
+
743
791
  OFF = 0
744
792
  ON = 1
745
793
 
746
794
 
747
795
  class ThermostatConst:
748
796
  """Constants for VeSync Aura thermostats."""
797
+
749
798
  ReminderCode = ThermostatReminderCodes
750
799
  AlarmCode = ThermostatAlarmCodes
751
800
  WorkMode = ThermostatWorkModes
@@ -756,3 +805,12 @@ class ThermostatConst:
756
805
  RoutineType = ThermostatRoutineTypes
757
806
  ScheduleOrHoldOption = ThermostatScheduleOrHoldOptions
758
807
  WorkStatus = ThermostatWorkStatusCodes
808
+
809
+
810
+ # ------------------- AIR FRYER CONST ------------------ #
811
+
812
+
813
+ CUSTOM_RECIPE_ID = 1
814
+ CUSTOM_RECIPE_TYPE = 3
815
+ CUSTOM_RECIPE_NAME = "Manual Cook"
816
+ CUSTOM_COOK_MODE = "custom"