mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
test(exposure): mid-floor-labelled flat with a lodged exposed roof 🟥
A gov-API cert can lodge dwelling_type="Mid-floor flat" while carrying a real exposed roof element (roof_construction != 7 "dwelling above") over a "(another dwelling below)" floor — i.e. a top-floor flat mislabelled mid-floor. Property 715363 (uprn 6027561) + sibling 715395 (6027563) do exactly this; the correctly-labelled top-floor sibling 715871 (6027574), same block + same flat roof, already computes the lodged SAP 74. _dwelling_exposure keys roof exposure on the dwelling_type label alone, so it drops the roof heat-loss term, under-reading space-heating demand ~32% (calc 1833 vs lodged RHI 2694) and over-reading SAP +7 (81 vs 74). Pins the fix: a mid-floor label + lodged exposed roof must expose the roof (floor stays party). Also corrects the existing mid-floor fixture to lodge the party-ceiling code 7 (the default 4 is an exposed pitched roof). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6303343575
commit
7a74aaecb9
1 changed files with 48 additions and 1 deletions
|
|
@ -5690,7 +5690,10 @@ def test_mid_floor_flat_dwelling_type_zeroes_floor_and_roof_heat_transmission()
|
|||
# Arrange — A "Mid-floor flat" has party floor (downstairs flat) and
|
||||
# party ceiling (upstairs flat). The mapper must wire DwellingExposure
|
||||
# to suppress both channels so the HLC matches what RdSAP-driven
|
||||
# assessor software produces.
|
||||
# assessor software produces. A genuine mid-floor flat lodges
|
||||
# roof_construction=7 ("dwelling above") — the party-ceiling code —
|
||||
# NOT an external-roof construction (the default 4 = exposed pitched
|
||||
# roof, which `_cert_lodges_exposed_roof` now reads as top-floor).
|
||||
epc = make_minimal_sap10_epc(
|
||||
total_floor_area_m2=_TYPICAL_TFA_M2,
|
||||
habitable_rooms_count=4,
|
||||
|
|
@ -5698,6 +5701,7 @@ def test_mid_floor_flat_dwelling_type_zeroes_floor_and_roof_heat_transmission()
|
|||
dwelling_type="Mid-floor flat",
|
||||
sap_building_parts=[
|
||||
make_building_part(
|
||||
roof_construction=7, # "dwelling above" — party ceiling
|
||||
floor_dimensions=[
|
||||
make_floor_dimension(total_floor_area_m2=_TYPICAL_TFA_M2, floor=0),
|
||||
],
|
||||
|
|
@ -5718,6 +5722,49 @@ def test_mid_floor_flat_dwelling_type_zeroes_floor_and_roof_heat_transmission()
|
|||
assert inputs.heat_transmission.walls_w_per_k > 0
|
||||
|
||||
|
||||
def test_mid_floor_label_with_exposed_roof_element_exposes_roof() -> None:
|
||||
# Arrange — gov-API certs lodge `dwelling_type` as the raw assessor
|
||||
# label, which can contradict the lodged fabric. Property 715363
|
||||
# (uprn 6027561) and its sibling 715395 (6027563) lodge
|
||||
# dwelling_type="Mid-floor flat" yet carry a real exposed flat roof
|
||||
# (roof_construction=1, "Flat", with lodged insulation) over a
|
||||
# "(another dwelling below)" floor — i.e. they are TOP-floor flats
|
||||
# mislabelled mid-floor. Keying roof exposure on the label alone
|
||||
# dropped the roof heat-loss term, under-reading space-heating demand
|
||||
# ~32% and over-reading SAP +7 (calc 81 vs lodged 74). The correctly
|
||||
# labelled top-floor sibling 715871 (6027574), same block + same flat
|
||||
# roof, already computes the lodged 74 — the ground truth here.
|
||||
#
|
||||
# The lodged roof element is the authoritative signal: an assessor
|
||||
# only lodges a non-party roof_construction (anything but 7 = "dwelling
|
||||
# above") when the roof is a heat-loss surface.
|
||||
epc = make_minimal_sap10_epc(
|
||||
total_floor_area_m2=_TYPICAL_TFA_M2,
|
||||
habitable_rooms_count=4,
|
||||
region_code="1",
|
||||
dwelling_type="Mid-floor flat",
|
||||
sap_building_parts=[
|
||||
make_building_part(
|
||||
roof_construction=1, # Flat — a genuine exposed roof
|
||||
floor_dimensions=[
|
||||
make_floor_dimension(total_floor_area_m2=_TYPICAL_TFA_M2, floor=0),
|
||||
],
|
||||
),
|
||||
],
|
||||
sap_heating=make_sap_heating(
|
||||
main_heating_details=[_gas_boiler_detail(sap_main_heating_code=102)],
|
||||
),
|
||||
)
|
||||
|
||||
# Act
|
||||
inputs = cert_to_inputs(epc)
|
||||
|
||||
# Assert — the floor stays party (dwelling below) but the lodged
|
||||
# exposed roof is honoured, matching the top-floor sibling.
|
||||
assert inputs.heat_transmission.floor_w_per_k == 0.0
|
||||
assert inputs.heat_transmission.roof_w_per_k > 0
|
||||
|
||||
|
||||
def test_top_floor_flat_keeps_roof_drops_floor() -> None:
|
||||
# Arrange — Top-floor flat: party floor, external roof.
|
||||
epc = make_minimal_sap10_epc(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue