mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Persist the measured at-rafters roof insulation thickness 🟥
RdSAP 10 §5.11.2 — a roof insulated at rafters lodges its thickness in `rafter_insulation_thickness`, not `roof_insulation_thickness`. The field had no DB column, so it was mapped from the gov-EPC API and silently dropped on save; every at-rafters roof then fell back to the Table 18 col (2) unknown-thickness default (2.30 W/m²K for bands A-D — the spec's *uninsulated* value). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ccba02b51a
commit
d2168d518f
1 changed files with 42 additions and 0 deletions
|
|
@ -240,3 +240,45 @@ def test_building_part_wall_insulation_thickness_preserves_int(
|
|||
value = reloaded.sap_building_parts[0].wall_insulation_thickness
|
||||
assert value == 100
|
||||
assert isinstance(value, int)
|
||||
|
||||
|
||||
def test_rafter_insulation_thickness_round_trips(db_engine: Engine) -> None:
|
||||
# RdSAP 10 §5.11.2 — a roof insulated AT RAFTERS lodges its insulation
|
||||
# thickness in `rafter_insulation_thickness`, NOT `roof_insulation_thickness`
|
||||
# (which stays null for rafter roofs, since rafters aren't loft joists).
|
||||
# `heat_transmission.py:922` prefers it when `roof_insulation_location == 1`
|
||||
# so the MEASURED Table 16 column (2) row applies. It had no DB column, so it
|
||||
# was silently dropped on save and every at-rafters roof fell back to the
|
||||
# Table 18 column (2) unknown-thickness default (persist != score).
|
||||
#
|
||||
# Real impact: property 749719 lodges "250mm" -> Table 16 col (2) U 0.23.
|
||||
# Dropped, the roof bills at U 2.30 — a 10x error worth -9.8 SAP (lodged 73,
|
||||
# calculated 63.2) that moved the dwelling a whole band, C -> D.
|
||||
#
|
||||
# Note this is an RdSAP INPUT (an insulation thickness feeding the standard
|
||||
# cascade), not a lodged U-value. The sibling `wall/roof/floor_u_value` and
|
||||
# `wall_is_basement` fields are full-SAP artefacts and are deliberately NOT
|
||||
# persisted — see the `_UNPERSISTED_ALLOWLIST` note in
|
||||
# test_epc_persistence_field_coverage.py.
|
||||
from dataclasses import replace
|
||||
|
||||
# Arrange — a green fixture carrying a measured at-rafters thickness.
|
||||
original = _load_epc("RdSAP-Schema-21.0.1")
|
||||
assert original.sap_building_parts, "fixture must have a building part"
|
||||
bp0 = replace(
|
||||
original.sap_building_parts[0],
|
||||
rafter_insulation_thickness="250mm",
|
||||
)
|
||||
original = replace(
|
||||
original, sap_building_parts=[bp0, *original.sap_building_parts[1:]]
|
||||
)
|
||||
|
||||
# Act
|
||||
with Session(db_engine) as session:
|
||||
epc_property_id = EpcPostgresRepository(session).save(original)
|
||||
session.commit()
|
||||
with Session(db_engine) as session:
|
||||
reloaded = EpcPostgresRepository(session).get(epc_property_id)
|
||||
|
||||
# Assert — the measured rafter thickness survives, deep-equal.
|
||||
assert reloaded == original
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue