diff --git a/domain/sap10_calculator/rdsap/cert_to_inputs.py b/domain/sap10_calculator/rdsap/cert_to_inputs.py index 5bb76429d..22d379c32 100644 --- a/domain/sap10_calculator/rdsap/cert_to_inputs.py +++ b/domain/sap10_calculator/rdsap/cert_to_inputs.py @@ -7126,6 +7126,20 @@ def _cylinder_storage_loss_override( insulation_label, thickness_mm = "loose_jacket", 0.0 if insulation_label is None and thickness_mm == 0.0: insulation_label = "loose_jacket" + # RdSAP 10 Table 29 (PDF p.56) "Hot water cylinder insulation if not + # accessible": a lodged cylinder with NO insulation data at all takes + # the age-band default — the same row the §10.7 no-water-heating + # default uses. An ABSENT thickness means not accessible (Table 29); + # a lodged 0 mm means uninsulated (handled above). When the age band + # itself is unresolvable, fall through to the legacy None (zero loss) + # rather than raising mid-rebaseline. + if insulation_label is None and thickness_mm is None: + band = (_dwelling_age_band(epc) or "")[:1].upper() + table_29_default = _TABLE_29_DEFAULT_CYLINDER_INSULATION_BY_AGE.get(band) + if table_29_default is not None: + default_code, default_mm = table_29_default + insulation_label = _cylinder_storage_loss_insulation_label(default_code) + thickness_mm = float(default_mm) if insulation_label is None: return None if thickness_mm is None: