Model/datatypes/epc
Khalim Conn-Kowlessar a002c7895f Slice S0380.175: Community heating main_heating_control extraction
SAP 10.2 Table 4e Group 3 (PDF p.173) — heat-network control codes
2301-2314 dispatch to control_type 1, 2, or 3. Code 2306 = "Charging
system linked to use of heating, programmer and TRVs" →
control_type=3, temperature_adjustment=0. Per Table 9 the elsewhere-
zone off-hours depend on control_type: type 1/2 → (7, 8); type 3 →
(9, 8). The two extra off-hours change the §7 (90) T_rest mean by
~0.6 K → (92) MIT by ~0.4 K → (98) SH demand by ~390 kWh/yr.

Pre-slice diagnosis: cascade defaulted `main_heating_control=2`
(modal RdSAP) when the §14.0 "Main Heating Controls Sap" field was
empty. The 5 community heating corpus variants ALL lodge the SAP
code in §14.1 Community Heating "Heating Controls SAP" instead
(format: bare 4-digit integer, e.g. "2306"). The extractor was
storing this in `CommunityHeating.heating_controls_sap` but the
mapper only read `mh.heating_controls_sap` (§14.0).

Two changes:

1. `_elmhurst_sap_control_code` extended to accept bare 4-digit form
   ("2306") in addition to the §14.0 narrative form ("SAP code 2106,
   Programmer, room thermostat and TRVs"). Empty-string returns None
   instead of swallowing through the original `re.match` regex.

2. `_map_elmhurst_sap_heating` falls through to
   `mh.community_heating.heating_controls_sap` when the §14.0 main
   block leaves `heating_controls_sap` empty.

Closures (heating-systems corpus 001431):
  CH1 ΔSAP_c -1.0572 → +0.0000  EXACT
      Δcost  +£24.36 → -£0.00   EXACT
  CH3 ΔSAP_c -1.0572 → +0.0000  EXACT
      Δcost  +£24.36 → -£0.00   EXACT
  CH2/CH4 SAP-side flip ±0.42 → ±0.53 (CHP-split blend reacts to
        the now-lower SH demand × CHP rate)
  CH6 ΔSAP_c -8.4406 → -7.4942 (DLF=1.0 P960 quirk untouched)

Remaining CH1/CH3 ΔCO2 -23.60 / ΔPE -208.23 is the §13a (372)
"Electrical energy for heat distribution" line (118.38 kWh × electric
factors 0.1993 CO2 / 1.760 PE). Cascade doesn't currently meter this
electricity overhead separately from heat-network heat — next slice.

932 pass + 0 fail (+5 new mapper tests). No regressions on the other
36 corpus variants — the mapper change is gated on `mh.community_
heating is not None` and only fires when §14.0 leaves the control
field empty. Pyright net-zero on mapper.py + corpus test.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 15:40:26 +00:00
..
domain Slice S0380.175: Community heating main_heating_control extraction 2026-06-04 15:40:26 +00:00
loaders demo generated for use in address2uprn 2026-05-08 14:48:15 +00:00
schema Merge remote-tracking branch 'origin/main' into feature/landlord_data 2026-06-01 17:02:20 +00:00
search bolstering testing 2026-04-28 13:46:09 +00:00
surveys Slice S0380.170: Community heating mapper unblock (Table 12 dispatch) 2026-06-04 15:40:25 +00:00
__init__.py testing out rebaselining 2026-02-12 22:25:03 +00:00
construction_age_band.py testing out rebaselining 2026-02-12 22:25:03 +00:00
efficiency.py beginning to assembly the parity class 2026-02-04 18:34:59 +00:00
floor.py preparing partiy class 2026-02-05 08:54:27 +00:00
fuel.py beginning to assembly the parity class 2026-02-04 18:34:59 +00:00
heating_controls.py beginning to assembly the parity class 2026-02-04 18:34:59 +00:00
hotwater.py beginning to assembly the parity class 2026-02-04 18:34:59 +00:00
main_heating.py beginning to assembly the parity class 2026-02-04 18:34:59 +00:00
property_type_built_form.py beginning to assembly the parity class 2026-02-04 18:34:59 +00:00
roof.py beginning to assembly the parity class 2026-02-04 18:34:59 +00:00
walls.py beginning to assembly the parity class 2026-02-04 18:34:59 +00:00
windows.py testing out rebaselining 2026-02-12 22:25:03 +00:00