pyvesync 3.0.0__py3-none-any.whl

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 (50) hide show
  1. pyvesync/__init__.py +5 -0
  2. pyvesync/base_devices/__init__.py +35 -0
  3. pyvesync/base_devices/bulb_base.py +330 -0
  4. pyvesync/base_devices/fan_base.py +392 -0
  5. pyvesync/base_devices/fryer_base.py +68 -0
  6. pyvesync/base_devices/humidifier_base.py +462 -0
  7. pyvesync/base_devices/outlet_base.py +327 -0
  8. pyvesync/base_devices/purifier_base.py +525 -0
  9. pyvesync/base_devices/switch_base.py +271 -0
  10. pyvesync/base_devices/thermostat_base.py +283 -0
  11. pyvesync/base_devices/vesyncbasedevice.py +572 -0
  12. pyvesync/const.py +825 -0
  13. pyvesync/device_container.py +373 -0
  14. pyvesync/device_map.py +1172 -0
  15. pyvesync/devices/__init__.py +1 -0
  16. pyvesync/devices/vesyncbulb.py +1126 -0
  17. pyvesync/devices/vesyncfan.py +233 -0
  18. pyvesync/devices/vesynchumidifier.py +808 -0
  19. pyvesync/devices/vesynckitchen.py +651 -0
  20. pyvesync/devices/vesyncoutlet.py +954 -0
  21. pyvesync/devices/vesyncpurifier.py +990 -0
  22. pyvesync/devices/vesyncswitch.py +415 -0
  23. pyvesync/devices/vesyncthermostat.py +171 -0
  24. pyvesync/models/__init__.py +11 -0
  25. pyvesync/models/base_models.py +129 -0
  26. pyvesync/models/bulb_models.py +197 -0
  27. pyvesync/models/bypass_models.py +289 -0
  28. pyvesync/models/fan_models.py +47 -0
  29. pyvesync/models/fryer_models.py +34 -0
  30. pyvesync/models/home_models.py +169 -0
  31. pyvesync/models/humidifier_models.py +202 -0
  32. pyvesync/models/outlet_models.py +220 -0
  33. pyvesync/models/purifier_models.py +261 -0
  34. pyvesync/models/switch_models.py +101 -0
  35. pyvesync/models/thermostat_models.py +134 -0
  36. pyvesync/models/vesync_models.py +439 -0
  37. pyvesync/utils/__init__.py +1 -0
  38. pyvesync/utils/colors.py +250 -0
  39. pyvesync/utils/device_mixins.py +362 -0
  40. pyvesync/utils/enum_utils.py +26 -0
  41. pyvesync/utils/errors.py +867 -0
  42. pyvesync/utils/helpers.py +700 -0
  43. pyvesync/utils/logs.py +525 -0
  44. pyvesync/vesync.py +638 -0
  45. pyvesync/vesynchome.py +152 -0
  46. pyvesync-3.0.0.dist-info/METADATA +567 -0
  47. pyvesync-3.0.0.dist-info/RECORD +50 -0
  48. pyvesync-3.0.0.dist-info/WHEEL +5 -0
  49. pyvesync-3.0.0.dist-info/licenses/LICENSE +21 -0
  50. pyvesync-3.0.0.dist-info/top_level.txt +1 -0
pyvesync/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ """VeSync API Library."""
2
+
3
+ from pyvesync.vesync import VeSync
4
+
5
+ __all__ = ['VeSync']
@@ -0,0 +1,35 @@
1
+ """Base devices and state classes for VeSync devices.
2
+
3
+ This module contains the base classes for VeSync devices, as well as the state classes
4
+ for each device type. The base classes are used to create the device objects, while the
5
+ state classes are used to store the current state of the device.
6
+ """
7
+
8
+ from .bulb_base import BulbState, VeSyncBulb
9
+ from .fan_base import FanState, VeSyncFanBase
10
+ from .fryer_base import FryerState, VeSyncFryer
11
+ from .humidifier_base import HumidifierState, VeSyncHumidifier
12
+ from .outlet_base import OutletState, VeSyncOutlet
13
+ from .purifier_base import PurifierState, VeSyncPurifier
14
+ from .switch_base import SwitchState, VeSyncSwitch
15
+ from .vesyncbasedevice import DeviceState, VeSyncBaseDevice, VeSyncBaseToggleDevice
16
+
17
+ __all__ = [
18
+ 'BulbState',
19
+ 'DeviceState',
20
+ 'FanState',
21
+ 'FryerState',
22
+ 'HumidifierState',
23
+ 'OutletState',
24
+ 'PurifierState',
25
+ 'SwitchState',
26
+ 'VeSyncBaseDevice',
27
+ 'VeSyncBaseToggleDevice',
28
+ 'VeSyncBulb',
29
+ 'VeSyncFanBase',
30
+ 'VeSyncFryer',
31
+ 'VeSyncHumidifier',
32
+ 'VeSyncOutlet',
33
+ 'VeSyncPurifier',
34
+ 'VeSyncSwitch',
35
+ ]
@@ -0,0 +1,330 @@
1
+ """Base classes for all VeSync bulbs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ from typing import TYPE_CHECKING
7
+
8
+ from typing_extensions import deprecated
9
+
10
+ from pyvesync.base_devices.vesyncbasedevice import DeviceState, VeSyncBaseToggleDevice
11
+ from pyvesync.const import BulbFeatures
12
+ from pyvesync.utils.colors import HSV, RGB, Color
13
+ from pyvesync.utils.helpers import Converters, Validators
14
+
15
+ if TYPE_CHECKING:
16
+ from pyvesync import VeSync
17
+ from pyvesync.device_map import BulbMap
18
+ from pyvesync.models.vesync_models import ResponseDeviceDetailsModel
19
+
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ class BulbState(DeviceState):
25
+ """VeSync Bulb State Base.
26
+
27
+ Base class to hold all state attributes for bulb devices. Inherits from
28
+ [`DeviceState`][pyvesync.base_devices.vesyncbasedevice.DeviceState]. This
29
+ class should not be used directly for devices, but rather subclassed for each
30
+ bulb type.
31
+
32
+ Args:
33
+ device (VeSyncBulb): VeSync Bulb device.
34
+ details (ResponseDeviceDetailsModel): Device details from API.
35
+ feature_map (BulbMap): Feature map for bulb.
36
+
37
+ Attributes:
38
+ _exclude_serialization (list[str]): List of attributes to exclude from
39
+ serialization.
40
+ active_time (int): Active time of device, defaults to None.
41
+ connection_status (str): Connection status of device.
42
+ device (VeSyncBaseDevice): Device object.
43
+ device_status (str): Device status.
44
+ features (dict): Features of device.
45
+ last_update_ts (int): Last update timestamp of device, defaults to None.
46
+ brightness (int): Brightness of bulb (0-100).
47
+ color_temp (int): White color temperature of bulb in percent (0-100).
48
+ color_temp_kelvin (int): White color temperature of bulb in Kelvin.
49
+ color (Color): Color of bulb in the form of a dataclass with two namedtuple
50
+ attributes - `hsv` & `rgb`. See
51
+ [utils.colors.Colors][pyvesync.utils.colors.Color].
52
+ color_mode (str): Color mode of bulb.
53
+ color_modes (list[str]): List of color modes supported by bulb.
54
+
55
+ Methods:
56
+ update_ts: Update last update timestamp.
57
+ to_dict: Dump state to JSON.
58
+ to_json: Dump state to JSON string.
59
+ to_jsonb: Dump state to JSON bytes.
60
+ as_tuple: Convert state to tuple of (name, value) tuples.
61
+
62
+ See Also:
63
+ - [`VeSyncBulb`][pyvesync.base_devices.bulb_base.VeSyncBulb]
64
+ - [`ResponseDeviceDetailsModel`][
65
+ pyvesync.models.device_list_models.ResponseDeviceDetailsModel]
66
+ - [`BulbMap`][pyvesync.device_map.BulbMap]
67
+ """
68
+
69
+ __slots__ = ('_brightness', '_color', '_color_temp', 'color_mode', 'color_modes')
70
+
71
+ def __init__(
72
+ self,
73
+ device: VeSyncBulb,
74
+ details: ResponseDeviceDetailsModel,
75
+ feature_map: BulbMap,
76
+ ) -> None:
77
+ """Initialize VeSync Bulb State Base."""
78
+ super().__init__(device, details, feature_map)
79
+ self._exclude_serialization: list[str] = ['rgb', 'hsv']
80
+ self.features: list[str] = feature_map.features
81
+ self.color_modes: list[str] = feature_map.color_modes
82
+ self.device: VeSyncBulb = device
83
+ self.color_mode: str | None = None
84
+ self._brightness: int | None = None
85
+ self._color_temp: int | None = None
86
+ self._color: Color | None = None
87
+
88
+ @property
89
+ def color(self) -> Color | None:
90
+ """Return color of bulb."""
91
+ return self._color
92
+
93
+ @color.setter
94
+ def color(self, color: Color | None) -> None:
95
+ """Set color of bulb."""
96
+ self._color = color
97
+
98
+ @property
99
+ def hsv(self) -> HSV | None:
100
+ """Return color of bulb as HSV."""
101
+ if self._color is not None:
102
+ return self._color.hsv
103
+ return None
104
+
105
+ @hsv.setter
106
+ def hsv(self, hsv_object: HSV | None) -> None:
107
+ """Set color property with HSV values."""
108
+ if hsv_object is None:
109
+ self._color = None
110
+ return
111
+ self._color = Color(hsv_object)
112
+
113
+ @property
114
+ def rgb(self) -> RGB | None:
115
+ """Return color of bulb as RGB."""
116
+ if self._color is not None:
117
+ return self._color.rgb
118
+ return None
119
+
120
+ @rgb.setter
121
+ def rgb(self, rgb_object: RGB | None) -> None:
122
+ """Set color property with RGB values."""
123
+ if rgb_object is None:
124
+ self._color = None
125
+ return
126
+ self._color = Color(rgb_object)
127
+
128
+ @property
129
+ def brightness(self) -> int | None:
130
+ """Brightness of vesync bulb 0-100."""
131
+ if not self.device.supports_brightness:
132
+ logger.warning('Brightness not supported by this bulb')
133
+ return None
134
+ return self._brightness
135
+
136
+ @brightness.setter
137
+ def brightness(self, value: int | None) -> None:
138
+ if not self.device.supports_brightness:
139
+ logger.warning('Brightness not supported by this bulb')
140
+ return
141
+ if Validators.validate_zero_to_hundred(value):
142
+ self._brightness = value
143
+ else:
144
+ self._brightness = None
145
+
146
+ @property
147
+ def color_temp(self) -> int | None:
148
+ """White color temperature of bulb in percent (0-100)."""
149
+ if not self.device.supports_color_temp:
150
+ logger.warning('Color temperature not supported by this bulb')
151
+ return None
152
+ return self._color_temp
153
+
154
+ @color_temp.setter
155
+ def color_temp(self, value: int) -> None:
156
+ if not self.device.supports_color_temp:
157
+ logger.warning('Color temperature not supported by this bulb')
158
+ return
159
+ if Validators.validate_zero_to_hundred(value):
160
+ self._color_temp = value
161
+ else:
162
+ logger.warning('Color temperature must be between 0 and 100')
163
+
164
+ @property
165
+ def color_temp_kelvin(self) -> int | None:
166
+ """Return white color temperature of bulb in Kelvin."""
167
+ if not self.device.supports_color_temp:
168
+ logger.warning('Color temperature not supported by this bulb')
169
+ return None
170
+ if self._color_temp is not None:
171
+ return Converters.color_temp_pct_to_kelvin(self._color_temp)
172
+ return None
173
+
174
+
175
+ class VeSyncBulb(VeSyncBaseToggleDevice[BulbState]):
176
+ """Base class for VeSync Bulbs.
177
+
178
+ Abstract base class to provide methods for controlling and
179
+ getting details of VeSync bulbs. Inherits from
180
+ [`VeSyncBaseDevice`][pyvesync.base_devices.vesyncbasedevice.VeSyncBaseDevice]. This
181
+ class should not be used directly for devices, but rather subclassed for each bulb.
182
+
183
+ Args:
184
+ details (ResponseDeviceDetailsModel): Device details from API.
185
+ manager (VeSync): VeSync API manager.
186
+ feature_map (BulbMap): Feature map for bulb.
187
+
188
+ Attributes:
189
+ state (BulbState): Device state object
190
+ Each device has a separate state base class in the base_devices module.
191
+ last_response (ResponseInfo): Last response from API call.
192
+ manager (VeSync): Manager object for API calls.
193
+ device_name (str): Name of device.
194
+ device_image (str): URL for device image.
195
+ cid (str): Device ID.
196
+ connection_type (str): Connection type of device.
197
+ device_type (str): Type of device.
198
+ type (str): Type of device.
199
+ uuid (str): UUID of device, not always present.
200
+ config_module (str): Configuration module of device.
201
+ mac_id (str): MAC ID of device.
202
+ current_firm_version (str): Current firmware version of device.
203
+ device_region (str): Region of device. (US, EU, etc.)
204
+ pid (str): Product ID of device, pulled by some devices on update.
205
+ sub_device_no (int): Sub-device number of device.
206
+ product_type (str): Product type of device.
207
+ features (dict): Features of device.
208
+ """
209
+
210
+ __slots__ = ()
211
+
212
+ def __init__(
213
+ self, details: ResponseDeviceDetailsModel, manager: VeSync, feature_map: BulbMap
214
+ ) -> None:
215
+ """Initialize VeSync smart bulb base class."""
216
+ super().__init__(details, manager, feature_map)
217
+ self.state: BulbState = BulbState(self, details, feature_map)
218
+
219
+ @property
220
+ def supports_brightness(self) -> bool:
221
+ """Return True if bulb supports brightness."""
222
+ return BulbFeatures.DIMMABLE in self.features
223
+
224
+ @property
225
+ def supports_color_temp(self) -> bool:
226
+ """Return True if bulb supports color temperature."""
227
+ return BulbFeatures.COLOR_TEMP in self.features
228
+
229
+ @property
230
+ def supports_multicolor(self) -> bool:
231
+ """Return True if bulb supports backlight."""
232
+ return BulbFeatures.MULTICOLOR in self.features
233
+
234
+ async def set_hsv(self, hue: float, saturation: float, value: float) -> bool:
235
+ """Set HSV if supported by bulb.
236
+
237
+ Args:
238
+ hue (float): Hue 0-360
239
+ saturation (float): Saturation 0-100
240
+ value (float): Value 0-100
241
+
242
+ Returns:
243
+ bool: True if successful, False otherwise.
244
+ """
245
+ del hue, saturation, value
246
+ if not self.supports_multicolor:
247
+ logger.debug('Color mode is not supported on this bulb.')
248
+ else:
249
+ logger.debug('set_hsv not configured for %s bulb', self.device_type)
250
+ return False
251
+
252
+ async def set_rgb(self, red: float, green: float, blue: float) -> bool:
253
+ """Set RGB if supported by bulb.
254
+
255
+ Args:
256
+ red (float): Red 0-255
257
+ green (float): green 0-255
258
+ blue (float): blue 0-255
259
+
260
+ Returns:
261
+ bool: True if successful, False otherwise.
262
+ """
263
+ del red, green, blue
264
+ if not self.supports_multicolor:
265
+ logger.debug('Color mode is not supported on this bulb.')
266
+ else:
267
+ logger.debug('set_rgb not configured for %s bulb', self.device_type)
268
+ return False
269
+
270
+ async def set_brightness(self, brightness: int) -> bool:
271
+ """Set brightness if supported by bulb.
272
+
273
+ Args:
274
+ brightness (NUMERIC_T): Brightness 0-100
275
+
276
+ Returns:
277
+ bool: True if successful, False otherwise.
278
+ """
279
+ del brightness
280
+ logger.warning('Brightness not supported/configured by this bulb')
281
+ return False
282
+
283
+ async def set_color_temp(self, color_temp: int) -> bool:
284
+ """Set color temperature if supported by bulb.
285
+
286
+ Args:
287
+ color_temp (int): Color temperature 0-100
288
+
289
+ Returns:
290
+ bool: True if successful, False otherwise.
291
+ """
292
+ del color_temp
293
+ if self.supports_color_temp:
294
+ logger.debug('Color temperature is not configured on this bulb.')
295
+ else:
296
+ logger.debug('Color temperature not supported by this bulb')
297
+ return False
298
+
299
+ async def set_white_mode(self) -> bool:
300
+ """Set white mode if supported by bulb.
301
+
302
+ Returns:
303
+ bool: True if successful, False otherwise.
304
+ """
305
+ if self.supports_multicolor:
306
+ logger.debug('White mode is not configured on this bulb.')
307
+ else:
308
+ logger.warning('White mode not supported by this bulb')
309
+ return False
310
+
311
+ async def set_color_mode(self, color_mode: str) -> bool:
312
+ """Set color mode if supported by bulb.
313
+
314
+ Args:
315
+ color_mode (str): Color mode to set.
316
+
317
+ Returns:
318
+ bool: True if successful, False otherwise.
319
+ """
320
+ del color_mode
321
+ if self.supports_multicolor:
322
+ logger.debug('Color mode is not configured on this bulb.')
323
+ else:
324
+ logger.warning('Color mode not supported by this bulb')
325
+ return False
326
+
327
+ @deprecated('Use `set_white_mode` instead.')
328
+ async def enable_white_mode(self) -> bool:
329
+ """Enable white mode if supported by bulb."""
330
+ return await self.set_white_mode()