PyPlumIO 0.5.21__py3-none-any.whl → 0.5.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {PyPlumIO-0.5.21.dist-info → PyPlumIO-0.5.23.dist-info}/METADATA +12 -10
- PyPlumIO-0.5.23.dist-info/RECORD +60 -0
- {PyPlumIO-0.5.21.dist-info → PyPlumIO-0.5.23.dist-info}/WHEEL +1 -1
- pyplumio/__init__.py +2 -2
- pyplumio/_version.py +2 -2
- pyplumio/connection.py +3 -12
- pyplumio/devices/__init__.py +16 -16
- pyplumio/devices/ecomax.py +126 -126
- pyplumio/devices/mixer.py +50 -44
- pyplumio/devices/thermostat.py +36 -35
- pyplumio/exceptions.py +9 -9
- pyplumio/filters.py +56 -37
- pyplumio/frames/__init__.py +6 -6
- pyplumio/frames/messages.py +4 -6
- pyplumio/helpers/data_types.py +8 -7
- pyplumio/helpers/event_manager.py +53 -33
- pyplumio/helpers/parameter.py +138 -52
- pyplumio/helpers/task_manager.py +7 -2
- pyplumio/helpers/timeout.py +0 -3
- pyplumio/helpers/uid.py +2 -2
- pyplumio/protocol.py +35 -28
- pyplumio/stream.py +2 -2
- pyplumio/structures/alerts.py +40 -31
- pyplumio/structures/ecomax_parameters.py +493 -282
- pyplumio/structures/frame_versions.py +5 -6
- pyplumio/structures/lambda_sensor.py +6 -6
- pyplumio/structures/mixer_parameters.py +136 -71
- pyplumio/structures/network_info.py +2 -3
- pyplumio/structures/product_info.py +0 -4
- pyplumio/structures/program_version.py +24 -17
- pyplumio/structures/schedules.py +35 -15
- pyplumio/structures/thermostat_parameters.py +82 -50
- pyplumio/utils.py +12 -7
- PyPlumIO-0.5.21.dist-info/RECORD +0 -61
- pyplumio/helpers/typing.py +0 -29
- {PyPlumIO-0.5.21.dist-info → PyPlumIO-0.5.23.dist-info}/LICENSE +0 -0
- {PyPlumIO-0.5.21.dist-info → PyPlumIO-0.5.23.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: PyPlumIO
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.23
|
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
|
@@ -22,24 +22,26 @@ Classifier: Topic :: Home Automation
|
|
22
22
|
Requires-Python: >=3.9
|
23
23
|
Description-Content-Type: text/markdown
|
24
24
|
License-File: LICENSE
|
25
|
+
Requires-Dist: dataslots ==1.2.0
|
25
26
|
Requires-Dist: pyserial-asyncio ==0.6
|
27
|
+
Requires-Dist: typing-extensions ==4.12.2
|
26
28
|
Provides-Extra: dev
|
27
29
|
Requires-Dist: pyplumio[docs,test] ; extra == 'dev'
|
28
|
-
Requires-Dist: pre-commit ==3.
|
30
|
+
Requires-Dist: pre-commit ==3.8.0 ; extra == 'dev'
|
29
31
|
Requires-Dist: tomli ==2.0.1 ; extra == 'dev'
|
30
32
|
Provides-Extra: docs
|
31
|
-
Requires-Dist: sphinx ==7.
|
33
|
+
Requires-Dist: sphinx ==7.4.7 ; extra == 'docs'
|
32
34
|
Requires-Dist: sphinx-rtd-theme ==2.0.0 ; extra == 'docs'
|
33
35
|
Requires-Dist: readthedocs-sphinx-search ==0.3.2 ; extra == 'docs'
|
34
36
|
Provides-Extra: test
|
35
37
|
Requires-Dist: codespell ==2.3.0 ; extra == 'test'
|
36
|
-
Requires-Dist: coverage ==7.
|
37
|
-
Requires-Dist: mypy ==1.
|
38
|
-
Requires-Dist: pyserial-asyncio-fast ==0.
|
39
|
-
Requires-Dist: pytest ==8.
|
40
|
-
Requires-Dist: pytest-asyncio ==0.23.
|
41
|
-
Requires-Dist: ruff ==0.
|
42
|
-
Requires-Dist: tox ==4.
|
38
|
+
Requires-Dist: coverage ==7.6.0 ; extra == 'test'
|
39
|
+
Requires-Dist: mypy ==1.11.1 ; extra == 'test'
|
40
|
+
Requires-Dist: pyserial-asyncio-fast ==0.14 ; extra == 'test'
|
41
|
+
Requires-Dist: pytest ==8.3.2 ; extra == 'test'
|
42
|
+
Requires-Dist: pytest-asyncio ==0.23.8 ; extra == 'test'
|
43
|
+
Requires-Dist: ruff ==0.5.5 ; extra == 'test'
|
44
|
+
Requires-Dist: tox ==4.16.0 ; extra == 'test'
|
43
45
|
Requires-Dist: types-pyserial ==3.5.0.20240527 ; extra == 'test'
|
44
46
|
|
45
47
|
# PyPlumIO is a native ecoNET library for Plum ecoMAX controllers.
|
@@ -0,0 +1,60 @@
|
|
1
|
+
pyplumio/__init__.py,sha256=ditJTIOFGJDg60atHzOpiggdUrZHpSynno7MtpZUGVk,3299
|
2
|
+
pyplumio/__main__.py,sha256=3IwHHSq-iay5FaeMc95klobe-xv82yydSKcBE7BFZ6M,500
|
3
|
+
pyplumio/_version.py,sha256=aPxuFslDuZCOtDq4ZO2Aa91a5YZAmkPaBMygrLp3Bo8,413
|
4
|
+
pyplumio/connection.py,sha256=6mUbcjGxxEhMVIbzZgCqH-Ez-fcYoRj7ZbVSzpikpNA,5949
|
5
|
+
pyplumio/const.py,sha256=8rpiVbVb5R_6Rm6J2sgCnaVrkD-2Fzhd1RYMz0MBgwo,3915
|
6
|
+
pyplumio/exceptions.py,sha256=Wn-y5AJ5xfaBlHhTUVKB27_0Us8_OVHqh-sicnr9sYA,700
|
7
|
+
pyplumio/filters.py,sha256=IZkvrRAHdv6s3CplK73mHomRHpo3rnoyX2u26FVr9XU,11386
|
8
|
+
pyplumio/protocol.py,sha256=e6-ns5i5DWlFD5tKot-kQtmZt3CJMFK6zFa5RMIKshw,8140
|
9
|
+
pyplumio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
+
pyplumio/stream.py,sha256=IVCQFKBtRafRgUkr93p_wN5mXZAD3Jw1d091dfEIK20,4479
|
11
|
+
pyplumio/utils.py,sha256=TnBzRopinyp92wruguijxcIYmaeyNVTFX0dygI5FCMU,823
|
12
|
+
pyplumio/devices/__init__.py,sha256=sb4wFJSM-j1rwJGQ0G7RSCF1t9-ZEwKzJl9mFrSr0EI,6564
|
13
|
+
pyplumio/devices/ecomax.py,sha256=jaIX0LySnryPrwFsYH4ES7U52P3ZaAxTdMKJAJ_XY5Q,16949
|
14
|
+
pyplumio/devices/ecoster.py,sha256=J4YtPmFmFwaq4LzYf28aMmB97cRAbMsVyUdBLGki42g,313
|
15
|
+
pyplumio/devices/mixer.py,sha256=pxZXoAOrZ52OxMirZdoCtbJ4b2yHg1A2Kn_QPZZqynQ,3271
|
16
|
+
pyplumio/devices/thermostat.py,sha256=9jI_cacIQoFq_ImAqAYhcnAx7PVO3FWZz4WdfatGNiw,2607
|
17
|
+
pyplumio/frames/__init__.py,sha256=uMjLWY0rCbCTBfXafA_TSfLORYBT0wLyhHSZEePsRxw,7504
|
18
|
+
pyplumio/frames/messages.py,sha256=7vyOjcxGDnaRlyB4jPsCt00yCc3Axme8NN7uK922DS8,3622
|
19
|
+
pyplumio/frames/requests.py,sha256=Ra8xH5oKYhkEUtadN-9ZsJKkt5xZkz5O7edQVsDhNsM,7221
|
20
|
+
pyplumio/frames/responses.py,sha256=j4awA2-MfsoPdENC4Fvae4_Oa70rDhH19ebmEoAqhh8,6532
|
21
|
+
pyplumio/helpers/__init__.py,sha256=H2xxdkF-9uADLwEbfBUoxNTdwru3L5Z2cfJjgsuRsn0,31
|
22
|
+
pyplumio/helpers/data_types.py,sha256=5yxHCnsoKLw5kBM3s6SxwsuKs1C0yK2khyeSrrPXQsQ,8255
|
23
|
+
pyplumio/helpers/event_manager.py,sha256=yH_VjEvIkuYwk31qb3rXtFDfKAStbA-YWWc4ED17jVI,6443
|
24
|
+
pyplumio/helpers/factory.py,sha256=eiTkYUCernUn0VNDDdEN4IyjNPrXK8vnJESXyLaqFzE,1017
|
25
|
+
pyplumio/helpers/parameter.py,sha256=d57e7Y04hnlQjMiZNkU-yPlBUQASdwbkZFp0LIan2Ig,10858
|
26
|
+
pyplumio/helpers/schedule.py,sha256=-IZJ-CU4PhFlsE586wTw--ovDrTo2Hs4JneCHhc0e-Y,5013
|
27
|
+
pyplumio/helpers/task_manager.py,sha256=HAd69yGTRL0zQsu-ywnbLu1UXiJzgHWuhYWA--vs4lQ,1181
|
28
|
+
pyplumio/helpers/timeout.py,sha256=XM58yaz93cNsxW7Ok6hfBw8i_92HdsGFQVBhpqbCZ70,770
|
29
|
+
pyplumio/helpers/uid.py,sha256=J7gN8i8LE0g6tfL66BJbwsQQqzBBxWx7giyvqaJh4BM,976
|
30
|
+
pyplumio/structures/__init__.py,sha256=EjK-5qJZ0F7lpP2b6epvTMg9cIBl4Kn91nqNkEcLwTc,1299
|
31
|
+
pyplumio/structures/alerts.py,sha256=wX58xWr1dJgZiQtEEMLRu8bcu6dTcc-aqEIY69gYGu0,3640
|
32
|
+
pyplumio/structures/boiler_load.py,sha256=p3mOzZUU-g7A2tG_yp8podEqpI81hlsOZmHELyPNRY8,838
|
33
|
+
pyplumio/structures/boiler_power.py,sha256=72qsvccg49FdRdXv2f2K5sGpjT7wAOLFjlIGWpO-DVg,901
|
34
|
+
pyplumio/structures/ecomax_parameters.py,sha256=a7sq2yhUSt6XiZWv48KkClWyjxsGAEJbES13-sx6G78,27710
|
35
|
+
pyplumio/structures/fan_power.py,sha256=Q5fv-7_2NVuLeQPIVIylvgN7M8-a9D8rRUE0QGjyS3w,871
|
36
|
+
pyplumio/structures/frame_versions.py,sha256=OMWU8tjnsrRWQsMSbmCJCmiKDwBmA75BcPZ6CqvKMLc,1566
|
37
|
+
pyplumio/structures/fuel_consumption.py,sha256=_p2dI4H67Eopn7IF0Gj77A8c_8lNKhhDDAtmugxLd4s,976
|
38
|
+
pyplumio/structures/fuel_level.py,sha256=mJpp1dnRD1wXi_6EyNX7TNXosjcr905rSHOnuZ5VD74,1069
|
39
|
+
pyplumio/structures/lambda_sensor.py,sha256=JNSCiBJoM8Uk3OGbmFIigaLOntQST5U_UrmCpaQBlM0,1595
|
40
|
+
pyplumio/structures/mixer_parameters.py,sha256=BQXC6vHx_b0OL-T6IU3bi2trjarLmlcMU1mmM5Q3AbI,8871
|
41
|
+
pyplumio/structures/mixer_sensors.py,sha256=O91929Ts1YXFmKdPRc1r_BYDgrqkv5QVtE1nGzLpuAI,2260
|
42
|
+
pyplumio/structures/modules.py,sha256=ukju4TQmRRJfgl94QU4zytZLU5px8nw3sgfSLn9JysU,2520
|
43
|
+
pyplumio/structures/network_info.py,sha256=rxGoTdjlUmgEzR4BjOh9XQgEqKI6OSIbhOJ8tsXocts,4063
|
44
|
+
pyplumio/structures/output_flags.py,sha256=07N0kxlvR5WZAURuChk_BqSiXR8eaQrtI5qlkgCf4Yc,1345
|
45
|
+
pyplumio/structures/outputs.py,sha256=1xsJPkjN643-aFawqVoupGatUIUJfQG_g252n051Qi0,1916
|
46
|
+
pyplumio/structures/pending_alerts.py,sha256=Uq9WpB4MW9AhDkqmDhk-g0J0h4pVq0Q50z12dYEv6kY,739
|
47
|
+
pyplumio/structures/product_info.py,sha256=uiEN6DFQlzmBvQByTirFzXQShoex0YGdFS9WI-MAxPc,2405
|
48
|
+
pyplumio/structures/program_version.py,sha256=p3Hzn1igxGyZ99jJjPswNGCAAQdJ5_-sgZPIy-MGISI,2506
|
49
|
+
pyplumio/structures/regulator_data.py,sha256=Dun3RjfHHoV2W5RTSQcAimBL0Or3O957vYQj7Pbi7CM,2309
|
50
|
+
pyplumio/structures/regulator_data_schema.py,sha256=BMshEpiP-lwTgSkbTuow9KlxCwKwQXV0nFPcBpW0SJg,1505
|
51
|
+
pyplumio/structures/schedules.py,sha256=tm5DVCUnJ3FTUMl8wPGgM5_DsL_9R_UQqx5bfPAuvUM,6717
|
52
|
+
pyplumio/structures/statuses.py,sha256=wkoynyMRr1VREwfBC6vU48kPA8ZQ83pcXuciy2xHJrk,1166
|
53
|
+
pyplumio/structures/temperatures.py,sha256=1CDzehNmbALz1Jyt_9gZNIk52q6Wv-xQXjijVDCVYec,2337
|
54
|
+
pyplumio/structures/thermostat_parameters.py,sha256=ybsab49teETR8pMsSCmPidNe5IclTq8tj7uxtHXGEAY,8045
|
55
|
+
pyplumio/structures/thermostat_sensors.py,sha256=ZmjWgYtTZ5M8Lnz_Q5N4JD8G3MvEmByPFjYsy6XZOmo,3177
|
56
|
+
PyPlumIO-0.5.23.dist-info/LICENSE,sha256=m-UuZFjXJ22uPTGm9kSHS8bqjsf5T8k2wL9bJn1Y04o,1088
|
57
|
+
PyPlumIO-0.5.23.dist-info/METADATA,sha256=yArChsVdmu73qgqL-aEc5ht30pmV9-7shz719yTTzSs,5490
|
58
|
+
PyPlumIO-0.5.23.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
59
|
+
PyPlumIO-0.5.23.dist-info/top_level.txt,sha256=kNBz9UPPkPD9teDn3U_sEy5LjzwLm9KfADCXtBlbw8A,9
|
60
|
+
PyPlumIO-0.5.23.dist-info/RECORD,,
|
pyplumio/__init__.py
CHANGED
@@ -10,7 +10,7 @@ from pyplumio.exceptions import (
|
|
10
10
|
ChecksumError,
|
11
11
|
ConnectionFailedError,
|
12
12
|
FrameDataError,
|
13
|
-
|
13
|
+
ProtocolError,
|
14
14
|
PyPlumIOError,
|
15
15
|
ReadError,
|
16
16
|
UnknownDeviceError,
|
@@ -97,8 +97,8 @@ __all__ = [
|
|
97
97
|
"EthernetParameters",
|
98
98
|
"Frame",
|
99
99
|
"FrameDataError",
|
100
|
-
"FrameError",
|
101
100
|
"Protocol",
|
101
|
+
"ProtocolError",
|
102
102
|
"PyPlumIOError",
|
103
103
|
"ReadError",
|
104
104
|
"SerialConnection",
|
pyplumio/_version.py
CHANGED
pyplumio/connection.py
CHANGED
@@ -4,7 +4,6 @@ from __future__ import annotations
|
|
4
4
|
|
5
5
|
from abc import ABC, abstractmethod
|
6
6
|
import asyncio
|
7
|
-
from collections.abc import MutableMapping
|
8
7
|
import logging
|
9
8
|
from typing import Any, Final, cast
|
10
9
|
|
@@ -36,7 +35,7 @@ class Connection(ABC, TaskManager):
|
|
36
35
|
|
37
36
|
_protocol: Protocol
|
38
37
|
_reconnect_on_failure: bool
|
39
|
-
_kwargs:
|
38
|
+
_kwargs: dict[str, Any]
|
40
39
|
|
41
40
|
def __init__(
|
42
41
|
self,
|
@@ -131,11 +130,7 @@ class TcpConnection(Connection):
|
|
131
130
|
**kwargs: Any,
|
132
131
|
) -> None:
|
133
132
|
"""Initialize a new TCP connection."""
|
134
|
-
super().__init__(
|
135
|
-
protocol,
|
136
|
-
reconnect_on_failure,
|
137
|
-
**kwargs,
|
138
|
-
)
|
133
|
+
super().__init__(protocol, reconnect_on_failure, **kwargs)
|
139
134
|
self.host = host
|
140
135
|
self.port = port
|
141
136
|
|
@@ -171,11 +166,7 @@ class SerialConnection(Connection):
|
|
171
166
|
**kwargs: Any,
|
172
167
|
) -> None:
|
173
168
|
"""Initialize a new serial connection."""
|
174
|
-
super().__init__(
|
175
|
-
protocol,
|
176
|
-
reconnect_on_failure,
|
177
|
-
**kwargs,
|
178
|
-
)
|
169
|
+
super().__init__(protocol, reconnect_on_failure, **kwargs)
|
179
170
|
self.device = device
|
180
171
|
self.baudrate = baudrate
|
181
172
|
|
pyplumio/devices/__init__.py
CHANGED
@@ -13,8 +13,7 @@ from pyplumio.exceptions import UnknownDeviceError
|
|
13
13
|
from pyplumio.frames import DataFrameDescription, Frame, Request
|
14
14
|
from pyplumio.helpers.event_manager import EventManager
|
15
15
|
from pyplumio.helpers.factory import create_instance
|
16
|
-
from pyplumio.helpers.parameter import SET_RETRIES, Parameter
|
17
|
-
from pyplumio.helpers.typing import ParameterValueType
|
16
|
+
from pyplumio.helpers.parameter import SET_RETRIES, Parameter, ParameterValueType
|
18
17
|
from pyplumio.structures.network_info import NetworkInfo
|
19
18
|
from pyplumio.utils import to_camelcase
|
20
19
|
|
@@ -45,9 +44,9 @@ def get_device_handler(device_type: int) -> str:
|
|
45
44
|
class Device(ABC, EventManager):
|
46
45
|
"""Represents a device."""
|
47
46
|
|
48
|
-
queue: asyncio.Queue
|
47
|
+
queue: asyncio.Queue[Frame]
|
49
48
|
|
50
|
-
def __init__(self, queue: asyncio.Queue):
|
49
|
+
def __init__(self, queue: asyncio.Queue[Frame]):
|
51
50
|
"""Initialize a new device."""
|
52
51
|
super().__init__()
|
53
52
|
self.queue = queue
|
@@ -64,7 +63,7 @@ class Device(ABC, EventManager):
|
|
64
63
|
:param name: Name of the parameter
|
65
64
|
:type name: str
|
66
65
|
:param value: New value for the parameter
|
67
|
-
:type value: int | float | bool | Literal["
|
66
|
+
:type value: int | float | bool | Literal["off", "on"]
|
68
67
|
:param timeout: Wait this amount of seconds for confirmation,
|
69
68
|
defaults to `None`
|
70
69
|
:type timeout: float, optional
|
@@ -96,7 +95,7 @@ class Device(ABC, EventManager):
|
|
96
95
|
:param name: Name of the parameter
|
97
96
|
:type name: str
|
98
97
|
:param value: New value for the parameter
|
99
|
-
:type value: int | float | bool | Literal["
|
98
|
+
:type value: int | float | bool | Literal["off", "on"]
|
100
99
|
:param timeout: Wait this amount of seconds for confirmation.
|
101
100
|
As this method operates in the background without waiting,
|
102
101
|
this value is used to determine failure when
|
@@ -124,7 +123,7 @@ class AddressableDevice(Device, ABC):
|
|
124
123
|
_network: NetworkInfo
|
125
124
|
_setup_frames: Iterable[DataFrameDescription]
|
126
125
|
|
127
|
-
def __init__(self, queue: asyncio.Queue, network: NetworkInfo):
|
126
|
+
def __init__(self, queue: asyncio.Queue[Frame], network: NetworkInfo):
|
128
127
|
"""Initialize a new addressable device."""
|
129
128
|
super().__init__(queue)
|
130
129
|
self._network = network
|
@@ -143,19 +142,20 @@ class AddressableDevice(Device, ABC):
|
|
143
142
|
async def async_setup(self) -> bool:
|
144
143
|
"""Set up addressable device."""
|
145
144
|
results = await asyncio.gather(
|
146
|
-
*
|
145
|
+
*(
|
147
146
|
self.request(description.provides, description.frame_type)
|
148
147
|
for description in self._setup_frames
|
149
|
-
|
148
|
+
),
|
150
149
|
return_exceptions=True,
|
151
150
|
)
|
152
151
|
|
153
152
|
errors = [
|
154
|
-
result.args[1] for result in results if isinstance(result,
|
153
|
+
result.args[1] for result in results if isinstance(result, BaseException)
|
155
154
|
]
|
156
155
|
|
157
|
-
await
|
158
|
-
|
156
|
+
await asyncio.gather(
|
157
|
+
self.dispatch(ATTR_FRAME_ERRORS, errors), self.dispatch(ATTR_LOADED, True)
|
158
|
+
)
|
159
159
|
return True
|
160
160
|
|
161
161
|
async def request(
|
@@ -178,9 +178,7 @@ class AddressableDevice(Device, ABC):
|
|
178
178
|
@classmethod
|
179
179
|
async def create(cls, device_type: int, **kwargs: Any) -> AddressableDevice:
|
180
180
|
"""Create a device handler object."""
|
181
|
-
return await create_instance(
|
182
|
-
get_device_handler(device_type), cls=AddressableDevice, **kwargs
|
183
|
-
)
|
181
|
+
return await create_instance(get_device_handler(device_type), cls=cls, **kwargs)
|
184
182
|
|
185
183
|
|
186
184
|
class SubDevice(Device, ABC):
|
@@ -189,7 +187,9 @@ class SubDevice(Device, ABC):
|
|
189
187
|
parent: AddressableDevice
|
190
188
|
index: int
|
191
189
|
|
192
|
-
def __init__(
|
190
|
+
def __init__(
|
191
|
+
self, queue: asyncio.Queue[Frame], parent: AddressableDevice, index: int = 0
|
192
|
+
):
|
193
193
|
"""Initialize a new sub-device."""
|
194
194
|
super().__init__(queue)
|
195
195
|
self.parent = parent
|