mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Fix has_hot_water_cylinder derivation to lodge the string convention, not a bool
The prior commit derived a Python bool (`cylinder_size != 1`), but `from_rdsap_schema_17_1` reads the field via `schema.has_hot_water_cylinder == "true"` — every real 15.0/16.x fixture lodges the lowercase string "true"/"false", not a JSON boolean. A bare bool compares False against that string check either way, so the derivation silently mapped every cylinder-present cert to has_hot_water_cylinder=False too. Caught by the requested true-branch test (mutating sap_16_2.json, which lodges cylinder_size=2/has_hot_water_cylinder="true", to omit the field) — it failed under the original bool-typed fix. Now emits "true"/"false" strings to match the lodged convention. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
4f9bec7a4a
commit
c0b4fd1e6a
2 changed files with 25 additions and 4 deletions
|
|
@ -4000,19 +4000,25 @@ def _normalize_sap_schema_16_x(data: Dict[str, Any]) -> Dict[str, Any]:
|
|||
|
||||
# Some 16.x/15.0 certs (e.g. cert 9568-3034-6211-6089-5960, UPRN
|
||||
# 100010349400, SAP-Schema-15.0) lodge `sap_heating.cylinder_size` but
|
||||
# omit the top-level `has_hot_water_cylinder` boolean entirely —
|
||||
# omit the top-level `has_hot_water_cylinder` field entirely —
|
||||
# RdSapSchema17_1 requires both as independent fields. Unlike
|
||||
# `multiple_glazed_proportion` above, this is NOT a guess: RdSAP 10
|
||||
# §10.5's `cylinder_size` code 1 means "no cylinder" by definition
|
||||
# (see `_CYLINDER_SIZE_CODE_TO_LITRES` / cert_to_inputs.py:5902), the
|
||||
# exact same fact `has_hot_water_cylinder` encodes — confirmed 1:1
|
||||
# across every real 15.0/16.x fixture that lodges both fields
|
||||
# (cylinder_size == 1 <-> has_hot_water_cylinder == false, every
|
||||
# other code <-> true). Derive rather than leave the cert unmappable.
|
||||
# (cylinder_size == 1 <-> has_hot_water_cylinder == "false", every
|
||||
# other code <-> "true"). Derive rather than leave the cert
|
||||
# unmappable. Lodged as the lowercase string "true"/"false" (RdSAP
|
||||
# convention every real fixture uses — `from_rdsap_schema_17_1`
|
||||
# reads it via `schema.has_hot_water_cylinder == "true"`, a bare
|
||||
# Python bool would silently compare False either way).
|
||||
if "has_hot_water_cylinder" not in d:
|
||||
cylinder_size = heating.get("cylinder_size")
|
||||
if isinstance(cylinder_size, int):
|
||||
d["has_hot_water_cylinder"] = cylinder_size != 1
|
||||
d["has_hot_water_cylinder"] = (
|
||||
"true" if cylinder_size != 1 else "false"
|
||||
)
|
||||
|
||||
for bp in _dicts(d.get("sap_building_parts")):
|
||||
for fd in _dicts(bp.get("sap_floor_dimensions")):
|
||||
|
|
|
|||
|
|
@ -107,3 +107,18 @@ class TestFromSapSchema15_0:
|
|||
|
||||
assert epc.has_hot_water_cylinder is False
|
||||
assert epc.sap_heating.cylinder_size == 1
|
||||
|
||||
def test_derives_has_hot_water_cylinder_true_from_a_sized_cylinder(
|
||||
self,
|
||||
) -> None:
|
||||
# Mirror of the above for the other branch: a lodged size code other
|
||||
# than 1 (here 2 = Normal/110L, per sap_16_2.json) means a cylinder
|
||||
# IS present, so an omitted `has_hot_water_cylinder` must derive
|
||||
# True — not just default-False by omission.
|
||||
data = load("sap_16_2.json")
|
||||
assert data["sap_heating"]["cylinder_size"] == 2
|
||||
del data["has_hot_water_cylinder"]
|
||||
|
||||
epc = EpcPropertyDataMapper.from_api_response(data)
|
||||
|
||||
assert epc.has_hot_water_cylinder is True
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue