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/vesynchome.py
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"""This is a WIP, not implemented yet."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
7
|
+
from dataclasses import fields
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from pyvesync.models.base_models import DefaultValues
|
|
11
|
+
from pyvesync.models.home_models import (
|
|
12
|
+
IntResponseHomeListModel,
|
|
13
|
+
IntResponseHomeResultModel,
|
|
14
|
+
RequestHomeModel,
|
|
15
|
+
ResponseHomeModel,
|
|
16
|
+
)
|
|
17
|
+
from pyvesync.utils.errors import ErrorCodes, VeSyncAPIResponseError
|
|
18
|
+
from pyvesync.utils.helpers import Helpers
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from pyvesync.base_devices import VeSyncBaseDevice
|
|
22
|
+
from pyvesync.models.base_models import RequestBaseModel
|
|
23
|
+
from pyvesync.vesync import VeSync
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
_LOGGER = logging.getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class VeSyncHome:
|
|
30
|
+
"""Class to handle home-related operations in VeSync."""
|
|
31
|
+
|
|
32
|
+
def __init__(self, home_id: int, name: str, nickname: str | None = None) -> None:
|
|
33
|
+
"""Initialize the VeSyncHome instance."""
|
|
34
|
+
self.home_id: int = home_id
|
|
35
|
+
self.name: str = name
|
|
36
|
+
self.nickname: str | None = nickname
|
|
37
|
+
self.rooms: list[VeSyncRoom] = []
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def devices(self) -> list[VeSyncBaseDevice]:
|
|
41
|
+
"""Return a list of all devices in the home."""
|
|
42
|
+
devices = []
|
|
43
|
+
for room in self.rooms:
|
|
44
|
+
devices.extend(room.devices)
|
|
45
|
+
return devices
|
|
46
|
+
|
|
47
|
+
async def update_devices(self, devices: list[VeSyncBaseDevice]) -> None:
|
|
48
|
+
"""Update the devices in the home."""
|
|
49
|
+
update_tasks = [device.update() for device in devices]
|
|
50
|
+
for update_coro in asyncio.as_completed(update_tasks):
|
|
51
|
+
try:
|
|
52
|
+
await update_coro
|
|
53
|
+
except Exception as e: # pylint: disable=broad-except
|
|
54
|
+
_LOGGER.debug('Error updating device %s', e)
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def _build_request_model(
|
|
58
|
+
manager: VeSync, request_model: type[RequestBaseModel]
|
|
59
|
+
) -> RequestBaseModel:
|
|
60
|
+
"""Build the request model for home data."""
|
|
61
|
+
req_fields = [field.name for field in fields(request_model) if field.init]
|
|
62
|
+
body = Helpers.get_class_attributes(DefaultValues, req_fields)
|
|
63
|
+
body.update(Helpers.get_class_attributes(manager, req_fields))
|
|
64
|
+
return request_model(**body)
|
|
65
|
+
|
|
66
|
+
@classmethod
|
|
67
|
+
def _process_home_list(
|
|
68
|
+
cls, home_list: list[IntResponseHomeListModel]
|
|
69
|
+
) -> list[VeSyncHome]:
|
|
70
|
+
"""Process the home list and return a list of VeSyncHome instances."""
|
|
71
|
+
homes = []
|
|
72
|
+
for home in home_list:
|
|
73
|
+
if not isinstance(home, IntResponseHomeListModel):
|
|
74
|
+
msg = (
|
|
75
|
+
'Invalid home list item type.'
|
|
76
|
+
f'Expected IntResponseHomeListModel, got {home}'
|
|
77
|
+
)
|
|
78
|
+
raise VeSyncAPIResponseError(msg)
|
|
79
|
+
homes.append(VeSyncHome(home.homeId, home.homeName, home.nickname))
|
|
80
|
+
return homes
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
async def build_homes(cls, manager: VeSync) -> bool:
|
|
84
|
+
"""Get home information.
|
|
85
|
+
|
|
86
|
+
This method retrieves the home list from the VeSync API and populates
|
|
87
|
+
the VeSyncHome instances in the manager. The objects are stored in
|
|
88
|
+
`manager.homes` attribute as a list.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
manager (VeSync): The VeSync instance to use for the API call.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
bool: True if the home list was successfully retrieved and populated.
|
|
95
|
+
|
|
96
|
+
Raises:
|
|
97
|
+
VeSyncAPIResponseError: If the API response contains an error or
|
|
98
|
+
if the home list is empty.
|
|
99
|
+
"""
|
|
100
|
+
body = cls._build_request_model(manager, RequestHomeModel)
|
|
101
|
+
response, _ = await manager.async_call_api(
|
|
102
|
+
'/cloud/v1/homeManaged/getHomeList', method='post', json_object=body
|
|
103
|
+
)
|
|
104
|
+
if response is None:
|
|
105
|
+
raise VeSyncAPIResponseError(
|
|
106
|
+
'Response is None, enable debugging to see more information.'
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
resp_model = ResponseHomeModel.from_dict(response)
|
|
110
|
+
if resp_model.code != 0:
|
|
111
|
+
error = ErrorCodes.get_error_info(resp_model.code)
|
|
112
|
+
if resp_model.msg is not None:
|
|
113
|
+
error.message = f'{resp_model.msg} ({error.message})'
|
|
114
|
+
|
|
115
|
+
msg = f'Failed to get home list with error: {error.to_json()}'
|
|
116
|
+
raise VeSyncAPIResponseError(msg)
|
|
117
|
+
result = resp_model.result
|
|
118
|
+
if not isinstance(result, IntResponseHomeResultModel):
|
|
119
|
+
msg = (
|
|
120
|
+
'Error in home list API response.'
|
|
121
|
+
f'Expected IntResponseHomeResultModel, got {result}'
|
|
122
|
+
)
|
|
123
|
+
raise VeSyncAPIResponseError(msg)
|
|
124
|
+
home_list = result.homeList
|
|
125
|
+
if not home_list:
|
|
126
|
+
raise VeSyncAPIResponseError('No homes found in the response.')
|
|
127
|
+
for home in home_list:
|
|
128
|
+
if not isinstance(home, IntResponseHomeListModel):
|
|
129
|
+
msg = ('Invalid home list item type.'
|
|
130
|
+
f'Expected IntResponseHomeListModel, got {home}')
|
|
131
|
+
raise VeSyncAPIResponseError(msg)
|
|
132
|
+
return True
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class VeSyncRoom:
|
|
136
|
+
"""Class to handle room-related operations in VeSync."""
|
|
137
|
+
|
|
138
|
+
def __init__(self, room_id: str, name: str) -> None:
|
|
139
|
+
"""Initialize the VeSyncRoom instance."""
|
|
140
|
+
self.room_id: str = room_id
|
|
141
|
+
self.name: str = name
|
|
142
|
+
self.devices: list[VeSyncBaseDevice] = []
|
|
143
|
+
|
|
144
|
+
@staticmethod
|
|
145
|
+
def _build_request_model(
|
|
146
|
+
manager: VeSync, request_model: type[RequestBaseModel]
|
|
147
|
+
) -> RequestBaseModel:
|
|
148
|
+
"""Build the request model for room data."""
|
|
149
|
+
req_fields = [field.name for field in fields(request_model) if field.init]
|
|
150
|
+
body = Helpers.get_class_attributes(DefaultValues, req_fields)
|
|
151
|
+
body.update(Helpers.get_class_attributes(manager, req_fields))
|
|
152
|
+
return request_model(**body)
|