python-duco-connectivity 0.11.0__tar.gz → 0.12.0__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.
- {python_duco_connectivity-0.11.0/src/python_duco_connectivity.egg-info → python_duco_connectivity-0.12.0}/PKG-INFO +2 -1
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/README.md +1 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/pyproject.toml +1 -1
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/client.py +32 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0/src/python_duco_connectivity.egg-info}/PKG-INFO +2 -1
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_client.py +75 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/LICENSE +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/setup.cfg +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/__init__.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/__main__.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/cli.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/exceptions.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/models.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/py.typed +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/python_duco_connectivity.egg-info/SOURCES.txt +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/python_duco_connectivity.egg-info/dependency_links.txt +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/python_duco_connectivity.egg-info/entry_points.txt +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/python_duco_connectivity.egg-info/requires.txt +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/python_duco_connectivity.egg-info/top_level.txt +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_api_reference.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_cli.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_exceptions.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_local_sample_validation.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_models.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_pytest_live_support.py +0 -0
- {python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_replay_helpers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-duco-connectivity
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.0
|
|
4
4
|
Summary: Async HTTP client for the local Duco Connectivity API
|
|
5
5
|
Author: Ronald van der Meer
|
|
6
6
|
License-Expression: MIT
|
|
@@ -184,6 +184,7 @@ For local function probes without activating the environment first:
|
|
|
184
184
|
.venv/bin/python -m duco_connectivity --host 192.168.1.10 call async_get_board_info
|
|
185
185
|
.venv/bin/duco-probe --host 192.168.1.10 call async_get_board_info
|
|
186
186
|
.venv/bin/duco-probe --host 192.168.1.10 call async_get_ventilation_temperature_info
|
|
187
|
+
.venv/bin/duco-probe --host 192.168.1.10 call async_get_bypass_supply_temperature_targets
|
|
187
188
|
.venv/bin/duco-probe --host 192.168.1.10 call async_get_bypass_supply_temperature_target --kwargs '{"zone_id": 1}'
|
|
188
189
|
```
|
|
189
190
|
|
|
@@ -152,6 +152,7 @@ For local function probes without activating the environment first:
|
|
|
152
152
|
.venv/bin/python -m duco_connectivity --host 192.168.1.10 call async_get_board_info
|
|
153
153
|
.venv/bin/duco-probe --host 192.168.1.10 call async_get_board_info
|
|
154
154
|
.venv/bin/duco-probe --host 192.168.1.10 call async_get_ventilation_temperature_info
|
|
155
|
+
.venv/bin/duco-probe --host 192.168.1.10 call async_get_bypass_supply_temperature_targets
|
|
155
156
|
.venv/bin/duco-probe --host 192.168.1.10 call async_get_bypass_supply_temperature_target --kwargs '{"zone_id": 1}'
|
|
156
157
|
```
|
|
157
158
|
|
{python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/client.py
RENAMED
|
@@ -400,6 +400,19 @@ class DucoClient:
|
|
|
400
400
|
|
|
401
401
|
return cls._build_bypass_supply_temperature_target(zone_id, raw_value)
|
|
402
402
|
|
|
403
|
+
@classmethod
|
|
404
|
+
def _extract_bypass_supply_temperature_targets(
|
|
405
|
+
cls,
|
|
406
|
+
config: Config,
|
|
407
|
+
) -> dict[int, BypassSupplyTemperatureTarget]:
|
|
408
|
+
"""Read all bypass supply targets from a typed config response."""
|
|
409
|
+
return {
|
|
410
|
+
zone_id: target
|
|
411
|
+
for zone_id in range(1, 9)
|
|
412
|
+
if (target := cls._extract_bypass_supply_temperature_target(config, zone_id))
|
|
413
|
+
is not None
|
|
414
|
+
}
|
|
415
|
+
|
|
403
416
|
@staticmethod
|
|
404
417
|
def _read_scalar_value(payload: dict[str, Any], key: str) -> Any:
|
|
405
418
|
raw_value = payload[key]
|
|
@@ -2318,6 +2331,25 @@ class DucoClient:
|
|
|
2318
2331
|
raise DucoError(msg)
|
|
2319
2332
|
return target
|
|
2320
2333
|
|
|
2334
|
+
async def async_get_bypass_supply_temperature_targets(
|
|
2335
|
+
self,
|
|
2336
|
+
) -> dict[int, BypassSupplyTemperatureTarget]:
|
|
2337
|
+
"""Return all bypass supply targets exposed through `/config` in Celsius."""
|
|
2338
|
+
try:
|
|
2339
|
+
config = await self.async_get_config(
|
|
2340
|
+
module=ConfigModuleSelector.HEAT_RECOVERY,
|
|
2341
|
+
submodule=ConfigHeatRecoverySubmoduleSelector.BYPASS,
|
|
2342
|
+
)
|
|
2343
|
+
except DucoResponseError as err:
|
|
2344
|
+
if _is_unsupported_optional_endpoint_error(err, "/config"):
|
|
2345
|
+
raise DucoUnsupportedCapabilityError(
|
|
2346
|
+
err.status,
|
|
2347
|
+
err.path,
|
|
2348
|
+
err.body,
|
|
2349
|
+
) from err
|
|
2350
|
+
raise
|
|
2351
|
+
return self._extract_bypass_supply_temperature_targets(config)
|
|
2352
|
+
|
|
2321
2353
|
async def async_set_bypass_supply_temperature_target(
|
|
2322
2354
|
self,
|
|
2323
2355
|
zone_id: int,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-duco-connectivity
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.12.0
|
|
4
4
|
Summary: Async HTTP client for the local Duco Connectivity API
|
|
5
5
|
Author: Ronald van der Meer
|
|
6
6
|
License-Expression: MIT
|
|
@@ -184,6 +184,7 @@ For local function probes without activating the environment first:
|
|
|
184
184
|
.venv/bin/python -m duco_connectivity --host 192.168.1.10 call async_get_board_info
|
|
185
185
|
.venv/bin/duco-probe --host 192.168.1.10 call async_get_board_info
|
|
186
186
|
.venv/bin/duco-probe --host 192.168.1.10 call async_get_ventilation_temperature_info
|
|
187
|
+
.venv/bin/duco-probe --host 192.168.1.10 call async_get_bypass_supply_temperature_targets
|
|
187
188
|
.venv/bin/duco-probe --host 192.168.1.10 call async_get_bypass_supply_temperature_target --kwargs '{"zone_id": 1}'
|
|
188
189
|
```
|
|
189
190
|
|
|
@@ -3794,6 +3794,81 @@ async def test_get_bypass_supply_temperature_target_returns_converted_values(
|
|
|
3794
3794
|
}
|
|
3795
3795
|
|
|
3796
3796
|
|
|
3797
|
+
async def test_get_bypass_supply_temperature_targets_returns_available_targets(
|
|
3798
|
+
config_data: dict[str, object],
|
|
3799
|
+
) -> None:
|
|
3800
|
+
"""Bulk bypass target reads should return all available targets in Celsius."""
|
|
3801
|
+
mock_response = _response(json_payload=config_data)
|
|
3802
|
+
|
|
3803
|
+
async with aiohttp.ClientSession() as session:
|
|
3804
|
+
client = DucoClient(session=session, host="192.0.2.94")
|
|
3805
|
+
request_mock = _request(mock_response)
|
|
3806
|
+
with patch.object(session, "request", request_mock):
|
|
3807
|
+
targets = await client.async_get_bypass_supply_temperature_targets()
|
|
3808
|
+
|
|
3809
|
+
assert targets == {
|
|
3810
|
+
1: BypassSupplyTemperatureTarget(
|
|
3811
|
+
zone_id=1,
|
|
3812
|
+
value=18.0,
|
|
3813
|
+
minimum=12.0,
|
|
3814
|
+
increment=0.5,
|
|
3815
|
+
maximum=22.0,
|
|
3816
|
+
),
|
|
3817
|
+
2: BypassSupplyTemperatureTarget(
|
|
3818
|
+
zone_id=2,
|
|
3819
|
+
value=18.5,
|
|
3820
|
+
minimum=12.0,
|
|
3821
|
+
increment=0.5,
|
|
3822
|
+
maximum=22.0,
|
|
3823
|
+
),
|
|
3824
|
+
}
|
|
3825
|
+
assert request_mock.call_args.kwargs["params"] == {
|
|
3826
|
+
"module": "HeatRecovery",
|
|
3827
|
+
"submodule": "Bypass",
|
|
3828
|
+
}
|
|
3829
|
+
|
|
3830
|
+
|
|
3831
|
+
async def test_get_bypass_supply_temperature_targets_returns_empty_when_absent() -> None:
|
|
3832
|
+
"""Bulk bypass target reads should omit targets absent from the response."""
|
|
3833
|
+
mock_response = _response(json_payload={"HeatRecovery": {"Bypass": {}}})
|
|
3834
|
+
|
|
3835
|
+
async with aiohttp.ClientSession() as session:
|
|
3836
|
+
client = DucoClient(session=session, host="192.0.2.94")
|
|
3837
|
+
with patch.object(session, "request", _request(mock_response)):
|
|
3838
|
+
targets = await client.async_get_bypass_supply_temperature_targets()
|
|
3839
|
+
|
|
3840
|
+
assert targets == {}
|
|
3841
|
+
|
|
3842
|
+
|
|
3843
|
+
async def test_get_bypass_supply_temperature_targets_raises_when_unsupported() -> None:
|
|
3844
|
+
"""Unsupported bulk bypass target reads should raise a typed capability error."""
|
|
3845
|
+
mock_response = _response(
|
|
3846
|
+
status=400,
|
|
3847
|
+
text_payload='{"Code":3,"Result":"FAILED"}',
|
|
3848
|
+
)
|
|
3849
|
+
|
|
3850
|
+
async with aiohttp.ClientSession() as session:
|
|
3851
|
+
client = DucoClient(session=session, host="192.0.2.94")
|
|
3852
|
+
with (
|
|
3853
|
+
patch.object(session, "request", _request(mock_response)),
|
|
3854
|
+
pytest.raises(DucoUnsupportedCapabilityError),
|
|
3855
|
+
):
|
|
3856
|
+
await client.async_get_bypass_supply_temperature_targets()
|
|
3857
|
+
|
|
3858
|
+
|
|
3859
|
+
async def test_get_bypass_supply_temperature_targets_reraises_other_client_errors() -> None:
|
|
3860
|
+
"""Unexpected bulk bypass target failures should remain visible to callers."""
|
|
3861
|
+
mock_response = _response(status=400, text_payload='{"Code":4,"Result":"FAILED"}')
|
|
3862
|
+
|
|
3863
|
+
async with aiohttp.ClientSession() as session:
|
|
3864
|
+
client = DucoClient(session=session, host="192.0.2.94")
|
|
3865
|
+
with (
|
|
3866
|
+
patch.object(session, "request", _request(mock_response)),
|
|
3867
|
+
pytest.raises(DucoResponseError),
|
|
3868
|
+
):
|
|
3869
|
+
await client.async_get_bypass_supply_temperature_targets()
|
|
3870
|
+
|
|
3871
|
+
|
|
3797
3872
|
async def test_get_bypass_supply_temperature_target_raises_when_not_reported() -> None:
|
|
3798
3873
|
"""Missing bypass targets should fail for parameter-specific helper reads."""
|
|
3799
3874
|
mock_response = _response(json_payload={"HeatRecovery": {"Bypass": {}}})
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/cli.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/models.py
RENAMED
|
File without changes
|
{python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/src/duco_connectivity/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_api_reference.py
RENAMED
|
File without changes
|
|
File without changes
|
{python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_duco_connectivity-0.11.0 → python_duco_connectivity-0.12.0}/tests/test_replay_helpers.py
RENAMED
|
File without changes
|