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.
Files changed (37) hide show
  1. {PyPlumIO-0.5.21.dist-info → PyPlumIO-0.5.23.dist-info}/METADATA +12 -10
  2. PyPlumIO-0.5.23.dist-info/RECORD +60 -0
  3. {PyPlumIO-0.5.21.dist-info → PyPlumIO-0.5.23.dist-info}/WHEEL +1 -1
  4. pyplumio/__init__.py +2 -2
  5. pyplumio/_version.py +2 -2
  6. pyplumio/connection.py +3 -12
  7. pyplumio/devices/__init__.py +16 -16
  8. pyplumio/devices/ecomax.py +126 -126
  9. pyplumio/devices/mixer.py +50 -44
  10. pyplumio/devices/thermostat.py +36 -35
  11. pyplumio/exceptions.py +9 -9
  12. pyplumio/filters.py +56 -37
  13. pyplumio/frames/__init__.py +6 -6
  14. pyplumio/frames/messages.py +4 -6
  15. pyplumio/helpers/data_types.py +8 -7
  16. pyplumio/helpers/event_manager.py +53 -33
  17. pyplumio/helpers/parameter.py +138 -52
  18. pyplumio/helpers/task_manager.py +7 -2
  19. pyplumio/helpers/timeout.py +0 -3
  20. pyplumio/helpers/uid.py +2 -2
  21. pyplumio/protocol.py +35 -28
  22. pyplumio/stream.py +2 -2
  23. pyplumio/structures/alerts.py +40 -31
  24. pyplumio/structures/ecomax_parameters.py +493 -282
  25. pyplumio/structures/frame_versions.py +5 -6
  26. pyplumio/structures/lambda_sensor.py +6 -6
  27. pyplumio/structures/mixer_parameters.py +136 -71
  28. pyplumio/structures/network_info.py +2 -3
  29. pyplumio/structures/product_info.py +0 -4
  30. pyplumio/structures/program_version.py +24 -17
  31. pyplumio/structures/schedules.py +35 -15
  32. pyplumio/structures/thermostat_parameters.py +82 -50
  33. pyplumio/utils.py +12 -7
  34. PyPlumIO-0.5.21.dist-info/RECORD +0 -61
  35. pyplumio/helpers/typing.py +0 -29
  36. {PyPlumIO-0.5.21.dist-info → PyPlumIO-0.5.23.dist-info}/LICENSE +0 -0
  37. {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.21
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.7.1 ; extra == 'dev'
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.3.7 ; extra == 'docs'
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.5.3 ; extra == 'test'
37
- Requires-Dist: mypy ==1.10.0 ; extra == 'test'
38
- Requires-Dist: pyserial-asyncio-fast ==0.12 ; extra == 'test'
39
- Requires-Dist: pytest ==8.2.2 ; extra == 'test'
40
- Requires-Dist: pytest-asyncio ==0.23.7 ; extra == 'test'
41
- Requires-Dist: ruff ==0.4.9 ; extra == 'test'
42
- Requires-Dist: tox ==4.15.1 ; extra == 'test'
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (72.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
pyplumio/__init__.py CHANGED
@@ -10,7 +10,7 @@ from pyplumio.exceptions import (
10
10
  ChecksumError,
11
11
  ConnectionFailedError,
12
12
  FrameDataError,
13
- FrameError,
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
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.5.21'
16
- __version_tuple__ = version_tuple = (0, 5, 21)
15
+ __version__ = version = '0.5.23'
16
+ __version_tuple__ = version_tuple = (0, 5, 23)
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: MutableMapping[str, Any]
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
 
@@ -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["on"] | Literal["off"]
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["on"] | Literal["off"]
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, ValueError)
153
+ result.args[1] for result in results if isinstance(result, BaseException)
155
154
  ]
156
155
 
157
- await self.dispatch(ATTR_FRAME_ERRORS, errors)
158
- await self.dispatch(ATTR_LOADED, True)
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__(self, queue: asyncio.Queue, parent: AddressableDevice, index: int = 0):
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