python-bsblan 6.1.0__tar.gz → 6.1.1__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_bsblan-6.1.0 → python_bsblan-6.1.1}/PKG-INFO +1 -1
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/examples/control.py +23 -3
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/pyproject.toml +1 -1
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/src/bsblan/bsblan.py +33 -4
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/src/bsblan/constants.py +4 -4
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/src/bsblan/models.py +7 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/dict_version.json +2 -2
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_circuit.py +8 -8
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_constants.py +4 -4
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_include_parameter.py +5 -2
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_static_state.py +5 -4
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_temperature_validation.py +6 -1
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_utility_additional.py +2 -2
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.editorconfig +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.gitattributes +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/CODE_OF_CONDUCT.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/CONTRIBUTING.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/ISSUE_TEMPLATE/PULL_REQUEST_TEMPLATE.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/SECURITY.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/agents/security-reviewer.agent.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/copilot-instructions.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/hooks/run-validation-after-edits.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/hooks/run_validation_after_edits.sh +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/labels.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/prompts/add-parameter.prompt.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/prompts/code-review.prompt.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/release-drafter.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/renovate.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/skills/bsblan-parameters/SKILL.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/skills/bsblan-testing/SKILL.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/skills/feature-doc-updates/SKILL.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/auto-approve-renovate.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/codeql.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/dependency-review.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/docs.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/labels.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/linting.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/lock.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/pr-labels.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/release-drafter.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/release.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/scorecard.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/stale.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/tests.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/workflows/typing.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.github/zizmor.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.gitignore +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.nvmrc +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.pre-commit-config.yaml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.prettierignore +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/.yamllint +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/AGENTS.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/CLAUDE.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/LICENSE.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/Makefile +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/README.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/docs/api/client.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/docs/api/constants.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/docs/api/exceptions.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/docs/api/models.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/docs/getting-started.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/docs/index.md +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/examples/discovery.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/examples/fetch_param.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/examples/profile_init.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/examples/ruff.toml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/examples/speed_test.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/mkdocs.yml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/package-lock.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/package.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/sonar-project.properties +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/src/bsblan/__init__.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/src/bsblan/exceptions.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/src/bsblan/py.typed +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/src/bsblan/utility.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/__init__.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/conftest.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/device.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/hot_water_state.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/info.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/password.txt +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/pps_device.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/pps_state.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/pps_static_values.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/sensor.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/state.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/state_circuit2.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/static_state.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/static_state_circuit2.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/thermostat_hvac.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/thermostat_temp.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/fixtures/time.json +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/ruff.toml +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_api_initialization.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_api_validation.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_auth.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_backoff_retry.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_bsblan.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_bsblan_edge_cases.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_configuration.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_context_manager.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_device.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_dhw_time_switch.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_entity_info.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_entity_info_ha.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_heating_schedule.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_hot_water_additional.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_hotwater_state.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_info.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_initialization.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_pps.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_read_parameters.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_reset_validation.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_schedule_models.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_sensor.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_set_heating_schedule.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_set_hot_water_schedule.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_set_hotwater.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_state.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_temperature_unit.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_thermostat.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_time.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_utility.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_utility_edge_cases.py +0 -0
- {python_bsblan-6.1.0 → python_bsblan-6.1.1}/tests/test_version_errors.py +0 -0
|
@@ -192,6 +192,22 @@ def print_device_info(device: Device, info: Info) -> None:
|
|
|
192
192
|
print_attributes("Device Information", attributes)
|
|
193
193
|
|
|
194
194
|
|
|
195
|
+
def _first_temperature_attribute(static_state: StaticState) -> Any:
|
|
196
|
+
"""Return the first available temperature attribute for unit detection."""
|
|
197
|
+
for attribute in (
|
|
198
|
+
static_state.heating_protective_setpoint,
|
|
199
|
+
static_state.temp_reduced_setpoint,
|
|
200
|
+
static_state.comfort_setpoint_max,
|
|
201
|
+
static_state.min_temp,
|
|
202
|
+
static_state.max_temp,
|
|
203
|
+
static_state.cooling_comfort_setpoint_min,
|
|
204
|
+
static_state.cooling_reduced_setpoint,
|
|
205
|
+
):
|
|
206
|
+
if attribute is not None:
|
|
207
|
+
return attribute
|
|
208
|
+
return None
|
|
209
|
+
|
|
210
|
+
|
|
195
211
|
def print_static_state(static_state: StaticState) -> None:
|
|
196
212
|
"""Print static state information, including heating and cooling bounds.
|
|
197
213
|
|
|
@@ -200,8 +216,10 @@ def print_static_state(static_state: StaticState) -> None:
|
|
|
200
216
|
|
|
201
217
|
"""
|
|
202
218
|
attributes = {
|
|
203
|
-
"
|
|
204
|
-
|
|
219
|
+
"Reduced Setpoint (eco/night)": get_attribute(
|
|
220
|
+
static_state.temp_reduced_setpoint
|
|
221
|
+
),
|
|
222
|
+
"Comfort Setpoint Max": get_attribute(static_state.comfort_setpoint_max),
|
|
205
223
|
"Heating Protective Setpoint": get_attribute(
|
|
206
224
|
static_state.heating_protective_setpoint
|
|
207
225
|
),
|
|
@@ -211,7 +229,9 @@ def print_static_state(static_state: StaticState) -> None:
|
|
|
211
229
|
"Cooling Setpoint Max (reduced)": get_attribute(
|
|
212
230
|
static_state.cooling_reduced_setpoint
|
|
213
231
|
),
|
|
214
|
-
"Temperature Unit": get_attribute(
|
|
232
|
+
"Temperature Unit": get_attribute(
|
|
233
|
+
_first_temperature_attribute(static_state), "unit"
|
|
234
|
+
),
|
|
215
235
|
}
|
|
216
236
|
print_attributes("Static State", attributes)
|
|
217
237
|
|
|
@@ -631,16 +631,45 @@ class BSBLAN:
|
|
|
631
631
|
)
|
|
632
632
|
return temp_range
|
|
633
633
|
|
|
634
|
-
|
|
635
|
-
|
|
634
|
+
# Prefer heating_protective_setpoint (714/1014) as the true lower bound
|
|
635
|
+
# for standard circuits. Fall back to min_temp for PPS circuits (15006)
|
|
636
|
+
# which have no separate protective setpoint. Skip sources whose value is
|
|
637
|
+
# inactive (BSB-LAN may return "---" which becomes value=None).
|
|
638
|
+
min_source = next(
|
|
639
|
+
(
|
|
640
|
+
source
|
|
641
|
+
for source in (
|
|
642
|
+
static_values.heating_protective_setpoint,
|
|
643
|
+
static_values.min_temp,
|
|
644
|
+
)
|
|
645
|
+
if source is not None and source.value is not None
|
|
646
|
+
),
|
|
647
|
+
None,
|
|
648
|
+
)
|
|
649
|
+
if min_source is not None:
|
|
650
|
+
temp_range["min"] = min_source.value
|
|
636
651
|
logger.debug(
|
|
637
652
|
"Circuit %d min temp initialized: %s",
|
|
638
653
|
circuit,
|
|
639
654
|
temp_range["min"],
|
|
640
655
|
)
|
|
641
656
|
|
|
642
|
-
|
|
643
|
-
|
|
657
|
+
# Prefer comfort_setpoint_max (716/1016) as the upper bound for standard
|
|
658
|
+
# circuits. Fall back to max_temp for PPS circuits (15007) which expose
|
|
659
|
+
# only a generic max. Skip sources whose value is inactive.
|
|
660
|
+
max_source = next(
|
|
661
|
+
(
|
|
662
|
+
source
|
|
663
|
+
for source in (
|
|
664
|
+
static_values.comfort_setpoint_max,
|
|
665
|
+
static_values.max_temp,
|
|
666
|
+
)
|
|
667
|
+
if source is not None and source.value is not None
|
|
668
|
+
),
|
|
669
|
+
None,
|
|
670
|
+
)
|
|
671
|
+
if max_source is not None:
|
|
672
|
+
temp_range["max"] = max_source.value
|
|
644
673
|
logger.debug(
|
|
645
674
|
"Circuit %d max temp initialized: %s",
|
|
646
675
|
circuit,
|
|
@@ -40,9 +40,9 @@ BASE_HEATING_PARAMS: Final[dict[str, str]] = {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
BASE_STATIC_VALUES_PARAMS: Final[dict[str, str]] = {
|
|
43
|
-
"712": "
|
|
43
|
+
"712": "temp_reduced_setpoint",
|
|
44
44
|
"714": "heating_protective_setpoint",
|
|
45
|
-
"716": "
|
|
45
|
+
"716": "comfort_setpoint_max",
|
|
46
46
|
"905": "cooling_comfort_setpoint_min",
|
|
47
47
|
"903": "cooling_reduced_setpoint",
|
|
48
48
|
}
|
|
@@ -107,9 +107,9 @@ BASE_HEATING_CIRCUIT2_PARAMS: Final[dict[str, str]] = {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
BASE_STATIC_VALUES_CIRCUIT2_PARAMS: Final[dict[str, str]] = {
|
|
110
|
-
"1012": "
|
|
110
|
+
"1012": "temp_reduced_setpoint",
|
|
111
111
|
"1014": "heating_protective_setpoint",
|
|
112
|
-
"1016": "
|
|
112
|
+
"1016": "comfort_setpoint_max",
|
|
113
113
|
"1205": "cooling_comfort_setpoint_min",
|
|
114
114
|
"1203": "cooling_reduced_setpoint",
|
|
115
115
|
}
|
|
@@ -479,8 +479,15 @@ class State(BaseModel):
|
|
|
479
479
|
class StaticState(BaseModel):
|
|
480
480
|
"""Class for entities that are not changing."""
|
|
481
481
|
|
|
482
|
+
# 712/1012: room temperature reduced (eco/night) setpoint
|
|
483
|
+
temp_reduced_setpoint: EntityInfo[float] | None = None
|
|
484
|
+
# PPS-only lower bound (15006)
|
|
482
485
|
min_temp: EntityInfo[float] | None = None
|
|
486
|
+
# 716/1016: comfort setpoint max upper bound
|
|
487
|
+
comfort_setpoint_max: EntityInfo[float] | None = None
|
|
488
|
+
# PPS-only upper bound (15007)
|
|
483
489
|
max_temp: EntityInfo[float] | None = None
|
|
490
|
+
# 714/1014: frost-protection lower bound
|
|
484
491
|
heating_protective_setpoint: EntityInfo[float] | None = None
|
|
485
492
|
cooling_comfort_setpoint_min: EntityInfo[float] | None = None
|
|
486
493
|
cooling_reduced_setpoint: EntityInfo[float] | None = None
|
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
"8740": "current_temperature"
|
|
8
8
|
},
|
|
9
9
|
"staticValues": {
|
|
10
|
-
"712": "
|
|
10
|
+
"712": "temp_reduced_setpoint",
|
|
11
11
|
"714": "heating_protective_setpoint",
|
|
12
|
-
"716": "
|
|
12
|
+
"716": "comfort_setpoint_max"
|
|
13
13
|
},
|
|
14
14
|
"device": {
|
|
15
15
|
"6224": "device_identification",
|
|
@@ -225,10 +225,10 @@ async def test_static_values_circuit2(monkeypatch: Any) -> None:
|
|
|
225
225
|
static: StaticState = await bsblan.static_values(circuit=2)
|
|
226
226
|
|
|
227
227
|
assert isinstance(static, StaticState)
|
|
228
|
-
assert static.
|
|
229
|
-
assert static.
|
|
230
|
-
assert static.
|
|
231
|
-
assert static.
|
|
228
|
+
assert static.temp_reduced_setpoint is not None
|
|
229
|
+
assert static.temp_reduced_setpoint.value == 16.0
|
|
230
|
+
assert static.comfort_setpoint_max is not None
|
|
231
|
+
assert static.comfort_setpoint_max.value == 28.0
|
|
232
232
|
assert static.heating_protective_setpoint is not None
|
|
233
233
|
assert static.heating_protective_setpoint.value == 8.0
|
|
234
234
|
assert static.cooling_comfort_setpoint_min is not None
|
|
@@ -490,7 +490,7 @@ async def test_circuit2_temp_range_initialization(
|
|
|
490
490
|
await bsblan._initialize_temperature_range(circuit=2)
|
|
491
491
|
|
|
492
492
|
assert 2 in bsblan._circuit_temp_initialized
|
|
493
|
-
assert bsblan._circuit_temp_ranges[2]["min"] ==
|
|
493
|
+
assert bsblan._circuit_temp_ranges[2]["min"] == 8.0
|
|
494
494
|
assert bsblan._circuit_temp_ranges[2]["max"] == 28.0
|
|
495
495
|
assert bsblan._circuit_temp_ranges[2]["cooling_min"] == 18.0
|
|
496
496
|
assert bsblan._circuit_temp_ranges[2]["cooling_max"] == 26.0
|
|
@@ -526,11 +526,11 @@ async def test_circuit1_temp_range_uses_reduced_lower_bound(
|
|
|
526
526
|
await bsblan._initialize_temperature_range(circuit=1)
|
|
527
527
|
|
|
528
528
|
assert 1 in bsblan._circuit_temp_initialized
|
|
529
|
-
assert bsblan._circuit_temp_ranges[1]["min"] ==
|
|
529
|
+
assert bsblan._circuit_temp_ranges[1]["min"] == 8.0
|
|
530
530
|
assert bsblan._circuit_temp_ranges[1]["max"] == 23.0
|
|
531
531
|
|
|
532
532
|
with pytest.raises(BSBLANInvalidParameterError):
|
|
533
|
-
await bsblan._validate_target_temperature("
|
|
533
|
+
await bsblan._validate_target_temperature("7.5", circuit=1)
|
|
534
534
|
|
|
535
535
|
|
|
536
536
|
@pytest.mark.asyncio
|
|
@@ -584,7 +584,7 @@ async def test_thermostat_circuit2_lazy_temp_init(
|
|
|
584
584
|
|
|
585
585
|
# Verify it was initialized
|
|
586
586
|
assert 2 in bsblan._circuit_temp_initialized
|
|
587
|
-
assert bsblan._circuit_temp_ranges[2]["min"] ==
|
|
587
|
+
assert bsblan._circuit_temp_ranges[2]["min"] == 8.0
|
|
588
588
|
assert bsblan._circuit_temp_ranges[2]["max"] == 28.0
|
|
589
589
|
|
|
590
590
|
|
|
@@ -128,14 +128,14 @@ def test_cooling_target_uses_single_base_parameter() -> None:
|
|
|
128
128
|
|
|
129
129
|
assert config["heating"]["902"] == "target_temperature_high"
|
|
130
130
|
assert config["heating_circuit2"]["1202"] == "target_temperature_high"
|
|
131
|
-
assert config["staticValues"]["712"] == "
|
|
131
|
+
assert config["staticValues"]["712"] == "temp_reduced_setpoint"
|
|
132
132
|
assert config["staticValues"]["714"] == "heating_protective_setpoint"
|
|
133
|
-
assert config["staticValues"]["716"] == "
|
|
133
|
+
assert config["staticValues"]["716"] == "comfort_setpoint_max"
|
|
134
134
|
assert config["staticValues"]["905"] == "cooling_comfort_setpoint_min"
|
|
135
135
|
assert config["staticValues"]["903"] == "cooling_reduced_setpoint"
|
|
136
|
-
assert config["staticValues_circuit2"]["1012"] == "
|
|
136
|
+
assert config["staticValues_circuit2"]["1012"] == "temp_reduced_setpoint"
|
|
137
137
|
assert config["staticValues_circuit2"]["1014"] == ("heating_protective_setpoint")
|
|
138
|
-
assert config["staticValues_circuit2"]["1016"] == "
|
|
138
|
+
assert config["staticValues_circuit2"]["1016"] == "comfort_setpoint_max"
|
|
139
139
|
assert config["staticValues_circuit2"]["1205"] == ("cooling_comfort_setpoint_min")
|
|
140
140
|
assert config["staticValues_circuit2"]["1203"] == "cooling_reduced_setpoint"
|
|
141
141
|
assert "908" not in config["staticValues"]
|
|
@@ -407,9 +407,12 @@ async def test_static_values_with_include(monkeypatch: Any) -> None:
|
|
|
407
407
|
request_mock: AsyncMock = AsyncMock(return_value=partial_response)
|
|
408
408
|
monkeypatch.setattr(bsblan, "_request", request_mock)
|
|
409
409
|
|
|
410
|
-
static: StaticState = await bsblan.static_values(
|
|
410
|
+
static: StaticState = await bsblan.static_values(
|
|
411
|
+
include=["temp_reduced_setpoint"]
|
|
412
|
+
)
|
|
411
413
|
|
|
412
|
-
assert static.
|
|
414
|
+
assert static.temp_reduced_setpoint is not None
|
|
415
|
+
assert static.min_temp is None
|
|
413
416
|
assert static.max_temp is None
|
|
414
417
|
|
|
415
418
|
|
|
@@ -40,10 +40,11 @@ async def test_sensor(monkeypatch: Any) -> None:
|
|
|
40
40
|
|
|
41
41
|
static: StaticState = await bsblan.static_values()
|
|
42
42
|
assert isinstance(static, StaticState)
|
|
43
|
-
assert static.
|
|
44
|
-
assert static.
|
|
45
|
-
assert static.
|
|
46
|
-
assert static.
|
|
43
|
+
assert static.temp_reduced_setpoint is not None
|
|
44
|
+
assert static.temp_reduced_setpoint.value == 17.0
|
|
45
|
+
assert static.min_temp is None
|
|
46
|
+
assert static.comfort_setpoint_max is not None
|
|
47
|
+
assert static.comfort_setpoint_max.value == 23.0
|
|
47
48
|
assert static.heating_protective_setpoint is not None
|
|
48
49
|
assert static.heating_protective_setpoint.value == 8.0
|
|
49
50
|
assert static.cooling_comfort_setpoint_min is not None
|
|
@@ -153,8 +153,11 @@ async def test_temperature_range_min_temp_not_available(monkeypatch: Any) -> Non
|
|
|
153
153
|
client._api_validator = APIValidator(client._api_data)
|
|
154
154
|
|
|
155
155
|
# Mock static_values to return data without min_temp
|
|
156
|
+
# Mock static_values without protective or pps min temp
|
|
156
157
|
static_values_mock = AsyncMock()
|
|
158
|
+
static_values_mock.return_value.heating_protective_setpoint = None
|
|
157
159
|
static_values_mock.return_value.min_temp = None
|
|
160
|
+
static_values_mock.return_value.comfort_setpoint_max = None
|
|
158
161
|
static_values_mock.return_value.max_temp = AsyncMock()
|
|
159
162
|
static_values_mock.return_value.max_temp.value = "30"
|
|
160
163
|
monkeypatch.setattr(client, "static_values", static_values_mock)
|
|
@@ -162,7 +165,7 @@ async def test_temperature_range_min_temp_not_available(monkeypatch: Any) -> Non
|
|
|
162
165
|
# This should log a warning
|
|
163
166
|
await client._initialize_temperature_range()
|
|
164
167
|
|
|
165
|
-
#
|
|
168
|
+
# min should remain None when neither protective nor pps min is available
|
|
166
169
|
temp_range = client._circuit_temp_ranges.get(1, {})
|
|
167
170
|
assert temp_range.get("min") is None
|
|
168
171
|
|
|
@@ -188,8 +191,10 @@ async def test_temperature_range_max_temp_not_available(monkeypatch: Any) -> Non
|
|
|
188
191
|
|
|
189
192
|
# Mock static_values to return data without max_temp
|
|
190
193
|
static_values_mock = AsyncMock()
|
|
194
|
+
static_values_mock.return_value.heating_protective_setpoint = None
|
|
191
195
|
static_values_mock.return_value.min_temp = AsyncMock()
|
|
192
196
|
static_values_mock.return_value.min_temp.value = "10"
|
|
197
|
+
static_values_mock.return_value.comfort_setpoint_max = None
|
|
193
198
|
static_values_mock.return_value.max_temp = None
|
|
194
199
|
monkeypatch.setattr(client, "static_values", static_values_mock)
|
|
195
200
|
|
|
@@ -41,9 +41,9 @@ def fresh_api_validator() -> APIValidator:
|
|
|
41
41
|
"710": "target_temperature",
|
|
42
42
|
},
|
|
43
43
|
"staticValues": {
|
|
44
|
-
"712": "
|
|
44
|
+
"712": "temp_reduced_setpoint",
|
|
45
45
|
"714": "heating_protective_setpoint",
|
|
46
|
-
"716": "
|
|
46
|
+
"716": "comfort_setpoint_max",
|
|
47
47
|
},
|
|
48
48
|
"hot_water": {
|
|
49
49
|
"8830": "dhw_actual_value_top_temperature",
|
|
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
|
|
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
|
|
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
|
|
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
|