PyPlumIO 0.5.53__tar.gz → 0.5.55__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.53 → pyplumio-0.5.55}/.pre-commit-config.yaml +2 -2
- {pyplumio-0.5.53 → pyplumio-0.5.55}/PKG-INFO +9 -9
- {pyplumio-0.5.53 → pyplumio-0.5.55}/PyPlumIO.egg-info/PKG-INFO +9 -9
- {pyplumio-0.5.53 → pyplumio-0.5.55}/PyPlumIO.egg-info/requires.txt +8 -8
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/_version.py +16 -3
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/devices/__init__.py +2 -1
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/devices/ecomax.py +14 -2
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/filters.py +2 -1
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyproject.toml +8 -8
- pyplumio-0.5.55/requirements_test.txt +13 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/test_ecomax.py +16 -2
- pyplumio-0.5.53/requirements_test.txt +0 -13
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.gitattributes +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/CODE_OF_CONDUCT.md +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/dependabot.yml +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/workflows/ci.yml +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/workflows/codeql.yml +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/workflows/deploy.yml +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/workflows/documentation.yml +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.gitignore +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.qlty/qlty.toml +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/.vscode/settings.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/LICENSE +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/MANIFEST.in +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/PyPlumIO.egg-info/SOURCES.txt +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/PyPlumIO.egg-info/dependency_links.txt +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/PyPlumIO.egg-info/top_level.txt +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/README.md +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/Makefile +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/make.bat +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/callbacks.rst +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/conf.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/connecting.rst +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/frames.rst +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/index.rst +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/mixers_thermostats.rst +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/protocol.rst +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/reading.rst +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/schedules.rst +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/writing.rst +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/images/ecomax.png +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/images/rs485.png +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/__main__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/connection.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/const.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/data_types.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/devices/ecoster.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/devices/mixer.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/devices/thermostat.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/exceptions.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/frames/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/frames/messages.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/frames/requests.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/frames/responses.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/helpers/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/helpers/async_cache.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/helpers/event_manager.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/helpers/factory.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/helpers/task_manager.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/custom/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/custom/ecomax_860d3_hb.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/ecomax.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/mixer.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/thermostat.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/protocol.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/py.typed +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/stream.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/alerts.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/boiler_load.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/boiler_power.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/ecomax_parameters.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/fan_power.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/frame_versions.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/fuel_consumption.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/fuel_level.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/lambda_sensor.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/mixer_parameters.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/mixer_sensors.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/modules.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/network_info.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/output_flags.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/outputs.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/pending_alerts.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/product_info.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/program_version.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/regulator_data.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/regulator_data_schema.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/schedules.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/statuses.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/temperatures.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/thermostat_parameters.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/thermostat_sensors.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/utils.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/requirements.txt +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/requirements_docs.txt +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/setup.cfg +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/conftest.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/test_ecoster.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/test_init.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/test_mixer.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/test_thermostat.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/frames/test_init.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/frames/test_messages.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/frames/test_requests.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/frames/test_responses.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/test_async_cache.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/test_event_manager.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/test_factory.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/test_task_manager.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/test_uid.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/custom/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/custom/test_ecomax_860d3_hb.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/custom/test_init.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/test_ecomax.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/test_init.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/test_mixers.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/test_thermostats.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/ruff.toml +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/__init__.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_alerts.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_boiler_load.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_boiler_power.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_ecomax_parameters.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_fan_power.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_frame_versions.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_fuel_consumption.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_fuel_level.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_lambda_sensor.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_mixer_parameters.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_product_info.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_schedules.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_connection.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_data_types.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_filters.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_init.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_main.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_protocol.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_stream.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_utils.py +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/messages/regulator_data.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/messages/sensor_data.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/parameters/ecomax_860d3_hb.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/alerts.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/ecomax_control.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/ecomax_parameters.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/mixer_parameters.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/set_ecomax_parameter.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/set_mixer_parameter.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/set_schedule.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/set_thermostat_parameter.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/thermostat_parameters.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/alerts.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/device_available.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/ecomax_parameters.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/mixer_parameters.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/password.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/program_version.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/regulator_data_schema.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/schedules.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/thermostat_parameters.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/uid.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/unknown/unknown_ecomax_parameter.json +0 -0
- {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/unknown/unknown_mixer_parameter.json +0 -0
@@ -3,7 +3,7 @@
|
|
3
3
|
# See https://pre-commit.com/hooks.html for more hooks
|
4
4
|
repos:
|
5
5
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
6
|
-
rev: v0.
|
6
|
+
rev: v0.12.11
|
7
7
|
hooks:
|
8
8
|
- id: ruff
|
9
9
|
args:
|
@@ -13,6 +13,6 @@ repos:
|
|
13
13
|
hooks:
|
14
14
|
- id: codespell
|
15
15
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
16
|
-
rev: v1.
|
16
|
+
rev: v1.17.1
|
17
17
|
hooks:
|
18
18
|
- id: mypy
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: PyPlumIO
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.55
|
4
4
|
Summary: PyPlumIO is a native ecoNET library for Plum ecoMAX controllers.
|
5
5
|
Author-email: Denis Paavilainen <denpa@denpa.pro>
|
6
6
|
License: MIT License
|
@@ -28,23 +28,23 @@ Requires-Dist: pyserial-asyncio==0.6
|
|
28
28
|
Requires-Dist: typing-extensions<5.0,>=4.14.0
|
29
29
|
Provides-Extra: test
|
30
30
|
Requires-Dist: codespell==2.4.1; extra == "test"
|
31
|
-
Requires-Dist: coverage==7.
|
32
|
-
Requires-Dist: freezegun==1.5.
|
33
|
-
Requires-Dist: mypy==1.
|
31
|
+
Requires-Dist: coverage==7.10.5; extra == "test"
|
32
|
+
Requires-Dist: freezegun==1.5.5; extra == "test"
|
33
|
+
Requires-Dist: mypy==1.17.1; extra == "test"
|
34
34
|
Requires-Dist: numpy<3.0.0,>=2.0.0; extra == "test"
|
35
35
|
Requires-Dist: pyserial-asyncio-fast==0.16; extra == "test"
|
36
36
|
Requires-Dist: pytest==8.4.1; extra == "test"
|
37
|
-
Requires-Dist: pytest-asyncio==1.
|
38
|
-
Requires-Dist: ruff==0.12.
|
39
|
-
Requires-Dist: tox==4.
|
40
|
-
Requires-Dist: types-pyserial==3.5.0.
|
37
|
+
Requires-Dist: pytest-asyncio==1.1.0; extra == "test"
|
38
|
+
Requires-Dist: ruff==0.12.10; extra == "test"
|
39
|
+
Requires-Dist: tox==4.28.4; extra == "test"
|
40
|
+
Requires-Dist: types-pyserial==3.5.0.20250822; extra == "test"
|
41
41
|
Provides-Extra: docs
|
42
42
|
Requires-Dist: sphinx==8.1.3; extra == "docs"
|
43
43
|
Requires-Dist: sphinx_rtd_theme==3.0.2; extra == "docs"
|
44
44
|
Requires-Dist: readthedocs-sphinx-search==0.3.2; extra == "docs"
|
45
45
|
Provides-Extra: dev
|
46
46
|
Requires-Dist: pyplumio[docs,test]; extra == "dev"
|
47
|
-
Requires-Dist: pre-commit==4.
|
47
|
+
Requires-Dist: pre-commit==4.3.0; extra == "dev"
|
48
48
|
Requires-Dist: tomli==2.2.1; extra == "dev"
|
49
49
|
Dynamic: license-file
|
50
50
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: PyPlumIO
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.55
|
4
4
|
Summary: PyPlumIO is a native ecoNET library for Plum ecoMAX controllers.
|
5
5
|
Author-email: Denis Paavilainen <denpa@denpa.pro>
|
6
6
|
License: MIT License
|
@@ -28,23 +28,23 @@ Requires-Dist: pyserial-asyncio==0.6
|
|
28
28
|
Requires-Dist: typing-extensions<5.0,>=4.14.0
|
29
29
|
Provides-Extra: test
|
30
30
|
Requires-Dist: codespell==2.4.1; extra == "test"
|
31
|
-
Requires-Dist: coverage==7.
|
32
|
-
Requires-Dist: freezegun==1.5.
|
33
|
-
Requires-Dist: mypy==1.
|
31
|
+
Requires-Dist: coverage==7.10.5; extra == "test"
|
32
|
+
Requires-Dist: freezegun==1.5.5; extra == "test"
|
33
|
+
Requires-Dist: mypy==1.17.1; extra == "test"
|
34
34
|
Requires-Dist: numpy<3.0.0,>=2.0.0; extra == "test"
|
35
35
|
Requires-Dist: pyserial-asyncio-fast==0.16; extra == "test"
|
36
36
|
Requires-Dist: pytest==8.4.1; extra == "test"
|
37
|
-
Requires-Dist: pytest-asyncio==1.
|
38
|
-
Requires-Dist: ruff==0.12.
|
39
|
-
Requires-Dist: tox==4.
|
40
|
-
Requires-Dist: types-pyserial==3.5.0.
|
37
|
+
Requires-Dist: pytest-asyncio==1.1.0; extra == "test"
|
38
|
+
Requires-Dist: ruff==0.12.10; extra == "test"
|
39
|
+
Requires-Dist: tox==4.28.4; extra == "test"
|
40
|
+
Requires-Dist: types-pyserial==3.5.0.20250822; extra == "test"
|
41
41
|
Provides-Extra: docs
|
42
42
|
Requires-Dist: sphinx==8.1.3; extra == "docs"
|
43
43
|
Requires-Dist: sphinx_rtd_theme==3.0.2; extra == "docs"
|
44
44
|
Requires-Dist: readthedocs-sphinx-search==0.3.2; extra == "docs"
|
45
45
|
Provides-Extra: dev
|
46
46
|
Requires-Dist: pyplumio[docs,test]; extra == "dev"
|
47
|
-
Requires-Dist: pre-commit==4.
|
47
|
+
Requires-Dist: pre-commit==4.3.0; extra == "dev"
|
48
48
|
Requires-Dist: tomli==2.2.1; extra == "dev"
|
49
49
|
Dynamic: license-file
|
50
50
|
|
@@ -4,7 +4,7 @@ typing-extensions<5.0,>=4.14.0
|
|
4
4
|
|
5
5
|
[dev]
|
6
6
|
pyplumio[docs,test]
|
7
|
-
pre-commit==4.
|
7
|
+
pre-commit==4.3.0
|
8
8
|
tomli==2.2.1
|
9
9
|
|
10
10
|
[docs]
|
@@ -14,13 +14,13 @@ readthedocs-sphinx-search==0.3.2
|
|
14
14
|
|
15
15
|
[test]
|
16
16
|
codespell==2.4.1
|
17
|
-
coverage==7.
|
18
|
-
freezegun==1.5.
|
19
|
-
mypy==1.
|
17
|
+
coverage==7.10.5
|
18
|
+
freezegun==1.5.5
|
19
|
+
mypy==1.17.1
|
20
20
|
numpy<3.0.0,>=2.0.0
|
21
21
|
pyserial-asyncio-fast==0.16
|
22
22
|
pytest==8.4.1
|
23
|
-
pytest-asyncio==1.
|
24
|
-
ruff==0.12.
|
25
|
-
tox==4.
|
26
|
-
types-pyserial==3.5.0.
|
23
|
+
pytest-asyncio==1.1.0
|
24
|
+
ruff==0.12.10
|
25
|
+
tox==4.28.4
|
26
|
+
types-pyserial==3.5.0.20250822
|
@@ -1,7 +1,14 @@
|
|
1
1
|
# file generated by setuptools-scm
|
2
2
|
# don't change, don't track in version control
|
3
3
|
|
4
|
-
__all__ = [
|
4
|
+
__all__ = [
|
5
|
+
"__version__",
|
6
|
+
"__version_tuple__",
|
7
|
+
"version",
|
8
|
+
"version_tuple",
|
9
|
+
"__commit_id__",
|
10
|
+
"commit_id",
|
11
|
+
]
|
5
12
|
|
6
13
|
TYPE_CHECKING = False
|
7
14
|
if TYPE_CHECKING:
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
9
16
|
from typing import Union
|
10
17
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
19
|
+
COMMIT_ID = Union[str, None]
|
12
20
|
else:
|
13
21
|
VERSION_TUPLE = object
|
22
|
+
COMMIT_ID = object
|
14
23
|
|
15
24
|
version: str
|
16
25
|
__version__: str
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
18
27
|
version_tuple: VERSION_TUPLE
|
28
|
+
commit_id: COMMIT_ID
|
29
|
+
__commit_id__: COMMIT_ID
|
19
30
|
|
20
|
-
__version__ = version = '0.5.
|
21
|
-
__version_tuple__ = version_tuple = (0, 5,
|
31
|
+
__version__ = version = '0.5.55'
|
32
|
+
__version_tuple__ = version_tuple = (0, 5, 55)
|
33
|
+
|
34
|
+
__commit_id__ = commit_id = 'gb0f1bcbdf'
|
@@ -195,6 +195,7 @@ class PhysicalDevice(Device, ABC):
|
|
195
195
|
"""
|
196
196
|
_LOGGER.info("Requesting '%s' with %s", name, repr(frame_type))
|
197
197
|
request = await Request.create(frame_type, recipient=self.address)
|
198
|
+
initial_retries = retries
|
198
199
|
while retries > 0:
|
199
200
|
try:
|
200
201
|
self.queue.put_nowait(request)
|
@@ -204,7 +205,7 @@ class PhysicalDevice(Device, ABC):
|
|
204
205
|
|
205
206
|
raise RequestError(
|
206
207
|
f"Failed to request '{name}' with frame type '{frame_type}' after "
|
207
|
-
f"{
|
208
|
+
f"{initial_retries} retries.",
|
208
209
|
frame_type=frame_type,
|
209
210
|
)
|
210
211
|
|
@@ -139,6 +139,8 @@ REQUIRED: tuple[DataFrameDescription, ...] = (
|
|
139
139
|
|
140
140
|
REQUIRED_TYPES = [description.frame_type for description in REQUIRED]
|
141
141
|
|
142
|
+
SETUP_TIMEOUT: Final = 60.0
|
143
|
+
|
142
144
|
|
143
145
|
class EcoMAX(PhysicalDevice):
|
144
146
|
"""Represents an ecoMAX controller."""
|
@@ -233,10 +235,19 @@ class EcoMAX(PhysicalDevice):
|
|
233
235
|
await super().shutdown()
|
234
236
|
|
235
237
|
@event_listener
|
236
|
-
async def on_event_setup(self, setup: bool) ->
|
238
|
+
async def on_event_setup(self, setup: bool) -> bool:
|
237
239
|
"""Request frames required to set up an ecoMAX entry."""
|
238
240
|
_LOGGER.debug("Setting up device entry")
|
239
|
-
|
241
|
+
|
242
|
+
try:
|
243
|
+
await self.wait_for(ATTR_SENSORS, timeout=SETUP_TIMEOUT)
|
244
|
+
except asyncio.TimeoutError:
|
245
|
+
_LOGGER.error(
|
246
|
+
"Could not setup device entry; no response from device for %u seconds",
|
247
|
+
SETUP_TIMEOUT,
|
248
|
+
)
|
249
|
+
return False
|
250
|
+
|
240
251
|
results = await asyncio.gather(
|
241
252
|
*(
|
242
253
|
self.request(description.provides, description.frame_type)
|
@@ -253,6 +264,7 @@ class EcoMAX(PhysicalDevice):
|
|
253
264
|
self.dispatch_nowait(ATTR_FRAME_ERRORS, errors)
|
254
265
|
|
255
266
|
_LOGGER.debug("Device entry setup done")
|
267
|
+
return True
|
256
268
|
|
257
269
|
@event_listener
|
258
270
|
async def on_event_ecomax_parameters(
|
@@ -186,9 +186,10 @@ class _Aggregate(Filter):
|
|
186
186
|
self._values.append(new_value)
|
187
187
|
time_since_call = current_time - self._last_call_time
|
188
188
|
if time_since_call >= self._timeout or len(self._values) >= self._sample_size:
|
189
|
-
|
189
|
+
sum_of_values = (
|
190
190
|
np.sum(self._values) if numpy_installed else sum(self._values)
|
191
191
|
)
|
192
|
+
result = await self._callback(float(sum_of_values))
|
192
193
|
self._last_call_time = current_time
|
193
194
|
self._values = []
|
194
195
|
return result
|
@@ -38,16 +38,16 @@ dynamic = ["version"]
|
|
38
38
|
[project.optional-dependencies]
|
39
39
|
test = [
|
40
40
|
"codespell==2.4.1",
|
41
|
-
"coverage==7.
|
42
|
-
"freezegun==1.5.
|
43
|
-
"mypy==1.
|
41
|
+
"coverage==7.10.5",
|
42
|
+
"freezegun==1.5.5",
|
43
|
+
"mypy==1.17.1",
|
44
44
|
"numpy<3.0.0,>=2.0.0",
|
45
45
|
"pyserial-asyncio-fast==0.16",
|
46
46
|
"pytest==8.4.1",
|
47
|
-
"pytest-asyncio==1.
|
48
|
-
"ruff==0.12.
|
49
|
-
"tox==4.
|
50
|
-
"types-pyserial==3.5.0.
|
47
|
+
"pytest-asyncio==1.1.0",
|
48
|
+
"ruff==0.12.10",
|
49
|
+
"tox==4.28.4",
|
50
|
+
"types-pyserial==3.5.0.20250822"
|
51
51
|
]
|
52
52
|
docs = [
|
53
53
|
"sphinx==8.1.3",
|
@@ -56,7 +56,7 @@ docs = [
|
|
56
56
|
]
|
57
57
|
dev = [
|
58
58
|
"pyplumio[test,docs]",
|
59
|
-
"pre-commit==4.
|
59
|
+
"pre-commit==4.3.0",
|
60
60
|
"tomli==2.2.1"
|
61
61
|
]
|
62
62
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
codespell==2.4.1
|
2
|
+
coverage==7.10.5
|
3
|
+
freezegun==1.5.5
|
4
|
+
mypy==1.17.1
|
5
|
+
numpy<3.0.0,>=2.0.0
|
6
|
+
pre-commit==4.3.0
|
7
|
+
pyserial-asyncio-fast==0.16
|
8
|
+
pytest-asyncio==1.1.0
|
9
|
+
pytest==8.4.1
|
10
|
+
ruff==0.12.10
|
11
|
+
tomli==2.2.1
|
12
|
+
tox==4.28.4
|
13
|
+
types-pyserial==3.5.0.20250822
|
@@ -1,5 +1,6 @@
|
|
1
1
|
"""Contains tests for the ecoMAX device."""
|
2
2
|
|
3
|
+
import asyncio
|
3
4
|
from datetime import timedelta
|
4
5
|
import logging
|
5
6
|
from typing import Any, cast
|
@@ -206,7 +207,20 @@ async def test_ecomax_setup(mock_wait_for, mock_request, ecomax: EcoMAX) -> None
|
|
206
207
|
await ecomax.wait_until_done()
|
207
208
|
assert ATTR_FRAME_ERRORS not in ecomax.data
|
208
209
|
assert mock_request.await_count == len(REQUIRED)
|
209
|
-
mock_wait_for.assert_awaited_once_with(ATTR_SENSORS)
|
210
|
+
mock_wait_for.assert_awaited_once_with(ATTR_SENSORS, timeout=60.0)
|
211
|
+
|
212
|
+
|
213
|
+
@patch("pyplumio.devices.ecomax.EcoMAX.request")
|
214
|
+
@patch("pyplumio.devices.ecomax.EcoMAX.wait_for", side_effect=(asyncio.TimeoutError,))
|
215
|
+
async def test_ecomax_setup_failed(
|
216
|
+
mock_wait_for, mock_request, ecomax: EcoMAX, caplog
|
217
|
+
) -> None:
|
218
|
+
"""Test setting up an ecoMAX entry with failure due to timeout."""
|
219
|
+
ecomax.dispatch_nowait(ATTR_SETUP, True)
|
220
|
+
await ecomax.wait_until_done()
|
221
|
+
assert ecomax.get_nowait(ATTR_SETUP) is False
|
222
|
+
assert "Could not setup device entry" in caplog.text
|
223
|
+
assert "no response from device for 60 seconds" in caplog.text
|
210
224
|
|
211
225
|
|
212
226
|
@patch(
|
@@ -220,7 +234,7 @@ async def test_ecomax_setup_errors(mock_wait_for, mock_request, ecomax: EcoMAX)
|
|
220
234
|
await ecomax.wait_until_done()
|
221
235
|
assert FrameType.REQUEST_ALERTS in ecomax.get_nowait(ATTR_FRAME_ERRORS, [])
|
222
236
|
assert mock_request.await_count == len(REQUIRED)
|
223
|
-
mock_wait_for.assert_awaited_once_with(ATTR_SENSORS)
|
237
|
+
mock_wait_for.assert_awaited_once_with(ATTR_SENSORS, timeout=60.0)
|
224
238
|
|
225
239
|
|
226
240
|
@patch("asyncio.Queue.put")
|
@@ -1,13 +0,0 @@
|
|
1
|
-
codespell==2.4.1
|
2
|
-
coverage==7.9.1
|
3
|
-
freezegun==1.5.2
|
4
|
-
mypy==1.16.1
|
5
|
-
numpy<3.0.0,>=2.0.0
|
6
|
-
pre-commit==4.2.0
|
7
|
-
pyserial-asyncio-fast==0.16
|
8
|
-
pytest-asyncio==1.0.0
|
9
|
-
pytest==8.4.1
|
10
|
-
ruff==0.12.1
|
11
|
-
tomli==2.2.1
|
12
|
-
tox==4.27.0
|
13
|
-
types-pyserial==3.5.0.20250326
|
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
|
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
|