PyPlumIO 0.5.2__tar.gz → 0.5.3__tar.gz
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-0.5.2 → PyPlumIO-0.5.3}/PKG-INFO +1 -1
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/PyPlumIO.egg-info/PKG-INFO +1 -1
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/PyPlumIO.egg-info/SOURCES.txt +2 -2
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/_version.py +2 -2
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/devices/ecomax.py +8 -26
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/devices/mixer.py +1 -8
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/devices/thermostat.py +1 -3
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/frames/messages.py +4 -4
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/helpers/parameter.py +22 -25
- PyPlumIO-0.5.2/pyplumio/structures/load.py → PyPlumIO-0.5.3/pyplumio/structures/boiler_load.py +5 -5
- PyPlumIO-0.5.2/pyplumio/structures/power.py → PyPlumIO-0.5.3/pyplumio/structures/boiler_power.py +6 -6
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/ecomax_parameters.py +13 -7
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/mixer_parameters.py +11 -5
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/thermostat_parameters.py +4 -4
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/helpers/test_parameter.py +5 -16
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/test_devices.py +1 -4
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/messages/sensor_data.json +2 -2
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.gitattributes +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.github/CODE_OF_CONDUCT.md +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.github/workflows/ci.yml +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.github/workflows/codeql-analysis.yml +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.github/workflows/deploy.yml +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.github/workflows/documentation.yml +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.gitignore +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.pre-commit-config.yaml +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/.vscode/settings.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/LICENSE +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/MANIFEST.in +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/PyPlumIO.egg-info/dependency_links.txt +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/PyPlumIO.egg-info/requires.txt +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/PyPlumIO.egg-info/top_level.txt +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/README.md +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/disagnostics.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/docs/Makefile +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/docs/make.bat +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/docs/source/conf.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/docs/source/index.rst +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/docs/source/protocol.rst +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/docs/source/usage.rst +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/images/ecomax.png +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/images/rs485.png +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/__init__.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/__main__.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/connection.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/const.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/devices/__init__.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/devices/ecoster.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/exceptions.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/filters.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/frames/__init__.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/frames/requests.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/frames/responses.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/helpers/__init__.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/helpers/data_types.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/helpers/event_manager.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/helpers/factory.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/helpers/schedule.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/helpers/task_manager.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/helpers/timeout.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/helpers/typing.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/helpers/uid.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/protocol.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/stream.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/__init__.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/alerts.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/data_schema.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/fan_power.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/frame_versions.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/fuel_consumption.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/fuel_level.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/lambda_sensor.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/mixer_sensors.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/modules.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/network_info.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/output_flags.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/outputs.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/pending_alerts.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/product_info.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/program_version.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/regulator_data.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/schedules.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/statuses.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/temperatures.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/structures/thermostat_sensors.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyplumio/utils.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/pyproject.toml +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/requirements.txt +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/requirements_test.txt +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/setup.cfg +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/__init__.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/conftest.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/frames/test_init.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/frames/test_messages.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/frames/test_requests.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/frames/test_responses.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/helpers/__init__.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/helpers/test_data_types.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/helpers/test_event_manager.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/helpers/test_factory.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/helpers/test_schedule.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/helpers/test_task_manager.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/helpers/test_timeout.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/helpers/test_uid.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/test_connection.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/test_filters.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/test_init.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/test_main.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/test_protocol.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/test_stream.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/test_utils.py +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/messages/regulator_data.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/requests/alerts.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/requests/ecomax_control.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/requests/ecomax_parameters.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/requests/mixer_parameters.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/requests/set_ecomax_parameter.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/requests/set_mixer_parameter.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/requests/set_schedule.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/requests/set_thermostat_parameter.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/requests/thermostat_parameters.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/responses/alerts.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/responses/data_schema.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/responses/device_available.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/responses/ecomax_parameters.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/responses/mixer_parameters.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/responses/password.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/responses/program_version.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/responses/schedules.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/responses/thermostat_parameters.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/responses/uid.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/unknown/unknown_ecomax_parameter.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tests/testdata/unknown/unknown_mixer_parameter.json +0 -0
- {PyPlumIO-0.5.2 → PyPlumIO-0.5.3}/tox.ini +0 -0
@@ -61,6 +61,8 @@ pyplumio/helpers/typing.py
|
|
61
61
|
pyplumio/helpers/uid.py
|
62
62
|
pyplumio/structures/__init__.py
|
63
63
|
pyplumio/structures/alerts.py
|
64
|
+
pyplumio/structures/boiler_load.py
|
65
|
+
pyplumio/structures/boiler_power.py
|
64
66
|
pyplumio/structures/data_schema.py
|
65
67
|
pyplumio/structures/ecomax_parameters.py
|
66
68
|
pyplumio/structures/fan_power.py
|
@@ -68,7 +70,6 @@ pyplumio/structures/frame_versions.py
|
|
68
70
|
pyplumio/structures/fuel_consumption.py
|
69
71
|
pyplumio/structures/fuel_level.py
|
70
72
|
pyplumio/structures/lambda_sensor.py
|
71
|
-
pyplumio/structures/load.py
|
72
73
|
pyplumio/structures/mixer_parameters.py
|
73
74
|
pyplumio/structures/mixer_sensors.py
|
74
75
|
pyplumio/structures/modules.py
|
@@ -76,7 +77,6 @@ pyplumio/structures/network_info.py
|
|
76
77
|
pyplumio/structures/output_flags.py
|
77
78
|
pyplumio/structures/outputs.py
|
78
79
|
pyplumio/structures/pending_alerts.py
|
79
|
-
pyplumio/structures/power.py
|
80
80
|
pyplumio/structures/product_info.py
|
81
81
|
pyplumio/structures/program_version.py
|
82
82
|
pyplumio/structures/regulator_data.py
|
@@ -12,8 +12,6 @@ from pyplumio.const import (
|
|
12
12
|
ATTR_PASSWORD,
|
13
13
|
ATTR_SENSORS,
|
14
14
|
ATTR_STATE,
|
15
|
-
STATE_OFF,
|
16
|
-
STATE_ON,
|
17
15
|
DeviceState,
|
18
16
|
DeviceType,
|
19
17
|
FrameType,
|
@@ -212,14 +210,7 @@ class EcoMAX(Addressable):
|
|
212
210
|
)
|
213
211
|
await self.dispatch(
|
214
212
|
description.name,
|
215
|
-
cls(
|
216
|
-
device=self,
|
217
|
-
description=description,
|
218
|
-
index=index,
|
219
|
-
value=values.value,
|
220
|
-
min_value=values.min_value,
|
221
|
-
max_value=values.max_value,
|
222
|
-
),
|
213
|
+
cls(device=self, description=description, index=index, values=values),
|
223
214
|
)
|
224
215
|
|
225
216
|
return True
|
@@ -322,14 +313,7 @@ class EcoMAX(Addressable):
|
|
322
313
|
)
|
323
314
|
await self.dispatch(
|
324
315
|
description.name,
|
325
|
-
cls(
|
326
|
-
device=self,
|
327
|
-
description=description,
|
328
|
-
index=index,
|
329
|
-
value=values.value,
|
330
|
-
min_value=values.min_value,
|
331
|
-
max_value=values.max_value,
|
332
|
-
),
|
316
|
+
cls(device=self, description=description, index=index, values=values),
|
333
317
|
)
|
334
318
|
|
335
319
|
return True
|
@@ -354,9 +338,11 @@ class EcoMAX(Addressable):
|
|
354
338
|
EcomaxBinaryParameter(
|
355
339
|
device=self,
|
356
340
|
description=ECOMAX_CONTROL_PARAMETER,
|
357
|
-
|
358
|
-
|
359
|
-
|
341
|
+
values=ParameterValues(
|
342
|
+
value=int(mode != DeviceState.OFF),
|
343
|
+
min_value=0,
|
344
|
+
max_value=1,
|
345
|
+
),
|
360
346
|
),
|
361
347
|
)
|
362
348
|
|
@@ -386,11 +372,7 @@ class EcoMAX(Addressable):
|
|
386
372
|
"""Add thermostat profile parameter to the dataset."""
|
387
373
|
if values is not None:
|
388
374
|
return EcomaxParameter(
|
389
|
-
device=self,
|
390
|
-
description=THERMOSTAT_PROFILE_PARAMETER,
|
391
|
-
value=values.value,
|
392
|
-
min_value=values.min_value,
|
393
|
-
max_value=values.max_value,
|
375
|
+
device=self, description=THERMOSTAT_PROFILE_PARAMETER, values=values
|
394
376
|
)
|
395
377
|
|
396
378
|
return None
|
@@ -73,14 +73,7 @@ class Mixer(SubDevice):
|
|
73
73
|
)
|
74
74
|
await self.dispatch(
|
75
75
|
description.name,
|
76
|
-
cls(
|
77
|
-
device=self,
|
78
|
-
description=description,
|
79
|
-
index=index,
|
80
|
-
value=values.value,
|
81
|
-
min_value=values.min_value,
|
82
|
-
max_value=values.max_value,
|
83
|
-
),
|
76
|
+
cls(device=self, description=description, index=index, values=values),
|
84
77
|
)
|
85
78
|
|
86
79
|
return True
|
@@ -13,18 +13,18 @@ from pyplumio.const import (
|
|
13
13
|
)
|
14
14
|
from pyplumio.frames import Message
|
15
15
|
from pyplumio.helpers.typing import EventDataType
|
16
|
+
from pyplumio.structures.boiler_load import BoilerLoadStructure
|
17
|
+
from pyplumio.structures.boiler_power import BoilerPowerStructure
|
16
18
|
from pyplumio.structures.fan_power import FanPowerStructure
|
17
19
|
from pyplumio.structures.frame_versions import FrameVersionsStructure
|
18
20
|
from pyplumio.structures.fuel_consumption import FuelConsumptionStructure
|
19
21
|
from pyplumio.structures.fuel_level import FuelLevelStructure
|
20
22
|
from pyplumio.structures.lambda_sensor import LambdaSensorStructure
|
21
|
-
from pyplumio.structures.load import LoadStructure
|
22
23
|
from pyplumio.structures.mixer_sensors import MixerSensorsStructure
|
23
24
|
from pyplumio.structures.modules import ModulesStructure
|
24
25
|
from pyplumio.structures.output_flags import OutputFlagsStructure
|
25
26
|
from pyplumio.structures.outputs import OutputsStructure
|
26
27
|
from pyplumio.structures.pending_alerts import PendingAlertsStructure
|
27
|
-
from pyplumio.structures.power import PowerStructure
|
28
28
|
from pyplumio.structures.regulator_data import RegulatorDataStructure
|
29
29
|
from pyplumio.structures.statuses import StatusesStructure
|
30
30
|
from pyplumio.structures.temperatures import TemperaturesStructure
|
@@ -64,8 +64,8 @@ class SensorDataMessage(Message):
|
|
64
64
|
sensors, offset = FuelLevelStructure(self).decode(message, offset, sensors)
|
65
65
|
sensors[ATTR_TRANSMISSION] = message[offset]
|
66
66
|
sensors, offset = FanPowerStructure(self).decode(message, offset + 1, sensors)
|
67
|
-
sensors, offset =
|
68
|
-
sensors, offset =
|
67
|
+
sensors, offset = BoilerLoadStructure(self).decode(message, offset, sensors)
|
68
|
+
sensors, offset = BoilerPowerStructure(self).decode(message, offset, sensors)
|
69
69
|
sensors, offset = FuelConsumptionStructure(self).decode(
|
70
70
|
message, offset, sensors
|
71
71
|
)
|
@@ -57,6 +57,8 @@ def _normalize_parameter_value(value: ParameterValueType) -> int:
|
|
57
57
|
class ParameterValues:
|
58
58
|
"""Represents a parameter values."""
|
59
59
|
|
60
|
+
__slots__ = "value", "min_value", "max_value"
|
61
|
+
|
60
62
|
value: int
|
61
63
|
min_value: int
|
62
64
|
max_value: int
|
@@ -80,18 +82,14 @@ class Parameter:
|
|
80
82
|
|
81
83
|
device: Device
|
82
84
|
description: ParameterDescription
|
83
|
-
|
84
|
-
_min_value: int
|
85
|
-
_max_value: int
|
85
|
+
_values: ParameterValues
|
86
86
|
_index: int
|
87
87
|
_pending_update: bool = False
|
88
88
|
|
89
89
|
def __init__(
|
90
90
|
self,
|
91
91
|
device: Device,
|
92
|
-
|
93
|
-
min_value: ParameterValueType,
|
94
|
-
max_value: ParameterValueType,
|
92
|
+
values: ParameterValues,
|
95
93
|
description: ParameterDescription,
|
96
94
|
index: int = 0,
|
97
95
|
):
|
@@ -99,9 +97,7 @@ class Parameter:
|
|
99
97
|
self.index = index
|
100
98
|
self.device = device
|
101
99
|
self.description = description
|
102
|
-
self.
|
103
|
-
self._min_value = _normalize_parameter_value(min_value)
|
104
|
-
self._max_value = _normalize_parameter_value(max_value)
|
100
|
+
self._values = values
|
105
101
|
self._pending_update = False
|
106
102
|
self._index = index
|
107
103
|
|
@@ -110,22 +106,18 @@ class Parameter:
|
|
110
106
|
return (
|
111
107
|
f"{self.__class__.__name__}("
|
112
108
|
f"device={self.device.__class__.__name__}, "
|
113
|
-
f"
|
114
|
-
f"
|
109
|
+
f"values={self._values}, "
|
110
|
+
f"description={self.description})"
|
115
111
|
)
|
116
112
|
|
117
|
-
def __getattr__(self, name: str):
|
118
|
-
"""Return attributes from the parameter description."""
|
119
|
-
return getattr(self.description, name)
|
120
|
-
|
121
113
|
def _call_relational_method(self, method_to_call, other):
|
122
114
|
"""Call a specified relational method."""
|
123
|
-
func = getattr(self.
|
115
|
+
func = getattr(self._values.value, method_to_call)
|
124
116
|
return func(_normalize_parameter_value(other))
|
125
117
|
|
126
118
|
def __int__(self) -> int:
|
127
119
|
"""Return an integer representation of parameter's value."""
|
128
|
-
return self.
|
120
|
+
return self._values.value
|
129
121
|
|
130
122
|
def __add__(self, other) -> int:
|
131
123
|
"""Return result of addition."""
|
@@ -167,7 +159,7 @@ class Parameter:
|
|
167
159
|
"""Compare if parameter value is less that other."""
|
168
160
|
return self._call_relational_method("__lt__", other)
|
169
161
|
|
170
|
-
async def _confirm_parameter_change(self,
|
162
|
+
async def _confirm_parameter_change(self, _: Parameter) -> None:
|
171
163
|
"""A callback for when parameter change is confirmed on
|
172
164
|
the device.
|
173
165
|
"""
|
@@ -175,15 +167,15 @@ class Parameter:
|
|
175
167
|
|
176
168
|
async def set(self, value: ParameterValueType, retries: int = SET_RETRIES) -> bool:
|
177
169
|
"""Set a parameter value."""
|
178
|
-
if (value := _normalize_parameter_value(value)) == self.
|
170
|
+
if (value := _normalize_parameter_value(value)) == self._values.value:
|
179
171
|
return True
|
180
172
|
|
181
|
-
if value < self.
|
173
|
+
if value < self._values.min_value or value > self._values.max_value:
|
182
174
|
raise ValueError(
|
183
175
|
f"Parameter value must be between '{self.min_value}' and '{self.max_value}'"
|
184
176
|
)
|
185
177
|
|
186
|
-
self.
|
178
|
+
self._values.value = value
|
187
179
|
self._pending_update = True
|
188
180
|
self.device.subscribe_once(
|
189
181
|
self.description.name, self._confirm_parameter_change
|
@@ -217,17 +209,22 @@ class Parameter:
|
|
217
209
|
@property
|
218
210
|
def value(self) -> ParameterValueType:
|
219
211
|
"""A parameter value."""
|
220
|
-
return self.
|
212
|
+
return self._values.value
|
221
213
|
|
222
214
|
@property
|
223
215
|
def min_value(self) -> ParameterValueType:
|
224
216
|
"""Minimum allowed value."""
|
225
|
-
return self.
|
217
|
+
return self._values.min_value
|
226
218
|
|
227
219
|
@property
|
228
220
|
def max_value(self) -> ParameterValueType:
|
229
221
|
"""Maximum allowed value."""
|
230
|
-
return self.
|
222
|
+
return self._values.max_value
|
223
|
+
|
224
|
+
@property
|
225
|
+
def unit_of_measurement(self) -> UnitOfMeasurement | Literal["%"] | None:
|
226
|
+
"""A unit of measurement."""
|
227
|
+
return self.description.unit_of_measurement
|
231
228
|
|
232
229
|
@property
|
233
230
|
def request(self) -> Request:
|
@@ -257,7 +254,7 @@ class BinaryParameter(Parameter):
|
|
257
254
|
@property
|
258
255
|
def value(self) -> ParameterValueType:
|
259
256
|
"""A parameter value."""
|
260
|
-
return STATE_ON if self.
|
257
|
+
return STATE_ON if self._values.value == 1 else STATE_OFF
|
261
258
|
|
262
259
|
@property
|
263
260
|
def min_value(self) -> ParameterValueType:
|
PyPlumIO-0.5.2/pyplumio/structures/load.py → PyPlumIO-0.5.3/pyplumio/structures/boiler_load.py
RENAMED
@@ -8,20 +8,20 @@ from pyplumio.helpers.typing import EventDataType
|
|
8
8
|
from pyplumio.structures import StructureDecoder
|
9
9
|
from pyplumio.utils import ensure_dict
|
10
10
|
|
11
|
-
|
11
|
+
ATTR_BOILER_LOAD: Final = "boiler_load"
|
12
12
|
|
13
13
|
|
14
|
-
class
|
14
|
+
class BoilerLoadStructure(StructureDecoder):
|
15
15
|
"""Represents a boiler load sensor data structure."""
|
16
16
|
|
17
17
|
def decode(
|
18
18
|
self, message: bytearray, offset: int = 0, data: EventDataType | None = None
|
19
19
|
) -> tuple[EventDataType, int]:
|
20
20
|
"""Decode bytes and return message data and offset."""
|
21
|
-
|
21
|
+
boiler_load = message[offset]
|
22
22
|
offset += 1
|
23
23
|
|
24
|
-
if
|
24
|
+
if boiler_load == BYTE_UNDEFINED:
|
25
25
|
return ensure_dict(data), offset
|
26
26
|
|
27
|
-
return (ensure_dict(data, {
|
27
|
+
return (ensure_dict(data, {ATTR_BOILER_LOAD: boiler_load}), offset)
|
PyPlumIO-0.5.2/pyplumio/structures/power.py → PyPlumIO-0.5.3/pyplumio/structures/boiler_power.py
RENAMED
@@ -9,20 +9,20 @@ from pyplumio.helpers.typing import EventDataType
|
|
9
9
|
from pyplumio.structures import StructureDecoder
|
10
10
|
from pyplumio.utils import ensure_dict
|
11
11
|
|
12
|
-
|
12
|
+
ATTR_BOILER_POWER: Final = "boiler_power"
|
13
13
|
|
14
14
|
|
15
|
-
class
|
15
|
+
class BoilerPowerStructure(StructureDecoder):
|
16
16
|
"""Represents a boiler power sensor data structure."""
|
17
17
|
|
18
18
|
def decode(
|
19
19
|
self, message: bytearray, offset: int = 0, data: EventDataType | None = None
|
20
20
|
) -> tuple[EventDataType, int]:
|
21
21
|
"""Decode bytes and return message data and offset."""
|
22
|
-
|
23
|
-
offset +=
|
22
|
+
boiler_power = Float.from_bytes(message, offset)
|
23
|
+
offset += boiler_power.size
|
24
24
|
|
25
|
-
if math.isnan(
|
25
|
+
if math.isnan(boiler_power.value):
|
26
26
|
return ensure_dict(data), offset
|
27
27
|
|
28
|
-
return ensure_dict(data, {
|
28
|
+
return ensure_dict(data, {ATTR_BOILER_POWER: boiler_power.value}), offset
|
@@ -51,17 +51,23 @@ class EcomaxParameter(Parameter):
|
|
51
51
|
@property
|
52
52
|
def value(self) -> ParameterValueType:
|
53
53
|
"""A parameter value."""
|
54
|
-
return (
|
54
|
+
return (
|
55
|
+
self._values.value - self.description.offset
|
56
|
+
) * self.description.multiplier
|
55
57
|
|
56
58
|
@property
|
57
59
|
def min_value(self) -> ParameterValueType:
|
58
60
|
"""Minimum allowed value."""
|
59
|
-
return (
|
61
|
+
return (
|
62
|
+
self._values.min_value - self.description.offset
|
63
|
+
) * self.description.multiplier
|
60
64
|
|
61
65
|
@property
|
62
66
|
def max_value(self) -> ParameterValueType:
|
63
67
|
"""Maximum allowed value."""
|
64
|
-
return (
|
68
|
+
return (
|
69
|
+
self._values.max_value - self.description.offset
|
70
|
+
) * self.description.multiplier
|
65
71
|
|
66
72
|
@property
|
67
73
|
def request(self) -> Request:
|
@@ -72,7 +78,7 @@ class EcomaxParameter(Parameter):
|
|
72
78
|
"frames.requests.EcomaxControlRequest",
|
73
79
|
recipient=self.device.address,
|
74
80
|
data={
|
75
|
-
ATTR_VALUE: self.
|
81
|
+
ATTR_VALUE: self._values.value,
|
76
82
|
},
|
77
83
|
)
|
78
84
|
|
@@ -82,7 +88,7 @@ class EcomaxParameter(Parameter):
|
|
82
88
|
recipient=self.device.address,
|
83
89
|
data={
|
84
90
|
ATTR_INDEX: self._index,
|
85
|
-
ATTR_VALUE: self.
|
91
|
+
ATTR_VALUE: self._values.value,
|
86
92
|
ATTR_OFFSET: 0,
|
87
93
|
ATTR_SIZE: 1,
|
88
94
|
},
|
@@ -93,7 +99,7 @@ class EcomaxParameter(Parameter):
|
|
93
99
|
recipient=self.device.address,
|
94
100
|
data={
|
95
101
|
ATTR_INDEX: self._index,
|
96
|
-
ATTR_VALUE: self.
|
102
|
+
ATTR_VALUE: self._values.value,
|
97
103
|
},
|
98
104
|
)
|
99
105
|
|
@@ -421,7 +427,7 @@ ECOMAX_PARAMETERS: dict[ProductType, tuple[EcomaxParameterDescription, ...]] = {
|
|
421
427
|
name="thermostat_decrease_target_temp",
|
422
428
|
unit_of_measurement=UnitOfMeasurement.CELSIUS,
|
423
429
|
),
|
424
|
-
EcomaxBinaryParameterDescription(name="
|
430
|
+
EcomaxBinaryParameterDescription(name="disable_pump_on_thermostat"),
|
425
431
|
EcomaxParameterDescription(
|
426
432
|
name="boiler_alert_temp", unit_of_measurement=UnitOfMeasurement.CELSIUS
|
427
433
|
),
|
@@ -49,17 +49,23 @@ class MixerParameter(Parameter):
|
|
49
49
|
@property
|
50
50
|
def value(self) -> ParameterValueType:
|
51
51
|
"""A parameter value."""
|
52
|
-
return (
|
52
|
+
return (
|
53
|
+
self._values.value - self.description.offset
|
54
|
+
) * self.description.multiplier
|
53
55
|
|
54
56
|
@property
|
55
57
|
def min_value(self) -> ParameterValueType:
|
56
58
|
"""Minimum allowed value."""
|
57
|
-
return (
|
59
|
+
return (
|
60
|
+
self._values.min_value - self.description.offset
|
61
|
+
) * self.description.multiplier
|
58
62
|
|
59
63
|
@property
|
60
64
|
def max_value(self) -> ParameterValueType:
|
61
65
|
"""Maximum allowed value."""
|
62
|
-
return (
|
66
|
+
return (
|
67
|
+
self._values.max_value - self.description.offset
|
68
|
+
) * self.description.multiplier
|
63
69
|
|
64
70
|
@property
|
65
71
|
def request(self) -> Request:
|
@@ -69,7 +75,7 @@ class MixerParameter(Parameter):
|
|
69
75
|
recipient=self.device.parent.address,
|
70
76
|
data={
|
71
77
|
ATTR_INDEX: self._index,
|
72
|
-
ATTR_VALUE: self.
|
78
|
+
ATTR_VALUE: self._values.value,
|
73
79
|
ATTR_DEVICE_INDEX: self.device.index,
|
74
80
|
},
|
75
81
|
)
|
@@ -125,7 +131,7 @@ MIXER_PARAMETERS: dict[ProductType, tuple[MixerParameterDescription, ...]] = {
|
|
125
131
|
),
|
126
132
|
MixerBinaryParameterDescription(name="thermostat_operation"),
|
127
133
|
MixerParameterDescription(name="thermostat_mode"),
|
128
|
-
MixerBinaryParameterDescription(name="
|
134
|
+
MixerBinaryParameterDescription(name="disable_pump_on_thermostat"),
|
129
135
|
MixerBinaryParameterDescription(name="summer_work"),
|
130
136
|
),
|
131
137
|
ProductType.ECOMAX_I: (
|
@@ -59,17 +59,17 @@ class ThermostatParameter(Parameter):
|
|
59
59
|
@property
|
60
60
|
def value(self) -> ParameterValueType:
|
61
61
|
"""A parameter value."""
|
62
|
-
return self.
|
62
|
+
return self._values.value * self.description.multiplier
|
63
63
|
|
64
64
|
@property
|
65
65
|
def min_value(self) -> ParameterValueType:
|
66
66
|
"""Minimum allowed value."""
|
67
|
-
return self.
|
67
|
+
return self._values.min_value * self.description.multiplier
|
68
68
|
|
69
69
|
@property
|
70
70
|
def max_value(self) -> ParameterValueType:
|
71
71
|
"""Maximum allowed value."""
|
72
|
-
return self.
|
72
|
+
return self._values.max_value * self.description.multiplier
|
73
73
|
|
74
74
|
@property
|
75
75
|
def request(self) -> Request:
|
@@ -81,7 +81,7 @@ class ThermostatParameter(Parameter):
|
|
81
81
|
# Increase the index by one to account for thermostat
|
82
82
|
# profile, which is being set at ecoMAX device level.
|
83
83
|
ATTR_INDEX: self._index + 1,
|
84
|
-
ATTR_VALUE: self.
|
84
|
+
ATTR_VALUE: self._values.value,
|
85
85
|
ATTR_OFFSET: self.offset,
|
86
86
|
ATTR_SIZE: self.description.size,
|
87
87
|
},
|
@@ -37,9 +37,7 @@ def fixture_parameter(ecomax: EcoMAX) -> Parameter:
|
|
37
37
|
"""Return a parameter object."""
|
38
38
|
return TestParameter(
|
39
39
|
device=ecomax,
|
40
|
-
value=1,
|
41
|
-
min_value=0,
|
42
|
-
max_value=5,
|
40
|
+
values=ParameterValues(value=1, min_value=0, max_value=5),
|
43
41
|
description=ParameterDescription(
|
44
42
|
name="test_parameter", unit_of_measurement=UnitOfMeasurement.CELSIUS
|
45
43
|
),
|
@@ -51,9 +49,7 @@ def fixture_binary_parameter(ecomax: EcoMAX) -> BinaryParameter:
|
|
51
49
|
"""Return a binary parameter object."""
|
52
50
|
return TestBinaryParameter(
|
53
51
|
device=ecomax,
|
54
|
-
value=
|
55
|
-
min_value=STATE_OFF,
|
56
|
-
max_value=STATE_ON,
|
52
|
+
values=ParameterValues(value=0, min_value=0, max_value=1),
|
57
53
|
description=ParameterDescription(name="test_binary_parameter"),
|
58
54
|
)
|
59
55
|
|
@@ -83,9 +79,7 @@ def test_base_parameter_request(ecomax: EcoMAX) -> None:
|
|
83
79
|
"""Test that a base class request throws not implemented error."""
|
84
80
|
parameter = Parameter(
|
85
81
|
device=ecomax,
|
86
|
-
value=1,
|
87
|
-
min_value=0,
|
88
|
-
max_value=5,
|
82
|
+
values=ParameterValues(value=1, min_value=0, max_value=5),
|
89
83
|
description=ParameterDescription(name="test_parameter"),
|
90
84
|
)
|
91
85
|
|
@@ -156,17 +150,12 @@ def test_parameter_repr(parameter: Parameter) -> None:
|
|
156
150
|
"""Test a parameter representation."""
|
157
151
|
assert repr(parameter) == (
|
158
152
|
"TestParameter(device=EcoMAX, "
|
153
|
+
"values=ParameterValues(value=1, min_value=0, max_value=5), "
|
159
154
|
"description=ParameterDescription(name='test_parameter', "
|
160
|
-
"unit_of_measurement=<UnitOfMeasurement.CELSIUS: '°C'>)
|
161
|
-
"value=1, min_value=0, max_value=5)"
|
155
|
+
"unit_of_measurement=<UnitOfMeasurement.CELSIUS: '°C'>))"
|
162
156
|
)
|
163
157
|
|
164
158
|
|
165
|
-
def test_parameter_getattr(parameter: Parameter):
|
166
|
-
"""Test getting attributes from the parameters description."""
|
167
|
-
assert parameter.unit_of_measurement == UnitOfMeasurement.CELSIUS
|
168
|
-
|
169
|
-
|
170
159
|
@patch("asyncio.Queue.put")
|
171
160
|
async def test_parameter_request_with_unchanged_value(
|
172
161
|
mock_put, parameter: Parameter, bypass_asyncio_sleep, caplog
|
@@ -226,10 +226,7 @@ async def test_ecomax_parameters_callbacks(ecomax: EcoMAX) -> None:
|
|
226
226
|
assert heating_heat_curve_shift.value == 0.0
|
227
227
|
assert heating_heat_curve_shift.min_value == -20.0
|
228
228
|
assert heating_heat_curve_shift.max_value == 20.0
|
229
|
-
assert
|
230
|
-
heating_heat_curve_shift.description.unit_of_measurement
|
231
|
-
== UnitOfMeasurement.CELSIUS
|
232
|
-
)
|
229
|
+
assert heating_heat_curve_shift.unit_of_measurement == UnitOfMeasurement.CELSIUS
|
233
230
|
|
234
231
|
# Test setting the parameter with the offset.
|
235
232
|
with patch(
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|