PyPlumIO 0.6.7__tar.gz → 0.7.0__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.6.7 → pyplumio-0.7.0}/.gitignore +6 -2
- {pyplumio-0.6.7 → pyplumio-0.7.0}/PKG-INFO +64 -36
- {pyplumio-0.6.7 → pyplumio-0.7.0}/README.md +54 -3
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/source/callbacks.rst +7 -3
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/source/connecting.rst +29 -38
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/source/frames.rst +94 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/source/index.rst +4 -2
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/source/mixers_thermostats.rst +2 -2
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/source/reading.rst +2 -2
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/source/schedules.rst +4 -4
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/source/writing.rst +4 -4
- pyplumio-0.7.0/pyplumio/__init__.py +120 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/__main__.py +1 -1
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/connection.py +32 -70
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/const.py +6 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/data_types.py +1 -1
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/devices/__init__.py +2 -2
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/devices/ecomax.py +63 -15
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/filters.py +19 -8
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/frames/__init__.py +30 -28
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/frames/messages.py +1 -1
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/frames/requests.py +65 -35
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/frames/responses.py +39 -10
- pyplumio-0.7.0/pyplumio/helpers/__init__.py +3 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/helpers/async_cache.py +2 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/helpers/event_manager.py +2 -2
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/parameters/__init__.py +4 -4
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/parameters/custom/ecomax_860d3_hb.py +2 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/parameters/ecomax.py +311 -3
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/parameters/mixer.py +1 -3
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/parameters/thermostat.py +3 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/protocol.py +1 -1
- pyplumio-0.7.0/pyplumio/py.typed +1 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/stream.py +3 -3
- pyplumio-0.7.0/pyplumio/structures/__init__.py +52 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/alerts.py +10 -24
- pyplumio-0.7.0/pyplumio/structures/ecomax_extended_parameters.py +50 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/ecomax_parameters.py +3 -20
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/frame_versions.py +4 -20
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/mixer_parameters.py +6 -21
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/network_info.py +25 -33
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/product_info.py +9 -20
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/program_version.py +25 -24
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/regulator_data.py +16 -25
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/regulator_data_schema.py +6 -23
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/schedules.py +8 -17
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/sensor_data.py +32 -57
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/structures/thermostat_parameters.py +8 -22
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/utils.py +2 -15
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyproject.toml +56 -96
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/conftest.py +10 -2
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/devices/test_ecomax.py +250 -6
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/devices/test_init.py +1 -1
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/frames/test_init.py +11 -11
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/frames/test_messages.py +6 -5
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/frames/test_requests.py +34 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/frames/test_responses.py +11 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/helpers/test_uid.py +3 -3
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/parameters/test_ecomax.py +38 -1
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/parameters/test_init.py +41 -8
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/structures/test_alerts.py +9 -8
- pyplumio-0.7.0/tests/structures/test_ecomax_extended_parameters.py +51 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/structures/test_ecomax_parameters.py +6 -3
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/structures/test_frame_versions.py +6 -3
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/structures/test_mixer_parameters.py +6 -3
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/structures/test_product_info.py +3 -3
- pyplumio-0.7.0/tests/structures/test_program_version.py +45 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/test_connection.py +70 -101
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/test_data_types.py +14 -14
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/test_filters.py +104 -1
- pyplumio-0.7.0/tests/test_init.py +37 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/test_main.py +2 -4
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/test_stream.py +7 -5
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/test_utils.py +4 -17
- pyplumio-0.7.0/tests/testdata/requests/ecomax_extended_parameters.json +15 -0
- pyplumio-0.7.0/tests/testdata/requests/set_ecomax_extended_parameter.json +54 -0
- pyplumio-0.7.0/tests/testdata/responses/ecomax_extended_parameters.json +3036 -0
- pyplumio-0.6.7/.gitattributes +0 -2
- pyplumio-0.6.7/.github/CODE_OF_CONDUCT.md +0 -132
- pyplumio-0.6.7/.github/ISSUE_TEMPLATE/bug_report.yml +0 -82
- pyplumio-0.6.7/.github/ISSUE_TEMPLATE/feature_request.yml +0 -71
- pyplumio-0.6.7/.github/dependabot.yml +0 -7
- pyplumio-0.6.7/.github/workflows/ci.yml +0 -50
- pyplumio-0.6.7/.github/workflows/codeql.yml +0 -103
- pyplumio-0.6.7/.github/workflows/deploy.yml +0 -41
- pyplumio-0.6.7/.github/workflows/documentation.yml +0 -44
- pyplumio-0.6.7/.pre-commit-config.yaml +0 -18
- pyplumio-0.6.7/.qlty/qlty.toml +0 -99
- pyplumio-0.6.7/.vscode/settings.json +0 -16
- pyplumio-0.6.7/MANIFEST.in +0 -4
- pyplumio-0.6.7/PyPlumIO.egg-info/PKG-INFO +0 -132
- pyplumio-0.6.7/PyPlumIO.egg-info/SOURCES.txt +0 -148
- pyplumio-0.6.7/PyPlumIO.egg-info/dependency_links.txt +0 -1
- pyplumio-0.6.7/PyPlumIO.egg-info/requires.txt +0 -24
- pyplumio-0.6.7/PyPlumIO.egg-info/top_level.txt +0 -1
- pyplumio-0.6.7/images/ecomax.png +0 -0
- pyplumio-0.6.7/images/rs485.png +0 -0
- pyplumio-0.6.7/pyplumio/__init__.py +0 -117
- pyplumio-0.6.7/pyplumio/_version.py +0 -34
- pyplumio-0.6.7/pyplumio/helpers/__init__.py +0 -1
- pyplumio-0.6.7/pyplumio/py.typed +0 -0
- pyplumio-0.6.7/pyplumio/structures/__init__.py +0 -52
- pyplumio-0.6.7/requirements.txt +0 -1
- pyplumio-0.6.7/requirements_docs.txt +0 -3
- pyplumio-0.6.7/requirements_test.txt +0 -13
- pyplumio-0.6.7/setup.cfg +0 -4
- pyplumio-0.6.7/tests/test_init.py +0 -25
- {pyplumio-0.6.7 → pyplumio-0.7.0}/LICENSE +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/Makefile +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/make.bat +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/source/conf.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/docs/source/protocol.rst +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/devices/ecoster.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/devices/mixer.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/devices/thermostat.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/exceptions.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/helpers/task_manager.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/pyplumio/parameters/custom/__init__.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/__init__.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/devices/__init__.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/devices/test_ecoster.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/devices/test_mixer.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/devices/test_thermostat.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/helpers/__init__.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/helpers/test_async_cache.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/helpers/test_event_manager.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/helpers/test_task_manager.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/parameters/__init__.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/parameters/custom/__init__.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/parameters/custom/test_ecomax_860d3_hb.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/parameters/custom/test_init.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/parameters/test_mixers.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/parameters/test_thermostats.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/ruff.toml +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/structures/__init__.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/structures/test_schedules.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/test_protocol.py +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/messages/regulator_data.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/messages/sensor_data.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/parameters/ecomax_860d3_hb.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/requests/alerts.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/requests/ecomax_control.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/requests/ecomax_parameters.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/requests/mixer_parameters.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/requests/set_ecomax_parameter.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/requests/set_mixer_parameter.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/requests/set_schedule.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/requests/set_thermostat_parameter.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/requests/thermostat_parameters.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/responses/alerts.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/responses/device_available.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/responses/ecomax_parameters.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/responses/mixer_parameters.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/responses/password.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/responses/program_version.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/responses/regulator_data_schema.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/responses/schedules.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/responses/thermostat_parameters.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/responses/uid.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/unknown/unknown_ecomax_parameter.json +0 -0
- {pyplumio-0.6.7 → pyplumio-0.7.0}/tests/testdata/unknown/unknown_mixer_parameter.json +0 -0
|
@@ -1,61 +1,39 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: PyPlumIO
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: PyPlumIO is a native ecoNET library for Plum ecoMAX controllers.
|
|
5
|
-
Author-email: Denis Paavilainen <denpa@denpa.pro>
|
|
6
|
-
License: MIT License
|
|
7
5
|
Project-URL: Documentation, https://pyplumio.denpa.pro
|
|
8
6
|
Project-URL: Source Code, https://github.com/denpamusic/PyPlumIO
|
|
9
7
|
Project-URL: Bug Tracker, https://github.com/denpamusic/PyPlumIO/issues
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
Author-email: Denis Paavilainen <denpa@denpa.pro>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: automation,heating,home
|
|
12
12
|
Classifier: Development Status :: 4 - Beta
|
|
13
13
|
Classifier: Intended Audience :: Developers
|
|
14
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
15
14
|
Classifier: Operating System :: OS Independent
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
17
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
18
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
18
|
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
-
Classifier: Topic :: Software Development :: Libraries
|
|
22
19
|
Classifier: Topic :: Home Automation
|
|
23
|
-
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: serialx>=1.14.0
|
|
24
24
|
Description-Content-Type: text/markdown
|
|
25
|
-
License-File: LICENSE
|
|
26
|
-
Requires-Dist: pyserial-asyncio==0.6
|
|
27
|
-
Provides-Extra: test
|
|
28
|
-
Requires-Dist: codespell==2.4.1; extra == "test"
|
|
29
|
-
Requires-Dist: coverage==7.12.0; extra == "test"
|
|
30
|
-
Requires-Dist: freezegun==1.5.5; extra == "test"
|
|
31
|
-
Requires-Dist: mypy==1.19.0; extra == "test"
|
|
32
|
-
Requires-Dist: numpy<3.0.0,>=2.0.0; extra == "test"
|
|
33
|
-
Requires-Dist: pyserial-asyncio-fast==0.16; extra == "test"
|
|
34
|
-
Requires-Dist: pytest==9.0.1; extra == "test"
|
|
35
|
-
Requires-Dist: pytest-asyncio==1.3.0; extra == "test"
|
|
36
|
-
Requires-Dist: ruff==0.14.7; extra == "test"
|
|
37
|
-
Requires-Dist: tox==4.32.0; extra == "test"
|
|
38
|
-
Requires-Dist: types-pyserial==3.5.0.20251001; extra == "test"
|
|
39
|
-
Provides-Extra: docs
|
|
40
|
-
Requires-Dist: sphinx==8.1.3; extra == "docs"
|
|
41
|
-
Requires-Dist: sphinx_rtd_theme==3.0.2; extra == "docs"
|
|
42
|
-
Requires-Dist: readthedocs-sphinx-search==0.3.2; extra == "docs"
|
|
43
|
-
Provides-Extra: dev
|
|
44
|
-
Requires-Dist: pyplumio[docs,test]; extra == "dev"
|
|
45
|
-
Requires-Dist: pre-commit==4.5.0; extra == "dev"
|
|
46
|
-
Requires-Dist: tomli==2.3.0; extra == "dev"
|
|
47
|
-
Dynamic: license-file
|
|
48
25
|
|
|
49
26
|
# PyPlumIO is a native ecoNET library for Plum ecoMAX controllers
|
|
50
27
|
|
|
51
28
|
[](https://badge.fury.io/py/PyPlumIO)
|
|
52
29
|
[](https://pypi.python.org/pypi/pyplumio/)
|
|
53
|
-
[](https://github.com/denpamusic/PyPlumIO/actions/workflows/ci.yml)
|
|
54
30
|
[](https://qlty.sh/gh/denpamusic/projects/PyPlumIO)
|
|
55
31
|
[](https://qlty.sh/gh/denpamusic/projects/PyPlumIO)
|
|
56
32
|
[](https://guidelines.denpa.pro/stability#release-candidate)
|
|
57
33
|
[](https://github.com/astral-sh/ruff)
|
|
58
34
|
|
|
35
|
+
---
|
|
36
|
+
|
|
59
37
|
## Overview
|
|
60
38
|
|
|
61
39
|
This package aims to provide complete and easy to use solution for
|
|
@@ -89,16 +67,18 @@ through network by using RS-485 to Ethernet/WiFi converter.
|
|
|
89
67
|
|
|
90
68
|
## Quickstart
|
|
91
69
|
|
|
92
|
-
1. To use PyPlumIO, first install it using pip:
|
|
70
|
+
1. To use PyPlumIO, first install it using [uv](https://docs.astral.sh/uv/) or pip:
|
|
93
71
|
|
|
94
72
|
```bash
|
|
73
|
+
uv add pyplumio
|
|
74
|
+
# or
|
|
95
75
|
pip install pyplumio
|
|
96
76
|
```
|
|
97
77
|
|
|
98
78
|
2. Connect to the ecoMAX controller:
|
|
99
79
|
|
|
100
80
|
```python
|
|
101
|
-
>>> connection = pyplumio.
|
|
81
|
+
>>> connection = pyplumio.serial_for_url("/dev/ttyUSB0")
|
|
102
82
|
>>> await connection.connect()
|
|
103
83
|
>>> ecomax = await connection.get("ecomax")
|
|
104
84
|
```
|
|
@@ -122,6 +102,54 @@ this package and depends on it. Click button below to check it out.
|
|
|
122
102
|
|
|
123
103
|
[](https://github.com/denpamusic/homeassistant-plum-ecomax)
|
|
124
104
|
|
|
105
|
+
## Development
|
|
106
|
+
|
|
107
|
+
This project uses [uv](https://docs.astral.sh/uv/) for project and dependency management, and [prek](https://github.com/j178/prek) for Git hooks.
|
|
108
|
+
|
|
109
|
+
### Setup
|
|
110
|
+
|
|
111
|
+
Install the project and development dependencies:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
uv sync
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Running Tests
|
|
118
|
+
|
|
119
|
+
Run the test suite with coverage enforcement (100% required):
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
uv run pytest
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Code Quality & Formatting
|
|
126
|
+
|
|
127
|
+
Run linters, format checks, and cognitive complexity analysis:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
uv run codespell
|
|
131
|
+
uv run ruff check .
|
|
132
|
+
uv run ruff format --check .
|
|
133
|
+
uv run complexipy . --max-complexity-allowed 15
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Type Checking
|
|
137
|
+
|
|
138
|
+
Run type checking with mypy:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
uv run mypy pyplumio tests
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Git Hooks
|
|
145
|
+
|
|
146
|
+
Install and run Git hooks via prek:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
prek install
|
|
150
|
+
prek run --all-files
|
|
151
|
+
```
|
|
152
|
+
|
|
125
153
|
## Attribution
|
|
126
154
|
|
|
127
155
|
Special thanks to [econetanalyze](https://github.com/twkrol/econetanalyze)
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/py/PyPlumIO)
|
|
4
4
|
[](https://pypi.python.org/pypi/pyplumio/)
|
|
5
|
-
[](https://github.com/denpamusic/PyPlumIO/actions/workflows/ci.yml)
|
|
6
5
|
[](https://qlty.sh/gh/denpamusic/projects/PyPlumIO)
|
|
7
6
|
[](https://qlty.sh/gh/denpamusic/projects/PyPlumIO)
|
|
8
7
|
[](https://guidelines.denpa.pro/stability#release-candidate)
|
|
9
8
|
[](https://github.com/astral-sh/ruff)
|
|
10
9
|
|
|
10
|
+
---
|
|
11
|
+
|
|
11
12
|
## Overview
|
|
12
13
|
|
|
13
14
|
This package aims to provide complete and easy to use solution for
|
|
@@ -41,16 +42,18 @@ through network by using RS-485 to Ethernet/WiFi converter.
|
|
|
41
42
|
|
|
42
43
|
## Quickstart
|
|
43
44
|
|
|
44
|
-
1. To use PyPlumIO, first install it using pip:
|
|
45
|
+
1. To use PyPlumIO, first install it using [uv](https://docs.astral.sh/uv/) or pip:
|
|
45
46
|
|
|
46
47
|
```bash
|
|
48
|
+
uv add pyplumio
|
|
49
|
+
# or
|
|
47
50
|
pip install pyplumio
|
|
48
51
|
```
|
|
49
52
|
|
|
50
53
|
2. Connect to the ecoMAX controller:
|
|
51
54
|
|
|
52
55
|
```python
|
|
53
|
-
>>> connection = pyplumio.
|
|
56
|
+
>>> connection = pyplumio.serial_for_url("/dev/ttyUSB0")
|
|
54
57
|
>>> await connection.connect()
|
|
55
58
|
>>> ecomax = await connection.get("ecomax")
|
|
56
59
|
```
|
|
@@ -74,6 +77,54 @@ this package and depends on it. Click button below to check it out.
|
|
|
74
77
|
|
|
75
78
|
[](https://github.com/denpamusic/homeassistant-plum-ecomax)
|
|
76
79
|
|
|
80
|
+
## Development
|
|
81
|
+
|
|
82
|
+
This project uses [uv](https://docs.astral.sh/uv/) for project and dependency management, and [prek](https://github.com/j178/prek) for Git hooks.
|
|
83
|
+
|
|
84
|
+
### Setup
|
|
85
|
+
|
|
86
|
+
Install the project and development dependencies:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
uv sync
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Running Tests
|
|
93
|
+
|
|
94
|
+
Run the test suite with coverage enforcement (100% required):
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
uv run pytest
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Code Quality & Formatting
|
|
101
|
+
|
|
102
|
+
Run linters, format checks, and cognitive complexity analysis:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
uv run codespell
|
|
106
|
+
uv run ruff check .
|
|
107
|
+
uv run ruff format --check .
|
|
108
|
+
uv run complexipy . --max-complexity-allowed 15
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Type Checking
|
|
112
|
+
|
|
113
|
+
Run type checking with mypy:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
uv run mypy pyplumio tests
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Git Hooks
|
|
120
|
+
|
|
121
|
+
Install and run Git hooks via prek:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
prek install
|
|
125
|
+
prek run --all-files
|
|
126
|
+
```
|
|
127
|
+
|
|
77
128
|
## Attribution
|
|
78
129
|
|
|
79
130
|
Special thanks to [econetanalyze](https://github.com/twkrol/econetanalyze)
|
|
@@ -96,6 +96,10 @@ value is changed.
|
|
|
96
96
|
This filter await the callback on signifacant changes only.
|
|
97
97
|
Significance is defined by ``tolerance`` argument (i. e. tolerance=0.1
|
|
98
98
|
will only await callback when value is changed by more that 0.1).
|
|
99
|
+
For Number parameters a change of min or max value always awaits the
|
|
100
|
+
callback; tolerance applies to the value only.
|
|
101
|
+
The ``on_change``, ``debounce`` and ``delta`` filters also treat a min or
|
|
102
|
+
max change as a change, so ``delta`` may await the callback with 0.
|
|
99
103
|
|
|
100
104
|
.. code-block:: python
|
|
101
105
|
|
|
@@ -177,7 +181,7 @@ processing.
|
|
|
177
181
|
|
|
178
182
|
async def main():
|
|
179
183
|
"""Subscribes callback to the current heating temperature."""
|
|
180
|
-
async with pyplumio.
|
|
184
|
+
async with pyplumio.serial_for_url("socket://localhost:8899") as conn:
|
|
181
185
|
async with conn.device("ecomax") as ecomax:
|
|
182
186
|
# Await the callback on value change but no faster than
|
|
183
187
|
# once per 5 seconds.
|
|
@@ -207,7 +211,7 @@ current heating temperature on every SensorDataMessage.
|
|
|
207
211
|
|
|
208
212
|
async def main():
|
|
209
213
|
"""Subscribes callback to the current heating temperature."""
|
|
210
|
-
async with pyplumio.
|
|
214
|
+
async with pyplumio.serial_for_url("socket://localhost:8899") as conn:
|
|
211
215
|
async with conn.device("ecomax") as ecomax:
|
|
212
216
|
# Subscribe my_callback to heating_temp event.
|
|
213
217
|
ecomax.subscribe("heating_temp", my_callback)
|
|
@@ -240,7 +244,7 @@ when heating temperature will change more the 0.1 degrees Celsius.
|
|
|
240
244
|
|
|
241
245
|
async def main():
|
|
242
246
|
"""Subscribes callback to the current heating temperature."""
|
|
243
|
-
async with pyplumio.
|
|
247
|
+
async with pyplumio.serial_for_url("socket://localhost:8899") as conn:
|
|
244
248
|
async with conn.device("ecomax") as ecomax:
|
|
245
249
|
# Subscribe my_callback to heating_target_temp event.
|
|
246
250
|
ecomax.subscribe_once("heating_target_temp", my_callback)
|
|
@@ -4,41 +4,30 @@ Connecting
|
|
|
4
4
|
Opening the connection
|
|
5
5
|
----------------------
|
|
6
6
|
|
|
7
|
-
.. autofunction:: pyplumio.
|
|
7
|
+
.. autofunction:: pyplumio.serial_for_url
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
You can connect to the ecoMAX controller via physical connection through
|
|
10
|
+
RS-485 to USB or RS-485 to TTL adapters, that are connected directly
|
|
11
|
+
to the device running PyPlumIO or wirelessly through tcp socket.
|
|
12
|
+
|
|
13
|
+
You MUST not connect RS-485 lines directly to the UART outputs of your
|
|
14
|
+
PC or you'll risk damaging your PC/controller or the ecoMAX controller itself.
|
|
12
15
|
|
|
13
16
|
.. code-block:: python
|
|
14
17
|
|
|
15
18
|
import pyplumio
|
|
16
19
|
|
|
17
|
-
async with pyplumio.
|
|
20
|
+
async with pyplumio.serial_for_url("/dev/ttyUSB0") as conn:
|
|
21
|
+
...
|
|
22
|
+
|
|
23
|
+
async with pyplumio.serial_for_url("socket://localhost:8899") as conn:
|
|
18
24
|
...
|
|
19
|
-
|
|
20
25
|
|
|
21
26
|
.. note::
|
|
22
27
|
|
|
23
28
|
Although **async with** syntax is preferred, you can initiate connection without it.
|
|
24
29
|
See following :ref:`examples<Connection Examples>` for more information.
|
|
25
30
|
|
|
26
|
-
.. autofunction:: pyplumio.open_serial_connection
|
|
27
|
-
|
|
28
|
-
You can connect to the ecoMAX controller via wired connection through
|
|
29
|
-
RS-485 to USB or RS-485 to TTL adapters, that are connected directly
|
|
30
|
-
to the device running PyPlumIO.
|
|
31
|
-
|
|
32
|
-
You MUST not connect RS-485 lines directly to the UART outputs of your
|
|
33
|
-
PC or you'll risk damaging your PC/controller or the ecoMAX controller itself.
|
|
34
|
-
|
|
35
|
-
.. code-block:: python
|
|
36
|
-
|
|
37
|
-
import pyplumio
|
|
38
|
-
|
|
39
|
-
async with pyplumio.open_serial_connection("/dev/ttyUSB0", baudrate=115200) as conn:
|
|
40
|
-
...
|
|
41
|
-
|
|
42
31
|
Protocols
|
|
43
32
|
---------
|
|
44
33
|
|
|
@@ -62,14 +51,12 @@ working with device classes and queues.
|
|
|
62
51
|
import asyncio
|
|
63
52
|
|
|
64
53
|
import pyplumio
|
|
65
|
-
from pyplumio
|
|
66
|
-
from pyplumio.frames import requests, responses
|
|
54
|
+
from pyplumio import DeviceType, DummyProtocol, requests, responses
|
|
67
55
|
|
|
68
56
|
|
|
69
57
|
async def main():
|
|
70
58
|
"""Open a connection and request alerts."""
|
|
71
|
-
async with pyplumio.
|
|
72
|
-
host="localhost", port=8899, protocol=pyplumio.DummyProtocol()
|
|
59
|
+
async with pyplumio.serial_for_url("socket://localhost:8899", protocol=DummyProtocol()
|
|
73
60
|
) as conn:
|
|
74
61
|
await conn.writer.write(
|
|
75
62
|
requests.AlertsRequest(recipient=DeviceType.ECOMAX, start=0, count=5)
|
|
@@ -116,21 +103,25 @@ In the example below, we'll set both ethernet and wireless parameters.
|
|
|
116
103
|
.. code-block:: python
|
|
117
104
|
|
|
118
105
|
import pyplumio
|
|
119
|
-
from pyplumio
|
|
106
|
+
from pyplumio import (
|
|
107
|
+
AsyncProtocol,
|
|
108
|
+
EthernetParameters,
|
|
109
|
+
WirelessParameters,
|
|
110
|
+
EncryptionType
|
|
111
|
+
)
|
|
120
112
|
|
|
121
113
|
|
|
122
114
|
async def main():
|
|
123
115
|
"""Initialize a connection with network parameters."""
|
|
124
|
-
async with pyplumio.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
ethernet_parameters=pyplumio.EthernetParameters(
|
|
116
|
+
async with pyplumio.serial_for_url(
|
|
117
|
+
"socket://localhost:8899",
|
|
118
|
+
protocol=AsyncProtocol(
|
|
119
|
+
ethernet_parameters=EthernetParameters(
|
|
129
120
|
ip="10.10.1.100",
|
|
130
121
|
netmask="255.255.255.0",
|
|
131
122
|
gateway="10.10.1.1",
|
|
132
123
|
),
|
|
133
|
-
wireless_parameters=
|
|
124
|
+
wireless_parameters=WirelessParameters(
|
|
134
125
|
ip="10.10.2.100",
|
|
135
126
|
netmask="255.255.255.0",
|
|
136
127
|
gateway="10.10.2.1",
|
|
@@ -176,7 +167,7 @@ connection.
|
|
|
176
167
|
|
|
177
168
|
async def main():
|
|
178
169
|
"""Print connection statistics."""
|
|
179
|
-
async with pyplumio.
|
|
170
|
+
async with pyplumio.serial_for_url("socket://localhost:8899") as conn:
|
|
180
171
|
print(conn.statistics)
|
|
181
172
|
...
|
|
182
173
|
|
|
@@ -199,12 +190,12 @@ context manager.
|
|
|
199
190
|
|
|
200
191
|
async def main():
|
|
201
192
|
"""Opens the connection and gets the ecoMAX device."""
|
|
202
|
-
async with pyplumio.
|
|
193
|
+
async with pyplumio.serial_for_url("socket://localhost:8899") as conn:
|
|
203
194
|
try:
|
|
204
195
|
# Get the ecoMAX device within 10 seconds or timeout.
|
|
205
196
|
async with conn.device("ecomax", timeout=10) as ecomax:
|
|
206
197
|
...
|
|
207
|
-
except
|
|
198
|
+
except TimeoutError:
|
|
208
199
|
# If device times out, log the error.
|
|
209
200
|
_LOGGER.error("Failed to get the device within 10 seconds")
|
|
210
201
|
|
|
@@ -228,7 +219,7 @@ using Python's context manager.
|
|
|
228
219
|
|
|
229
220
|
async def main():
|
|
230
221
|
"""Opens the connection and gets the ecoMAX device."""
|
|
231
|
-
connection = pyplumio.
|
|
222
|
+
connection = pyplumio.serial_for_url("socket://localhost:8899")
|
|
232
223
|
|
|
233
224
|
# Connect to the device.
|
|
234
225
|
await connection.connect()
|
|
@@ -237,7 +228,7 @@ using Python's context manager.
|
|
|
237
228
|
# Get the ecoMAX device within 10 seconds or timeout.
|
|
238
229
|
async with conn.device("ecomax", timeout=10) as ecomax:
|
|
239
230
|
...
|
|
240
|
-
except
|
|
231
|
+
except TimeoutError:
|
|
241
232
|
# If device times out, log the error.
|
|
242
233
|
_LOGGER.error("Failed to get the device within 10 seconds")
|
|
243
234
|
|
|
@@ -99,6 +99,60 @@ Handler
|
|
|
99
99
|
|
|
100
100
|
.. autoclass:: pyplumio.structures.ecomax_parameters.EcomaxParametersStructure
|
|
101
101
|
|
|
102
|
+
EcomaxExtendedParameters
|
|
103
|
+
------------------------
|
|
104
|
+
|
|
105
|
+
Get the ecoMAX controller editable parameters from the extended parameter
|
|
106
|
+
table. Newer controllers, such as ecoMAX 860P4-NM TOUCH, keep part of their
|
|
107
|
+
settings only in this table.
|
|
108
|
+
|
|
109
|
+
PyPlumIO requests this table only if the controller announces frame type 97
|
|
110
|
+
in the frame version table, and requests it again each time its version
|
|
111
|
+
changes.
|
|
112
|
+
|
|
113
|
+
Parameters are represented in the same way as in :ref:`ecomaxparameters`.
|
|
114
|
+
Raw parameters are available under the ``ecomax_extended_parameters`` key.
|
|
115
|
+
Parameters with known meaning are also available by name for verified
|
|
116
|
+
products only.
|
|
117
|
+
|
|
118
|
+
Request
|
|
119
|
+
^^^^^^^
|
|
120
|
+
|
|
121
|
+
.. autoattribute:: pyplumio.const.FrameType.REQUEST_ECOMAX_EXTENDED_PARAMETERS
|
|
122
|
+
|
|
123
|
+
.. list-table::
|
|
124
|
+
:widths: 20 65 10
|
|
125
|
+
:header-rows: 1
|
|
126
|
+
|
|
127
|
+
* - Name
|
|
128
|
+
- Description
|
|
129
|
+
- Default
|
|
130
|
+
* - start
|
|
131
|
+
- Parameter index to start on.
|
|
132
|
+
- 0
|
|
133
|
+
* - count
|
|
134
|
+
- Number of parameters to request.
|
|
135
|
+
- 255
|
|
136
|
+
|
|
137
|
+
Response
|
|
138
|
+
^^^^^^^^
|
|
139
|
+
|
|
140
|
+
.. autoattribute:: pyplumio.const.FrameType.RESPONSE_ECOMAX_EXTENDED_PARAMETERS
|
|
141
|
+
|
|
142
|
+
.. list-table::
|
|
143
|
+
:widths: 50 50
|
|
144
|
+
:header-rows: 1
|
|
145
|
+
|
|
146
|
+
* - Name
|
|
147
|
+
- Description
|
|
148
|
+
* - ecomax_extended_parameters
|
|
149
|
+
- Contains a list of ecomax extended parameters.
|
|
150
|
+
|
|
151
|
+
Handler
|
|
152
|
+
^^^^^^^
|
|
153
|
+
|
|
154
|
+
.. autoclass:: pyplumio.structures.ecomax_extended_parameters.EcomaxExtendedParametersStructure
|
|
155
|
+
|
|
102
156
|
MixerParameters
|
|
103
157
|
---------------
|
|
104
158
|
|
|
@@ -174,6 +228,46 @@ Response
|
|
|
174
228
|
|
|
175
229
|
.. autoattribute:: pyplumio.const.FrameType.RESPONSE_SET_ECOMAX_PARAMETER
|
|
176
230
|
|
|
231
|
+
SetEcomaxExtendedParameter
|
|
232
|
+
--------------------------
|
|
233
|
+
|
|
234
|
+
Set the editable parameter value in the extended parameter table.
|
|
235
|
+
|
|
236
|
+
The message is the number of values, the index of the first parameter and
|
|
237
|
+
the new raw values for consecutive indexes. In a panel capture, a single
|
|
238
|
+
write was ``01 <index> <value>`` and one frame ``05 3b 47 16 1e 0a 46`` set
|
|
239
|
+
indexes 0x3b to 0x3f to 71, 22, 30, 10 and 70. PyPlumIO always sets one
|
|
240
|
+
parameter per frame.
|
|
241
|
+
|
|
242
|
+
In captures, after every panel write the controller increased the frame
|
|
243
|
+
type 97 version in the regulator data frame version table within 1-3 seconds
|
|
244
|
+
(6, 7, 8, 9, 10, 11 for five writes), so PyPlumIO re-reads the extended
|
|
245
|
+
parameter table and confirms the set from it.
|
|
246
|
+
|
|
247
|
+
Request
|
|
248
|
+
^^^^^^^
|
|
249
|
+
|
|
250
|
+
.. autoattribute:: pyplumio.const.FrameType.REQUEST_SET_ECOMAX_EXTENDED_PARAMETER
|
|
251
|
+
|
|
252
|
+
.. list-table::
|
|
253
|
+
:widths: 20 65 10
|
|
254
|
+
:header-rows: 1
|
|
255
|
+
|
|
256
|
+
* - Name
|
|
257
|
+
- Description
|
|
258
|
+
- Default
|
|
259
|
+
* - index
|
|
260
|
+
- Parameter index.
|
|
261
|
+
-
|
|
262
|
+
* - value
|
|
263
|
+
- Value to set parameter to.
|
|
264
|
+
-
|
|
265
|
+
|
|
266
|
+
Response
|
|
267
|
+
^^^^^^^^
|
|
268
|
+
|
|
269
|
+
.. autoattribute:: pyplumio.const.FrameType.RESPONSE_SET_ECOMAX_EXTENDED_PARAMETER
|
|
270
|
+
|
|
177
271
|
SetMixerParameter
|
|
178
272
|
-----------------
|
|
179
273
|
|
|
@@ -19,15 +19,17 @@ RS-485 to Ethernet/WiFi converter.
|
|
|
19
19
|
|
|
20
20
|
Quickstart
|
|
21
21
|
==========
|
|
22
|
-
1. To use PyPlumIO, first install it using pip:
|
|
22
|
+
1. To use PyPlumIO, first install it using uv or pip:
|
|
23
23
|
|
|
24
24
|
.. code-block:: console
|
|
25
25
|
|
|
26
|
+
$ uv add pyplumio
|
|
27
|
+
# or
|
|
26
28
|
(.venv) $ pip install pyplumio
|
|
27
29
|
|
|
28
30
|
2. Connect to the ecoMAX controller:
|
|
29
31
|
|
|
30
|
-
>>> connection = pyplumio.
|
|
32
|
+
>>> connection = pyplumio.serial_for_url("/dev/ttyUSB0")
|
|
31
33
|
>>> await connection.connect()
|
|
32
34
|
>>> ecomax = await connection.get("ecomax")
|
|
33
35
|
|
|
@@ -32,7 +32,7 @@ get it's current_temp property and set it's target temperature to
|
|
|
32
32
|
|
|
33
33
|
.. code-block:: python
|
|
34
34
|
|
|
35
|
-
from pyplumio
|
|
35
|
+
from pyplumio import Mixer
|
|
36
36
|
|
|
37
37
|
async with conn.device("ecomax") as ecomax:
|
|
38
38
|
# Get connected mixers.
|
|
@@ -56,7 +56,7 @@ degrees Celsius.
|
|
|
56
56
|
|
|
57
57
|
.. code-block:: python
|
|
58
58
|
|
|
59
|
-
from pyplumio
|
|
59
|
+
from pyplumio import Thermostat
|
|
60
60
|
|
|
61
61
|
async with conn.device("ecomax") as ecomax:
|
|
62
62
|
# Get connected thermostats.
|
|
@@ -34,7 +34,7 @@ and close the connection.
|
|
|
34
34
|
|
|
35
35
|
async def main():
|
|
36
36
|
"""Read the current heating temperature."""
|
|
37
|
-
async with pyplumio.
|
|
37
|
+
async with pyplumio.serial_for_url("socket://localhost:8899") as conn:
|
|
38
38
|
# Get the ecoMAX device.
|
|
39
39
|
async with conn.device("ecomax") as ecomax:
|
|
40
40
|
# Get the heating temperature.
|
|
@@ -119,7 +119,7 @@ to the terminal.
|
|
|
119
119
|
"""Read current temp, target temp and device state from
|
|
120
120
|
the regdata.
|
|
121
121
|
"""
|
|
122
|
-
async with pyplumio.
|
|
122
|
+
async with pyplumio.serial_for_url("socket://localhost:8899") as conn:
|
|
123
123
|
# Get the ecoMAX device.
|
|
124
124
|
async with conn.device("ecomax") as ecomax:
|
|
125
125
|
# Get heating temperature, if it's available otherwise
|
|
@@ -60,11 +60,11 @@ switches back to daytime mode from 07:00 to 00:00.
|
|
|
60
60
|
await heating_schedule.commit()
|
|
61
61
|
|
|
62
62
|
For clarity sake, you might want to use ``STATE_OFF`` and
|
|
63
|
-
``STATE_ON`` constants
|
|
63
|
+
``STATE_ON`` constants.
|
|
64
64
|
|
|
65
65
|
.. code-block:: python
|
|
66
66
|
|
|
67
|
-
from pyplumio
|
|
67
|
+
from pyplumio import STATE_OFF
|
|
68
68
|
|
|
69
69
|
heating_schedule.monday["18:00"] = STATE_OFF
|
|
70
70
|
heating_schedule.monday.set_state(STATE_OFF, "00:00", "07:00")
|
|
@@ -110,12 +110,12 @@ Schedule Examples
|
|
|
110
110
|
.. code-block:: python
|
|
111
111
|
|
|
112
112
|
import pyplumio
|
|
113
|
-
from pyplumio
|
|
113
|
+
from pyplumio import STATE_ON, STATE_OFF
|
|
114
114
|
|
|
115
115
|
|
|
116
116
|
async def main():
|
|
117
117
|
"""Set a device schedule."""
|
|
118
|
-
async with pyplumio.
|
|
118
|
+
async with pyplumio.serial_for_url("socket://localhost:8899") as conn:
|
|
119
119
|
async with conn.device("ecomax") as ecomax:
|
|
120
120
|
schedules = await ecomax.get("schedules")
|
|
121
121
|
heating_schedule = schedules["heating"]
|
|
@@ -45,7 +45,7 @@ Numbers are parameters that have numerical value associated with them.
|
|
|
45
45
|
|
|
46
46
|
.. code-block:: python
|
|
47
47
|
|
|
48
|
-
from pyplumio
|
|
48
|
+
from pyplumio import Number
|
|
49
49
|
|
|
50
50
|
async with conn.device("ecomax") as ecomax:
|
|
51
51
|
heating_target: Number = ecomax.get("heating_target_temp")
|
|
@@ -61,7 +61,7 @@ Please note, that both values are **inclusive**.
|
|
|
61
61
|
|
|
62
62
|
.. code-block:: python
|
|
63
63
|
|
|
64
|
-
from pyplumio
|
|
64
|
+
from pyplumio import Number
|
|
65
65
|
|
|
66
66
|
async with conn.device("ecomax") as ecomax:
|
|
67
67
|
target_temp: Number = await ecomax.get("heating_target_temp")
|
|
@@ -95,7 +95,7 @@ object.
|
|
|
95
95
|
|
|
96
96
|
.. code-block:: python
|
|
97
97
|
|
|
98
|
-
from pyplumio
|
|
98
|
+
from pyplumio import Switch
|
|
99
99
|
|
|
100
100
|
# Get an ecomax_control parameter and turn it on.
|
|
101
101
|
ecomax_control: Switch = await ecomax.get("ecomax_control")
|
|
@@ -127,7 +127,7 @@ outputting the result to the terminal.
|
|
|
127
127
|
|
|
128
128
|
async def main():
|
|
129
129
|
"""Turn on the controller and set target temperature."""
|
|
130
|
-
async with pyplumio.
|
|
130
|
+
async with pyplumio.serial_for_url("socket://localhost:8899") as conn:
|
|
131
131
|
# Get the ecoMAX device.
|
|
132
132
|
async with conn.device("ecomax") as ecomax:
|
|
133
133
|
# Turn on controller without waiting for the result.
|