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.
- pyvesync/__init__.py +5 -0
- pyvesync/base_devices/__init__.py +35 -0
- pyvesync/base_devices/bulb_base.py +330 -0
- pyvesync/base_devices/fan_base.py +392 -0
- pyvesync/base_devices/fryer_base.py +68 -0
- pyvesync/base_devices/humidifier_base.py +462 -0
- pyvesync/base_devices/outlet_base.py +327 -0
- pyvesync/base_devices/purifier_base.py +525 -0
- pyvesync/base_devices/switch_base.py +271 -0
- pyvesync/base_devices/thermostat_base.py +283 -0
- pyvesync/base_devices/vesyncbasedevice.py +572 -0
- pyvesync/const.py +825 -0
- pyvesync/device_container.py +373 -0
- pyvesync/device_map.py +1172 -0
- pyvesync/devices/__init__.py +1 -0
- pyvesync/devices/vesyncbulb.py +1126 -0
- pyvesync/devices/vesyncfan.py +233 -0
- pyvesync/devices/vesynchumidifier.py +808 -0
- pyvesync/devices/vesynckitchen.py +651 -0
- pyvesync/devices/vesyncoutlet.py +954 -0
- pyvesync/devices/vesyncpurifier.py +990 -0
- pyvesync/devices/vesyncswitch.py +415 -0
- pyvesync/devices/vesyncthermostat.py +171 -0
- pyvesync/models/__init__.py +11 -0
- pyvesync/models/base_models.py +129 -0
- pyvesync/models/bulb_models.py +197 -0
- pyvesync/models/bypass_models.py +289 -0
- pyvesync/models/fan_models.py +47 -0
- pyvesync/models/fryer_models.py +34 -0
- pyvesync/models/home_models.py +169 -0
- pyvesync/models/humidifier_models.py +202 -0
- pyvesync/models/outlet_models.py +220 -0
- pyvesync/models/purifier_models.py +261 -0
- pyvesync/models/switch_models.py +101 -0
- pyvesync/models/thermostat_models.py +134 -0
- pyvesync/models/vesync_models.py +439 -0
- pyvesync/utils/__init__.py +1 -0
- pyvesync/utils/colors.py +250 -0
- pyvesync/utils/device_mixins.py +362 -0
- pyvesync/utils/enum_utils.py +26 -0
- pyvesync/utils/errors.py +867 -0
- pyvesync/utils/helpers.py +700 -0
- pyvesync/utils/logs.py +525 -0
- pyvesync/vesync.py +638 -0
- pyvesync/vesynchome.py +152 -0
- pyvesync-3.0.0.dist-info/METADATA +567 -0
- pyvesync-3.0.0.dist-info/RECORD +50 -0
- pyvesync-3.0.0.dist-info/WHEEL +5 -0
- pyvesync-3.0.0.dist-info/licenses/LICENSE +21 -0
- pyvesync-3.0.0.dist-info/top_level.txt +1 -0
pyvesync/__init__.py
ADDED
|
@@ -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()
|