PyPlumIO 0.4.1__tar.gz → 0.4.2__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 (111) hide show
  1. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/PKG-INFO +1 -1
  2. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/PyPlumIO.egg-info/PKG-INFO +1 -1
  3. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/_version.py +2 -2
  4. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/const.py +2 -0
  5. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/filters.py +63 -27
  6. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/helpers/typing.py +9 -1
  7. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/test_filters.py +58 -0
  8. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.gitattributes +0 -0
  9. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.github/CODE_OF_CONDUCT.md +0 -0
  10. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  11. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  12. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.github/workflows/ci.yml +0 -0
  13. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.github/workflows/codeql-analysis.yml +0 -0
  14. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.github/workflows/deploy.yml +0 -0
  15. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.github/workflows/documentation.yml +0 -0
  16. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.gitignore +0 -0
  17. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.pre-commit-config.yaml +0 -0
  18. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/.vscode/settings.json +0 -0
  19. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/LICENSE +0 -0
  20. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/MANIFEST.in +0 -0
  21. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/PyPlumIO.egg-info/SOURCES.txt +0 -0
  22. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/PyPlumIO.egg-info/dependency_links.txt +0 -0
  23. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/PyPlumIO.egg-info/requires.txt +0 -0
  24. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/PyPlumIO.egg-info/top_level.txt +0 -0
  25. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/README.md +0 -0
  26. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/docs/Makefile +0 -0
  27. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/docs/make.bat +0 -0
  28. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/docs/source/conf.py +0 -0
  29. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/docs/source/index.rst +0 -0
  30. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/docs/source/protocol.rst +0 -0
  31. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/docs/source/usage.rst +0 -0
  32. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/images/ecomax.png +0 -0
  33. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/images/rs485.png +0 -0
  34. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/__init__.py +0 -0
  35. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/__main__.py +0 -0
  36. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/connection.py +0 -0
  37. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/devices/__init__.py +0 -0
  38. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/devices/ecomax.py +0 -0
  39. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/devices/ecoster.py +0 -0
  40. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/devices/mixer.py +0 -0
  41. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/devices/thermostat.py +0 -0
  42. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/exceptions.py +0 -0
  43. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/frames/__init__.py +0 -0
  44. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/frames/messages.py +0 -0
  45. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/frames/requests.py +0 -0
  46. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/frames/responses.py +0 -0
  47. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/helpers/__init__.py +0 -0
  48. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/helpers/data_types.py +0 -0
  49. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/helpers/event_manager.py +0 -0
  50. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/helpers/factory.py +0 -0
  51. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/helpers/parameter.py +0 -0
  52. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/helpers/schedule.py +0 -0
  53. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/helpers/task_manager.py +0 -0
  54. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/helpers/timeout.py +0 -0
  55. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/helpers/uid.py +0 -0
  56. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/protocol.py +0 -0
  57. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/stream.py +0 -0
  58. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/__init__.py +0 -0
  59. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/alerts.py +0 -0
  60. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/data_schema.py +0 -0
  61. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/ecomax_parameters.py +0 -0
  62. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/fan_power.py +0 -0
  63. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/frame_versions.py +0 -0
  64. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/fuel_consumption.py +0 -0
  65. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/fuel_level.py +0 -0
  66. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/lambda_sensor.py +0 -0
  67. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/load.py +0 -0
  68. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/mixer_parameters.py +0 -0
  69. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/mixer_sensors.py +0 -0
  70. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/modules.py +0 -0
  71. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/network_info.py +0 -0
  72. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/output_flags.py +0 -0
  73. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/outputs.py +0 -0
  74. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/pending_alerts.py +0 -0
  75. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/power.py +0 -0
  76. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/product_info.py +0 -0
  77. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/program_version.py +0 -0
  78. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/regulator_data.py +0 -0
  79. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/schedules.py +0 -0
  80. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/statuses.py +0 -0
  81. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/temperatures.py +0 -0
  82. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/thermostat_parameters.py +0 -0
  83. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/structures/thermostat_sensors.py +0 -0
  84. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyplumio/util.py +0 -0
  85. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/pyproject.toml +0 -0
  86. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/requirements.txt +0 -0
  87. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/requirements_test.txt +0 -0
  88. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/setup.cfg +0 -0
  89. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/__init__.py +0 -0
  90. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/conftest.py +0 -0
  91. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/frames/test_init.py +0 -0
  92. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/frames/test_messages.py +0 -0
  93. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/frames/test_requests.py +0 -0
  94. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/frames/test_responses.py +0 -0
  95. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/helpers/__init__.py +0 -0
  96. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/helpers/test_data_types.py +0 -0
  97. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/helpers/test_event_manager.py +0 -0
  98. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/helpers/test_factory.py +0 -0
  99. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/helpers/test_parameter.py +0 -0
  100. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/helpers/test_schedule.py +0 -0
  101. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/helpers/test_task_manager.py +0 -0
  102. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/helpers/test_timeout.py +0 -0
  103. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/helpers/test_uid.py +0 -0
  104. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/test_connection.py +0 -0
  105. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/test_devices.py +0 -0
  106. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/test_init.py +0 -0
  107. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/test_main.py +0 -0
  108. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/test_protocol.py +0 -0
  109. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/test_stream.py +0 -0
  110. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tests/test_util.py +0 -0
  111. {PyPlumIO-0.4.1 → PyPlumIO-0.4.2}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyPlumIO
3
- Version: 0.4.1
3
+ Version: 0.4.2
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyPlumIO
3
- Version: 0.4.1
3
+ Version: 0.4.2
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
@@ -1,4 +1,4 @@
1
1
  # file generated by setuptools_scm
2
2
  # don't change, don't track in version control
3
- __version__ = version = '0.4.1'
4
- __version_tuple__ = version_tuple = (0, 4, 1)
3
+ __version__ = version = '0.4.2'
4
+ __version_tuple__ = version_tuple = (0, 4, 2)
@@ -4,6 +4,8 @@ from __future__ import annotations
4
4
  from enum import IntEnum, unique
5
5
  from typing import Final
6
6
 
7
+ UNDEFINED: Final = "undefined"
8
+
7
9
  # Binary states.
8
10
  STATE_ON: Final = "on"
9
11
  STATE_OFF: Final = "off"
@@ -4,34 +4,70 @@ from __future__ import annotations
4
4
  from abc import ABC, abstractmethod
5
5
  import math
6
6
  import time
7
- from typing import Any, Final
7
+ from typing import Any, Final, SupportsFloat, SupportsIndex, overload
8
8
 
9
+ from pyplumio.const import UNDEFINED
9
10
  from pyplumio.helpers.parameter import Parameter
10
- from pyplumio.helpers.typing import EventCallbackType
11
+ from pyplumio.helpers.typing import EventCallbackType, SupportsSubtraction
11
12
 
12
13
  TOLERANCE: Final = 0.1
13
14
 
14
15
 
15
- def _significantly_changed(old_value, new_value) -> bool:
16
+ @overload
17
+ def _significantly_changed(old: Parameter, new: Parameter) -> bool:
18
+ """Check if parameter is significantly changed."""
19
+
20
+
21
+ @overload
22
+ def _significantly_changed(
23
+ old: SupportsFloat | SupportsIndex, new: SupportsFloat | SupportsIndex
24
+ ) -> bool:
25
+ """Check if float value is significantly changed."""
26
+
27
+
28
+ def _significantly_changed(old, new) -> bool:
16
29
  """Check if value is significantly changed."""
17
- if old_value is None or (isinstance(old_value, Parameter) and old_value.is_changed):
30
+ if old == UNDEFINED:
18
31
  return True
19
32
 
33
+ if isinstance(old, Parameter) and old.is_changed:
34
+ return True
35
+
36
+ if isinstance(old, Parameter) and isinstance(new, Parameter):
37
+ return (
38
+ old.value != new.value
39
+ or old.min_value != new.min_value
40
+ or old.max_value != new.max_value
41
+ )
42
+
20
43
  try:
21
- return not math.isclose(old_value, new_value, abs_tol=TOLERANCE)
44
+ return not math.isclose(old, new, abs_tol=TOLERANCE)
22
45
  except TypeError:
23
46
  pass
24
47
 
25
- return old_value != new_value
48
+ return old != new
49
+
50
+
51
+ @overload
52
+ def _diffence_between(old: list, new: list) -> list:
53
+ """Return the difference between lists."""
26
54
 
27
55
 
28
- def _diffence_between(old_value, new_value):
56
+ @overload
57
+ def _diffence_between(old: SupportsSubtraction, new: SupportsSubtraction) -> list:
58
+ """Return the difference between lists."""
59
+
60
+
61
+ def _diffence_between(old, new):
29
62
  """Return the difference between values."""
30
- if isinstance(old_value, list) and isinstance(new_value, list):
31
- return [x for x in new_value if x not in old_value]
63
+ if old == UNDEFINED:
64
+ return None
65
+
66
+ if isinstance(old, list) and isinstance(new, list):
67
+ return [x for x in new if x not in old]
32
68
 
33
- if hasattr(old_value, "__sub__") and hasattr(new_value, "__sub__"):
34
- return new_value - old_value
69
+ if hasattr(old, "__sub__") and hasattr(new, "__sub__"):
70
+ return new - old
35
71
 
36
72
  return None
37
73
 
@@ -40,12 +76,12 @@ class Filter(ABC):
40
76
  """Represents base for value callback modifiers."""
41
77
 
42
78
  _callback: Any
43
- _value: Any
79
+ _value: Any = UNDEFINED
44
80
 
45
81
  def __init__(self, callback: EventCallbackType):
46
82
  """Initialize new Filter object."""
47
83
  self._callback = callback
48
- self._value = None
84
+ self._value = UNDEFINED
49
85
 
50
86
  def __eq__(self, other) -> bool:
51
87
  """Compare debounced callbacks."""
@@ -59,21 +95,21 @@ class Filter(ABC):
59
95
 
60
96
  @abstractmethod
61
97
  async def __call__(self, new_value):
62
- """Set new value for the callback."""
98
+ """Set a new value for the callback."""
63
99
 
64
100
 
65
101
  class _OnChange(Filter):
66
102
  """Provides changed functionality to the callback."""
67
103
 
68
104
  async def __call__(self, new_value):
69
- """Set new value for the callback."""
105
+ """Set a new value for the callback."""
70
106
  if _significantly_changed(self._value, new_value):
71
107
  self._value = new_value
72
108
  return await self._callback(new_value)
73
109
 
74
110
 
75
111
  def on_change(callback: EventCallbackType) -> _OnChange:
76
- """Helper for change callback filter."""
112
+ """Helper for a change callback filter."""
77
113
  return _OnChange(callback)
78
114
 
79
115
 
@@ -90,20 +126,20 @@ class _Debounce(Filter):
90
126
  self._min_calls = min_calls
91
127
 
92
128
  async def __call__(self, new_value):
93
- """Set new value for the callback."""
129
+ """Set a new value for the callback."""
94
130
  if _significantly_changed(self._value, new_value):
95
131
  self._calls += 1
96
132
  else:
97
133
  self._calls = 0
98
134
 
99
- if self._calls >= self._min_calls or self._value is None:
135
+ if self._value == UNDEFINED or self._calls >= self._min_calls:
100
136
  self._value = new_value
101
137
  self._calls = 0
102
138
  return await self._callback(new_value)
103
139
 
104
140
 
105
141
  def debounce(callback: EventCallbackType, min_calls) -> _Debounce:
106
- """Helper method for debounce callback filter."""
142
+ """Helper method for a debounce callback filter."""
107
143
  return _Debounce(callback, min_calls)
108
144
 
109
145
 
@@ -120,7 +156,7 @@ class _Throttle(Filter):
120
156
  self._timeout = seconds
121
157
 
122
158
  async def __call__(self, new_value):
123
- """set new value for the callback."""
159
+ """Set a new value for the callback."""
124
160
  current_timestamp = time.monotonic()
125
161
  if (
126
162
  self._last_called is None
@@ -131,7 +167,7 @@ class _Throttle(Filter):
131
167
 
132
168
 
133
169
  def throttle(callback: EventCallbackType, seconds: float) -> _Throttle:
134
- """Helper method for throttle callback filter."""
170
+ """Helper method for a throttle callback filter."""
135
171
  return _Throttle(callback, seconds)
136
172
 
137
173
 
@@ -139,16 +175,16 @@ class _Delta(Filter):
139
175
  """Provides ability to pass call difference to the callback."""
140
176
 
141
177
  async def __call__(self, new_value):
142
- """set new value for the callback."""
143
- old_value = self._value
144
- if _significantly_changed(old_value, new_value):
178
+ """Set new value for the callback."""
179
+ if _significantly_changed(self._value, new_value):
180
+ old_value = self._value
145
181
  self._value = new_value
146
182
  if (difference := _diffence_between(old_value, new_value)) is not None:
147
183
  return await self._callback(difference)
148
184
 
149
185
 
150
186
  def delta(callback: EventCallbackType) -> _Delta:
151
- """Helper method for delta callback filter."""
187
+ """Helper method for a delta callback filter."""
152
188
  return _Delta(callback)
153
189
 
154
190
 
@@ -168,7 +204,7 @@ class _Aggregate(Filter):
168
204
  self._sum = 0.0
169
205
 
170
206
  async def __call__(self, new_value):
171
- """Set new value for the callback."""
207
+ """Set a new value for the callback."""
172
208
  current_timestamp = time.monotonic()
173
209
  try:
174
210
  self._sum += new_value
@@ -185,5 +221,5 @@ class _Aggregate(Filter):
185
221
 
186
222
 
187
223
  def aggregate(callback: EventCallbackType, seconds: float) -> _Aggregate:
188
- """Helper method for total callback filter."""
224
+ """Helper method for a total callback filter."""
189
225
  return _Aggregate(callback, seconds)
@@ -2,9 +2,17 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  from collections.abc import Awaitable, Callable
5
- from typing import Any, Literal, Union
5
+ from typing import Any, Literal, Protocol, Union
6
6
 
7
7
  ParameterDataType = tuple[int, int, int]
8
8
  ParameterValueType = Union[int, float, bool, Literal["off"], Literal["on"]]
9
9
  EventDataType = dict[Union[str, int], Any]
10
10
  EventCallbackType = Callable[[Any], Awaitable[Any]]
11
+ UndefinedType = Literal["undefined"]
12
+
13
+
14
+ class SupportsSubtraction(Protocol):
15
+ """Supports subtraction operation."""
16
+
17
+ def __sub__(self, other):
18
+ """Subtracts a value."""
@@ -6,6 +6,7 @@ from unittest.mock import AsyncMock, patch
6
6
  import pytest
7
7
 
8
8
  from pyplumio.filters import aggregate, debounce, delta, on_change, throttle
9
+ from pyplumio.helpers.parameter import Parameter
9
10
  from pyplumio.structures.alerts import Alert
10
11
 
11
12
 
@@ -31,6 +32,63 @@ async def test_on_change() -> None:
31
32
  _ = wrapped_callback == "you shall not pass"
32
33
 
33
34
 
35
+ async def test_on_change_parameter() -> None:
36
+ """Test on change filter with parameters."""
37
+ test_callback = AsyncMock()
38
+ test_parameter = AsyncMock(spec=Parameter)
39
+ test_parameter.value = 0
40
+ test_parameter.min_value = 0
41
+ test_parameter.max_value = 1
42
+ test_parameter.is_changed = False
43
+ wrapped_callback = on_change(test_callback)
44
+ await wrapped_callback(test_parameter)
45
+ test_callback.assert_awaited_once_with(test_parameter)
46
+ test_callback.reset_mock()
47
+
48
+ # Check that callback is not awaited with no change.
49
+ await wrapped_callback(test_parameter)
50
+ test_callback.assert_not_awaited()
51
+
52
+ # Check that callback is awaited on local value change.
53
+ test_parameter = AsyncMock(spec=Parameter)
54
+ test_parameter.value = 1
55
+ test_parameter.min_value = 0
56
+ test_parameter.max_value = 1
57
+ test_parameter.is_changed = True
58
+ await wrapped_callback(test_parameter)
59
+ test_callback.assert_awaited_once_with(test_parameter)
60
+ test_callback.reset_mock()
61
+
62
+ # Check that callback is awaited on value change.
63
+ test_parameter = AsyncMock(spec=Parameter)
64
+ test_parameter.value = 1
65
+ test_parameter.min_value = 0
66
+ test_parameter.max_value = 1
67
+ test_parameter.is_changed = False
68
+ await wrapped_callback(test_parameter)
69
+ test_callback.assert_awaited_once_with(test_parameter)
70
+ test_callback.reset_mock()
71
+
72
+ # Check that callback is awaited on min value change.
73
+ test_parameter = AsyncMock(spec=Parameter)
74
+ test_parameter.value = 1
75
+ test_parameter.min_value = 1
76
+ test_parameter.max_value = 1
77
+ test_parameter.is_changed = False
78
+ await wrapped_callback(test_parameter)
79
+ test_callback.assert_awaited_once_with(test_parameter)
80
+ test_callback.reset_mock()
81
+
82
+ # Check that callback is awaited on max value change.
83
+ test_parameter = AsyncMock(spec=Parameter)
84
+ test_parameter.value = 1
85
+ test_parameter.min_value = 1
86
+ test_parameter.max_value = 2
87
+ test_parameter.is_changed = False
88
+ await wrapped_callback(test_parameter)
89
+ test_callback.assert_awaited_once_with(test_parameter)
90
+
91
+
34
92
  async def test_debounce() -> None:
35
93
  """Test debounce filter."""
36
94
  test_callback = AsyncMock()
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes