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
@@ -0,0 +1,261 @@
1
+ """Data models for VeSync Purifiers.
2
+
3
+ These models inherit from `ResponseBaseModel` and `RequestBaseModel` from the
4
+ `base_models` module.
5
+
6
+ The `InnerPurifierBaseResult` class is used as a base class for the inner purifier
7
+ result models for all models and the mashumaro discriminator determines the correct
8
+ subclass when deserializing.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from dataclasses import dataclass
14
+
15
+ from mashumaro.config import BaseConfig
16
+ from mashumaro.types import Discriminator
17
+
18
+ from pyvesync.models.base_models import (
19
+ RequestBaseModel,
20
+ ResponseBaseModel,
21
+ )
22
+ from pyvesync.models.bypass_models import (
23
+ BypassV1Result,
24
+ BypassV2InnerResult,
25
+ RequestBypassV1,
26
+ )
27
+
28
+
29
+ @dataclass
30
+ class InnerPurifierBaseResult(BypassV2InnerResult):
31
+ """Base class for inner purifier results model."""
32
+
33
+ class Config(BaseConfig): # type: ignore[override]
34
+ """Configure the results model to use subclass discriminator."""
35
+
36
+ discriminator = Discriminator(include_subtypes=True)
37
+
38
+
39
+ @dataclass
40
+ class PurifierVitalDetailsResult(InnerPurifierBaseResult):
41
+ """Vital 100S/200S and Everest Purifier Result Model."""
42
+
43
+ powerSwitch: int
44
+ filterLifePercent: int
45
+ workMode: str
46
+ manualSpeedLevel: int
47
+ fanSpeedLevel: int
48
+ AQLevel: int
49
+ PM25: int
50
+ screenState: int
51
+ childLockSwitch: int
52
+ screenSwitch: int
53
+ lightDetectionSwitch: int
54
+ environmentLightState: int
55
+ scheduleCount: int
56
+ timerRemain: int
57
+ efficientModeTimeRemain: int
58
+ errorCode: int
59
+ autoPreference: V2AutoPreferences | None = None
60
+ fanRotateAngle: int | None = None
61
+ filterOpenState: int | None = None
62
+ PM1: int | None = None
63
+ PM10: int | None = None
64
+ AQPercent: int | None = None
65
+
66
+
67
+ @dataclass
68
+ class V2AutoPreferences:
69
+ """Vital 100S/200S Auto Preferences."""
70
+
71
+ autoPreferenceType: str
72
+ roomSize: int
73
+
74
+
75
+ @dataclass
76
+ class PurifierSproutResult(InnerPurifierBaseResult):
77
+ """Sprout Purifier Result Model."""
78
+
79
+ powerSwitch: int
80
+ workMode: str
81
+ manualSpeedLevel: int | None
82
+ fanSpeedLevel: int | None
83
+ PM1: int | None
84
+ PM25: int | None
85
+ PM10: int | None
86
+ screenState: int
87
+ childLockSwitch: int
88
+ screenSwitch: int
89
+ scheduleCount: int
90
+ timerRemain: int
91
+ humidity: int | None
92
+ AQI: int | None
93
+ AQLevel: int | None
94
+ temperature: int | None
95
+ VOC: int | None
96
+ CO2: int | None
97
+ errorCode: int
98
+ nightlight: PurifierNightlight | None = None
99
+ autoPreference: V2AutoPreferences | None = None
100
+
101
+
102
+ @dataclass
103
+ class PurifierNightlight(ResponseBaseModel):
104
+ """Purifier Nightlight Response Dict."""
105
+
106
+ nightLightSwitch: bool
107
+ brightness: int
108
+ colorTemperature: int
109
+
110
+
111
+ @dataclass
112
+ class PurifierCoreDetailsResult(InnerPurifierBaseResult):
113
+ """Purifier inner Result Dict."""
114
+
115
+ enabled: bool
116
+ filter_life: int
117
+ mode: str
118
+ level: int
119
+ device_error_code: int
120
+ levelNew: int | None = None
121
+ air_quality: int | None = None
122
+ display: bool | None = None
123
+ child_lock: bool | None = None
124
+ configuration: PurifierCoreDetailsConfig | None = None
125
+ extension: dict | None = None
126
+ air_quality_value: int | None = None
127
+ night_light: str | None = None
128
+ fan_rotate: str | None = None
129
+
130
+
131
+ # Purifier Timer Models
132
+
133
+
134
+ @dataclass
135
+ class PurifierModifyTimerResult(InnerPurifierBaseResult):
136
+ """Purifier inner Add Timer Result Dict."""
137
+
138
+ id: int
139
+
140
+
141
+ @dataclass
142
+ class PurifierGetTimerResult(InnerPurifierBaseResult):
143
+ """Purifier inner Timer Result Dict."""
144
+
145
+ timers: list[ResponsePurifierTimerItems] | None
146
+
147
+
148
+ @dataclass
149
+ class ResponsePurifierTimerItems(ResponseBaseModel):
150
+ """Purifier Timer Items Response Dict."""
151
+
152
+ id: int
153
+ remain: int
154
+ total: int
155
+ action: str
156
+
157
+
158
+ @dataclass
159
+ class PurifierV2TimerPayloadData(RequestBaseModel):
160
+ """Purifier Timer Payload Data Request Dict."""
161
+
162
+ enabled: bool
163
+ startAct: list[PurifierV2TimerActionItems]
164
+ tmgEvt: PurifierV2EventTiming | None = None
165
+ type: int = 0
166
+ subDeviceNo: int = 0
167
+ repeat: int = 0
168
+
169
+
170
+ @dataclass
171
+ class PurifierV2TimerActionItems(RequestBaseModel):
172
+ """Purifier Timer Action Items Request Dict."""
173
+
174
+ type: str
175
+ act: int
176
+ num: int = 0
177
+
178
+
179
+ @dataclass
180
+ class PurifierV2EventTiming(RequestBaseModel):
181
+ """Purifier Event Timing Request Dict."""
182
+
183
+ clkSec: int
184
+
185
+
186
+ # Internal Purifier Details Models
187
+
188
+
189
+ @dataclass
190
+ class PurifierCoreDetailsConfig(ResponseBaseModel):
191
+ """Config dict in Core purifier details response."""
192
+
193
+ display: bool
194
+ display_forever: bool
195
+ auto_preference: None | PurifierCoreAutoConfig
196
+
197
+
198
+ @dataclass
199
+ class PurifierCoreAutoConfig(ResponseBaseModel):
200
+ """Auto configuration Core dict in purifier details response."""
201
+
202
+ type: str
203
+ room_size: int
204
+
205
+
206
+ @dataclass
207
+ class PurifierDetailsExtension(ResponseBaseModel):
208
+ """Extension dict in purifier details response for Core 200/300/400."""
209
+
210
+ schedule_count: int
211
+ timer_remain: int
212
+
213
+
214
+ # LV - PUR131S Purifier Models
215
+
216
+
217
+ @dataclass
218
+ class RequestPurifier131(RequestBypassV1):
219
+ """Purifier 131 Request Dict."""
220
+
221
+ status: str | None = None
222
+
223
+
224
+ @dataclass
225
+ class RequestPurifier131Mode(RequestBypassV1):
226
+ """Purifier 131 Request Dict."""
227
+
228
+ mode: str
229
+
230
+
231
+ @dataclass
232
+ class RequestPurifier131Level(RequestBypassV1):
233
+ """Purifier 131 Request Dict."""
234
+
235
+ level: int
236
+
237
+
238
+ @dataclass
239
+ class Purifier131Result(BypassV1Result):
240
+ """Purifier 131 Details Response Dict."""
241
+
242
+ screenStatus: str
243
+ filterLife: Purifier131Filter
244
+ activeTime: int
245
+ levelNew: int
246
+ level: int | None
247
+ mode: str
248
+ airQuality: str
249
+ deviceName: str
250
+ childLock: str
251
+ deviceStatus: str
252
+ connectionStatus: str
253
+
254
+
255
+ @dataclass
256
+ class Purifier131Filter(ResponseBaseModel):
257
+ """Filter details model for LV PUR131."""
258
+
259
+ change: bool
260
+ useHour: int
261
+ percent: int
@@ -0,0 +1,101 @@
1
+ """Data models for VeSync switches.
2
+
3
+ These models inherit from `ResponseBaseModel` and `RequestBaseModel` from the
4
+ `base_models` module.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from dataclasses import dataclass
10
+ from typing import Any
11
+
12
+ import orjson
13
+ from mashumaro.config import BaseConfig
14
+
15
+ from pyvesync.models.base_models import ResponseBaseModel, ResponseCodeModel
16
+ from pyvesync.models.bypass_models import RequestBypassV1
17
+
18
+
19
+ @dataclass
20
+ class ResponseSwitchDetails(ResponseCodeModel):
21
+ """Dimmer and Wall Switch Details Response Dict."""
22
+
23
+ result: InternalDimmerDetailsResult | InternalSwitchResult | None = None
24
+
25
+
26
+ @dataclass
27
+ class InternalSwitchResult(ResponseBaseModel):
28
+ """Dimmer Status Response Dict."""
29
+
30
+ deviceStatus: str
31
+ connectionStatus: str
32
+ activeTime: int
33
+
34
+
35
+ @dataclass
36
+ class InternalDimmerDetailsResult(ResponseBaseModel):
37
+ """Dimmer Details Result Dict."""
38
+
39
+ devicename: str
40
+ brightness: int
41
+ indicatorlightStatus: str
42
+ rgbStatus: str
43
+ rgbValue: DimmerRGB
44
+ deviceStatus: str
45
+ connectionStatus: str
46
+ activeTime: int = 0
47
+ timer: Any | None = None
48
+ schedule: Any | None = None
49
+ deviceImg: str | None = None
50
+
51
+
52
+ @dataclass
53
+ class DimmerRGB:
54
+ """Dimmer RGB Color Dict."""
55
+
56
+ red: int
57
+ green: int
58
+ blue: int
59
+
60
+
61
+ @dataclass
62
+ class RequestSwitchBase(RequestBypassV1):
63
+ """Base Dimmer Request Dict.
64
+
65
+ Inherits from RequestBypassV1 to include the common fields for all requests.
66
+ """
67
+
68
+
69
+ @dataclass
70
+ class RequestDimmerBrightness(RequestBypassV1):
71
+ """Dimmer Status Request Dict."""
72
+
73
+ brightness: str
74
+
75
+
76
+ @dataclass
77
+ class RequestDimmerDetails(RequestBypassV1):
78
+ """Dimmer Details Request Dict."""
79
+
80
+
81
+ @dataclass
82
+ class RequestSwitchStatus(RequestBypassV1):
83
+ """Dimmer Details Request Dict."""
84
+
85
+ status: str
86
+ switchNo: int
87
+
88
+
89
+ @dataclass
90
+ class RequestDimmerStatus(RequestBypassV1):
91
+ """Dimmer Status Request Dict."""
92
+
93
+ status: str
94
+ rgbValue: dict | None = None
95
+
96
+ class Config(BaseConfig): # type: ignore[override]
97
+ """Dimmer Indicator Control Config Dict."""
98
+
99
+ omit_none = True
100
+ omit_default = True
101
+ orjson_options = orjson.OPT_NON_STR_KEYS
@@ -0,0 +1,134 @@
1
+ """Data models for VeSync thermostats."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+
7
+ from mashumaro import field_options
8
+ from mashumaro.mixins.orjson import DataClassORJSONMixin
9
+
10
+ from pyvesync.const import ThermostatConst
11
+ from pyvesync.models.bypass_models import BypassV2InnerResult
12
+
13
+
14
+ @dataclass
15
+ class ResultThermostatDetails(BypassV2InnerResult):
16
+ """Result model for thermostat details."""
17
+
18
+ supportMode: list[int]
19
+ workMode: int
20
+ workStatus: int
21
+ fanMode: int
22
+ fanStatus: int
23
+ tempUnit: str
24
+ temperature: float
25
+ humidity: int
26
+ heatToTemp: int
27
+ coolToTemp: int
28
+ lockStatus: bool
29
+ scheduleOrHold: int
30
+ holdEndTime: int
31
+ holdOption: int
32
+ deadband: int
33
+ ecoType: int
34
+ alertStatus: int
35
+ routines: list[ThermostatSimpleRoutine]
36
+ routineRunningId: int | None = None
37
+
38
+
39
+ @dataclass
40
+ class ThermostatSimpleRoutine(DataClassORJSONMixin):
41
+ """Thermostat routine model."""
42
+
43
+ name: str
44
+ routineId: int
45
+
46
+
47
+ @dataclass
48
+ class ThermostatRoutine(DataClassORJSONMixin):
49
+ """Model for full thermostat routine."""
50
+
51
+ name: str
52
+ routineId: int
53
+ type: int
54
+ heatToTemp: int
55
+ coolToTemp: int
56
+ heatFanMode: int
57
+ coolFanMode: int
58
+ usuallyMask: int
59
+ sensorIds: list[str]
60
+
61
+
62
+ @dataclass
63
+ class ThermostatMinorDetails(DataClassORJSONMixin):
64
+ """Model for thermostat minor details."""
65
+
66
+ mcu_version: str = field(metadata=field_options(alias='mcuVersion'))
67
+ hvac_capacity: int = field(metadata=field_options(alias='hvacCapcity'))
68
+ timestamp: int = field(metadata=field_options(alias='timeStamp'))
69
+ time_zone: int = field(metadata=field_options(alias='timeZone'))
70
+ offset_in_sec: int = field(metadata=field_options(alias='offsetInSec'))
71
+ time_fmt: int = field(metadata=field_options(alias='timeFmt'))
72
+ date_fmt: int = field(metadata=field_options(alias='dateFmt'))
73
+ fan_delay_time: int = field(metadata=field_options(alias='fanDelayTime'))
74
+ fan_circulation_time: int = field(metadata=field_options(alias='fanCirTime'))
75
+ hvac_protect_time: int = field(metadata=field_options(alias='hvacProtecTime'))
76
+ hvac_min_on_time: int = field(metadata=field_options(alias='hvacMinOnTime'))
77
+ aux_min_on_time: int = field(metadata=field_options(alias='auxMinOnTime'))
78
+ screen_brightness: int = field(metadata=field_options(alias='screenBrightness'))
79
+ standby_timeout: int = field(metadata=field_options(alias='standbyTimeOut'))
80
+ aux_low_temperature: int = field(metadata=field_options(alias='auxLowBalanceTemp'))
81
+ aux_high_temperature: int = field(metadata=field_options(alias='auxHighBalanceTemp'))
82
+ keytone: bool = field(metadata=field_options(alias='keyTone'))
83
+ smart_schedule_enabled: bool = field(
84
+ metadata=field_options(alias='smartScheduleEnabled')
85
+ )
86
+ time_to_temp_enabled: bool = field(metadata=field_options(alias='timeToTempEnabled'))
87
+ early_on_enabled: bool = field(metadata=field_options(alias='earlyOnEnabled'))
88
+ reminder_list: list[ThermostatReminder] = field(
89
+ metadata=field_options(alias='reminderList')
90
+ )
91
+ alarm_list: list[ThermostatAlarm] = field(metadata=field_options(alias='alarmList'))
92
+
93
+
94
+ @dataclass
95
+ class ThermostatReminder(DataClassORJSONMixin):
96
+ """Model for thermostat reminder."""
97
+
98
+ code: int
99
+ enabled: bool
100
+ frequency: int
101
+ code_name: str | None = None
102
+ last_maintenance_time: int | None = field(
103
+ default=None, metadata=field_options(alias='lastMaintenTime')
104
+ )
105
+
106
+ @classmethod
107
+ def __post_deserialize__( # type: ignore[override]
108
+ cls, obj: ThermostatReminder
109
+ ) -> ThermostatReminder:
110
+ """Post-deserialization processing."""
111
+ if isinstance(obj.code, int):
112
+ obj.code_name = ThermostatConst.ReminderCode(obj.code).name
113
+ return obj
114
+
115
+
116
+ @dataclass
117
+ class ThermostatAlarm(DataClassORJSONMixin):
118
+ """Model for thermostat alarm."""
119
+
120
+ code: int
121
+ enabled: bool
122
+ code_name: str | None = None
123
+ aux_runtime_limit: int | None = field(
124
+ default=None, metadata=field_options(alias='auxRunTimeLimit')
125
+ )
126
+
127
+ @classmethod
128
+ def __post_deserialize__( # type: ignore[override]
129
+ cls, obj: ThermostatAlarm
130
+ ) -> ThermostatAlarm:
131
+ """Post-deserialization processing."""
132
+ if obj.code is not None:
133
+ obj.code_name = ThermostatConst.AlarmCode(obj.code).name
134
+ return obj