PyPlumIO 0.5.42__py3-none-any.whl → 0.5.43__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.
- pyplumio/__init__.py +3 -2
- pyplumio/_version.py +2 -2
- pyplumio/connection.py +14 -14
- pyplumio/const.py +7 -0
- pyplumio/devices/__init__.py +32 -19
- pyplumio/devices/ecomax.py +112 -128
- pyplumio/devices/ecoster.py +5 -0
- pyplumio/devices/mixer.py +21 -31
- pyplumio/devices/thermostat.py +19 -29
- pyplumio/filters.py +166 -147
- pyplumio/frames/__init__.py +20 -8
- pyplumio/frames/messages.py +3 -0
- pyplumio/frames/requests.py +21 -0
- pyplumio/frames/responses.py +18 -0
- pyplumio/helpers/data_types.py +23 -21
- pyplumio/helpers/event_manager.py +40 -3
- pyplumio/helpers/factory.py +5 -2
- pyplumio/helpers/schedule.py +8 -5
- pyplumio/helpers/task_manager.py +3 -0
- pyplumio/helpers/timeout.py +8 -8
- pyplumio/helpers/uid.py +8 -5
- pyplumio/{helpers/parameter.py → parameters/__init__.py} +98 -4
- pyplumio/parameters/ecomax.py +868 -0
- pyplumio/parameters/mixer.py +245 -0
- pyplumio/parameters/thermostat.py +197 -0
- pyplumio/protocol.py +6 -3
- pyplumio/stream.py +3 -0
- pyplumio/structures/__init__.py +3 -0
- pyplumio/structures/alerts.py +8 -5
- pyplumio/structures/boiler_load.py +3 -0
- pyplumio/structures/boiler_power.py +3 -0
- pyplumio/structures/ecomax_parameters.py +6 -800
- pyplumio/structures/fan_power.py +3 -0
- pyplumio/structures/frame_versions.py +3 -0
- pyplumio/structures/fuel_consumption.py +3 -0
- pyplumio/structures/fuel_level.py +3 -0
- pyplumio/structures/lambda_sensor.py +8 -0
- pyplumio/structures/mixer_parameters.py +8 -230
- pyplumio/structures/mixer_sensors.py +9 -0
- pyplumio/structures/modules.py +14 -0
- pyplumio/structures/network_info.py +11 -0
- pyplumio/structures/output_flags.py +9 -0
- pyplumio/structures/outputs.py +21 -0
- pyplumio/structures/pending_alerts.py +3 -0
- pyplumio/structures/product_info.py +5 -2
- pyplumio/structures/program_version.py +3 -0
- pyplumio/structures/regulator_data.py +4 -1
- pyplumio/structures/regulator_data_schema.py +3 -0
- pyplumio/structures/schedules.py +18 -1
- pyplumio/structures/statuses.py +9 -0
- pyplumio/structures/temperatures.py +22 -0
- pyplumio/structures/thermostat_parameters.py +13 -177
- pyplumio/structures/thermostat_sensors.py +9 -0
- pyplumio/utils.py +14 -12
- {pyplumio-0.5.42.dist-info → pyplumio-0.5.43.dist-info}/METADATA +30 -17
- pyplumio-0.5.43.dist-info/RECORD +63 -0
- {pyplumio-0.5.42.dist-info → pyplumio-0.5.43.dist-info}/WHEEL +1 -1
- pyplumio-0.5.42.dist-info/RECORD +0 -60
- {pyplumio-0.5.42.dist-info → pyplumio-0.5.43.dist-info}/licenses/LICENSE +0 -0
- {pyplumio-0.5.42.dist-info → pyplumio-0.5.43.dist-info}/top_level.txt +0 -0
pyplumio/structures/fan_power.py
CHANGED
@@ -3,245 +3,17 @@
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
5
|
from collections.abc import Generator
|
6
|
-
from
|
7
|
-
from typing import TYPE_CHECKING, Any, Final
|
6
|
+
from typing import Any, Final
|
8
7
|
|
9
|
-
from
|
10
|
-
|
11
|
-
from pyplumio.const import (
|
12
|
-
ATTR_DEVICE_INDEX,
|
13
|
-
ATTR_INDEX,
|
14
|
-
ATTR_VALUE,
|
15
|
-
FrameType,
|
16
|
-
ProductType,
|
17
|
-
UnitOfMeasurement,
|
18
|
-
)
|
19
|
-
from pyplumio.frames import Request
|
20
|
-
from pyplumio.helpers.parameter import (
|
21
|
-
Number,
|
22
|
-
NumberDescription,
|
23
|
-
NumericType,
|
24
|
-
Parameter,
|
25
|
-
ParameterDescription,
|
26
|
-
ParameterValues,
|
27
|
-
Switch,
|
28
|
-
SwitchDescription,
|
29
|
-
unpack_parameter,
|
30
|
-
)
|
8
|
+
from pyplumio.parameters import ParameterValues, unpack_parameter
|
31
9
|
from pyplumio.structures import StructureDecoder
|
32
10
|
from pyplumio.utils import ensure_dict
|
33
11
|
|
34
|
-
if TYPE_CHECKING:
|
35
|
-
from pyplumio.devices.mixer import Mixer
|
36
|
-
|
37
12
|
ATTR_MIXER_PARAMETERS: Final = "mixer_parameters"
|
38
13
|
|
39
14
|
MIXER_PARAMETER_SIZE: Final = 3
|
40
15
|
|
41
16
|
|
42
|
-
@dataclass
|
43
|
-
class MixerParameterDescription(ParameterDescription):
|
44
|
-
"""Represents a mixer parameter description."""
|
45
|
-
|
46
|
-
__slots__ = ()
|
47
|
-
|
48
|
-
|
49
|
-
class MixerParameter(Parameter):
|
50
|
-
"""Represent a mixer parameter."""
|
51
|
-
|
52
|
-
__slots__ = ()
|
53
|
-
|
54
|
-
device: Mixer
|
55
|
-
description: MixerParameterDescription
|
56
|
-
|
57
|
-
async def create_request(self) -> Request:
|
58
|
-
"""Create a request to change the parameter."""
|
59
|
-
return await Request.create(
|
60
|
-
FrameType.REQUEST_SET_MIXER_PARAMETER,
|
61
|
-
recipient=self.device.parent.address,
|
62
|
-
data={
|
63
|
-
ATTR_INDEX: self._index,
|
64
|
-
ATTR_VALUE: self.values.value,
|
65
|
-
ATTR_DEVICE_INDEX: self.device.index,
|
66
|
-
},
|
67
|
-
)
|
68
|
-
|
69
|
-
|
70
|
-
@dataslots
|
71
|
-
@dataclass
|
72
|
-
class MixerNumberDescription(MixerParameterDescription, NumberDescription):
|
73
|
-
"""Represent a mixer number description."""
|
74
|
-
|
75
|
-
offset: int = 0
|
76
|
-
|
77
|
-
|
78
|
-
class MixerNumber(MixerParameter, Number):
|
79
|
-
"""Represents a mixer number."""
|
80
|
-
|
81
|
-
__slots__ = ()
|
82
|
-
|
83
|
-
description: MixerNumberDescription
|
84
|
-
|
85
|
-
def _pack_value(self, value: NumericType) -> int:
|
86
|
-
"""Pack the parameter value."""
|
87
|
-
return super()._pack_value(value + self.description.offset)
|
88
|
-
|
89
|
-
def _unpack_value(self, value: int) -> NumericType:
|
90
|
-
"""Unpack the parameter value."""
|
91
|
-
return super()._unpack_value(value - self.description.offset)
|
92
|
-
|
93
|
-
|
94
|
-
@dataslots
|
95
|
-
@dataclass
|
96
|
-
class MixerSwitchDescription(MixerParameterDescription, SwitchDescription):
|
97
|
-
"""Represents a mixer switch description."""
|
98
|
-
|
99
|
-
|
100
|
-
class MixerSwitch(MixerParameter, Switch):
|
101
|
-
"""Represents a mixer switch."""
|
102
|
-
|
103
|
-
__slots__ = ()
|
104
|
-
|
105
|
-
description: MixerSwitchDescription
|
106
|
-
|
107
|
-
|
108
|
-
MIXER_PARAMETERS: dict[ProductType, tuple[MixerParameterDescription, ...]] = {
|
109
|
-
ProductType.ECOMAX_P: (
|
110
|
-
MixerNumberDescription(
|
111
|
-
name="mixer_target_temp",
|
112
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
113
|
-
),
|
114
|
-
MixerNumberDescription(
|
115
|
-
name="min_target_temp",
|
116
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
117
|
-
),
|
118
|
-
MixerNumberDescription(
|
119
|
-
name="max_target_temp",
|
120
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
121
|
-
),
|
122
|
-
MixerNumberDescription(
|
123
|
-
name="thermostat_decrease_target_temp",
|
124
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
125
|
-
),
|
126
|
-
MixerSwitchDescription(
|
127
|
-
name="weather_control",
|
128
|
-
),
|
129
|
-
MixerNumberDescription(
|
130
|
-
name="heating_curve",
|
131
|
-
step=0.1,
|
132
|
-
),
|
133
|
-
MixerNumberDescription(
|
134
|
-
name="heating_curve_shift",
|
135
|
-
offset=20,
|
136
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
137
|
-
),
|
138
|
-
MixerNumberDescription(
|
139
|
-
name="weather_factor",
|
140
|
-
),
|
141
|
-
MixerNumberDescription(
|
142
|
-
name="work_mode",
|
143
|
-
),
|
144
|
-
MixerNumberDescription(
|
145
|
-
name="mixer_input_dead_zone",
|
146
|
-
step=0.1,
|
147
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
148
|
-
),
|
149
|
-
MixerSwitchDescription(
|
150
|
-
name="thermostat_operation",
|
151
|
-
),
|
152
|
-
MixerNumberDescription(
|
153
|
-
name="thermostat_mode",
|
154
|
-
),
|
155
|
-
MixerSwitchDescription(
|
156
|
-
name="disable_pump_on_thermostat",
|
157
|
-
),
|
158
|
-
MixerSwitchDescription(
|
159
|
-
name="summer_work",
|
160
|
-
),
|
161
|
-
),
|
162
|
-
ProductType.ECOMAX_I: (
|
163
|
-
MixerNumberDescription(
|
164
|
-
name="work_mode",
|
165
|
-
),
|
166
|
-
MixerNumberDescription(
|
167
|
-
name="circuit_target_temp",
|
168
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
169
|
-
),
|
170
|
-
MixerNumberDescription(
|
171
|
-
name="day_target_temp",
|
172
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
173
|
-
),
|
174
|
-
MixerNumberDescription(
|
175
|
-
name="night_target_temp",
|
176
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
177
|
-
),
|
178
|
-
MixerNumberDescription(
|
179
|
-
name="min_target_temp",
|
180
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
181
|
-
),
|
182
|
-
MixerNumberDescription(
|
183
|
-
name="max_target_temp",
|
184
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
185
|
-
),
|
186
|
-
MixerSwitchDescription(
|
187
|
-
name="summer_work",
|
188
|
-
),
|
189
|
-
MixerSwitchDescription(
|
190
|
-
name="weather_control",
|
191
|
-
),
|
192
|
-
MixerNumberDescription(
|
193
|
-
name="enable_circuit",
|
194
|
-
),
|
195
|
-
MixerNumberDescription(
|
196
|
-
name="constant_water_preset_temp",
|
197
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
198
|
-
),
|
199
|
-
MixerNumberDescription(
|
200
|
-
name="thermostat_decrease_temp",
|
201
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
202
|
-
),
|
203
|
-
MixerNumberDescription(
|
204
|
-
name="thermostat_correction",
|
205
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
206
|
-
),
|
207
|
-
MixerSwitchDescription(
|
208
|
-
name="thermostat_pump_lock",
|
209
|
-
),
|
210
|
-
MixerNumberDescription(
|
211
|
-
name="valve_opening_time",
|
212
|
-
unit_of_measurement=UnitOfMeasurement.SECONDS,
|
213
|
-
),
|
214
|
-
MixerNumberDescription(
|
215
|
-
name="mixer_input_dead_zone",
|
216
|
-
step=0.1,
|
217
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
218
|
-
),
|
219
|
-
MixerNumberDescription(
|
220
|
-
name="proportional_range",
|
221
|
-
),
|
222
|
-
MixerNumberDescription(
|
223
|
-
name="integration_time_constant",
|
224
|
-
),
|
225
|
-
MixerNumberDescription(
|
226
|
-
name="heating_curve",
|
227
|
-
step=0.1,
|
228
|
-
),
|
229
|
-
MixerNumberDescription(
|
230
|
-
name="heating_curve_shift",
|
231
|
-
offset=20,
|
232
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
233
|
-
),
|
234
|
-
MixerNumberDescription(
|
235
|
-
name="thermostat_mode",
|
236
|
-
),
|
237
|
-
MixerNumberDescription(
|
238
|
-
name="decreasing_constant_water_temp",
|
239
|
-
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
240
|
-
),
|
241
|
-
),
|
242
|
-
}
|
243
|
-
|
244
|
-
|
245
17
|
class MixerParametersStructure(StructureDecoder):
|
246
18
|
"""Represents a mixer parameters data structure."""
|
247
19
|
|
@@ -286,3 +58,9 @@ class MixerParametersStructure(StructureDecoder):
|
|
286
58
|
),
|
287
59
|
self._offset,
|
288
60
|
)
|
61
|
+
|
62
|
+
|
63
|
+
__all__ = [
|
64
|
+
"ATTR_MIXER_PARAMETERS",
|
65
|
+
"MixerParametersStructure",
|
66
|
+
]
|
pyplumio/structures/modules.py
CHANGED
@@ -89,3 +89,17 @@ class ModulesStructure(StructureDecoder):
|
|
89
89
|
),
|
90
90
|
self._offset,
|
91
91
|
)
|
92
|
+
|
93
|
+
|
94
|
+
__all__ = [
|
95
|
+
"ATTR_MODULES",
|
96
|
+
"ATTR_MODULE_A",
|
97
|
+
"ATTR_MODULE_B",
|
98
|
+
"ATTR_MODULE_C",
|
99
|
+
"ATTR_ECOLAMBDA",
|
100
|
+
"ATTR_ECOSTER",
|
101
|
+
"ATTR_PANEL",
|
102
|
+
"MODULES",
|
103
|
+
"ConnectedModules",
|
104
|
+
"ModulesStructure",
|
105
|
+
]
|
@@ -114,3 +114,14 @@ class NetworkInfoStructure(Structure):
|
|
114
114
|
),
|
115
115
|
offset + NETWORK_INFO_SIZE,
|
116
116
|
)
|
117
|
+
|
118
|
+
|
119
|
+
__all__ = [
|
120
|
+
"EthernetParameters",
|
121
|
+
"WirelessParameters",
|
122
|
+
"NetworkInfo",
|
123
|
+
"NetworkInfoStructure",
|
124
|
+
"ATTR_NETWORK",
|
125
|
+
"DEFAULT_IP",
|
126
|
+
"DEFAULT_NETMASK",
|
127
|
+
]
|
@@ -36,3 +36,12 @@ class OutputFlagsStructure(StructureDecoder):
|
|
36
36
|
),
|
37
37
|
offset + output_flags.size,
|
38
38
|
)
|
39
|
+
|
40
|
+
|
41
|
+
__all__ = [
|
42
|
+
"ATTR_HEATING_PUMP_FLAG",
|
43
|
+
"ATTR_WATER_HEATER_PUMP_FLAG",
|
44
|
+
"ATTR_CIRCULATION_PUMP_FLAG",
|
45
|
+
"ATTR_SOLAR_PUMP_FLAG",
|
46
|
+
"OutputFlagsStructure",
|
47
|
+
]
|
pyplumio/structures/outputs.py
CHANGED
@@ -65,3 +65,24 @@ class OutputsStructure(StructureDecoder):
|
|
65
65
|
),
|
66
66
|
offset + outputs.size,
|
67
67
|
)
|
68
|
+
|
69
|
+
|
70
|
+
__all__ = [
|
71
|
+
"ATTR_FAN",
|
72
|
+
"ATTR_FEEDER",
|
73
|
+
"ATTR_HEATING_PUMP",
|
74
|
+
"ATTR_WATER_HEATER_PUMP",
|
75
|
+
"ATTR_CIRCULATION_PUMP",
|
76
|
+
"ATTR_LIGHTER",
|
77
|
+
"ATTR_ALARM",
|
78
|
+
"ATTR_OUTER_BOILER",
|
79
|
+
"ATTR_FAN2_EXHAUST",
|
80
|
+
"ATTR_FEEDER2",
|
81
|
+
"ATTR_OUTER_FEEDER",
|
82
|
+
"ATTR_SOLAR_PUMP",
|
83
|
+
"ATTR_FIREPLACE_PUMP",
|
84
|
+
"ATTR_GCZ_CONTACT",
|
85
|
+
"ATTR_BLOW_FAN1",
|
86
|
+
"ATTR_BLOW_FAN2",
|
87
|
+
"OutputsStructure",
|
88
|
+
]
|
@@ -20,7 +20,7 @@ ATTR_PRODUCT: Final = "product"
|
|
20
20
|
@cache
|
21
21
|
def format_model_name(model_name: str) -> str:
|
22
22
|
"""Format a device model name."""
|
23
|
-
if m := re.match(r"^([A-Z]+)\s
|
23
|
+
if m := re.match(r"^([A-Z]+)\s*(\d{3,})(.+)$", model_name, re.IGNORECASE):
|
24
24
|
model_device, model_number, model_suffix = m.groups()
|
25
25
|
model_device = "ecoMAX" if model_device == "EM" else model_device
|
26
26
|
return f"{model_device} {model_number}{model_suffix}"
|
@@ -28,7 +28,7 @@ def format_model_name(model_name: str) -> str:
|
|
28
28
|
return model_name
|
29
29
|
|
30
30
|
|
31
|
-
@dataclass
|
31
|
+
@dataclass(frozen=True)
|
32
32
|
class ProductInfo:
|
33
33
|
"""Represents a product info provided by an UID response."""
|
34
34
|
|
@@ -78,3 +78,6 @@ class ProductInfoStructure(StructureDecoder):
|
|
78
78
|
),
|
79
79
|
offset,
|
80
80
|
)
|
81
|
+
|
82
|
+
|
83
|
+
__all__ = ["ATTR_PRODUCT", "ProductInfo", "ProductInfoStructure"]
|
@@ -45,7 +45,7 @@ class RegulatorDataStructure(StructureDecoder):
|
|
45
45
|
"""Decode bytes and return message data and offset."""
|
46
46
|
data = ensure_dict(data)
|
47
47
|
offset += 2
|
48
|
-
regdata_version = f"{message[offset+1]}.{message[offset]}"
|
48
|
+
regdata_version = f"{message[offset + 1]}.{message[offset]}"
|
49
49
|
if regdata_version != REGDATA_VERSION:
|
50
50
|
return data, offset
|
51
51
|
|
@@ -63,3 +63,6 @@ class RegulatorDataStructure(StructureDecoder):
|
|
63
63
|
}
|
64
64
|
|
65
65
|
return data, self._offset
|
66
|
+
|
67
|
+
|
68
|
+
__all__ = ["ATTR_REGDATA", "REGDATA_VERSION", "RegulatorDataStructure"]
|
pyplumio/structures/schedules.py
CHANGED
@@ -19,7 +19,7 @@ from pyplumio.const import (
|
|
19
19
|
from pyplumio.devices import Device, PhysicalDevice
|
20
20
|
from pyplumio.exceptions import FrameDataError
|
21
21
|
from pyplumio.frames import Request
|
22
|
-
from pyplumio.
|
22
|
+
from pyplumio.parameters import (
|
23
23
|
Number,
|
24
24
|
NumberDescription,
|
25
25
|
Parameter,
|
@@ -238,3 +238,20 @@ class SchedulesStructure(Structure):
|
|
238
238
|
),
|
239
239
|
self._offset,
|
240
240
|
)
|
241
|
+
|
242
|
+
|
243
|
+
__all__ = [
|
244
|
+
"ATTR_SCHEDULES",
|
245
|
+
"ATTR_SCHEDULE_PARAMETERS",
|
246
|
+
"ATTR_SCHEDULE_SWITCH",
|
247
|
+
"ATTR_SCHEDULE_PARAMETER",
|
248
|
+
"ScheduleParameterDescription",
|
249
|
+
"ScheduleParameter",
|
250
|
+
"ScheduleNumberDescription",
|
251
|
+
"ScheduleNumber",
|
252
|
+
"ScheduleSwitchDescription",
|
253
|
+
"ScheduleSwitch",
|
254
|
+
"SCHEDULE_PARAMETERS",
|
255
|
+
"collect_schedule_data",
|
256
|
+
"SchedulesStructure",
|
257
|
+
]
|
pyplumio/structures/statuses.py
CHANGED
@@ -70,3 +70,25 @@ class TemperaturesStructure(StructureDecoder):
|
|
70
70
|
data[TEMPERATURES[index]] = temp.value
|
71
71
|
|
72
72
|
return data, offset
|
73
|
+
|
74
|
+
|
75
|
+
__all__ = [
|
76
|
+
"ATTR_HEATING_TEMP",
|
77
|
+
"ATTR_FEEDER_TEMP",
|
78
|
+
"ATTR_WATER_HEATER_TEMP",
|
79
|
+
"ATTR_OUTSIDE_TEMP",
|
80
|
+
"ATTR_RETURN_TEMP",
|
81
|
+
"ATTR_EXHAUST_TEMP",
|
82
|
+
"ATTR_OPTICAL_TEMP",
|
83
|
+
"ATTR_UPPER_BUFFER_TEMP",
|
84
|
+
"ATTR_LOWER_BUFFER_TEMP",
|
85
|
+
"ATTR_UPPER_SOLAR_TEMP",
|
86
|
+
"ATTR_LOWER_SOLAR_TEMP",
|
87
|
+
"ATTR_FIREPLACE_TEMP",
|
88
|
+
"ATTR_TOTAL_GAIN",
|
89
|
+
"ATTR_HYDRAULIC_COUPLER_TEMP",
|
90
|
+
"ATTR_EXCHANGER_TEMP",
|
91
|
+
"ATTR_AIR_IN_TEMP",
|
92
|
+
"ATTR_AIR_OUT_TEMP",
|
93
|
+
"TemperaturesStructure",
|
94
|
+
]
|