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/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)