PyPlumIO 0.5.17__tar.gz → 0.5.18__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 (142) hide show
  1. {pyplumio-0.5.17 → pyplumio-0.5.18}/PKG-INFO +4 -4
  2. {pyplumio-0.5.17 → pyplumio-0.5.18}/PyPlumIO.egg-info/PKG-INFO +4 -4
  3. {pyplumio-0.5.17 → pyplumio-0.5.18}/PyPlumIO.egg-info/requires.txt +3 -3
  4. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/source/schedules.rst +3 -3
  5. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/_version.py +2 -2
  6. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/helpers/factory.py +10 -5
  7. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/helpers/schedule.py +7 -7
  8. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/protocol.py +4 -3
  9. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/ecomax_parameters.py +20 -30
  10. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyproject.toml +3 -3
  11. {pyplumio-0.5.17 → pyplumio-0.5.18}/requirements_test.txt +3 -3
  12. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/helpers/test_schedule.py +5 -4
  13. {pyplumio-0.5.17 → pyplumio-0.5.18}/.gitattributes +0 -0
  14. {pyplumio-0.5.17 → pyplumio-0.5.18}/.github/CODE_OF_CONDUCT.md +0 -0
  15. {pyplumio-0.5.17 → pyplumio-0.5.18}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  16. {pyplumio-0.5.17 → pyplumio-0.5.18}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  17. {pyplumio-0.5.17 → pyplumio-0.5.18}/.github/dependabot.yml +0 -0
  18. {pyplumio-0.5.17 → pyplumio-0.5.18}/.github/workflows/ci.yml +0 -0
  19. {pyplumio-0.5.17 → pyplumio-0.5.18}/.github/workflows/codeql-analysis.yml +0 -0
  20. {pyplumio-0.5.17 → pyplumio-0.5.18}/.github/workflows/deploy.yml +0 -0
  21. {pyplumio-0.5.17 → pyplumio-0.5.18}/.github/workflows/documentation.yml +0 -0
  22. {pyplumio-0.5.17 → pyplumio-0.5.18}/.gitignore +0 -0
  23. {pyplumio-0.5.17 → pyplumio-0.5.18}/.pre-commit-config.yaml +0 -0
  24. {pyplumio-0.5.17 → pyplumio-0.5.18}/.vscode/settings.json +0 -0
  25. {pyplumio-0.5.17 → pyplumio-0.5.18}/LICENSE +0 -0
  26. {pyplumio-0.5.17 → pyplumio-0.5.18}/MANIFEST.in +0 -0
  27. {pyplumio-0.5.17 → pyplumio-0.5.18}/PyPlumIO.egg-info/SOURCES.txt +0 -0
  28. {pyplumio-0.5.17 → pyplumio-0.5.18}/PyPlumIO.egg-info/dependency_links.txt +0 -0
  29. {pyplumio-0.5.17 → pyplumio-0.5.18}/PyPlumIO.egg-info/top_level.txt +0 -0
  30. {pyplumio-0.5.17 → pyplumio-0.5.18}/README.md +0 -0
  31. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/Makefile +0 -0
  32. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/make.bat +0 -0
  33. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/source/callbacks.rst +0 -0
  34. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/source/conf.py +0 -0
  35. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/source/connecting.rst +0 -0
  36. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/source/index.rst +0 -0
  37. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/source/mixers_thermostats.rst +0 -0
  38. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/source/protocol.rst +0 -0
  39. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/source/reading.rst +0 -0
  40. {pyplumio-0.5.17 → pyplumio-0.5.18}/docs/source/writing.rst +0 -0
  41. {pyplumio-0.5.17 → pyplumio-0.5.18}/images/ecomax.png +0 -0
  42. {pyplumio-0.5.17 → pyplumio-0.5.18}/images/rs485.png +0 -0
  43. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/__init__.py +0 -0
  44. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/__main__.py +0 -0
  45. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/connection.py +0 -0
  46. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/const.py +0 -0
  47. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/devices/__init__.py +0 -0
  48. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/devices/ecomax.py +0 -0
  49. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/devices/ecoster.py +0 -0
  50. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/devices/mixer.py +0 -0
  51. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/devices/thermostat.py +0 -0
  52. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/exceptions.py +0 -0
  53. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/filters.py +0 -0
  54. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/frames/__init__.py +0 -0
  55. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/frames/messages.py +0 -0
  56. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/frames/requests.py +0 -0
  57. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/frames/responses.py +0 -0
  58. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/helpers/__init__.py +0 -0
  59. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/helpers/data_types.py +0 -0
  60. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/helpers/event_manager.py +0 -0
  61. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/helpers/parameter.py +0 -0
  62. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/helpers/task_manager.py +0 -0
  63. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/helpers/timeout.py +0 -0
  64. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/helpers/typing.py +0 -0
  65. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/helpers/uid.py +0 -0
  66. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/py.typed +0 -0
  67. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/stream.py +0 -0
  68. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/__init__.py +0 -0
  69. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/alerts.py +0 -0
  70. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/boiler_load.py +0 -0
  71. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/boiler_power.py +0 -0
  72. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/fan_power.py +0 -0
  73. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/frame_versions.py +0 -0
  74. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/fuel_consumption.py +0 -0
  75. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/fuel_level.py +0 -0
  76. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/lambda_sensor.py +0 -0
  77. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/mixer_parameters.py +0 -0
  78. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/mixer_sensors.py +0 -0
  79. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/modules.py +0 -0
  80. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/network_info.py +0 -0
  81. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/output_flags.py +0 -0
  82. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/outputs.py +0 -0
  83. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/pending_alerts.py +0 -0
  84. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/product_info.py +0 -0
  85. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/program_version.py +0 -0
  86. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/regulator_data.py +0 -0
  87. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/regulator_data_schema.py +0 -0
  88. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/schedules.py +0 -0
  89. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/statuses.py +0 -0
  90. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/temperatures.py +0 -0
  91. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/thermostat_parameters.py +0 -0
  92. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/structures/thermostat_sensors.py +0 -0
  93. {pyplumio-0.5.17 → pyplumio-0.5.18}/pyplumio/utils.py +0 -0
  94. {pyplumio-0.5.17 → pyplumio-0.5.18}/requirements.txt +0 -0
  95. {pyplumio-0.5.17 → pyplumio-0.5.18}/requirements_docs.txt +0 -0
  96. {pyplumio-0.5.17 → pyplumio-0.5.18}/setup.cfg +0 -0
  97. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/__init__.py +0 -0
  98. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/conftest.py +0 -0
  99. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/frames/test_init.py +0 -0
  100. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/frames/test_messages.py +0 -0
  101. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/frames/test_requests.py +0 -0
  102. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/frames/test_responses.py +0 -0
  103. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/helpers/__init__.py +0 -0
  104. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/helpers/test_data_types.py +0 -0
  105. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/helpers/test_event_manager.py +0 -0
  106. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/helpers/test_factory.py +0 -0
  107. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/helpers/test_parameter.py +0 -0
  108. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/helpers/test_task_manager.py +0 -0
  109. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/helpers/test_timeout.py +0 -0
  110. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/helpers/test_uid.py +0 -0
  111. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/ruff.toml +0 -0
  112. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/test_connection.py +0 -0
  113. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/test_devices.py +0 -0
  114. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/test_filters.py +0 -0
  115. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/test_init.py +0 -0
  116. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/test_main.py +0 -0
  117. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/test_protocol.py +0 -0
  118. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/test_stream.py +0 -0
  119. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/test_utils.py +0 -0
  120. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/messages/regulator_data.json +0 -0
  121. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/messages/sensor_data.json +0 -0
  122. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/requests/alerts.json +0 -0
  123. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/requests/ecomax_control.json +0 -0
  124. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/requests/ecomax_parameters.json +0 -0
  125. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/requests/mixer_parameters.json +0 -0
  126. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/requests/set_ecomax_parameter.json +0 -0
  127. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/requests/set_mixer_parameter.json +0 -0
  128. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/requests/set_schedule.json +0 -0
  129. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/requests/set_thermostat_parameter.json +0 -0
  130. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/requests/thermostat_parameters.json +0 -0
  131. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/responses/alerts.json +0 -0
  132. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/responses/device_available.json +0 -0
  133. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/responses/ecomax_parameters.json +0 -0
  134. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/responses/mixer_parameters.json +0 -0
  135. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/responses/password.json +0 -0
  136. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/responses/program_version.json +0 -0
  137. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/responses/regulator_data_schema.json +0 -0
  138. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/responses/schedules.json +0 -0
  139. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/responses/thermostat_parameters.json +0 -0
  140. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/responses/uid.json +0 -0
  141. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/unknown/unknown_ecomax_parameter.json +0 -0
  142. {pyplumio-0.5.17 → pyplumio-0.5.18}/tests/testdata/unknown/unknown_mixer_parameter.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyPlumIO
3
- Version: 0.5.17
3
+ Version: 0.5.18
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
@@ -25,12 +25,12 @@ License-File: LICENSE
25
25
  Requires-Dist: pyserial-asyncio==0.6
26
26
  Provides-Extra: test
27
27
  Requires-Dist: codespell==2.2.6; extra == "test"
28
- Requires-Dist: coverage==7.5.0; extra == "test"
29
- Requires-Dist: mypy==1.9.0; extra == "test"
28
+ Requires-Dist: coverage==7.5.1; extra == "test"
29
+ Requires-Dist: mypy==1.10.0; extra == "test"
30
30
  Requires-Dist: pyserial-asyncio-fast==0.11; extra == "test"
31
31
  Requires-Dist: pytest==8.2.0; extra == "test"
32
32
  Requires-Dist: pytest-asyncio==0.23.6; extra == "test"
33
- Requires-Dist: ruff==0.4.2; extra == "test"
33
+ Requires-Dist: ruff==0.4.3; extra == "test"
34
34
  Requires-Dist: tox==4.15.0; extra == "test"
35
35
  Requires-Dist: types-pyserial==3.5.0.20240311; extra == "test"
36
36
  Provides-Extra: docs
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyPlumIO
3
- Version: 0.5.17
3
+ Version: 0.5.18
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
@@ -25,12 +25,12 @@ License-File: LICENSE
25
25
  Requires-Dist: pyserial-asyncio==0.6
26
26
  Provides-Extra: test
27
27
  Requires-Dist: codespell==2.2.6; extra == "test"
28
- Requires-Dist: coverage==7.5.0; extra == "test"
29
- Requires-Dist: mypy==1.9.0; extra == "test"
28
+ Requires-Dist: coverage==7.5.1; extra == "test"
29
+ Requires-Dist: mypy==1.10.0; extra == "test"
30
30
  Requires-Dist: pyserial-asyncio-fast==0.11; extra == "test"
31
31
  Requires-Dist: pytest==8.2.0; extra == "test"
32
32
  Requires-Dist: pytest-asyncio==0.23.6; extra == "test"
33
- Requires-Dist: ruff==0.4.2; extra == "test"
33
+ Requires-Dist: ruff==0.4.3; extra == "test"
34
34
  Requires-Dist: tox==4.15.0; extra == "test"
35
35
  Requires-Dist: types-pyserial==3.5.0.20240311; extra == "test"
36
36
  Provides-Extra: docs
@@ -12,11 +12,11 @@ readthedocs-sphinx-search==0.3.2
12
12
 
13
13
  [test]
14
14
  codespell==2.2.6
15
- coverage==7.5.0
16
- mypy==1.9.0
15
+ coverage==7.5.1
16
+ mypy==1.10.0
17
17
  pyserial-asyncio-fast==0.11
18
18
  pytest==8.2.0
19
19
  pytest-asyncio==0.23.6
20
- ruff==0.4.2
20
+ ruff==0.4.3
21
21
  tox==4.15.0
22
22
  types-pyserial==3.5.0.20240311
@@ -55,7 +55,7 @@ switches back to daytime mode from 07:00 to 00:00.
55
55
  heating_schedule = schedules["heating"]
56
56
  heating_schedule.monday.set_off(start="00:00", end="07:00")
57
57
  heating_schedule.monday.set_on(start="07:00", end="00:00")
58
- heating_schedule.commit()
58
+ await heating_schedule.commit()
59
59
 
60
60
  For clarity sake, you might want to use ``STATE_NIGHT`` and
61
61
  ``STATE_DAY`` constants from ``pyplumio.helpers.schedule`` module.
@@ -99,7 +99,7 @@ Schedule object:
99
99
  weekday.set_off("07:00", "00:00")
100
100
 
101
101
  # Commit changes to the device.
102
- heating_schedule.commit()
102
+ await heating_schedule.commit()
103
103
 
104
104
  Schedule Examples
105
105
  -----------------
@@ -131,7 +131,7 @@ Schedule Examples
131
131
  # There will be no nighttime mode on sunday.
132
132
  heating_schedule.sunday.set_state(STATE_DAY)
133
133
 
134
- heating_schedule.commit()
134
+ await heating_schedule.commit()
135
135
 
136
136
 
137
137
  asyncio.run(main())
@@ -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.17'
16
- __version_tuple__ = version_tuple = (0, 5, 17)
15
+ __version__ = version = '0.5.18'
16
+ __version_tuple__ = version_tuple = (0, 5, 18)
@@ -2,21 +2,26 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  import asyncio
5
- from importlib import import_module
5
+ import importlib
6
6
  import logging
7
+ from types import ModuleType
7
8
  from typing import Any
8
9
 
9
10
  _LOGGER = logging.getLogger(__name__)
10
11
 
11
12
 
13
+ async def _load_module(module_name: str) -> ModuleType:
14
+ """Load a module by name."""
15
+ return await asyncio.get_running_loop().run_in_executor(
16
+ None, importlib.import_module, f".{module_name}", "pyplumio"
17
+ )
18
+
19
+
12
20
  async def create_instance(class_path: str, **kwargs: Any) -> Any:
13
21
  """Return a class instance from the class path."""
14
- loop = asyncio.get_running_loop()
15
22
  module_name, class_name = class_path.rsplit(".", 1)
16
23
  try:
17
- module = await loop.run_in_executor(
18
- None, import_module, "." + module_name, "pyplumio"
19
- )
24
+ module = await _load_module(module_name)
20
25
  return getattr(module, class_name)(**kwargs)
21
26
  except Exception:
22
27
  _LOGGER.error("Failed to load module (%s)", class_path)
@@ -9,7 +9,7 @@ from typing import Final, Literal
9
9
 
10
10
  from pyplumio.const import STATE_OFF, STATE_ON
11
11
  from pyplumio.devices import AddressableDevice
12
- from pyplumio.frames.requests import SetScheduleRequest
12
+ from pyplumio.helpers.factory import create_instance
13
13
  from pyplumio.structures.schedules import collect_schedule_data
14
14
 
15
15
  TIME_FORMAT: Final = "%H:%M"
@@ -158,11 +158,11 @@ class Schedule(Iterable):
158
158
  self.saturday,
159
159
  ).__iter__()
160
160
 
161
- def commit(self) -> None:
161
+ async def commit(self) -> None:
162
162
  """Commit a weekly schedule to the device."""
163
- self.device.queue.put_nowait(
164
- SetScheduleRequest(
165
- recipient=self.device.address,
166
- data=collect_schedule_data(self.name, self.device),
167
- )
163
+ request = await create_instance(
164
+ "frames.requests.SetScheduleRequest",
165
+ recipient=self.device.address,
166
+ data=collect_schedule_data(self.name, self.device),
168
167
  )
168
+ await self.device.queue.put(request)
@@ -233,9 +233,10 @@ class AsyncProtocol(Protocol, EventManager):
233
233
  async def get_device_entry(self, device_type: DeviceType) -> AddressableDevice:
234
234
  """Set up device entry."""
235
235
  handler, name = get_device_handler_and_name(device_type)
236
- return self.data.setdefault(
237
- name, await self._create_device_entry(name, handler)
238
- )
236
+ if name not in self.data:
237
+ self.data[name] = await self._create_device_entry(name, handler)
238
+
239
+ return self.data[name]
239
240
 
240
241
  async def _create_device_entry(self, name: str, handler: str) -> AddressableDevice:
241
242
  """Create device entry."""
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
 
4
4
  from collections.abc import Generator
5
5
  from dataclasses import dataclass
6
- from typing import Any, Final
6
+ from typing import Any, Final, cast
7
7
 
8
8
  from pyplumio.const import (
9
9
  ATTR_INDEX,
@@ -47,37 +47,27 @@ class EcomaxParameter(Parameter):
47
47
  async def create_request(self) -> Request:
48
48
  """Create a request to change the parameter."""
49
49
  if self.description.name == ATTR_ECOMAX_CONTROL:
50
- request: Request = await create_instance(
51
- "frames.requests.EcomaxControlRequest",
52
- recipient=self.device.address,
53
- data={
54
- ATTR_VALUE: self.values.value,
55
- },
56
- )
57
-
50
+ cls = "frames.requests.EcomaxControlRequest"
51
+ data = {ATTR_VALUE: self.values.value}
58
52
  elif self.description.name == ATTR_THERMOSTAT_PROFILE:
59
- request = await create_instance(
60
- "frames.requests.SetThermostatParameterRequest",
61
- recipient=self.device.address,
62
- data={
63
- ATTR_INDEX: self._index,
64
- ATTR_VALUE: self.values.value,
65
- ATTR_OFFSET: 0,
66
- ATTR_SIZE: 1,
67
- },
68
- )
69
-
53
+ cls = "frames.requests.SetThermostatParameterRequest"
54
+ data = {
55
+ ATTR_INDEX: self._index,
56
+ ATTR_VALUE: self.values.value,
57
+ ATTR_OFFSET: 0,
58
+ ATTR_SIZE: 1,
59
+ }
70
60
  else:
71
- request = await create_instance(
72
- "frames.requests.SetEcomaxParameterRequest",
73
- recipient=self.device.address,
74
- data={
75
- ATTR_INDEX: self._index,
76
- ATTR_VALUE: self.values.value,
77
- },
78
- )
79
-
80
- return request
61
+ cls = "frames.requests.SetEcomaxParameterRequest"
62
+ data = {
63
+ ATTR_INDEX: self._index,
64
+ ATTR_VALUE: self.values.value,
65
+ }
66
+
67
+ return cast(
68
+ Request,
69
+ await create_instance(cls, recipient=self.device.address, data=data),
70
+ )
81
71
 
82
72
  async def set(self, value: ParameterValueType, retries: int = 5) -> bool:
83
73
  """Set a parameter value."""
@@ -33,12 +33,12 @@ dynamic = ["version"]
33
33
  [project.optional-dependencies]
34
34
  test = [
35
35
  "codespell==2.2.6",
36
- "coverage==7.5.0",
37
- "mypy==1.9.0",
36
+ "coverage==7.5.1",
37
+ "mypy==1.10.0",
38
38
  "pyserial-asyncio-fast==0.11",
39
39
  "pytest==8.2.0",
40
40
  "pytest-asyncio==0.23.6",
41
- "ruff==0.4.2",
41
+ "ruff==0.4.3",
42
42
  "tox==4.15.0",
43
43
  "types-pyserial==3.5.0.20240311"
44
44
  ]
@@ -1,11 +1,11 @@
1
1
  codespell==2.2.6
2
- coverage==7.5.0
3
- mypy==1.9.0
2
+ coverage==7.5.1
3
+ mypy==1.10.0
4
4
  pre-commit==3.7.0
5
5
  pyserial-asyncio-fast==0.11
6
6
  pytest==8.2.0
7
7
  pytest-asyncio==0.23.6
8
- ruff==0.4.2
8
+ ruff==0.4.3
9
9
  tomli==2.0.1
10
10
  tox==4.15.0
11
11
  types-pyserial==3.5.0.20240311
@@ -100,8 +100,8 @@ def test_schedule(schedule: Schedule) -> None:
100
100
  assert next(schedule_iter)[0]
101
101
 
102
102
 
103
- @patch("pyplumio.helpers.schedule.SetScheduleRequest")
104
- def test_schedule_commit(mock_set_schedule_request, schedule: Schedule) -> None:
103
+ @patch("pyplumio.helpers.schedule.create_instance")
104
+ async def test_schedule_commit(mock_create_instance, schedule: Schedule) -> None:
105
105
  """Test committing a schedule."""
106
106
  schedule.device = Mock(spec=Device)
107
107
  schedule.device.address = DeviceType.ECOMAX
@@ -112,8 +112,9 @@ def test_schedule_commit(mock_set_schedule_request, schedule: Schedule) -> None:
112
112
  }
113
113
  schedule.device.queue = Mock(spec=asyncio.Queue)
114
114
 
115
- schedule.commit()
116
- mock_set_schedule_request.assert_called_once_with(
115
+ await schedule.commit()
116
+ mock_create_instance.assert_awaited_once_with(
117
+ "frames.requests.SetScheduleRequest",
117
118
  recipient=DeviceType.ECOMAX,
118
119
  data={
119
120
  ATTR_TYPE: "test",
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