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.
Files changed (172) hide show
  1. {pyplumio-0.5.53 → pyplumio-0.5.55}/.pre-commit-config.yaml +2 -2
  2. {pyplumio-0.5.53 → pyplumio-0.5.55}/PKG-INFO +9 -9
  3. {pyplumio-0.5.53 → pyplumio-0.5.55}/PyPlumIO.egg-info/PKG-INFO +9 -9
  4. {pyplumio-0.5.53 → pyplumio-0.5.55}/PyPlumIO.egg-info/requires.txt +8 -8
  5. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/_version.py +16 -3
  6. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/devices/__init__.py +2 -1
  7. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/devices/ecomax.py +14 -2
  8. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/filters.py +2 -1
  9. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyproject.toml +8 -8
  10. pyplumio-0.5.55/requirements_test.txt +13 -0
  11. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/test_ecomax.py +16 -2
  12. pyplumio-0.5.53/requirements_test.txt +0 -13
  13. {pyplumio-0.5.53 → pyplumio-0.5.55}/.gitattributes +0 -0
  14. {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/CODE_OF_CONDUCT.md +0 -0
  15. {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  16. {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  17. {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/dependabot.yml +0 -0
  18. {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/workflows/ci.yml +0 -0
  19. {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/workflows/codeql.yml +0 -0
  20. {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/workflows/deploy.yml +0 -0
  21. {pyplumio-0.5.53 → pyplumio-0.5.55}/.github/workflows/documentation.yml +0 -0
  22. {pyplumio-0.5.53 → pyplumio-0.5.55}/.gitignore +0 -0
  23. {pyplumio-0.5.53 → pyplumio-0.5.55}/.qlty/qlty.toml +0 -0
  24. {pyplumio-0.5.53 → pyplumio-0.5.55}/.vscode/settings.json +0 -0
  25. {pyplumio-0.5.53 → pyplumio-0.5.55}/LICENSE +0 -0
  26. {pyplumio-0.5.53 → pyplumio-0.5.55}/MANIFEST.in +0 -0
  27. {pyplumio-0.5.53 → pyplumio-0.5.55}/PyPlumIO.egg-info/SOURCES.txt +0 -0
  28. {pyplumio-0.5.53 → pyplumio-0.5.55}/PyPlumIO.egg-info/dependency_links.txt +0 -0
  29. {pyplumio-0.5.53 → pyplumio-0.5.55}/PyPlumIO.egg-info/top_level.txt +0 -0
  30. {pyplumio-0.5.53 → pyplumio-0.5.55}/README.md +0 -0
  31. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/Makefile +0 -0
  32. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/make.bat +0 -0
  33. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/callbacks.rst +0 -0
  34. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/conf.py +0 -0
  35. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/connecting.rst +0 -0
  36. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/frames.rst +0 -0
  37. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/index.rst +0 -0
  38. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/mixers_thermostats.rst +0 -0
  39. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/protocol.rst +0 -0
  40. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/reading.rst +0 -0
  41. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/schedules.rst +0 -0
  42. {pyplumio-0.5.53 → pyplumio-0.5.55}/docs/source/writing.rst +0 -0
  43. {pyplumio-0.5.53 → pyplumio-0.5.55}/images/ecomax.png +0 -0
  44. {pyplumio-0.5.53 → pyplumio-0.5.55}/images/rs485.png +0 -0
  45. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/__init__.py +0 -0
  46. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/__main__.py +0 -0
  47. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/connection.py +0 -0
  48. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/const.py +0 -0
  49. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/data_types.py +0 -0
  50. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/devices/ecoster.py +0 -0
  51. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/devices/mixer.py +0 -0
  52. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/devices/thermostat.py +0 -0
  53. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/exceptions.py +0 -0
  54. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/frames/__init__.py +0 -0
  55. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/frames/messages.py +0 -0
  56. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/frames/requests.py +0 -0
  57. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/frames/responses.py +0 -0
  58. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/helpers/__init__.py +0 -0
  59. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/helpers/async_cache.py +0 -0
  60. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/helpers/event_manager.py +0 -0
  61. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/helpers/factory.py +0 -0
  62. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/helpers/task_manager.py +0 -0
  63. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/__init__.py +0 -0
  64. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/custom/__init__.py +0 -0
  65. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/custom/ecomax_860d3_hb.py +0 -0
  66. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/ecomax.py +0 -0
  67. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/mixer.py +0 -0
  68. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/parameters/thermostat.py +0 -0
  69. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/protocol.py +0 -0
  70. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/py.typed +0 -0
  71. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/stream.py +0 -0
  72. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/__init__.py +0 -0
  73. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/alerts.py +0 -0
  74. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/boiler_load.py +0 -0
  75. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/boiler_power.py +0 -0
  76. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/ecomax_parameters.py +0 -0
  77. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/fan_power.py +0 -0
  78. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/frame_versions.py +0 -0
  79. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/fuel_consumption.py +0 -0
  80. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/fuel_level.py +0 -0
  81. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/lambda_sensor.py +0 -0
  82. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/mixer_parameters.py +0 -0
  83. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/mixer_sensors.py +0 -0
  84. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/modules.py +0 -0
  85. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/network_info.py +0 -0
  86. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/output_flags.py +0 -0
  87. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/outputs.py +0 -0
  88. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/pending_alerts.py +0 -0
  89. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/product_info.py +0 -0
  90. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/program_version.py +0 -0
  91. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/regulator_data.py +0 -0
  92. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/regulator_data_schema.py +0 -0
  93. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/schedules.py +0 -0
  94. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/statuses.py +0 -0
  95. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/temperatures.py +0 -0
  96. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/thermostat_parameters.py +0 -0
  97. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/structures/thermostat_sensors.py +0 -0
  98. {pyplumio-0.5.53 → pyplumio-0.5.55}/pyplumio/utils.py +0 -0
  99. {pyplumio-0.5.53 → pyplumio-0.5.55}/requirements.txt +0 -0
  100. {pyplumio-0.5.53 → pyplumio-0.5.55}/requirements_docs.txt +0 -0
  101. {pyplumio-0.5.53 → pyplumio-0.5.55}/setup.cfg +0 -0
  102. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/__init__.py +0 -0
  103. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/conftest.py +0 -0
  104. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/__init__.py +0 -0
  105. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/test_ecoster.py +0 -0
  106. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/test_init.py +0 -0
  107. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/test_mixer.py +0 -0
  108. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/devices/test_thermostat.py +0 -0
  109. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/frames/test_init.py +0 -0
  110. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/frames/test_messages.py +0 -0
  111. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/frames/test_requests.py +0 -0
  112. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/frames/test_responses.py +0 -0
  113. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/__init__.py +0 -0
  114. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/test_async_cache.py +0 -0
  115. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/test_event_manager.py +0 -0
  116. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/test_factory.py +0 -0
  117. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/test_task_manager.py +0 -0
  118. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/helpers/test_uid.py +0 -0
  119. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/__init__.py +0 -0
  120. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/custom/__init__.py +0 -0
  121. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/custom/test_ecomax_860d3_hb.py +0 -0
  122. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/custom/test_init.py +0 -0
  123. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/test_ecomax.py +0 -0
  124. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/test_init.py +0 -0
  125. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/test_mixers.py +0 -0
  126. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/parameters/test_thermostats.py +0 -0
  127. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/ruff.toml +0 -0
  128. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/__init__.py +0 -0
  129. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_alerts.py +0 -0
  130. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_boiler_load.py +0 -0
  131. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_boiler_power.py +0 -0
  132. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_ecomax_parameters.py +0 -0
  133. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_fan_power.py +0 -0
  134. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_frame_versions.py +0 -0
  135. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_fuel_consumption.py +0 -0
  136. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_fuel_level.py +0 -0
  137. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_lambda_sensor.py +0 -0
  138. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_mixer_parameters.py +0 -0
  139. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_product_info.py +0 -0
  140. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/structures/test_schedules.py +0 -0
  141. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_connection.py +0 -0
  142. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_data_types.py +0 -0
  143. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_filters.py +0 -0
  144. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_init.py +0 -0
  145. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_main.py +0 -0
  146. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_protocol.py +0 -0
  147. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_stream.py +0 -0
  148. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/test_utils.py +0 -0
  149. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/messages/regulator_data.json +0 -0
  150. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/messages/sensor_data.json +0 -0
  151. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/parameters/ecomax_860d3_hb.json +0 -0
  152. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/alerts.json +0 -0
  153. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/ecomax_control.json +0 -0
  154. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/ecomax_parameters.json +0 -0
  155. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/mixer_parameters.json +0 -0
  156. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/set_ecomax_parameter.json +0 -0
  157. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/set_mixer_parameter.json +0 -0
  158. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/set_schedule.json +0 -0
  159. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/set_thermostat_parameter.json +0 -0
  160. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/requests/thermostat_parameters.json +0 -0
  161. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/alerts.json +0 -0
  162. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/device_available.json +0 -0
  163. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/ecomax_parameters.json +0 -0
  164. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/mixer_parameters.json +0 -0
  165. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/password.json +0 -0
  166. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/program_version.json +0 -0
  167. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/regulator_data_schema.json +0 -0
  168. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/schedules.json +0 -0
  169. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/thermostat_parameters.json +0 -0
  170. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/responses/uid.json +0 -0
  171. {pyplumio-0.5.53 → pyplumio-0.5.55}/tests/testdata/unknown/unknown_ecomax_parameter.json +0 -0
  172. {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.11.11
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.15.0
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.53
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.9.1; extra == "test"
32
- Requires-Dist: freezegun==1.5.2; extra == "test"
33
- Requires-Dist: mypy==1.16.1; extra == "test"
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.0.0; extra == "test"
38
- Requires-Dist: ruff==0.12.1; extra == "test"
39
- Requires-Dist: tox==4.27.0; extra == "test"
40
- Requires-Dist: types-pyserial==3.5.0.20250326; extra == "test"
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.2.0; extra == "dev"
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.53
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.9.1; extra == "test"
32
- Requires-Dist: freezegun==1.5.2; extra == "test"
33
- Requires-Dist: mypy==1.16.1; extra == "test"
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.0.0; extra == "test"
38
- Requires-Dist: ruff==0.12.1; extra == "test"
39
- Requires-Dist: tox==4.27.0; extra == "test"
40
- Requires-Dist: types-pyserial==3.5.0.20250326; extra == "test"
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.2.0; extra == "dev"
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.2.0
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.9.1
18
- freezegun==1.5.2
19
- mypy==1.16.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.0.0
24
- ruff==0.12.1
25
- tox==4.27.0
26
- types-pyserial==3.5.0.20250326
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__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
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.53'
21
- __version_tuple__ = version_tuple = (0, 5, 53)
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"{retries} retries.",
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) -> None:
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
- await self.wait_for(ATTR_SENSORS)
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
- result = await self._callback(
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.9.1",
42
- "freezegun==1.5.2",
43
- "mypy==1.16.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.0.0",
48
- "ruff==0.12.1",
49
- "tox==4.27.0",
50
- "types-pyserial==3.5.0.20250326"
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.2.0",
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