violet-poolController-api 0.0.24__tar.gz → 0.0.26__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.
- {violet_poolcontroller_api-0.0.24/violet_poolController_api.egg-info → violet_poolcontroller_api-0.0.26}/PKG-INFO +69 -3
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/README.md +66 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/pyproject.toml +5 -5
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/setup.py +1 -1
- violet_poolcontroller_api-0.0.26/tests/conftest.py +40 -0
- violet_poolcontroller_api-0.0.26/tests/mock_server.py +684 -0
- violet_poolcontroller_api-0.0.26/tests/test_api_smoke.py +607 -0
- violet_poolcontroller_api-0.0.26/tests/test_mock_server.py +231 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26/violet_poolController_api.egg-info}/PKG-INFO +69 -3
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/violet_poolController_api.egg-info/SOURCES.txt +4 -0
- violet_poolcontroller_api-0.0.26/violet_poolController_api.egg-info/requires.txt +6 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/violet_poolcontroller_api/__init__.py +22 -1
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/violet_poolcontroller_api/api.py +25 -17
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/violet_poolcontroller_api/const_api.py +0 -7
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/violet_poolcontroller_api/const_devices.py +10 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/violet_poolcontroller_api/utils_rate_limiter.py +3 -8
- violet_poolcontroller_api-0.0.24/violet_poolController_api.egg-info/requires.txt +0 -6
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/LICENSE +0 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/setup.cfg +0 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/tests/__init__.py +0 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/tests/test_api.py +0 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/violet_poolController_api.egg-info/dependency_links.txt +0 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/violet_poolController_api.egg-info/top_level.txt +0 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/violet_poolcontroller_api/circuit_breaker.py +0 -0
- {violet_poolcontroller_api-0.0.24 → violet_poolcontroller_api-0.0.26}/violet_poolcontroller_api/utils_sanitizer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: violet-poolController-api
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.26
|
|
4
4
|
Summary: Asynchronous Python client for the Violet Pool Controller.
|
|
5
5
|
Home-page: https://github.com/Xerolux/violet-poolController-api
|
|
6
6
|
Author: Basti (Xerolux)
|
|
@@ -22,9 +22,9 @@ Classifier: Topic :: Home Automation
|
|
|
22
22
|
Requires-Python: >=3.12
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
License-File: LICENSE
|
|
25
|
-
Requires-Dist: aiohttp
|
|
25
|
+
Requires-Dist: aiohttp<3.14,>=3.11.0
|
|
26
26
|
Provides-Extra: test
|
|
27
|
-
Requires-Dist: aioresponses>=0.7.
|
|
27
|
+
Requires-Dist: aioresponses>=0.7.8; extra == "test"
|
|
28
28
|
Requires-Dist: pytest>=8.3; extra == "test"
|
|
29
29
|
Requires-Dist: pytest-asyncio>=0.24; extra == "test"
|
|
30
30
|
Dynamic: author
|
|
@@ -158,6 +158,72 @@ print(profile)
|
|
|
158
158
|
```
|
|
159
159
|
This detection parses `get_readings()` to check for the presence of certain internal status parameters (`SYSTEM_dosagemodule_cpu_temperature`, `EXT1_1`, `EXT2_1`), allowing your application to dynamically adapt to the connected modules (Base Module, Dosing Module, Relay Extension 1 and 2). By utilizing this detection, developers and integrations can accurately filter out features for missing hardware, ensuring that only supported options are exposed to the user.
|
|
160
160
|
|
|
161
|
+
## Mock Server (Testing Without Hardware)
|
|
162
|
+
|
|
163
|
+
The project includes a full mock server that simulates the Violet Pool Controller. This allows you to develop and test without needing the physical controller.
|
|
164
|
+
|
|
165
|
+
### Start the Mock Server
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Without authentication (default port 8480)
|
|
169
|
+
python tests/mock_server.py
|
|
170
|
+
|
|
171
|
+
# With Basic Auth (like the real controller)
|
|
172
|
+
python tests/mock_server.py --user admin --password secret
|
|
173
|
+
|
|
174
|
+
# With simulated network latency (300ms)
|
|
175
|
+
python tests/mock_server.py --user admin --password secret --delay 0.3
|
|
176
|
+
|
|
177
|
+
# Dosing-standalone mode (list format responses)
|
|
178
|
+
python tests/mock_server.py --standalone
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Connect Your Code
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
import asyncio, aiohttp
|
|
185
|
+
from violet_poolcontroller_api import VioletPoolAPI
|
|
186
|
+
|
|
187
|
+
async def main():
|
|
188
|
+
async with aiohttp.ClientSession() as session:
|
|
189
|
+
api = VioletPoolAPI(
|
|
190
|
+
host="localhost:8480",
|
|
191
|
+
session=session,
|
|
192
|
+
username="admin",
|
|
193
|
+
password="secret",
|
|
194
|
+
)
|
|
195
|
+
readings = await api.get_readings()
|
|
196
|
+
print(f"pH={readings['pH_value']}, PUMP={readings['PUMP']}")
|
|
197
|
+
|
|
198
|
+
asyncio.run(main())
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Run the Smoke Test
|
|
202
|
+
|
|
203
|
+
The smoke test automatically starts the mock server, tests every public API method, and prints a detailed report:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
python tests/test_api_smoke.py --user admin --password secret
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Mock Server Control Endpoints
|
|
210
|
+
|
|
211
|
+
These endpoints exist only on the mock server (not the real controller):
|
|
212
|
+
|
|
213
|
+
| Endpoint | Description |
|
|
214
|
+
|---|---|
|
|
215
|
+
| `GET /mock/state` | View internal state (outputs, sensors, config) as JSON |
|
|
216
|
+
| `GET /mock/error?code=500&count=3` | Force next 3 requests to return HTTP 500 |
|
|
217
|
+
| `GET /mock/reset` | Reset all state to defaults |
|
|
218
|
+
|
|
219
|
+
### Mock Server Features
|
|
220
|
+
|
|
221
|
+
- **Stateful:** Switch/dosing changes are reflected in `getReadings` (e.g. PUMP ON -> PUMP=4)
|
|
222
|
+
- **Sensor drift:** pH, ORP, chlorine, and CPU temperature change slowly over time
|
|
223
|
+
- **Config persistence:** Values set via `setConfig` are returned by `getConfig`
|
|
224
|
+
- **Log history:** Actions are logged and returned by `getLog`
|
|
225
|
+
- **Error simulation:** Test your error handling with forced HTTP errors
|
|
226
|
+
|
|
161
227
|
## License
|
|
162
228
|
GNU Affero General Public License v3.0 or later (AGPLv3+)
|
|
163
229
|
|
|
@@ -124,6 +124,72 @@ print(profile)
|
|
|
124
124
|
```
|
|
125
125
|
This detection parses `get_readings()` to check for the presence of certain internal status parameters (`SYSTEM_dosagemodule_cpu_temperature`, `EXT1_1`, `EXT2_1`), allowing your application to dynamically adapt to the connected modules (Base Module, Dosing Module, Relay Extension 1 and 2). By utilizing this detection, developers and integrations can accurately filter out features for missing hardware, ensuring that only supported options are exposed to the user.
|
|
126
126
|
|
|
127
|
+
## Mock Server (Testing Without Hardware)
|
|
128
|
+
|
|
129
|
+
The project includes a full mock server that simulates the Violet Pool Controller. This allows you to develop and test without needing the physical controller.
|
|
130
|
+
|
|
131
|
+
### Start the Mock Server
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# Without authentication (default port 8480)
|
|
135
|
+
python tests/mock_server.py
|
|
136
|
+
|
|
137
|
+
# With Basic Auth (like the real controller)
|
|
138
|
+
python tests/mock_server.py --user admin --password secret
|
|
139
|
+
|
|
140
|
+
# With simulated network latency (300ms)
|
|
141
|
+
python tests/mock_server.py --user admin --password secret --delay 0.3
|
|
142
|
+
|
|
143
|
+
# Dosing-standalone mode (list format responses)
|
|
144
|
+
python tests/mock_server.py --standalone
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Connect Your Code
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
import asyncio, aiohttp
|
|
151
|
+
from violet_poolcontroller_api import VioletPoolAPI
|
|
152
|
+
|
|
153
|
+
async def main():
|
|
154
|
+
async with aiohttp.ClientSession() as session:
|
|
155
|
+
api = VioletPoolAPI(
|
|
156
|
+
host="localhost:8480",
|
|
157
|
+
session=session,
|
|
158
|
+
username="admin",
|
|
159
|
+
password="secret",
|
|
160
|
+
)
|
|
161
|
+
readings = await api.get_readings()
|
|
162
|
+
print(f"pH={readings['pH_value']}, PUMP={readings['PUMP']}")
|
|
163
|
+
|
|
164
|
+
asyncio.run(main())
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Run the Smoke Test
|
|
168
|
+
|
|
169
|
+
The smoke test automatically starts the mock server, tests every public API method, and prints a detailed report:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
python tests/test_api_smoke.py --user admin --password secret
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Mock Server Control Endpoints
|
|
176
|
+
|
|
177
|
+
These endpoints exist only on the mock server (not the real controller):
|
|
178
|
+
|
|
179
|
+
| Endpoint | Description |
|
|
180
|
+
|---|---|
|
|
181
|
+
| `GET /mock/state` | View internal state (outputs, sensors, config) as JSON |
|
|
182
|
+
| `GET /mock/error?code=500&count=3` | Force next 3 requests to return HTTP 500 |
|
|
183
|
+
| `GET /mock/reset` | Reset all state to defaults |
|
|
184
|
+
|
|
185
|
+
### Mock Server Features
|
|
186
|
+
|
|
187
|
+
- **Stateful:** Switch/dosing changes are reflected in `getReadings` (e.g. PUMP ON -> PUMP=4)
|
|
188
|
+
- **Sensor drift:** pH, ORP, chlorine, and CPU temperature change slowly over time
|
|
189
|
+
- **Config persistence:** Values set via `setConfig` are returned by `getConfig`
|
|
190
|
+
- **Log history:** Actions are logged and returned by `getLog`
|
|
191
|
+
- **Error simulation:** Test your error handling with forced HTTP errors
|
|
192
|
+
|
|
127
193
|
## License
|
|
128
194
|
GNU Affero General Public License v3.0 or later (AGPLv3+)
|
|
129
195
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "violet-poolController-api"
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.26"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Basti (Xerolux)", email="git@xerolux.de" },
|
|
10
10
|
]
|
|
@@ -24,12 +24,12 @@ classifiers = [
|
|
|
24
24
|
"Topic :: Home Automation",
|
|
25
25
|
]
|
|
26
26
|
dependencies = [
|
|
27
|
-
"aiohttp>=3.11.0",
|
|
27
|
+
"aiohttp>=3.11.0,<3.14",
|
|
28
28
|
]
|
|
29
29
|
|
|
30
30
|
[project.optional-dependencies]
|
|
31
31
|
test = [
|
|
32
|
-
"aioresponses>=0.7.
|
|
32
|
+
"aioresponses>=0.7.8",
|
|
33
33
|
"pytest>=8.3",
|
|
34
34
|
"pytest-asyncio>=0.24",
|
|
35
35
|
]
|
|
@@ -45,13 +45,13 @@ asyncio_mode = "auto"
|
|
|
45
45
|
|
|
46
46
|
[tool.ruff]
|
|
47
47
|
line-length = 100
|
|
48
|
-
target-version = "0.0.
|
|
48
|
+
target-version = "0.0.26"
|
|
49
49
|
|
|
50
50
|
[tool.ruff.lint]
|
|
51
51
|
select = ["E", "F", "W", "I", "UP"]
|
|
52
52
|
ignore = ["E501"]
|
|
53
53
|
|
|
54
54
|
[tool.mypy]
|
|
55
|
-
python_version = "0.0.
|
|
55
|
+
python_version = "0.0.26"
|
|
56
56
|
warn_return_any = true
|
|
57
57
|
warn_unused_configs = true
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# violet-poolController-api - API für Violet Pool Controller
|
|
2
|
+
# Copyright (C) 2024-2026 Xerolux
|
|
3
|
+
#
|
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU Affero General Public License as published
|
|
6
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU Affero General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+
"""Pytest configuration and fixtures."""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from inspect import signature
|
|
22
|
+
|
|
23
|
+
import aiohttp.client_reqrep
|
|
24
|
+
|
|
25
|
+
_original_client_response_init = aiohttp.client_reqrep.ClientResponse.__init__
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _patched_client_response_init(
|
|
29
|
+
self: aiohttp.client_reqrep.ClientResponse,
|
|
30
|
+
*args: object,
|
|
31
|
+
**kwargs: object,
|
|
32
|
+
) -> None:
|
|
33
|
+
"""Patched ClientResponse.__init__ that adds stream_writer if missing."""
|
|
34
|
+
sig = signature(_original_client_response_init)
|
|
35
|
+
if "stream_writer" in sig.parameters and "stream_writer" not in kwargs:
|
|
36
|
+
kwargs["stream_writer"] = None
|
|
37
|
+
_original_client_response_init(self, *args, **kwargs)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
aiohttp.client_reqrep.ClientResponse.__init__ = _patched_client_response_init
|