Carry donor's display heating + control into predicted EPC 🟩

_apply_heating_donor now also deepcopies the donor's main_heating and
main_heating_controls EnergyElements alongside its calc sap_heating cluster, so
the building-passport heating rows are coherent with the donated system and a
control row the size-template lacked (but the donor lodges) is populated. Fixes
'Heating Control: Unknown' on predicted properties (e.g. 721167). Display-only:
component-accuracy gate + corpus harness unchanged (26/6 green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-26 10:44:05 +00:00
parent 5cf5b67420
commit 44726469d4

View file

@ -93,7 +93,15 @@ class EpcPrediction:
electricity tariff (`sap_energy_source.meter_type`) and hot-water flags
live on loose top-level fields. Carry the donor's whole set, not a subset
otherwise a donated storage system lands on the template's single-rate
meter and the SAP score collapses (off-peak heat billed at the peak rate)."""
meter and the SAP score collapses (off-peak heat billed at the peak rate).
The system also has a DISPLAY face the building-passport "Main Heating"
and "Heating Control" rows (`main_heating` / `main_heating_controls`
EnergyElements). These describe the same system as the calc cluster, so
they travel with the donor too; left on the structural template they are
incoherent with the donated calc heating, and `main_heating_controls`
shows "Unknown" whenever the size-template lodged no control row but the
donor does (predicted property 721167, ADR-0029 follow-up)."""
donor = _heating_donor(comparables.members)
if donor is None:
return
@ -101,6 +109,10 @@ class EpcPrediction:
predicted.has_hot_water_cylinder = donor.epc.has_hot_water_cylinder
predicted.solar_water_heating = donor.epc.solar_water_heating
predicted.sap_energy_source.meter_type = donor.epc.sap_energy_source.meter_type
predicted.main_heating = copy.deepcopy(donor.epc.main_heating)
predicted.main_heating_controls = copy.deepcopy(
donor.epc.main_heating_controls
)
@staticmethod
def _apply_glazing_mode(