From b9f1f428b92e24bd10cbb371166bd9c503e1cefb Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 18:28:20 +0000 Subject: [PATCH 01/84] test(accuracy): corpus-1000 campaign ledger + C001 4510053280 pinned 75 (lodged-software PSR gap) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setup for the RdSAP-21.0.1 corpus gauge campaign (74.2% within-0.5, SAP MAE 0.721 at HEAD, 1000/1000 computed): - scripts/corpus_1000/build_worklist.py — runs all 1000 corpus certs through the gauge's own path (from_api_response -> Sap10Calculator), ranks |engine - lodged| descending, clusters by dwelling signature, and (re)writes scripts/corpus_1000/worklist.md preserving per-cert statuses and notes. 258 certs outside 0.5 in 249 clusters. - C001 (worst cert, Δ +23.9): uprn 4510053280, ground-floor flat 47 m² on ASHP PCDB 100053 (Mitsubishi Ecodan 5 kW, PSR table 0.2-2.0). Dwelling PSR 2.031 -> SAP 10.2 N2 footnotes 44/45 heat-pump extension (reciprocal interpolation toward 100% at 2x largest PSR) = 305% space efficiency, which accredited Elmhurst also applies (golden case 56, record 100061). The LODGED software instead treated the out-of-range record as invalid and billed 100% direct electric + standard schedule (reproduces lodged CO2 to 1%). Lodged-software methodology gap, worklist ⚠, engine untouched; observed engine 75 pinned in test_real_cert_sap_accuracy. Gauge floors unchanged (no engine change). Co-Authored-By: Claude Fable 5 --- .../uprn_4510053280/epc.json | 299 ++++ scripts/corpus_1000/build_worklist.py | 243 +++ scripts/corpus_1000/worklist.md | 1512 +++++++++++++++++ .../test_real_cert_sap_accuracy.py | 25 + 4 files changed, 2079 insertions(+) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_4510053280/epc.json create mode 100644 scripts/corpus_1000/build_worklist.py create mode 100644 scripts/corpus_1000/worklist.md diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_4510053280/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_4510053280/epc.json new file mode 100644 index 000000000..5e14204ab --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_4510053280/epc.json @@ -0,0 +1,299 @@ +{ + "uprn": 4510053280, + "roofs": [ + { + "description": "(another dwelling above)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "walls": [ + { + "description": "Solid brick, as built, no insulation (assumed)", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + { + "description": "Solid brick, as built, partial insulation (assumed)", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "floors": [ + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 2, + "window": { + "description": "Full secondary glazing", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "lighting": { + "description": "Good lighting efficiency", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "NE1 4DG", + "hot_water": { + "description": "From main system, no cylinder thermostat", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 4 + }, + "post_town": "NEWCASTLE UPON TYNE", + "built_form": "NR", + "created_at": "2026-05-24 12:41:32", + "door_count": 0, + "region_code": 1, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 29, + "secondary_fuel_type": 29, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 29, + "heat_emitter_type": 1, + "emitter_temperature": 0, + "main_heating_number": 1, + "main_heating_control": 2203, + "main_heating_category": 4, + "main_heating_fraction": 1, + "mcs_installed_heat_pump": "false", + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 100053 + } + ], + "immersion_heating_type": "NA", + "secondary_heating_type": 691, + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "orientation": 4, + "window_type": 1, + "glazing_type": 4, + "window_width": 1.3, + "window_height": 1.46, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 4, + "window_type": 1, + "glazing_type": 4, + "window_width": 1.3, + "window_height": 1.46, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Air source heat pump, radiators, electric", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 5 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Ground-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "64 Waterloo Street", + "assessment_type": "RdSAP", + "completion_date": "2026-05-24", + "inspection_date": "2026-05-22", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 1, + "top_storey": "N", + "storey_count": 3, + "flat_location": 0, + "heat_loss_corridor": 2, + "unheated_corridor_length": 3.5 + }, + "total_floor_area": 47, + "transaction_type": 8, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 2, + "registration_date": "2026-05-24", + "sap_energy_source": { + "mains_gas": "N", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 1, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "Room heaters, electric", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "lzc_energy_sources": [ + 9 + ], + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 520, + "floor_heat_loss": 7, + "roof_construction": 3, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.32, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 47, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 8, + "quantity": "metres" + }, + "floor_construction": 1, + "heat_loss_perimeter": { + "value": 14.15, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "B", + "sap_alternative_wall_1": { + "wall_area": 8.12, + "sheltered_wall": "Y", + "wall_dry_lined": "N", + "wall_thickness": 520, + "wall_construction": 3, + "wall_insulation_type": 4, + "wall_thickness_measured": "Y", + "wall_insulation_thickness": "NI" + }, + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": "ND", + "roof_insulation_thickness": "ND", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 2, + "heating_cost_current": { + "value": 278, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 0.8, + "energy_rating_average": 60, + "energy_rating_current": 51, + "lighting_cost_current": { + "value": 39, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Room thermostat only", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 272, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 1295, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 68, + "currency": "GBP" + }, + "indicative_cost": "\u00a3220 - \u00a3250", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 16 + }, + "improvement_category": 5, + "energy_performance_rating": 53, + "environmental_impact_rating": 88 + } + ], + "co2_emissions_potential": 0.8, + "energy_rating_potential": 53, + "lighting_cost_potential": { + "value": 39, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 1233, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 5072.68, + "space_heating_existing_dwelling": 2884.0 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 190, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 182, + "environmental_impact_current": 88, + "current_energy_efficiency_band": "E", + "environmental_impact_potential": 88, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "E", + "co2_emissions_current_per_floor_area": 18, + "low_energy_fixed_lighting_bulbs_count": 6, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/scripts/corpus_1000/build_worklist.py b/scripts/corpus_1000/build_worklist.py new file mode 100644 index 000000000..55df6586d --- /dev/null +++ b/scripts/corpus_1000/build_worklist.py @@ -0,0 +1,243 @@ +"""Build the RdSAP-21.0.1 corpus campaign ledger (scripts/corpus_1000/worklist.md). + +Runs all 1000 corpus certs through the gauge's own path +(from_api_response -> Sap10Calculator.calculate, mirroring +tests/infrastructure/epc_client/test_sap_accuracy_corpus.py), ranks by +|engine - lodged| descending, attaches a short dwelling signature per cert, +and groups same-signature certs into named clusters. + +USAGE +----- + PYTHONPATH=/workspaces/model python scripts/corpus_1000/build_worklist.py + +Rewrites worklist.md in place, PRESERVING existing per-cert statuses +([x] / 🔧 / ⚠ / ⛔ and trailing `<-` notes) keyed by uprn, so it doubles as +the re-rank step after each fix lands. +""" +from __future__ import annotations + +import json +import re +from collections import defaultdict +from pathlib import Path +from typing import Any, Optional + +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +from domain.sap10_calculator.calculator import Sap10Calculator + +ROOT = Path(__file__).resolve().parents[2] +CORPUS = ROOT / "backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl" +WORKLIST = ROOT / "scripts/corpus_1000/worklist.md" + +# Table 12 fuel names (abbreviated) for the signature column. +_FUEL = { + 1: "gas", 2: "gas-bulk", 3: "biogas", 4: "biogas", 7: "bLPG", 9: "LPG", + 17: "LPG-sc", 10: "oil", 15: "bioliquid", 16: "B30K", 18: "rapeseed", + 58: "biodiesel", 51: "housecoal", 20: "coal-anth", 21: "smokeless", + 22: "anthracite", 23: "manuf-smokeless", 12: "wood-log", 13: "wood-pellet", + 75: "wood-pellet-bag", 71: "wood-chip", 48: "dual-mineral-wood", + 26: "gas", 25: "elec", 29: "elec", 30: "elec7hr", 31: "elec10hr", + 32: "elec18hr", 33: "elec24hr", 34: "elec-heatnet", 35: "elec", + 36: "elec", 37: "elec", 47: "heatnet", 6: "heatnet", +} + + +def _fuel_name(code: Optional[int]) -> str: + if code is None: + return "?" + return _FUEL.get(code, f"fuel{code}") + + +def _lead(desc: Optional[str], n: int = 3) -> str: + """First n comma/word tokens of a register description, lowercased.""" + if not desc: + return "?" + return " ".join(desc.lower().replace(",", " ").split()[:n]) + + +def signature(doc: dict[str, Any]) -> tuple[str, str]: + """(cluster_key, human signature) for one cert.""" + h = doc.get("sap_heating") or {} + mhd = (h.get("main_heating_details") or [{}]) + m0 = mhd[0] if mhd else {} + code = m0.get("sap_main_heating_code") + idx = m0.get("main_heating_index_number") + fuel = _fuel_name(m0.get("main_fuel_type")) + heat = f"h{code or ('pcdb' + str(idx) if idx else '?')}/{fuel}" + if len(mhd) > 1: + heat += "+2mains" + + walls = doc.get("walls") or [] + wall = _lead(walls[0].get("description") if walls else None, 2) + roofs = doc.get("roofs") or [] + roof = _lead(roofs[0].get("description") if roofs else None, 2) + + es = doc.get("sap_energy_source") or {} + sec = (doc.get("secondary_heating") or {}).get("description") or "None" + feats: list[str] = [] + pv = es.get("photovoltaic_supply") or {} + if es.get("pv_connection") not in (0, None) or not pv.get("none_or_no_details"): + feats.append("PV") + if (es.get("wind_turbines_count") or 0) > 0: + feats.append("wind") + if sec != "None": + feats.append("sec:" + _lead(sec, 2)) + if (doc.get("extensions_count") or 0) > 0: + feats.append(f"ext{doc.get('extensions_count')}") + if (doc.get("conservatory_type") or 1) != 1: + feats.append(f"consv{doc.get('conservatory_type')}") + for bp in doc.get("sap_building_parts") or []: + if bp.get("sap_room_in_roof") is not None: + feats.append("RR") + break + mv = doc.get("mechanical_ventilation") + if mv not in (0, None): + feats.append(f"mv{mv}") + if (h.get("water_heating_code") or 901) != 901: + feats.append(f"whw{h.get('water_heating_code')}") + + key = f"{heat} | {wall} | {roof}" + (" | " + ",".join(sorted(set(feats))) if feats else "") + sig = key + return key, sig + + +_LINE_RE = re.compile( + r"^- \[(?P[ x])\] |^- (?P🔧|⚠|⛔) " +) + + +def load_existing_statuses() -> dict[str, tuple[str, str]]: + """uprn -> (status token, trailing note) from the current worklist.""" + out: dict[str, tuple[str, str]] = {} + if not WORKLIST.exists(): + return out + for line in WORKLIST.read_text().splitlines(): + m = re.match(r"^- (?:\[(?P[ x])\]|(?P🔧|⚠|⛔)) `(?P\w+)`", line) + if not m: + continue + status = f"[{m.group('st')}]" if m.group("st") is not None else m.group("emoji") + note = "" + if "<-" in line: + note = "<-" + line.split("<-", 1)[1] + out[m.group("uprn")] = (status, note) + return out + + +def main() -> None: + docs = [json.loads(l) for l in CORPUS.read_text().splitlines() if l.strip()] + calc = Sap10Calculator() + rows: list[dict[str, Any]] = [] + skipped: list[tuple[str, str]] = [] + sap_abs: list[float] = [] + + for idx, doc in enumerate(docs, 1): + # Some corpus docs lodge no top-level uprn; fall back to the corpus + # line number so ledger statuses don't collide on "None". + uprn = str(doc.get("uprn") or f"line{idx}") + lodged = doc.get("energy_rating_current") + if lodged is None: + skipped.append((uprn, "no lodged SAP")) + continue + try: + epc = EpcPropertyDataMapper.from_api_response(doc) + result = calc.calculate(epc) + except Exception as e: + skipped.append((uprn, f"{type(e).__name__}: {str(e)[:70]}")) + continue + eng = result.sap_score_continuous + delta = eng - lodged + sap_abs.append(abs(delta)) + key, sig = signature(doc) + rows.append({ + "uprn": uprn, "lodged": lodged, "eng": eng, "delta": delta, + "key": key, "sig": sig, + }) + + n = len(sap_abs) + within = sum(1 for e in sap_abs if e < 0.5) / n + mae = sum(sap_abs) / n + + # Cluster: same signature key, only certs still outside 0.5. + clusters: dict[str, list[dict[str, Any]]] = defaultdict(list) + for r in rows: + if abs(r["delta"]) >= 0.5: + clusters[r["key"]].append(r) + ranked = sorted( + clusters.items(), + key=lambda kv: -sum(abs(r["delta"]) for r in kv[1]), + ) + + prev = load_existing_statuses() + + lines: list[str] = [] + lines.append("# RdSAP-21.0.1 corpus campaign ledger") + lines.append("") + lines.append( + f"**Gauge:** {n} computed / {len(skipped)} skipped · " + f"SAP within-0.5 = **{within:.1%}** · MAE = **{mae:.3f}** " + f"(floors in test_sap_accuracy_corpus.py)" + ) + lines.append("") + lines.append( + "Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · " + "⚠ xfail engine bug · ⛔ unbuildable. " + "Line: `uprn · lodged L / eng E / Δ · signature`. " + "Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` " + "(preserves statuses & `<-` notes)." + ) + lines.append("") + lines.append(f"## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — {sum(len(v) for v in clusters.values())} certs in {len(ranked)} clusters") + lines.append("") + + for i, (key, members) in enumerate(ranked, 1): + members.sort(key=lambda r: -abs(r["delta"])) + tot = sum(abs(r["delta"]) for r in members) + lines.append( + f"### C{i:03d} · Σ|Δ| {tot:.1f} · {len(members)} certs · `{key}`" + ) + for r in members: + st, note = prev.get(r["uprn"], ("[ ]", "")) + frag = ( + f"- {st} `{r['uprn']}` · L {r['lodged']} / E {r['eng']:.2f} / " + f"Δ {r['delta']:+.2f}" + ) + if note: + frag += f" {note}" + lines.append(frag) + lines.append("") + + if skipped: + lines.append(f"## Skipped ({len(skipped)})") + for uprn, why in skipped: + st, note = prev.get(uprn, ("⛔", "")) + lines.append(f"- {st} `{uprn}` · {why} {note}".rstrip()) + lines.append("") + + resolved = [r for r in rows if abs(r["delta"]) < 0.5] + lines.append(f"## Resolved ≤0.5 ({len(resolved)} certs — no action)") + lines.append("") + lines.append("
expand") + lines.append("") + for r in sorted(resolved, key=lambda r: -abs(r["delta"])): + st, note = prev.get(r["uprn"], ("[x]", "")) + if st == "[ ]": + st = "[x]" + lines.append( + f"- {st} `{r['uprn']}` · L {r['lodged']} / E {r['eng']:.2f} / " + f"Δ {r['delta']:+.2f} · `{r['key']}` {note}".rstrip() + ) + lines.append("") + lines.append("
") + lines.append("") + + WORKLIST.write_text("\n".join(lines)) + print(f"wrote {WORKLIST}") + print(f"gauge: {n} computed / {len(skipped)} skipped, within-0.5 {within:.1%}, MAE {mae:.3f}") + print(f"clusters: {len(ranked)}, worst 5:") + for key, members in ranked[:5]: + tot = sum(abs(r["delta"]) for r in members) + print(f" Σ{tot:7.1f} n={len(members):3d} {key}") + + +if __name__ == "__main__": + main() diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md new file mode 100644 index 000000000..09bd7e96a --- /dev/null +++ b/scripts/corpus_1000/worklist.md @@ -0,0 +1,1512 @@ +# RdSAP-21.0.1 corpus campaign ledger + +**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **74.2%** · MAE = **0.721** (floors in test_sap_accuracy_corpus.py) + +Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail engine bug · ⛔ unbuildable. Line: `uprn · lodged L / eng E / Δ · signature`. Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` (preserves statuses & `<-` notes). + +## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 258 certs in 249 clusters + +### C001 · Σ|Δ| 23.9 · 1 certs · `hpcdb100053/elec | solid brick | (another dwelling | sec:room heaters` +- ⚠ `4510053280` · L 51 / E 74.94 / Δ +23.94 <- lodged software billed out-of-range-PSR (2.031 > 2.0) PCDB 100053 as 100% direct electric; engine follows SAP10.2 N2 extension (305%), Elmhurst-validated on case 56. Pinned engine 75 in test_real_cert_sap_accuracy. + +### C002 · Σ|Δ| 19.7 · 1 certs · `h301/coal-anth | cavity wall | pitched unknown | whw903` +- [ ] `103001004` · L 50 / E 69.69 / Δ +19.69 + +### C003 · Σ|Δ| 15.2 · 1 certs · `h117/gas | cavity wall | pitched 200 | ext2,sec:room heaters` +- [ ] `100050355518` · L 36 / E 20.82 / Δ -15.18 + +### C004 · Σ|Δ| 14.5 · 1 certs · `h195/elec | system built | (another dwelling` +- [ ] `10012334488` · L 72 / E 86.47 / Δ +14.47 + +### C005 · Σ|Δ| 13.1 · 1 certs · `hpcdb10326/gas | solid brick | pitched 75 | ext1,sec:room heaters` +- [ ] `12109191` · L 58 / E 71.10 / Δ +13.10 + +### C006 · Σ|Δ| 10.3 · 4 certs · `h691/elec | cavity wall | (another dwelling | whw909` +- [ ] `line279` · L 81 / E 78.44 / Δ -2.56 +- [ ] `line301` · L 81 / E 78.44 / Δ -2.56 +- [ ] `line318` · L 81 / E 78.44 / Δ -2.56 +- [ ] `10093237426` · L 81 / E 78.44 / Δ -2.56 + +### C007 · Σ|Δ| 10.1 · 1 certs · `h691/elec | granite or | pitched 175 | RR,ext1,whw903` +- [ ] `100040550095` · L 40 / E 29.87 / Δ -10.13 + +### C008 · Σ|Δ| 8.7 · 1 certs · `h125/fuel28 | cavity wall | pitched 250 | consv2,sec:room heaters` +- [ ] `100121325434` · L 48 / E 56.75 / Δ +8.75 + +### C009 · Σ|Δ| 8.1 · 1 certs · `hpcdb17958/gas | system built | pitched 300 | PV,ext1,mv1` +- [ ] `100022294004` · L 75 / E 83.13 / Δ +8.13 + +### C010 · Σ|Δ| 8.0 · 1 certs · `hpcdb18760/gas | solid brick | pitched 100 | RR,ext2,sec:room heaters` +- [ ] `100010391723` · L 66 / E 57.96 / Δ -8.04 + +### C011 · Σ|Δ| 7.8 · 1 certs · `h195/elec | cavity wall | (another dwelling` +- [ ] `10091578598` · L 71 / E 78.81 / Δ +7.81 + +### C012 · Σ|Δ| 7.7 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` +- [ ] `74061136` · L 73 / E 80.72 / Δ +7.72 + +### C013 · Σ|Δ| 7.1 · 1 certs · `h408/elec | cavity wall | (another dwelling | whw941` +- [ ] `200000322700` · L 58 / E 65.05 / Δ +7.05 + +### C014 · Σ|Δ| 6.7 · 1 certs · `h691/elec | solid brick | pitched 100 | RR,ext1,whw909` +- [ ] `100032223878` · L 11 / E 17.67 / Δ +6.67 + +### C015 · Σ|Δ| 6.6 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` +- [ ] `200004296092` · L 71 / E 64.35 / Δ -6.65 + +### C016 · Σ|Δ| 6.5 · 1 certs · `h408/elec | granite or | (another dwelling | sec:portable electric,whw903` +- [ ] `100121397382` · L 69 / E 75.49 / Δ +6.49 + +### C017 · Σ|Δ| 6.5 · 1 certs · `h691/elec | solid brick | (another dwelling | ext1,sec:room heaters,whw903` +- [ ] `100062100640` · L 54 / E 47.51 / Δ -6.49 + +### C018 · Σ|Δ| 6.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 225` +- [ ] `100050844968` · L 71 / E 65.02 / Δ -5.98 + +### C019 · Σ|Δ| 5.8 · 1 certs · `hpcdb17777/gas+2mains | cavity wall | pitched insulated | ext1,sec:room heaters,whw914` +- [ ] `line804` · L 52 / E 57.76 / Δ +5.76 + +### C020 · Σ|Δ| 5.7 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` +- [ ] `200049463` · L 69 / E 63.28 / Δ -5.72 + +### C021 · Σ|Δ| 5.6 · 2 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` +- [ ] `11071248` · L 78 / E 81.86 / Δ +3.86 +- [ ] `12126160` · L 69 / E 70.71 / Δ +1.71 + +### C022 · Σ|Δ| 5.5 · 1 certs · `hpcdb17033/gas | cavity wall | pitched insulated | RR,ext3,sec:room heaters` +- [ ] `10090368756` · L 80 / E 74.52 / Δ -5.48 + +### C023 · Σ|Δ| 4.6 · 1 certs · `hpcdb18560/gas | solid brick | pitched no | RR` +- [ ] `100051233481` · L 65 / E 69.64 / Δ +4.64 + +### C024 · Σ|Δ| 4.5 · 1 certs · `h691/elec | timber frame | pitched limited | RR,ext2,whw903` +- [ ] `100061646773` · L 68 / E 63.46 / Δ -4.54 + +### C025 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` +- [ ] `100071010014` · L 55 / E 50.47 / Δ -4.53 + +### C026 · Σ|Δ| 4.5 · 1 certs · `hpcdb17815/gas | cavity wall | flat insulated` +- [ ] `47084930` · L 74 / E 69.51 / Δ -4.49 + +### C027 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` +- [ ] `10093342182` · L 82 / E 77.51 / Δ -4.49 + +### C028 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` +- [ ] `5117280` · L 76 / E 71.56 / Δ -4.44 + +### C029 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` +- [ ] `217060420` · L 42 / E 37.58 / Δ -4.42 + +### C030 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` +- [ ] `72399971` · L 69 / E 64.60 / Δ -4.40 + +### C031 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` +- [ ] `10007016314` · L 57 / E 52.64 / Δ -4.36 + +### C032 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` +- [ ] `100052159386` · L 56 / E 51.92 / Δ -4.08 + +### C033 · Σ|Δ| 4.0 · 1 certs · `h191/elec | cavity wall | (another dwelling` +- [ ] `10002272664` · L 79 / E 74.96 / Δ -4.04 + +### C034 · Σ|Δ| 3.6 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` +- [ ] `72351021` · L 64 / E 60.45 / Δ -3.55 + +### C035 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` +- [ ] `39066537` · L 78 / E 81.49 / Δ +3.49 + +### C036 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` +- [ ] `100100137438` · L 69 / E 72.48 / Δ +3.48 + +### C037 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` +- [ ] `100080122910` · L 60 / E 63.45 / Δ +3.45 + +### C038 · Σ|Δ| 3.4 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` +- [ ] `100040767294` · L 43 / E 46.38 / Δ +3.38 + +### C039 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` +- [ ] `452010022` · L 42 / E 38.67 / Δ -3.33 + +### C040 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` +- [ ] `200004818752` · L 34 / E 30.73 / Δ -3.27 + +### C041 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` +- [ ] `22077224` · L 37 / E 33.90 / Δ -3.10 + +### C042 · Σ|Δ| 3.1 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` +- [ ] `10002188054` · L 68 / E 64.93 / Δ -3.07 + +### C043 · Σ|Δ| 3.1 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` +- [ ] `100032043038` · L 74 / E 77.06 / Δ +3.06 + +### C044 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` +- [ ] `10011740578` · L 70 / E 67.00 / Δ -3.00 + +### C045 · Σ|Δ| 2.9 · 2 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` +- [ ] `22027335` · L 76 / E 73.77 / Δ -2.23 +- [ ] `200002819281` · L 72 / E 71.29 / Δ -0.71 + +### C046 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +- [ ] `100110680822` · L 79 / E 76.07 / Δ -2.93 + +### C047 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` +- [ ] `452032915` · L 75 / E 72.09 / Δ -2.91 + +### C048 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` +- [ ] `100071306639` · L 73 / E 70.14 / Δ -2.86 + +### C049 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` +- [ ] `100061346049` · L 55 / E 52.15 / Δ -2.85 + +### C050 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` +- [ ] `10013008238` · L 41 / E 38.26 / Δ -2.74 + +### C051 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` +- [ ] `10033187652` · L 70 / E 71.21 / Δ +1.21 +- [ ] `200002730` · L 65 / E 64.13 / Δ -0.87 +- [ ] `10023328117` · L 78 / E 78.64 / Δ +0.64 + +### C052 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` +- [ ] `10004873253` · L 65 / E 62.29 / Δ -2.71 + +### C053 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` +- [ ] `10090793715` · L 73 / E 75.71 / Δ +2.71 + +### C054 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` +- [ ] `100120745600` · L 65 / E 67.69 / Δ +2.69 + +### C055 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` +- [ ] `100051178830` · L 63 / E 65.66 / Δ +2.66 + +### C056 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` +- [ ] `100120018282` · L 64 / E 61.36 / Δ -2.64 + +### C057 · Σ|Δ| 2.6 · 1 certs · `hpcdb10599/fuel28 | sandstone as | pitched insulated | ext2,sec:room heaters` +- [ ] `666329` · L 69 / E 66.39 / Δ -2.61 + +### C058 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +- [ ] `83035979` · L 65 / E 67.60 / Δ +2.60 + +### C059 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` +- [ ] `10014073761` · L 75 / E 72.52 / Δ -2.48 + +### C060 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` +- [ ] `100120752995` · L 71 / E 73.42 / Δ +2.42 + +### C061 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` +- [ ] `100032230128` · L 55 / E 52.60 / Δ -2.40 + +### C062 · Σ|Δ| 2.4 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` +- [ ] `100012368622` · L 39 / E 41.40 / Δ +2.40 + +### C063 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` +- [ ] `100000034023` · L 73 / E 70.71 / Δ -2.29 + +### C064 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` +- [ ] `100020377671` · L 62 / E 64.23 / Δ +2.23 + +### C065 · Σ|Δ| 2.2 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` +- [ ] `80838` · L 41 / E 43.19 / Δ +2.19 + +### C066 · Σ|Δ| 2.1 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` +- [ ] `100050964834` · L 60 / E 62.13 / Δ +2.13 + +### C067 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` +- [ ] `48056153` · L 65 / E 62.89 / Δ -2.11 + +### C068 · Σ|Δ| 2.0 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` +- [ ] `100070295212` · L 75 / E 77.01 / Δ +2.01 + +### C069 · Σ|Δ| 2.0 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` +- [ ] `100100274789` · L 60 / E 62.00 / Δ +2.00 + +### C070 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` +- [ ] `100021924710` · L 63 / E 65.00 / Δ +2.00 + +### C071 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` +- [ ] `100031270375` · L 69 / E 70.93 / Δ +1.93 + +### C072 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` +- [ ] `10001118522` · L 80 / E 78.07 / Δ -1.93 + +### C073 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` +- [ ] `10010234711` · L 81 / E 79.08 / Δ -1.92 + +### C074 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` +- [ ] `100031768368` · L 61 / E 59.12 / Δ -1.88 + +### C075 · Σ|Δ| 1.9 · 1 certs · `hpcdb18559/gas | solid brick | pitched insulated` +- [ ] `10094975827` · L 66 / E 64.13 / Δ -1.87 + +### C076 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` +- [ ] `4510729926` · L 73 / E 71.15 / Δ -1.85 + +### C077 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` +- [ ] `100091329112` · L 49 / E 50.82 / Δ +1.82 + +### C078 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` +- [ ] `100061275133` · L 76 / E 77.24 / Δ +1.24 +- [ ] `207032630` · L 74 / E 73.47 / Δ -0.53 + +### C079 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` +- [ ] `10011797347` · L 47 / E 48.77 / Δ +1.77 + +### C080 · Σ|Δ| 1.8 · 1 certs · `hpcdb17679/gas | solid brick | pitched insulated` +- [ ] `line621` · L 78 / E 76.24 / Δ -1.76 + +### C081 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` +- [ ] `100022668387` · L 68 / E 66.25 / Δ -1.75 + +### C082 · Σ|Δ| 1.8 · 1 certs · `hpcdb17803/gas | timber frame | pitched 100` +- [ ] `200004017091` · L 71 / E 72.75 / Δ +1.75 + +### C083 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` +- [ ] `100100892216` · L 69 / E 67.28 / Δ -1.72 + +### C084 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` +- [ ] `100060878876` · L 49 / E 50.71 / Δ +1.71 + +### C085 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` +- [ ] `22032926` · L 61 / E 62.71 / Δ +1.71 + +### C086 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` +- [ ] `100010942905` · L 72 / E 73.70 / Δ +1.70 + +### C087 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` +- [ ] `100030307976` · L 71 / E 69.37 / Δ -1.63 + +### C088 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` +- [ ] `100061404488` · L 70 / E 68.38 / Δ -1.62 + +### C089 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` +- [ ] `21067296` · L 67 / E 68.60 / Δ +1.60 + +### C090 · Σ|Δ| 1.6 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` +- [ ] `100050477371` · L 65 / E 63.40 / Δ -1.60 + +### C091 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` +- [ ] `5870047440` · L 58 / E 59.58 / Δ +1.58 + +### C092 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` +- [ ] `100070450818` · L 65 / E 63.43 / Δ -1.57 + +### C093 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` +- [ ] `100050881708` · L 70 / E 71.55 / Δ +1.55 + +### C094 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` +- [ ] `10010254955` · L 79 / E 77.46 / Δ -1.54 + +### C095 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` +- [ ] `3455011834` · L 69 / E 67.48 / Δ -1.52 + +### C096 · Σ|Δ| 1.5 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` +- [ ] `100051109723` · L 60 / E 61.52 / Δ +1.52 + +### C097 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` +- [ ] `100050852755` · L 65 / E 66.49 / Δ +1.49 + +### C098 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` +- [ ] `100021326422` · L 70 / E 68.51 / Δ -1.49 + +### C099 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` +- [ ] `100050988345` · L 61 / E 59.51 / Δ -1.49 + +### C100 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` +- [ ] `100030285758` · L 54 / E 55.48 / Δ +1.48 + +### C101 · Σ|Δ| 1.5 · 1 certs · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` +- [ ] `100090536443` · L 86 / E 84.52 / Δ -1.48 + +### C102 · Σ|Δ| 1.5 · 1 certs · `h158/heatnet+2mains | solid brick | pitched insulated | ext4,sec:room heaters,whw903` +- [ ] `100120881623` · L 53 / E 51.55 / Δ -1.45 + +### C103 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` +- [ ] `line80` · L 72 / E 70.56 / Δ -1.44 + +### C104 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` +- [ ] `100080518673` · L 57 / E 58.42 / Δ +1.42 + +### C105 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` +- [ ] `235025284` · L 69 / E 67.59 / Δ -1.41 + +### C106 · Σ|Δ| 1.4 · 1 certs · `hpcdb16401/gas | cavity wall | pitched insulated | mv2` +- [ ] `10093200879` · L 71 / E 69.59 / Δ -1.41 + +### C107 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` +- [ ] `250063088` · L 73 / E 71.60 / Δ -1.40 + +### C108 · Σ|Δ| 1.4 · 1 certs · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` +- [ ] `100050048691` · L 58 / E 59.39 / Δ +1.39 + +### C109 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` +- [ ] `100110097281` · L 64 / E 65.37 / Δ +1.37 + +### C110 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` +- [ ] `10091630692` · L 58 / E 56.63 / Δ -1.37 + +### C111 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` +- [ ] `100031433810` · L 70 / E 68.63 / Δ -1.37 + +### C112 · Σ|Δ| 1.4 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` +- [ ] `100051051866` · L 70 / E 68.64 / Δ -1.36 + +### C113 · Σ|Δ| 1.3 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` +- [ ] `10002945522` · L 61 / E 62.32 / Δ +1.32 + +### C114 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +- [ ] `90077194` · L 65 / E 63.69 / Δ -1.31 + +### C115 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` +- [ ] `100031461986` · L 70 / E 71.29 / Δ +1.29 + +### C116 · Σ|Δ| 1.3 · 1 certs · `hpcdb15100/gas | cavity wall | pitched insulated | consv2,sec:room heaters` +- [ ] `100031193650` · L 70 / E 68.73 / Δ -1.27 + +### C117 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` +- [ ] `30095054` · L 46 / E 44.74 / Δ -1.26 + +### C118 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` +- [ ] `100100055589` · L 58 / E 59.26 / Δ +1.26 + +### C119 · Σ|Δ| 1.3 · 1 certs · `hpcdb15049/gas | cavity wall | pitched insulated` +- [ ] `565298` · L 68 / E 66.75 / Δ -1.25 + +### C120 · Σ|Δ| 1.2 · 1 certs · `hpcdb108793/elec | solid brick | pitched insulated | ext2` +- [ ] `100120850835` · L 59 / E 57.77 / Δ -1.23 + +### C121 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` +- [ ] `100091435353` · L 65 / E 66.23 / Δ +1.23 + +### C122 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` +- [ ] `10091070164` · L 69 / E 69.60 / Δ +0.60 +- [ ] `10090927185` · L 79 / E 79.60 / Δ +0.60 + +### C123 · Σ|Δ| 1.2 · 1 certs · `hpcdb16842/gas | cavity wall | pitched no | ext1,sec:room heaters` +- [ ] `100090834242` · L 53 / E 54.20 / Δ +1.20 + +### C124 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` +- [ ] `100100614412` · L 53 / E 51.81 / Δ -1.19 + +### C125 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` +- [ ] `217091901` · L 62 / E 60.82 / Δ -1.18 + +### C126 · Σ|Δ| 1.2 · 1 certs · `hpcdb17978/gas | solid brick | pitched 200 | ext1,sec:room heaters` +- [ ] `10034812814` · L 65 / E 66.16 / Δ +1.16 + +### C127 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` +- [ ] `217061895` · L 61 / E 59.84 / Δ -1.16 + +### C128 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` +- [ ] `10002349227` · L 76 / E 77.14 / Δ +1.14 + +### C129 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` +- [ ] `200001634005` · L 66 / E 67.11 / Δ +1.11 + +### C130 · Σ|Δ| 1.1 · 1 certs · `hpcdb18250/gas | solid brick | pitched insulated` +- [ ] `5128014` · L 67 / E 65.91 / Δ -1.09 + +### C131 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [ ] `100071059081` · L 63 / E 64.09 / Δ +1.09 + +### C132 · Σ|Δ| 1.1 · 1 certs · `hpcdb19020/gas | solid brick | pitched insulated | RR,sec:room heaters` +- [ ] `100050567367` · L 64 / E 65.07 / Δ +1.07 + +### C133 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` +- [ ] `100011820199` · L 55 / E 56.06 / Δ +1.06 + +### C134 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` +- [ ] `90214753` · L 83 / E 81.95 / Δ -1.05 + +### C135 · Σ|Δ| 1.0 · 1 certs · `hpcdb18759/gas | sandstone with | pitched 150 | ext1,mv5,sec:room heaters` +- [ ] `10010159639` · L 65 / E 66.05 / Δ +1.05 + +### C136 · Σ|Δ| 1.0 · 1 certs · `hpcdb19038/gas | cavity wall | pitched insulated | sec:room heaters` +- [ ] `100051248025` · L 57 / E 55.96 / Δ -1.04 + +### C137 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` +- [ ] `10013836852` · L 100 / E 98.97 / Δ -1.03 + +### C138 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` +- [ ] `line899` · L 73 / E 71.97 / Δ -1.03 + +### C139 · Σ|Δ| 1.0 · 1 certs · `hpcdb15921/fuel28 | cavity wall | pitched 200 | sec:room heaters` +- [ ] `100120765933` · L 57 / E 58.03 / Δ +1.03 + +### C140 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` +- [ ] `40037847` · L 81 / E 79.98 / Δ -1.02 + +### C141 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` +- [ ] `10070056075` · L 80 / E 78.99 / Δ -1.01 + +### C142 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` +- [ ] `200131078` · L 86 / E 85.00 / Δ -1.00 + +### C143 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` +- [ ] `10000245212` · L 101 / E 100.00 / Δ -1.00 + +### C144 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` +- [ ] `15129162` · L 62 / E 61.00 / Δ -1.00 + +### C145 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` +- [ ] `23032873` · L 73 / E 72.00 / Δ -1.00 + +### C146 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` +- [ ] `45019020` · L 62 / E 61.01 / Δ -0.99 + +### C147 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` +- [ ] `42065028` · L 59 / E 58.02 / Δ -0.98 + +### C148 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` +- [ ] `10032928147` · L 77 / E 76.04 / Δ -0.96 + +### C149 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` +- [ ] `10010678937` · L 78 / E 77.04 / Δ -0.96 + +### C150 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` +- [ ] `100011010151` · L 62 / E 62.96 / Δ +0.96 + +### C151 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` +- [ ] `10032957680` · L 45 / E 45.94 / Δ +0.94 + +### C152 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` +- [ ] `2465057465` · L 81 / E 81.93 / Δ +0.93 + +### C153 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` +- [ ] `100012753833` · L 74 / E 73.07 / Δ -0.93 + +### C154 · Σ|Δ| 0.9 · 1 certs · `hpcdb17505/gas | cavity wall | pitched 200 | sec:room heaters` +- [ ] `200002626191` · L 63 / E 63.92 / Δ +0.92 + +### C155 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` +- [ ] `100031269525` · L 53 / E 53.91 / Δ +0.91 + +### C156 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` +- [ ] `200003725358` · L 75 / E 74.09 / Δ -0.91 + +### C157 · Σ|Δ| 0.9 · 1 certs · `hpcdb18435/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +- [ ] `100060109253` · L 62 / E 62.91 / Δ +0.91 + +### C158 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` +- [ ] `100050986162` · L 62 / E 61.10 / Δ -0.90 + +### C159 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` +- [ ] `5300000141` · L 78 / E 77.10 / Δ -0.90 + +### C160 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` +- [ ] `100050618404` · L 73 / E 73.89 / Δ +0.89 + +### C161 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` +- [ ] `100090476016` · L 81 / E 81.89 / Δ +0.89 + +### C162 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` +- [ ] `10012119141` · L 45 / E 45.89 / Δ +0.89 + +### C163 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` +- [ ] `100040938206` · L 75 / E 75.89 / Δ +0.89 + +### C164 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` +- [ ] `38188474` · L 76 / E 76.87 / Δ +0.87 + +### C165 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +- [ ] `100061194957` · L 69 / E 69.87 / Δ +0.87 + +### C166 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` +- [ ] `100021236527` · L 72 / E 71.13 / Δ -0.87 + +### C167 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` +- [ ] `100040193752` · L 71 / E 71.86 / Δ +0.86 + +### C168 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` +- [ ] `100060701552` · L 74 / E 74.86 / Δ +0.86 + +### C169 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` +- [ ] `10070396146` · L 61 / E 60.14 / Δ -0.86 + +### C170 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` +- [ ] `100030528930` · L 74 / E 73.16 / Δ -0.84 + +### C171 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` +- [ ] `100020982570` · L 72 / E 71.17 / Δ -0.83 + +### C172 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` +- [ ] `394024487` · L 75 / E 74.17 / Δ -0.83 + +### C173 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` +- [ ] `217070698` · L 78 / E 78.83 / Δ +0.83 + +### C174 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` +- [ ] `77022508` · L 69 / E 68.18 / Δ -0.82 + +### C175 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched 270 | ext1,sec:room heaters` +- [ ] `10024298029` · L 72 / E 72.82 / Δ +0.82 + +### C176 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` +- [ ] `100040259104` · L 68 / E 68.82 / Δ +0.82 + +### C177 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` +- [ ] `100031399026` · L 70 / E 70.81 / Δ +0.81 + +### C178 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` +- [ ] `10009645698` · L 67 / E 67.81 / Δ +0.81 + +### C179 · Σ|Δ| 0.8 · 1 certs · `hpcdb16136/gas | cavity wall | pitched insulated` +- [ ] `100011594820` · L 70 / E 69.19 / Δ -0.81 + +### C180 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` +- [ ] `100080818887` · L 56 / E 55.19 / Δ -0.81 + +### C181 · Σ|Δ| 0.8 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | sec:room heaters` +- [ ] `72103702` · L 70 / E 70.80 / Δ +0.80 + +### C182 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` +- [ ] `100012374381` · L 69 / E 69.80 / Δ +0.80 + +### C183 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` +- [ ] `100012350270` · L 78 / E 77.20 / Δ -0.80 + +### C184 · Σ|Δ| 0.8 · 1 certs · `hpcdb17956/gas | sandstone as | pitched insulated` +- [ ] `100010434688` · L 72 / E 71.20 / Δ -0.80 + +### C185 · Σ|Δ| 0.8 · 1 certs · `h104/gas | sandstone as | pitched insulated | ext1` +- [ ] `100050413774` · L 63 / E 62.21 / Δ -0.79 + +### C186 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` +- [ ] `100061616915` · L 63 / E 62.22 / Δ -0.78 + +### C187 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` +- [ ] `line71` · L 74 / E 74.77 / Δ +0.77 + +### C188 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` +- [ ] `100011603934` · L 72 / E 71.23 / Δ -0.77 + +### C189 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` +- [ ] `24030987` · L 73 / E 73.76 / Δ +0.76 + +### C190 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` +- [ ] `100010866608` · L 71 / E 70.24 / Δ -0.76 + +### C191 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` +- [ ] `100090399615` · L 67 / E 67.75 / Δ +0.75 + +### C192 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` +- [ ] `100062174575` · L 46 / E 46.75 / Δ +0.75 + +### C193 · Σ|Δ| 0.7 · 1 certs · `hpcdb19082/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [ ] `63015070` · L 69 / E 69.74 / Δ +0.74 + +### C194 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` +- [ ] `10012341135` · L 79 / E 79.73 / Δ +0.73 + +### C195 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +- [ ] `100091005853` · L 70 / E 69.27 / Δ -0.73 + +### C196 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` +- [ ] `100021533514` · L 71 / E 71.73 / Δ +0.73 + +### C197 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` +- [ ] `5062075` · L 69 / E 69.72 / Δ +0.72 + +### C198 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` +- [ ] `100040813308` · L 62 / E 62.72 / Δ +0.72 + +### C199 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` +- [ ] `38105600` · L 68 / E 67.28 / Δ -0.72 + +### C200 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` +- [ ] `line255` · L 72 / E 71.29 / Δ -0.71 + +### C201 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` +- [ ] `5300047580` · L 69 / E 68.30 / Δ -0.70 + +### C202 · Σ|Δ| 0.7 · 1 certs · `hpcdb18559/gas | cavity wall | pitched 75 | consv2,sec:room heaters` +- [ ] `10010610915` · L 69 / E 69.69 / Δ +0.69 + +### C203 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` +- [ ] `100110433403` · L 69 / E 68.32 / Δ -0.68 + +### C204 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` +- [ ] `10093416558` · L 79 / E 78.32 / Δ -0.68 + +### C205 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` +- [ ] `100050958217` · L 68 / E 68.68 / Δ +0.68 + +### C206 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` +- [ ] `100022667797` · L 68 / E 67.32 / Δ -0.68 + +### C207 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` +- [ ] `100030528925` · L 78 / E 78.65 / Δ +0.65 + +### C208 · Σ|Δ| 0.6 · 1 certs · `h691/elec | timber frame | pitched insulated | ext1,sec:room heaters,whw909` +- [ ] `10094257000` · L 55 / E 55.65 / Δ +0.65 + +### C209 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` +- [ ] `100110300037` · L 74 / E 73.35 / Δ -0.65 + +### C210 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` +- [ ] `217092450` · L 52 / E 52.64 / Δ +0.64 + +### C211 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` +- [ ] `100061164545` · L 72 / E 71.36 / Δ -0.64 + +### C212 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` +- [ ] `100051075936` · L 71 / E 70.36 / Δ -0.64 + +### C213 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` +- [ ] `100011565830` · L 72 / E 72.64 / Δ +0.64 + +### C214 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` +- [ ] `61010956` · L 75 / E 74.37 / Δ -0.63 + +### C215 · Σ|Δ| 0.6 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` +- [ ] `10091707271` · L 41 / E 41.63 / Δ +0.63 + +### C216 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` +- [ ] `100110752514` · L 67 / E 67.62 / Δ +0.62 + +### C217 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` +- [ ] `100012534027` · L 65 / E 64.38 / Δ -0.62 + +### C218 · Σ|Δ| 0.6 · 1 certs · `hpcdb19094/gas | sandstone as | pitched 270 | ext2,sec:room heaters` +- [ ] `10070089948` · L 64 / E 64.60 / Δ +0.60 + +### C219 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` +- [ ] `34080035` · L 77 / E 76.41 / Δ -0.59 + +### C220 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` +- [ ] `21032732` · L 69 / E 69.59 / Δ +0.59 + +### C221 · Σ|Δ| 0.6 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` +- [ ] `100090616327` · L 63 / E 63.59 / Δ +0.59 + +### C222 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` +- [ ] `100060562056` · L 66 / E 65.41 / Δ -0.59 + +### C223 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` +- [ ] `100091086558` · L 79 / E 79.58 / Δ +0.58 + +### C224 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` +- [ ] `line599` · L 74 / E 73.42 / Δ -0.58 + +### C225 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` +- [ ] `100020407741` · L 72 / E 71.42 / Δ -0.58 + +### C226 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` +- [ ] `100050839457` · L 70 / E 70.57 / Δ +0.57 + +### C227 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` +- [ ] `42105250` · L 59 / E 59.57 / Δ +0.57 + +### C228 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` +- [ ] `77200509` · L 69 / E 69.57 / Δ +0.57 + +### C229 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` +- [ ] `200040534` · L 65 / E 65.56 / Δ +0.56 + +### C230 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` +- [ ] `100062527568` · L 61 / E 61.56 / Δ +0.56 + +### C231 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` +- [ ] `100100268900` · L 69 / E 69.56 / Δ +0.56 + +### C232 · Σ|Δ| 0.6 · 1 certs · `hpcdb15100/gas | cavity wall | pitched unknown | sec:room heaters` +- [ ] `100031166296` · L 58 / E 58.55 / Δ +0.55 + +### C233 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` +- [ ] `90036914` · L 60 / E 60.55 / Δ +0.55 + +### C234 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` +- [ ] `10004742671` · L 70 / E 69.46 / Δ -0.54 + +### C235 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` +- [ ] `100010657450` · L 75 / E 75.54 / Δ +0.54 + +### C236 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` +- [ ] `100061834344` · L 71 / E 70.46 / Δ -0.54 + +### C237 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` +- [ ] `4510097194` · L 70 / E 70.53 / Δ +0.53 + +### C238 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` +- [ ] `100010913220` · L 72 / E 72.53 / Δ +0.53 + +### C239 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` +- [ ] `43074051` · L 63 / E 62.48 / Δ -0.52 + +### C240 · Σ|Δ| 0.5 · 1 certs · `h104/gas | cavity wall | pitched 300` +- [ ] `100010723814` · L 69 / E 69.52 / Δ +0.52 + +### C241 · Σ|Δ| 0.5 · 1 certs · `hpcdb16137/gas | cavity wall | (another dwelling` +- [ ] `100020955792` · L 77 / E 77.52 / Δ +0.52 + +### C242 · Σ|Δ| 0.5 · 1 certs · `hpcdb19079/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +- [ ] `77172223` · L 65 / E 65.52 / Δ +0.52 + +### C243 · Σ|Δ| 0.5 · 1 certs · `hpcdb10242/gas | granite or | pitched insulated | RR,sec:room heaters` +- [ ] `100051245439` · L 62 / E 61.48 / Δ -0.52 + +### C244 · Σ|Δ| 0.5 · 1 certs · `hpcdb10328/gas | cavity wall | (another dwelling` +- [ ] `100012553958` · L 67 / E 66.48 / Δ -0.52 + +### C245 · Σ|Δ| 0.5 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` +- [ ] `200004522639` · L 37 / E 36.48 / Δ -0.52 + +### C246 · Σ|Δ| 0.5 · 1 certs · `hpcdb10033/gas | cavity wall | pitched 200 | ext2,sec:room heaters` +- [ ] `100110108632` · L 63 / E 63.51 / Δ +0.51 + +### C247 · Σ|Δ| 0.5 · 1 certs · `h109/gas | cavity wall | pitched 270 | consv2,ext1,sec:room heaters` +- [ ] `100091102581` · L 65 / E 65.51 / Δ +0.51 + +### C248 · Σ|Δ| 0.5 · 1 certs · `hpcdb19008/gas | cavity wall | pitched 150 | ext1,sec:room heaters` +- [ ] `10002326688` · L 69 / E 68.50 / Δ -0.50 + +### C249 · Σ|Δ| 0.5 · 1 certs · `h129/fuel28 | granite or | pitched 200 | ext2,sec:room heaters` +- [ ] `10023132869` · L 46 / E 45.50 / Δ -0.50 + +## Resolved ≤0.5 (742 certs — no action) + +
expand + +- [x] `100090733462` · L 67 / E 67.50 / Δ +0.50 · `hpcdb17974/gas | solid brick | pitched insulated | ext1` +- [x] `10034815294` · L 78 / E 77.51 / Δ -0.49 · `hpcdb18559/gas | timber frame | pitched 125` +- [x] `100110206000` · L 57 / E 56.51 / Δ -0.49 · `h111/gas | cavity wall | pitched 175 | ext1,sec:room heaters` +- [x] `100090478973` · L 86 / E 86.49 / Δ +0.49 · `hpcdb18907/gas | cavity wall | pitched 150 | PV` +- [x] `217039192` · L 70 / E 69.51 / Δ -0.49 · `hpcdb17975/gas | solid brick | (another dwelling | mv4` +- [x] `100050839462` · L 69 / E 68.51 / Δ -0.49 · `hpcdb19007/gas | cavity wall | pitched 150 | ext1` +- [x] `100021753513` · L 77 / E 76.51 / Δ -0.49 · `hpcdb17511/gas | cavity wall | pitched insulated` +- [x] `100010402433` · L 70 / E 70.49 / Δ +0.49 · `hpcdb15705/gas | cavity wall | pitched insulated | PV,RR` +- [x] `100031059396` · L 75 / E 74.51 / Δ -0.49 · `hpcdb17982/gas | cavity wall | (another dwelling` +- [x] `100040387235` · L 72 / E 71.51 / Δ -0.49 · `hpcdb18907/gas | sandstone as | pitched insulated | ext1,sec:room heaters` +- [x] `100121020262` · L 63 / E 63.49 / Δ +0.49 · `hpcdb18432/gas | cavity wall | pitched insulated | sec:room heaters` +- [x] `100060596060` · L 68 / E 68.49 / Δ +0.49 · `hpcdb4048/gas | cavity wall | pitched 150 | ext1` +- [x] `100110101713` · L 73 / E 72.51 / Δ -0.49 · `hpcdb100061/elec | cavity wall | (another dwelling | PV` +- [x] `100052163521` · L 73 / E 72.51 / Δ -0.49 · `h104/gas | cavity wall | pitched 300` +- [x] `202030317` · L 74 / E 74.49 / Δ +0.49 · `hpcdb18820/gas | solid brick | (another dwelling` +- [x] `10022829122` · L 82 / E 82.49 / Δ +0.49 · `hpcdb104568/elec | cavity wall | (another dwelling` +- [x] `100091572782` · L 74 / E 74.48 / Δ +0.48 · `hpcdb19168/gas | cavity wall | pitched 100 | ext1` +- [x] `28012066` · L 71 / E 71.48 / Δ +0.48 · `hpcdb16212/gas | cavity wall | pitched 400+` +- [x] `74057326` · L 73 / E 72.52 / Δ -0.48 · `h691/elec | solid brick | pitched 270 | whw909` +- [x] `34087745` · L 68 / E 67.52 / Δ -0.48 · `hpcdb10243/gas | solid brick | (another dwelling | ext1` +- [x] `61016813` · L 72 / E 71.52 / Δ -0.48 · `hpcdb17590/gas | sandstone as | pitched insulated` +- [x] `33042105` · L 54 / E 54.48 / Δ +0.48 · `h691/elec | cavity wall | pitched 100 | whw903` +- [x] `100040286465` · L 65 / E 64.52 / Δ -0.48 · `hpcdb16210/gas | cavity wall | pitched 175 | ext2,sec:room heaters` +- [x] `10034663764` · L 74 / E 74.48 / Δ +0.48 · `h104/gas | cavity wall | pitched 350 | ext1` +- [x] `100060858571` · L 67 / E 66.52 / Δ -0.48 · `h104/gas | cavity wall | pitched 100` +- [x] `100090444184` · L 69 / E 68.52 / Δ -0.48 · `hpcdb15032/gas | solid brick | pitched 270 | RR,ext1` +- [x] `100110139702` · L 69 / E 68.52 / Δ -0.48 · `hpcdb18684/gas | cavity wall | pitched 200 | consv2,sec:room heaters` +- [x] `100070365977` · L 78 / E 77.52 / Δ -0.48 · `hpcdb19001/gas | solid brick | pitched 400+ | PV` +- [x] `100080323739` · L 67 / E 67.48 / Δ +0.48 · `hpcdb10327/gas | cavity wall | pitched 150` +- [x] `100100840201` · L 60 / E 60.48 / Δ +0.48 · `hpcdb10244/gas | granite or | pitched 100 | ext1` +- [x] `100061125812` · L 75 / E 75.48 / Δ +0.48 · `hpcdb17983/gas | solid brick | pitched 50 | PV,ext2,sec:room heaters` +- [x] `100071135609` · L 68 / E 68.48 / Δ +0.48 · `hpcdb18229/gas | solid brick | pitched 200 | ext2` +- [x] `100121043224` · L 77 / E 77.48 / Δ +0.48 · `hpcdb1758/gas | cavity wall | pitched 300` +- [x] `30025401` · L 70 / E 69.52 / Δ -0.48 · `hpcdb18433/gas | cavity wall | pitched 270 | ext2` +- [x] `100021037247` · L 71 / E 70.52 / Δ -0.48 · `hpcdb10112/gas | solid brick | (another dwelling` +- [x] `10013778285` · L 80 / E 79.52 / Δ -0.48 · `hpcdb16138/gas | cavity wall | (another dwelling` +- [x] `100010348502` · L 76 / E 75.52 / Δ -0.48 · `hpcdb16839/gas | cavity wall | pitched 175` +- [x] `100040227808` · L 58 / E 58.48 / Δ +0.48 · `hpcdb15502/gas | solid brick | pitched 270 | sec:room heaters` +- [x] `100051118081` · L 73 / E 73.47 / Δ +0.47 · `hpcdb18907/gas | cavity wall | pitched 300 | PV` +- [x] `100110190943` · L 67 / E 66.53 / Δ -0.47 · `hpcdb16777/gas | cavity wall | pitched 200` +- [x] `545523` · L 59 / E 59.47 / Δ +0.47 · `hpcdb16840/gas | cavity wall | pitched 100` +- [x] `100091241575` · L 70 / E 69.53 / Δ -0.47 · `hpcdb18908/gas | cavity wall | (another dwelling | mv2` +- [x] `100091265662` · L 63 / E 63.47 / Δ +0.47 · `h104/gas | cavity wall | pitched no` +- [x] `32066846` · L 59 / E 59.47 / Δ +0.47 · `hpcdb17507/gas | solid brick | pitched insulated | ext2,sec:room heaters` +- [x] `100030896498` · L 51 / E 51.47 / Δ +0.47 · `hpcdb10244/gas | solid brick | pitched no | ext1,sec:room heaters` +- [x] `100120636023` · L 72 / E 71.53 / Δ -0.47 · `hpcdb19009/gas | cavity wall | pitched 200` +- [x] `2465112185` · L 73 / E 73.47 / Δ +0.47 · `hpcdb18511/gas | cavity wall | pitched 270` +- [x] `200000569282` · L 69 / E 69.47 / Δ +0.47 · `hpcdb19076/gas | cavity wall | (another dwelling` +- [x] `10008075105` · L 77 / E 76.53 / Δ -0.47 · `hpcdb16810/gas | cavity wall | pitched 270` +- [x] `100010677806` · L 70 / E 70.47 / Δ +0.47 · `hpcdb10354/gas | cavity wall | pitched 150 | RR,ext1,sec:room heaters` +- [x] `100100607883` · L 67 / E 67.46 / Δ +0.46 · `hpcdb17679/gas | cavity wall | pitched 250` +- [x] `40032301` · L 72 / E 72.46 / Δ +0.46 · `hpcdb18234/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `21035507` · L 72 / E 71.54 / Δ -0.46 · `hpcdb16137/gas | cavity wall | (another dwelling` +- [x] `100071073344` · L 73 / E 73.46 / Δ +0.46 · `hpcdb10244/gas | cavity wall | (another dwelling | sec:room heaters` +- [x] `100091287350` · L 67 / E 67.46 / Δ +0.46 · `hpcdb17507/gas | solid brick | pitched insulated` +- [x] `10023324935` · L 72 / E 72.46 / Δ +0.46 · `h104/gas | cavity wall | pitched insulated` +- [x] `12027355` · L 70 / E 69.54 / Δ -0.46 · `hpcdb1838/gas | solid brick | pitched insulated | ext1` +- [x] `1775072187` · L 70 / E 69.54 / Δ -0.46 · `hpcdb15273/gas | timber frame | flat limited` +- [x] `5870069932` · L 73 / E 72.54 / Δ -0.46 · `hpcdb17483/gas | cavity wall | pitched insulated | PV` +- [x] `10033057673` · L 77 / E 76.54 / Δ -0.46 · `hpcdb18204/gas | cavity wall | pitched 250` +- [x] `42027366` · L 73 / E 72.54 / Δ -0.46 · `hpcdb10446/gas | cavity wall | pitched 150 | PV,sec:room heaters` +- [x] `100031607789` · L 75 / E 75.46 / Δ +0.46 · `hpcdb10457/gas | system built | pitched 250 | ext1` +- [x] `100061423798` · L 75 / E 74.54 / Δ -0.46 · `hpcdb18820/gas | cavity wall | pitched 100` +- [x] `100110090714` · L 71 / E 71.46 / Δ +0.46 · `hpcdb8587/gas | cavity wall | pitched 175` +- [x] `1775121297` · L 79 / E 78.55 / Δ -0.45 · `hpcdb16400/gas | cavity wall | pitched 300 | PV` +- [x] `100070304824` · L 76 / E 76.45 / Δ +0.45 · `hpcdb18119/gas | cavity wall | pitched insulated` +- [x] `41229335` · L 76 / E 75.55 / Δ -0.45 · `hpcdb16839/gas | cavity wall | pitched 200` +- [x] `200000571972` · L 64 / E 63.55 / Δ -0.45 · `hpcdb17986/gas | solid brick | pitched 250 | ext1` +- [x] `600039` · L 71 / E 70.55 / Δ -0.45 · `h104/gas | cavity wall | pitched 200` +- [x] `100050635265` · L 68 / E 67.55 / Δ -0.45 · `hpcdb17956/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `100040685184` · L 59 / E 59.45 / Δ +0.45 · `hpcdb18432/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `100070537862` · L 97 / E 96.55 / Δ -0.45 · `hpcdb10244/gas | cavity wall | pitched 400+ | PV,sec:room heaters` +- [x] `100100607333` · L 65 / E 64.55 / Δ -0.45 · `hpcdb15752/gas | granite or | pitched 175 | ext1` +- [x] `100090385996` · L 90 / E 90.45 / Δ +0.45 · `h409/elec | solid brick | pitched 270 | PV,mv2,sec:room heaters,whw903` +- [x] `200051823` · L 83 / E 82.55 / Δ -0.45 · `hpcdb17505/gas | cavity wall | (another dwelling` +- [x] `100040647307` · L 67 / E 66.55 / Δ -0.45 · `hpcdb10326/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `10091709997` · L 80 / E 79.55 / Δ -0.45 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `422000130066` · L 77 / E 77.45 / Δ +0.45 · `hpcdb18225/gas | cavity wall | pitched 200` +- [x] `200004196713` · L 69 / E 68.55 / Δ -0.45 · `hpcdb19083/gas | cavity wall | pitched 200 | ext1` +- [x] `100020988934` · L 70 / E 69.55 / Δ -0.45 · `hpcdb17974/gas | solid brick | pitched 100` +- [x] `10013448474` · L 80 / E 79.55 / Δ -0.45 · `h408/elec | cavity wall | (another dwelling | whw903` +- [x] `100010542167` · L 65 / E 65.45 / Δ +0.45 · `hpcdb15445/gas | cavity wall | pitched 100 | consv3` +- [x] `100050721946` · L 73 / E 72.56 / Δ -0.44 · `hpcdb15024/gas | cavity wall | (another dwelling | ext1` +- [x] `10002589494` · L 70 / E 70.44 / Δ +0.44 · `hpcdb8642/gas | cavity wall | pitched 200` +- [x] `100010460076` · L 67 / E 66.56 / Δ -0.44 · `hpcdb17515/gas | cavity wall | pitched 100` +- [x] `100051178837` · L 63 / E 63.44 / Δ +0.44 · `h104/gas | sandstone as | pitched no | RR` +- [x] `10014526109` · L 59 / E 59.44 / Δ +0.44 · `h126/fuel28 | solid brick | flat insulated | consv2,ext1,sec:room heaters` +- [x] `63017340` · L 74 / E 73.56 / Δ -0.44 · `hpcdb17956/gas | solid brick | pitched insulated` +- [x] `50101945` · L 75 / E 74.56 / Δ -0.44 · `hpcdb10243/gas | timber frame | (another dwelling | ext1` +- [x] `10032778242` · L 65 / E 65.44 / Δ +0.44 · `hpcdb9209/gas | sandstone as | pitched 100` +- [x] `40002036` · L 64 / E 63.56 / Δ -0.44 · `hpcdb17904/gas | cavity wall | pitched no` +- [x] `200004695006` · L 69 / E 68.56 / Δ -0.44 · `hpcdb10243/gas | sandstone as | pitched insulated` +- [x] `100010170141` · L 61 / E 61.44 / Δ +0.44 · `hpcdb4045/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `100090412407` · L 71 / E 70.56 / Δ -0.44 · `hpcdb18908/gas | cavity wall | pitched 200` +- [x] `10070623452` · L 84 / E 84.44 / Δ +0.44 · `hpcdb18616/gas | cavity wall | (another dwelling` +- [x] `100000059044` · L 73 / E 72.56 / Δ -0.44 · `hpcdb17983/gas | cavity wall | (another dwelling` +- [x] `10012437206` · L 67 / E 67.44 / Δ +0.44 · `hpcdb16136/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `100070391608` · L 65 / E 64.56 / Δ -0.44 · `hpcdb18283/gas | solid brick | pitched 225 | ext2` +- [x] `100050849874` · L 70 / E 70.44 / Δ +0.44 · `hpcdb19007/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +- [x] `10094494653` · L 76 / E 75.57 / Δ -0.43 · `hpcdb18559/gas | solid brick | (another dwelling` +- [x] `10070088126` · L 74 / E 73.57 / Δ -0.43 · `hpcdb16210/gas | cavity wall | pitched 270 | consv3` +- [x] `39036600` · L 72 / E 72.43 / Δ +0.43 · `hpcdb18225/gas | cavity wall | pitched 400 | mv2` +- [x] `100021219619` · L 69 / E 68.57 / Δ -0.43 · `hpcdb18559/gas | solid brick | pitched 100` +- [x] `100100579892` · L 71 / E 71.43 / Δ +0.43 · `hpcdb10244/gas | cavity wall | pitched 400+` +- [x] `200000795879` · L 58 / E 57.57 / Δ -0.43 · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` +- [x] `39096576` · L 82 / E 81.57 / Δ -0.43 · `hpcdb17617/gas | timber frame | pitched 400+` +- [x] `1775045933` · L 69 / E 69.43 / Δ +0.43 · `hpcdb8180/gas | cavity wall | pitched 150` +- [x] `83105081` · L 67 / E 67.43 / Δ +0.43 · `hpcdb18119/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `21072782` · L 66 / E 65.57 / Δ -0.43 · `hpcdb18045/gas | cavity wall | pitched 175 | sec:room heaters` +- [x] `100090106879` · L 70 / E 70.43 / Δ +0.43 · `hpcdb16836/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `100031468327` · L 69 / E 69.43 / Δ +0.43 · `hpcdb19083/gas | cavity wall | pitched 300 | consv2` +- [x] `100100253270` · L 71 / E 71.43 / Δ +0.43 · `hpcdb18496/gas | cavity wall | pitched 250 | ext1` +- [x] `100071116347` · L 62 / E 62.43 / Δ +0.43 · `h104/gas | solid brick | pitched 150` +- [x] `422000030203` · L 75 / E 75.42 / Δ +0.42 · `hpcdb10328/gas | cavity wall | pitched 225` +- [x] `100010399776` · L 63 / E 63.42 / Δ +0.42 · `hpcdb10462/gas | cavity wall | pitched 270 | RR,ext1,sec:room heaters` +- [x] `100080945063` · L 70 / E 70.42 / Δ +0.42 · `hpcdb10326/gas | cavity wall | (another dwelling | ext1` +- [x] `100100284086` · L 69 / E 69.42 / Δ +0.42 · `hpcdb17983/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `100031674118` · L 66 / E 66.42 / Δ +0.42 · `hpcdb17986/gas | cavity wall | pitched 125 | consv2,sec:room heaters` +- [x] `10023449405` · L 59 / E 58.58 / Δ -0.42 · `hpcdb18219/gas | granite or | pitched insulated | consv3,ext1,sec:room heaters` +- [x] `47237825` · L 79 / E 79.42 / Δ +0.42 · `hpcdb15707/gas | cavity wall | (another dwelling` +- [x] `100010265441` · L 69 / E 69.42 / Δ +0.42 · `hpcdb16839/gas | cavity wall | pitched 200` +- [x] `100010197780` · L 65 / E 65.42 / Δ +0.42 · `hpcdb1839/gas | cavity wall | pitched 75 | sec:room heaters` +- [x] `100100991435` · L 74 / E 74.42 / Δ +0.42 · `hpcdb18907/gas | cavity wall | (another dwelling` +- [x] `100070537860` · L 91 / E 91.42 / Δ +0.42 · `hpcdb18225/gas | cavity wall | pitched 400+ | PV,sec:room heaters` +- [x] `100051145841` · L 70 / E 70.42 / Δ +0.42 · `hpcdb18559/gas | cavity wall | pitched 150` +- [x] `100030488548` · L 62 / E 62.42 / Δ +0.42 · `hpcdb1848/gas | solid brick | pitched insulated | ext1,sec:room heaters` +- [x] `100030538980` · L 68 / E 68.42 / Δ +0.42 · `hpcdb19109/gas | solid brick | pitched insulated | ext1` +- [x] `4510015395` · L 70 / E 69.58 / Δ -0.42 · `hpcdb19007/gas | cavity wall | pitched 200` +- [x] `100021798076` · L 56 / E 55.58 / Δ -0.42 · `hpcdb17505/gas | cavity wall | pitched 12 | ext1,sec:room heaters` +- [x] `200002597778` · L 73 / E 72.58 / Δ -0.42 · `hpcdb15282/gas | cavity wall | pitched 200` +- [x] `200004402879` · L 74 / E 73.58 / Δ -0.42 · `hpcdb17983/gas | cavity wall | pitched 200` +- [x] `10091186955` · L 82 / E 82.42 / Δ +0.42 · `hpcdb17505/gas | cavity wall | (another dwelling` +- [x] `100000054651` · L 70 / E 70.42 / Δ +0.42 · `hpcdb17983/gas | cavity wall | pitched 125` +- [x] `100030769969` · L 58 / E 57.59 / Δ -0.41 · `h130/fuel28 | cavity wall | pitched 250` +- [x] `10070086972` · L 18 / E 17.59 / Δ -0.41 · `hpcdb710/fuel28+2mains | sandstone as | pitched insulated | RR,ext4,sec:room heaters` +- [x] `100050397944` · L 65 / E 64.59 / Δ -0.41 · `hpcdb17681/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `63105357` · L 74 / E 74.41 / Δ +0.41 · `hpcdb17507/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `10009812472` · L 40 / E 40.41 / Δ +0.41 · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` +- [x] `100090989765` · L 70 / E 70.41 / Δ +0.41 · `hpcdb16408/gas | timber frame | pitched 300 | consv3,ext1,sec:room heaters` +- [x] `200004700463` · L 65 / E 65.40 / Δ +0.40 · `hpcdb18559/gas | sandstone as | pitched 75` +- [x] `100020675575` · L 60 / E 60.40 / Δ +0.40 · `h102/gas | cavity wall | pitched 12` +- [x] `100110694244` · L 72 / E 72.40 / Δ +0.40 · `hpcdb18512/gas | granite or | pitched 200 | sec:room heaters` +- [x] `10003910753` · L 64 / E 63.60 / Δ -0.40 · `h409/elec | granite or | pitched 300 | sec:room heaters,whw903` +- [x] `100040881207` · L 73 / E 73.40 / Δ +0.40 · `hpcdb16839/gas | solid brick | pitched 100 | ext1` +- [x] `100070601575` · L 68 / E 68.40 / Δ +0.40 · `hpcdb18560/gas | solid brick | pitched 250` +- [x] `100010596378` · L 67 / E 67.40 / Δ +0.40 · `hpcdb16839/gas | cavity wall | pitched 350 | RR,consv3,ext1,sec:room heaters` +- [x] `100051185130` · L 67 / E 66.60 / Δ -0.40 · `hpcdb18156/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `38198539` · L 80 / E 80.40 / Δ +0.40 · `hpcdb18229/gas | cavity wall | (another dwelling` +- [x] `10008501568` · L 76 / E 76.40 / Δ +0.40 · `hpcdb16909/gas | cavity wall | (another dwelling` +- [x] `10090849417` · L 73 / E 72.60 / Δ -0.40 · `hpcdb17000/fuel27 | cavity wall | (another dwelling` +- [x] `100110494926` · L 66 / E 66.40 / Δ +0.40 · `h104/gas | cavity wall | pitched 250` +- [x] `100050553337` · L 70 / E 69.60 / Δ -0.40 · `hpcdb16839/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100071356612` · L 69 / E 68.61 / Δ -0.39 · `h301/coal-anth | solid brick | (another dwelling` +- [x] `74041417` · L 79 / E 79.39 / Δ +0.39 · `hpcdb17507/gas | cavity wall | pitched 300 | PV` +- [x] `100022607800` · L 73 / E 72.61 / Δ -0.39 · `hpcdb18119/gas | solid brick | pitched 270` +- [x] `100040268694` · L 58 / E 58.39 / Δ +0.39 · `h127/fuel28 | granite or | pitched insulated | RR,ext1,sec:room heaters` +- [x] `100022277442` · L 58 / E 58.39 / Δ +0.39 · `h409/elec | cavity wall | pitched insulated | whw903` +- [x] `250029611` · L 73 / E 72.61 / Δ -0.39 · `hpcdb17553/gas | cavity wall | pitched 250 | consv2,ext1` +- [x] `100022887979` · L 72 / E 72.39 / Δ +0.39 · `hpcdb18861/gas | solid brick | (another dwelling` +- [x] `44006508` · L 78 / E 78.39 / Δ +0.39 · `hpcdb17683/gas | cavity wall | pitched 150` +- [x] `38081666` · L 69 / E 68.61 / Δ -0.39 · `hpcdb17919/gas | solid brick | pitched 400+ | sec:room heaters` +- [x] `10090034244` · L 80 / E 80.39 / Δ +0.39 · `h691/elec | system built | (another dwelling | whw903` +- [x] `100010692849` · L 74 / E 73.61 / Δ -0.39 · `hpcdb16455/gas | cavity wall | pitched 300 | consv4,ext2,sec:room heaters` +- [x] `100090148760` · L 67 / E 67.39 / Δ +0.39 · `hpcdb15032/gas | cavity wall | pitched 100 | consv2` +- [x] `72304070` · L 76 / E 75.61 / Δ -0.39 · `hpcdb18225/gas | cavity wall | pitched 200` +- [x] `100070668967` · L 76 / E 76.39 / Δ +0.39 · `hpcdb17816/gas | cavity wall | pitched 200 | consv2` +- [x] `100040892555` · L 71 / E 71.39 / Δ +0.39 · `hpcdb16840/gas | cavity wall | pitched insulated` +- [x] `100061274293` · L 71 / E 71.39 / Δ +0.39 · `hpcdb17553/gas | cavity wall | pitched 300 | ext1` +- [x] `11064046` · L 65 / E 64.61 / Δ -0.39 · `h104/gas | solid brick | pitched insulated | ext2` +- [x] `77069148` · L 71 / E 71.39 / Δ +0.39 · `hpcdb17507/gas | cavity wall | pitched 200` +- [x] `148002976` · L 72 / E 71.61 / Δ -0.39 · `hpcdb16840/gas | cavity wall | pitched insulated | ext1` +- [x] `10096536318` · L 66 / E 65.62 / Δ -0.38 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100030585620` · L 59 / E 59.38 / Δ +0.38 · `h102/gas | cavity wall | pitched insulated | ext4,sec:room heaters` +- [x] `10008325030` · L 82 / E 81.62 / Δ -0.38 · `h301/coal-anth | system built | (another dwelling` +- [x] `100060061070` · L 70 / E 70.38 / Δ +0.38 · `hpcdb17986/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `100050869353` · L 75 / E 74.62 / Δ -0.38 · `hpcdb10547/gas | solid brick | pitched 300` +- [x] `45034352` · L 70 / E 70.38 / Δ +0.38 · `hpcdb18684/gas | cavity wall | pitched 250 | ext1` +- [x] `10009274535` · L 31 / E 31.38 / Δ +0.38 · `h126/fuel28 | sandstone as | pitched 50 | consv4,ext2,sec:room heaters` +- [x] `1710007756` · L 76 / E 76.38 / Δ +0.38 · `h104/gas | cavity wall | pitched 250 | RR,ext1,sec:room heaters` +- [x] `72274934` · L 66 / E 66.38 / Δ +0.38 · `hpcdb17985/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `100030893211` · L 70 / E 69.62 / Δ -0.38 · `hpcdb17546/gas | cavity wall | pitched 200 | ext1` +- [x] `21018821` · L 67 / E 67.38 / Δ +0.38 · `hpcdb19014/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `100080145093` · L 69 / E 69.38 / Δ +0.38 · `hpcdb18907/gas | cavity wall | pitched 225 | ext1` +- [x] `100021434831` · L 74 / E 74.38 / Δ +0.38 · `h102/gas | cavity wall | pitched insulated | RR,ext1` +- [x] `100090160202` · L 78 / E 77.62 / Δ -0.38 · `hpcdb18120/gas | cavity wall | pitched 300 | PV` +- [x] `100000001899` · L 70 / E 70.38 / Δ +0.38 · `hpcdb17507/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `100032207872` · L 71 / E 71.38 / Δ +0.38 · `hpcdb17505/gas | cavity wall | (another dwelling` +- [x] `90089745` · L 62 / E 61.62 / Δ -0.38 · `hpcdb10243/gas | solid brick | pitched 150` +- [x] `100090379526` · L 67 / E 66.62 / Δ -0.38 · `hpcdb17992/gas | cavity wall | pitched 150 | ext2` +- [x] `100031755813` · L 73 / E 73.37 / Δ +0.37 · `hpcdb15706/gas | cavity wall | pitched 150` +- [x] `100040668971` · L 14 / E 13.63 / Δ -0.37 · `h631/LPG | cavity wall | pitched 250 | consv2,sec:portable electric,whw908` +- [x] `10013258835` · L 78 / E 77.63 / Δ -0.37 · `hpcdb16138/gas | timber frame | pitched 270 | ext1` +- [x] `10008774426` · L 77 / E 77.37 / Δ +0.37 · `h402/elec | cavity wall | pitched 250 | sec:room heaters,whw903` +- [x] `100090183995` · L 70 / E 70.37 / Δ +0.37 · `hpcdb15018/gas | cavity wall | pitched insulated` +- [x] `100100904720` · L 82 / E 81.63 / Δ -0.37 · `hpcdb19023/gas+2mains | cavity wall | flat insulated | RR,ext1,sec:room heaters` +- [x] `100050111553` · L 39 / E 39.37 / Δ +0.37 · `h191/elec | cavity wall | pitched 200 | whw903` +- [x] `100052105637` · L 59 / E 58.63 / Δ -0.37 · `hpcdb17741/gas | solid brick | pitched 200 | ext1,sec:room heaters` +- [x] `1775071220` · L 74 / E 73.63 / Δ -0.37 · `hpcdb10326/gas | cavity wall | (another dwelling` +- [x] `10000452538` · L 77 / E 76.63 / Δ -0.37 · `h104/gas | timber frame | pitched insulated` +- [x] `100120650297` · L 77 / E 76.63 / Δ -0.37 · `hpcdb17507/gas | cavity wall | (another dwelling` +- [x] `1775087250` · L 75 / E 74.63 / Δ -0.37 · `hpcdb18861/gas | cavity wall | pitched 250 | ext1` +- [x] `100061253556` · L 60 / E 59.63 / Δ -0.37 · `hpcdb18907/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `6083595` · L 76 / E 76.37 / Δ +0.37 · `hpcdb17685/gas | cavity wall | pitched insulated` +- [x] `100110452552` · L 67 / E 66.64 / Δ -0.36 · `hpcdb15068/gas | cavity wall | pitched 175 | mv2,sec:room heaters` +- [x] `200033141` · L 76 / E 75.64 / Δ -0.36 · `hpcdb16738/gas | cavity wall | flat insulated` +- [x] `100030357741` · L 72 / E 72.36 / Δ +0.36 · `hpcdb18560/gas | cavity wall | pitched 300 | consv2,ext1` +- [x] `100080707176` · L 72 / E 71.64 / Δ -0.36 · `hpcdb10243/gas | cavity wall | pitched 100` +- [x] `100062132377` · L 81 / E 80.64 / Δ -0.36 · `h214/elec | cavity wall | (another dwelling` +- [x] `100062132384` · L 81 / E 80.64 / Δ -0.36 · `h214/elec | cavity wall | (another dwelling` +- [x] `100031679582` · L 66 / E 66.36 / Δ +0.36 · `hpcdb10243/gas | cavity wall | pitched insulated` +- [x] `100031300973` · L 70 / E 70.36 / Δ +0.36 · `hpcdb10328/gas | cavity wall | pitched insulated` +- [x] `100090373553` · L 50 / E 49.64 / Δ -0.36 · `h102/gas | cavity wall | pitched insulated | ext1` +- [x] `100110122381` · L 70 / E 70.36 / Δ +0.36 · `hpcdb18119/gas | solid brick | pitched 300 | ext1` +- [x] `100110084287` · L 69 / E 68.64 / Δ -0.36 · `hpcdb17513/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100050858546` · L 58 / E 58.36 / Δ +0.36 · `hpcdb19030/gas | cavity wall | pitched 150 | sec:room heaters` +- [x] `100061152006` · L 66 / E 66.36 / Δ +0.36 · `hpcdb17503/gas | cavity wall | pitched 270 | ext1,sec:room heaters` +- [x] `100070649980` · L 69 / E 68.64 / Δ -0.36 · `hpcdb17505/gas | solid brick | pitched 200` +- [x] `100121236760` · L 58 / E 58.36 / Δ +0.36 · `hpcdb18044/gas | sandstone as | pitched insulated | RR,ext3,sec:room heaters` +- [x] `64024859` · L 54 / E 53.64 / Δ -0.36 · `hpcdb8358/gas | cavity wall | pitched 125 | consv3,ext1,sec:room heaters` +- [x] `100110061827` · L 71 / E 70.64 / Δ -0.36 · `hpcdb16688/gas | cavity wall | pitched 150 | ext2` +- [x] `100110394521` · L 73 / E 72.64 / Δ -0.36 · `hpcdb10328/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `10023253242` · L 72 / E 72.36 / Δ +0.36 · `h104/gas | cavity wall | pitched insulated` +- [x] `90090727` · L 67 / E 66.64 / Δ -0.36 · `h104/gas | cavity wall | pitched 200 | ext1` +- [x] `21055668` · L 61 / E 61.36 / Δ +0.36 · `hpcdb17546/gas | cavity wall | pitched no` +- [x] `100110496019` · L 76 / E 75.65 / Δ -0.35 · `hpcdb18560/gas | cavity wall | pitched 200` +- [x] `422000037738` · L 72 / E 72.35 / Δ +0.35 · `hpcdb17975/gas | cavity wall | pitched 400+` +- [x] `77102428` · L 78 / E 77.65 / Δ -0.35 · `hpcdb17558/gas | cavity wall | pitched 300 | ext1` +- [x] `100071034423` · L 72 / E 71.65 / Δ -0.35 · `hpcdb18908/gas | cavity wall | pitched 100` +- [x] `100071026195` · L 71 / E 71.35 / Δ +0.35 · `hpcdb18907/gas | solid brick | pitched insulated | ext1` +- [x] `200003757985` · L 72 / E 71.65 / Δ -0.35 · `h301/coal-anth | cavity wall | (another dwelling | PV` +- [x] `100051029525` · L 67 / E 67.35 / Δ +0.35 · `hpcdb17986/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `100051332624` · L 66 / E 65.65 / Δ -0.35 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `10094297916` · L 80 / E 80.35 / Δ +0.35 · `hpcdb17929/gas | timber frame | pitched unknown` +- [x] `2465002794` · L 64 / E 64.35 / Δ +0.35 · `h104/gas | solid brick | pitched insulated` +- [x] `28018668` · L 58 / E 58.35 / Δ +0.35 · `hpcdb17115/gas | solid brick | pitched 250 | ext1,sec:room heaters` +- [x] `100020275185` · L 67 / E 67.35 / Δ +0.35 · `hpcdb17975/gas | solid brick | pitched 100` +- [x] `100000320896` · L 71 / E 70.65 / Δ -0.35 · `hpcdb18559/gas | cavity wall | (another dwelling | ext1,sec:room heaters` +- [x] `4510706229` · L 71 / E 71.35 / Δ +0.35 · `h402/elec | solid brick | (another dwelling | sec:room heaters,whw903` +- [x] `10023179506` · L 77 / E 76.65 / Δ -0.35 · `hpcdb16400/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `32039356` · L 72 / E 72.34 / Δ +0.34 · `hpcdb17983/gas | cavity wall | pitched 200` +- [x] `100071281443` · L 72 / E 71.66 / Δ -0.34 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100050971905` · L 46 / E 46.34 / Δ +0.34 · `hpcdb19059/fuel27 | cavity wall | flat limited` +- [x] `50120779` · L 76 / E 75.66 / Δ -0.34 · `hpcdb16848/gas | solid brick | (another dwelling` +- [x] `23018106` · L 66 / E 66.34 / Δ +0.34 · `hpcdb18250/gas | cavity wall | pitched 150 | sec:room heaters` +- [x] `100090866399` · L 79 / E 79.34 / Δ +0.34 · `hpcdb18435/gas | cavity wall | pitched 200 | PV,ext2,sec:room heaters` +- [x] `100110515241` · L 64 / E 63.66 / Δ -0.34 · `hpcdb18559/gas | solid brick | pitched insulated | ext1,sec:room heaters` +- [x] `100010779964` · L 72 / E 72.34 / Δ +0.34 · `hpcdb17683/gas | sandstone as | pitched 75` +- [x] `64106486` · L 72 / E 71.66 / Δ -0.34 · `hpcdb17926/fuel27 | timber frame | pitched 270 | ext1` +- [x] `100120926050` · L 71 / E 70.67 / Δ -0.33 · `hpcdb18514/gas | cavity wall | pitched 175 | ext2` +- [x] `100012548450` · L 74 / E 74.33 / Δ +0.33 · `hpcdb10338/gas | cavity wall | (another dwelling` +- [x] `10012184174` · L 75 / E 74.67 / Δ -0.33 · `hpcdb19006/gas | solid brick | pitched insulated` +- [x] `100031680815` · L 61 / E 60.67 / Δ -0.33 · `h402/elec | cavity wall | pitched 150 | sec:room heaters,whw903` +- [x] `100070057052` · L 66 / E 65.67 / Δ -0.33 · `hpcdb10200/gas | cavity wall | pitched 250 | ext1` +- [x] `100060240863` · L 75 / E 75.33 / Δ +0.33 · `hpcdb15032/gas | solid brick | pitched 150` +- [x] `10008295210` · L 75 / E 74.67 / Δ -0.33 · `hpcdb18224/gas | system built | (another dwelling | ext1` +- [x] `83171858` · L 74 / E 73.67 / Δ -0.33 · `hpcdb18119/gas | system built | pitched 250` +- [x] `72304132` · L 67 / E 67.33 / Δ +0.33 · `hpcdb17986/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `12160542` · L 81 / E 81.32 / Δ +0.32 · `hpcdb18737/gas | cavity wall | (another dwelling` +- [x] `100062035546` · L 75 / E 74.68 / Δ -0.32 · `h104/gas | cavity wall | pitched 100` +- [x] `100071033825` · L 63 / E 63.32 / Δ +0.32 · `hpcdb17505/gas | cavity wall | pitched 225 | sec:room heaters` +- [x] `100040027178` · L 65 / E 64.68 / Δ -0.32 · `hpcdb19262/fuel28 | system built | pitched 270 | sec:room heaters` +- [x] `10091482156` · L 74 / E 74.32 / Δ +0.32 · `h104/gas | cavity wall | flat insulated` +- [x] `5182876` · L 80 / E 79.68 / Δ -0.32 · `hpcdb16841/gas | cavity wall | (another dwelling` +- [x] `100031703043` · L 63 / E 62.68 / Δ -0.32 · `hpcdb17284/gas | cavity wall | pitched 100 | ext1` +- [x] `200001480500` · L 75 / E 74.68 / Δ -0.32 · `h409/elec | cavity wall | pitched 100 | whw903` +- [x] `21037089` · L 68 / E 68.32 / Δ +0.32 · `hpcdb19007/gas | cavity wall | pitched insulated | ext1,mv5,sec:room heaters` +- [x] `100031318648` · L 79 / E 78.68 / Δ -0.32 · `hpcdb18907/gas | timber frame | pitched 400+ | PV,sec:room heaters` +- [x] `21089432` · L 64 / E 63.68 / Δ -0.32 · `hpcdb18045/gas | cavity wall | pitched no | ext1` +- [x] `93099` · L 63 / E 63.32 / Δ +0.32 · `hpcdb18250/gas | solid brick | pitched 200 | ext2` +- [x] `100051053673` · L 66 / E 66.32 / Δ +0.32 · `hpcdb17660/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `200002919291` · L 59 / E 59.32 / Δ +0.32 · `h691/elec | system built | (another dwelling | whw903` +- [x] `21082835` · L 78 / E 77.69 / Δ -0.31 · `hpcdb16137/gas | system built | pitched 270` +- [x] `100070126788` · L 58 / E 57.69 / Δ -0.31 · `hpcdb18090/gas | system built | pitched 75 | sec:room heaters` +- [x] `100010997844` · L 71 / E 71.31 / Δ +0.31 · `hpcdb18651/gas | cavity wall | pitched insulated` +- [x] `72207515` · L 71 / E 70.69 / Δ -0.31 · `hpcdb17973/gas | cavity wall | (another dwelling | sec:room heaters` +- [x] `100070312027` · L 72 / E 71.69 / Δ -0.31 · `hpcdb18908/gas | solid brick | pitched 270 | ext2,sec:room heaters` +- [x] `100071105301` · L 72 / E 72.31 / Δ +0.31 · `hpcdb10312/gas | solid brick | pitched 150` +- [x] `10008275334` · L 76 / E 76.31 / Δ +0.31 · `h691/elec | system built | (another dwelling | whw903` +- [x] `100110174472` · L 74 / E 74.31 / Δ +0.31 · `hpcdb8368/gas | solid brick | pitched 175 | ext2,mv5` +- [x] `100071450760` · L 55 / E 54.69 / Δ -0.31 · `h691/elec | cavity wall | (another dwelling | whw903` +- [x] `207096040` · L 69 / E 69.31 / Δ +0.31 · `hpcdb18219/gas | solid brick | pitched insulated | ext1` +- [x] `100100800577` · L 64 / E 64.31 / Δ +0.31 · `h301/coal-anth | system built | pitched 200 | whw903` +- [x] `100110234047` · L 71 / E 70.70 / Δ -0.30 · `hpcdb16136/gas | cavity wall | pitched 300` +- [x] `10007966883` · L 64 / E 64.30 / Δ +0.30 · `hpcdb17785/gas | solid brick | pitched 100 | ext1` +- [x] `100091292858` · L 59 / E 59.30 / Δ +0.30 · `h691/elec | solid brick | (another dwelling | whw903` +- [x] `100010719461` · L 56 / E 56.30 / Δ +0.30 · `hpcdb16930/gas | cavity wall | pitched no` +- [x] `100070487183` · L 66 / E 66.30 / Δ +0.30 · `h691/elec | timber frame | pitched 150 | whw909` +- [x] `116895` · L 73 / E 72.70 / Δ -0.30 · `hpcdb18119/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `10008031947` · L 79 / E 78.70 / Δ -0.30 · `hpcdb16406/gas+2mains | cavity wall | pitched 250 | ext2` +- [x] `100050834171` · L 73 / E 72.70 / Δ -0.30 · `hpcdb10547/gas | cavity wall | pitched 100` +- [x] `100110455808` · L 67 / E 66.70 / Δ -0.30 · `hpcdb10242/gas | cavity wall | pitched no` +- [x] `100070968292` · L 72 / E 71.70 / Δ -0.30 · `h104/gas | cavity wall | pitched insulated` +- [x] `100011754031` · L 69 / E 69.30 / Δ +0.30 · `hpcdb16839/gas | cavity wall | pitched 150 | ext1` +- [x] `61008954` · L 67 / E 67.30 / Δ +0.30 · `hpcdb18559/gas | sandstone as | pitched insulated` +- [x] `100061379950` · L 32 / E 31.70 / Δ -0.30 · `h104/fuel27+2mains | solid brick | pitched unknown | ext1,sec:room heaters,whw907` +- [x] `100050549118` · L 69 / E 68.70 / Δ -0.30 · `hpcdb15282/gas | cavity wall | pitched 100 | RR` +- [x] `100021754159` · L 57 / E 57.30 / Δ +0.30 · `hpcdb17503/gas | solid brick | pitched 100 | consv2,ext1,sec:room heaters` +- [x] `200000323155` · L 74 / E 74.30 / Δ +0.30 · `hpcdb17974/gas | timber frame | pitched 100 | consv2,ext1` +- [x] `422000091523` · L 71 / E 70.70 / Δ -0.30 · `hpcdb18767/gas | solid brick | pitched 50` +- [x] `100040531566` · L 70 / E 69.71 / Δ -0.29 · `hpcdb15706/gas | cavity wall | pitched 75` +- [x] `100010159140` · L 77 / E 77.29 / Δ +0.29 · `hpcdb17688/gas | cavity wall | pitched 300 | PV,ext1,sec:room heaters` +- [x] `77110396` · L 76 / E 75.71 / Δ -0.29 · `hpcdb18737/gas | cavity wall | pitched 200` +- [x] `100080908496` · L 81 / E 80.71 / Δ -0.29 · `hpcdb19006/gas | cavity wall | (another dwelling` +- [x] `100031831649` · L 67 / E 67.29 / Δ +0.29 · `hpcdb17663/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +- [x] `100052098782` · L 70 / E 69.71 / Δ -0.29 · `hpcdb15706/gas | cavity wall | pitched 150` +- [x] `10014035608` · L 79 / E 78.71 / Δ -0.29 · `h301/elec10hr | system built | (another dwelling` +- [x] `100022206341` · L 66 / E 66.29 / Δ +0.29 · `hpcdb15100/gas | solid brick | pitched insulated | RR,ext1` +- [x] `10091185672` · L 84 / E 84.29 / Δ +0.29 · `hpcdb16400/gas | cavity wall | (another dwelling` +- [x] `32049938` · L 63 / E 62.71 / Δ -0.29 · `hpcdb17983/gas | solid brick | pitched 350 | sec:room heaters` +- [x] `100110433442` · L 70 / E 69.71 / Δ -0.29 · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1` +- [x] `100070532674` · L 76 / E 76.29 / Δ +0.29 · `hpcdb17983/gas | cavity wall | pitched insulated` +- [x] `200003110548` · L 29 / E 29.29 / Δ +0.29 · `hpcdb17004/fuel27+2mains | sandstone as | pitched no | ext3,sec:room heaters` +- [x] `5079850` · L 39 / E 39.29 / Δ +0.29 · `h301/coal-anth | system built | (another dwelling | ext1,whw903` +- [x] `10001235167` · L 74 / E 73.71 / Δ -0.29 · `hpcdb17645/gas | solid brick | pitched 225` +- [x] `100080531660` · L 64 / E 63.71 / Δ -0.29 · `hpcdb16408/gas | cavity wall | pitched 50 | ext1` +- [x] `100110515199` · L 91 / E 91.28 / Δ +0.28 · `hpcdb17741/gas | cavity wall | pitched 400+ | PV` +- [x] `200001186113` · L 82 / E 82.28 / Δ +0.28 · `h409/elec | cavity wall | pitched 270 | PV,mv2,sec:room heaters,whw903` +- [x] `3040022036` · L 69 / E 69.28 / Δ +0.28 · `hpcdb17986/gas | cavity wall | (another dwelling` +- [x] `100070536189` · L 75 / E 75.28 / Δ +0.28 · `hpcdb10244/gas | cavity wall | pitched insulated | PV` +- [x] `90204248` · L 41 / E 40.72 / Δ -0.28 · `h691/elec | cavity wall | pitched 100 | whw909` +- [x] `28054454` · L 74 / E 73.72 / Δ -0.28 · `hpcdb102431/elec | cavity wall | pitched 200` +- [x] `303001211` · L 72 / E 72.28 / Δ +0.28 · `h301/coal-anth | cavity wall | pitched 250` +- [x] `202215644` · L 80 / E 79.72 / Δ -0.28 · `hpcdb17560/gas | cavity wall | (another dwelling | ext1` +- [x] `202207892` · L 77 / E 77.28 / Δ +0.28 · `h301/coal-anth | system built | (another dwelling` +- [x] `100120836206` · L 73 / E 73.28 / Δ +0.28 · `hpcdb17762/gas | cavity wall | pitched 100` +- [x] `100010450242` · L 70 / E 70.28 / Δ +0.28 · `h104/gas | sandstone as | pitched 270 | ext1` +- [x] `100031416239` · L 70 / E 70.27 / Δ +0.27 · `h104/gas | cavity wall | pitched 125` +- [x] `100061093506` · L 73 / E 72.73 / Δ -0.27 · `hpcdb18276/gas | cavity wall | pitched 125 | ext1` +- [x] `100000488045` · L 76 / E 75.73 / Δ -0.27 · `hpcdb15709/gas | cavity wall | pitched 250` +- [x] `100000025104` · L 76 / E 75.73 / Δ -0.27 · `hpcdb19007/gas | system built | (another dwelling` +- [x] `10093494727` · L 69 / E 68.73 / Δ -0.27 · `h691/elec | cavity wall | pitched insulated | whw903` +- [x] `1775073252` · L 76 / E 76.27 / Δ +0.27 · `h104/gas | cavity wall | (another dwelling` +- [x] `1775121299` · L 81 / E 81.27 / Δ +0.27 · `hpcdb17044/gas | cavity wall | pitched 300 | PV` +- [x] `100110136322` · L 66 / E 66.27 / Δ +0.27 · `hpcdb16882/gas | cavity wall | pitched insulated | RR,ext1` +- [x] `100022243530` · L 61 / E 61.27 / Δ +0.27 · `hpcdb17959/gas | solid brick | pitched 250 | sec:room heaters` +- [x] `83159458` · L 77 / E 76.73 / Δ -0.27 · `hpcdb17683/gas | system built | pitched 250 | sec:room heaters` +- [x] `100110435186` · L 75 / E 74.73 / Δ -0.27 · `hpcdb15709/gas | cavity wall | pitched 300 | PV,ext1,mv2,sec:room heaters` +- [x] `38327244` · L 81 / E 80.73 / Δ -0.27 · `hpcdb17507/gas | timber frame | pitched 300 | ext1` +- [x] `100031388370` · L 71 / E 71.27 / Δ +0.27 · `hpcdb16931/gas | solid brick | pitched 300 | ext2` +- [x] `45115812` · L 75 / E 74.73 / Δ -0.27 · `h304/elec | system built | (another dwelling` +- [x] `207084872` · L 60 / E 59.74 / Δ -0.26 · `h114/gas | solid brick | pitched 75 | ext1` +- [x] `100021026327` · L 72 / E 71.74 / Δ -0.26 · `hpcdb15502/gas | solid brick | (another dwelling` +- [x] `50016716` · L 62 / E 62.26 / Δ +0.26 · `hpcdb18431/gas | cavity wall | pitched 100` +- [x] `100040724662` · L 73 / E 73.26 / Δ +0.26 · `hpcdb18229/gas | cavity wall | pitched insulated | ext1` +- [x] `72155875` · L 68 / E 67.74 / Δ -0.26 · `hpcdb17038/gas | cavity wall | pitched 150 | ext1,sec:room heaters` +- [x] `5870012976` · L 62 / E 62.26 / Δ +0.26 · `hpcdb17501/gas | solid brick | pitched 200` +- [x] `100010049310` · L 70 / E 70.26 / Δ +0.26 · `hpcdb15706/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +- [x] `100070642087` · L 68 / E 68.26 / Δ +0.26 · `hpcdb18560/gas | cavity wall | pitched 100 | ext1` +- [x] `100050429574` · L 70 / E 70.26 / Δ +0.26 · `hpcdb19110/gas | solid brick | pitched 250 | sec:room heaters` +- [x] `10012816887` · L 65 / E 65.26 / Δ +0.26 · `h402/elec | cavity wall | pitched 50 | sec:portable electric,whw903` +- [x] `100051080419` · L 69 / E 68.74 / Δ -0.26 · `hpcdb10328/gas | cavity wall | pitched 200` +- [x] `68144811` · L 80 / E 79.74 / Δ -0.26 · `hpcdb8867/gas | cavity wall | (another dwelling` +- [x] `100050424781` · L 69 / E 69.26 / Δ +0.26 · `hpcdb17507/gas | cavity wall | pitched 175 | mv5` +- [x] `50011586` · L 69 / E 68.74 / Δ -0.26 · `hpcdb10328/gas | cavity wall | pitched 225 | consv2` +- [x] `100010680786` · L 73 / E 73.26 / Δ +0.26 · `hpcdb18907/gas | granite or | pitched 400+ | ext1` +- [x] `422000127372` · L 79 / E 78.75 / Δ -0.25 · `hpcdb17741/gas | cavity wall | pitched 400+` +- [x] `200000339841` · L 72 / E 72.25 / Δ +0.25 · `hpcdb18736/gas | cavity wall | (another dwelling` +- [x] `72380835` · L 82 / E 82.25 / Δ +0.25 · `hpcdb17507/gas | cavity wall | pitched 200 | PV,sec:room heaters` +- [x] `38193503` · L 65 / E 65.25 / Δ +0.25 · `hpcdb18907/gas | cavity wall | pitched 100 | ext2,sec:room heaters` +- [x] `100070155960` · L 53 / E 53.25 / Δ +0.25 · `hpcdb10462/gas | cavity wall | pitched 150 | ext2` +- [x] `83147775` · L 71 / E 71.25 / Δ +0.25 · `hpcdb16839/gas | cavity wall | pitched insulated` +- [x] `72303880` · L 63 / E 62.75 / Δ -0.25 · `hpcdb17507/gas | cavity wall | pitched 150 | sec:room heaters` +- [x] `100022711136` · L 72 / E 71.75 / Δ -0.25 · `hpcdb16495/gas | cavity wall | (another dwelling` +- [x] `83147745` · L 75 / E 75.25 / Δ +0.25 · `hpcdb16839/gas | cavity wall | (another dwelling | sec:room heaters` +- [x] `200002598542` · L 61 / E 61.25 / Δ +0.25 · `h402/elec | cavity wall | pitched 175 | ext1,sec:room heaters,whw903` +- [x] `100010572385` · L 62 / E 62.25 / Δ +0.25 · `hpcdb18817/gas | cavity wall | pitched 250 | ext2,sec:room heaters` +- [x] `100120874299` · L 72 / E 71.75 / Δ -0.25 · `hpcdb107234/elec | cavity wall | pitched 200 | mv2` +- [x] `100030332130` · L 51 / E 50.76 / Δ -0.24 · `h402/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` +- [x] `100060721835` · L 68 / E 67.76 / Δ -0.24 · `hpcdb16841/gas | system built | pitched 250` +- [x] `5067734` · L 67 / E 67.24 / Δ +0.24 · `hpcdb17726/gas | solid brick | (another dwelling` +- [x] `100021942272` · L 69 / E 69.24 / Δ +0.24 · `hpcdb17501/gas | solid brick | pitched insulated | RR` +- [x] `100050587694` · L 70 / E 70.24 / Δ +0.24 · `hpcdb18516/gas | cavity wall | pitched 270` +- [x] `100062195466` · L 73 / E 72.76 / Δ -0.24 · `h104/gas | cavity wall | (another dwelling` +- [x] `100100880740` · L 69 / E 69.24 / Δ +0.24 · `hpcdb17733/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `10090015178` · L 77 / E 76.76 / Δ -0.24 · `hpcdb16138/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `200001745207` · L 59 / E 59.24 / Δ +0.24 · `hpcdb1761/fuel28 | cavity wall | pitched 250 | ext1` +- [x] `250021965` · L 71 / E 71.24 / Δ +0.24 · `hpcdb10244/gas | cavity wall | pitched 200 | RR` +- [x] `100051346364` · L 63 / E 62.77 / Δ -0.23 · `hpcdb17983/gas | sandstone as | pitched no | sec:room heaters` +- [x] `100110203348` · L 66 / E 65.77 / Δ -0.23 · `hpcdb18559/gas | solid brick | pitched insulated | ext2` +- [x] `90164142` · L 80 / E 79.77 / Δ -0.23 · `h402/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +- [x] `5870055814` · L 72 / E 72.23 / Δ +0.23 · `hpcdb15100/gas | cavity wall | pitched 125 | ext1` +- [x] `100040118353` · L 74 / E 73.77 / Δ -0.23 · `h402/elec | cavity wall | (another dwelling | ext1,sec:portable electric,whw903` +- [x] `100011419346` · L 69 / E 68.77 / Δ -0.23 · `hpcdb16839/gas | cavity wall | pitched insulated` +- [x] `10091678339` · L 95 / E 94.77 / Δ -0.23 · `hpcdb110399/elec | cavity wall | pitched insulated | PV,RR` +- [x] `100031779857` · L 64 / E 64.23 / Δ +0.23 · `hpcdb16210/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +- [x] `100010470853` · L 67 / E 66.77 / Δ -0.23 · `hpcdb17505/gas | sandstone as | pitched 300 | ext1` +- [x] `10002147299` · L 71 / E 71.23 / Δ +0.23 · `hpcdb16810/gas | cavity wall | pitched 200 | consv2` +- [x] `200003864157` · L 73 / E 72.77 / Δ -0.23 · `hpcdb17039/gas | cavity wall | pitched 100 | ext1` +- [x] `6040073` · L 72 / E 71.77 / Δ -0.23 · `h301/coal-anth | solid brick | (another dwelling` +- [x] `100062014047` · L 76 / E 75.77 / Δ -0.23 · `hpcdb10547/gas | cavity wall | pitched 200` +- [x] `14003893` · L 69 / E 69.22 / Δ +0.22 · `hpcdb16931/gas | cavity wall | pitched 150` +- [x] `6721183` · L 82 / E 81.78 / Δ -0.22 · `h301/coal-anth | system built | (another dwelling` +- [x] `100051035527` · L 74 / E 74.22 / Δ +0.22 · `hpcdb16842/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `100040914059` · L 72 / E 72.22 / Δ +0.22 · `hpcdb10244/gas | solid brick | pitched 400+` +- [x] `10034523788` · L 69 / E 69.22 / Δ +0.22 · `hpcdb10459/gas+2mains | cavity wall | pitched 250 | RR,ext4,sec:room heaters,whw914` +- [x] `41223299` · L 76 / E 76.22 / Δ +0.22 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100091119847` · L 79 / E 78.78 / Δ -0.22 · `hpcdb17105/fuel28 | cavity wall | pitched 300 | PV` +- [x] `100020453894` · L 63 / E 63.22 / Δ +0.22 · `hpcdb10321/gas | solid brick | pitched 200` +- [x] `100080166105` · L 57 / E 56.78 / Δ -0.22 · `hpcdb17507/gas | solid brick | pitched insulated | consv2,mv2` +- [x] `10013855655` · L 78 / E 78.22 / Δ +0.22 · `hpcdb10071/gas | cavity wall | pitched insulated | RR` +- [x] `100010842519` · L 69 / E 68.78 / Δ -0.22 · `hpcdb17507/gas | cavity wall | pitched insulated | RR` +- [x] `100061696040` · L 72 / E 71.78 / Δ -0.22 · `hpcdb19015/gas | cavity wall | pitched 300 | PV,ext1` +- [x] `100071098291` · L 59 / E 59.22 / Δ +0.22 · `hpcdb9571/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `10012437388` · L 62 / E 62.22 / Δ +0.22 · `hpcdb19014/gas | cavity wall | pitched no` +- [x] `100080154263` · L 70 / E 69.78 / Δ -0.22 · `hpcdb10444/gas | cavity wall | pitched 125` +- [x] `100030564080` · L 67 / E 66.79 / Δ -0.21 · `hpcdb15282/gas | solid brick | pitched 200 | ext1` +- [x] `100023491276` · L 74 / E 74.21 / Δ +0.21 · `hpcdb19051/gas | solid brick | (another dwelling` +- [x] `100071320610` · L 75 / E 74.79 / Δ -0.21 · `h104/gas | system built | (another dwelling` +- [x] `10090835500` · L 83 / E 82.79 / Δ -0.21 · `hpcdb16321/gas | cavity wall | pitched 270 | PV` +- [x] `10090383598` · L 76 / E 76.21 / Δ +0.21 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100050841010` · L 69 / E 69.21 / Δ +0.21 · `hpcdb10546/gas | cavity wall | pitched 100 | ext1` +- [x] `10090481366` · L 77 / E 76.79 / Δ -0.21 · `h691/elec | cavity wall | (another dwelling | whw909` +- [x] `100070308464` · L 65 / E 65.21 / Δ +0.21 · `h104/gas | cavity wall | pitched 250 | PV` +- [x] `100012547948` · L 75 / E 74.79 / Δ -0.21 · `hpcdb17931/gas | cavity wall | pitched 100` +- [x] `100061316828` · L 69 / E 69.21 / Δ +0.21 · `hpcdb18403/gas | cavity wall | pitched 250 | mv2` +- [x] `83067520` · L 65 / E 64.79 / Δ -0.21 · `hpcdb18119/gas | cavity wall | pitched 200` +- [x] `100120954950` · L 66 / E 65.79 / Δ -0.21 · `hpcdb10243/gas | cavity wall | pitched 250` +- [x] `68100715` · L 39 / E 39.20 / Δ +0.20 · `h691/elec | cavity wall | (another dwelling | whw903` +- [x] `10090641681` · L 82 / E 82.20 / Δ +0.20 · `hpcdb17045/gas | cavity wall | (another dwelling` +- [x] `100070189144` · L 49 / E 49.20 / Δ +0.20 · `h402/elec | cavity wall | pitched 150 | consv2,sec:portable electric,whw903` +- [x] `6007002` · L 76 / E 76.20 / Δ +0.20 · `hpcdb17702/gas | system built | (another dwelling` +- [x] `100040926648` · L 70 / E 69.80 / Δ -0.20 · `hpcdb10244/gas | cavity wall | pitched 250 | ext1` +- [x] `100100299483` · L 67 / E 66.80 / Δ -0.20 · `hpcdb17507/gas | granite or | pitched 50 | ext3` +- [x] `100110431858` · L 84 / E 83.80 / Δ -0.20 · `hpcdb18119/gas | cavity wall | pitched 400+ | PV` +- [x] `30102683` · L 78 / E 77.80 / Δ -0.20 · `hpcdb9969/gas | cavity wall | roof room(s) | RR,consv2` +- [x] `200000800903` · L 75 / E 74.80 / Δ -0.20 · `hpcdb2040/gas | timber frame | pitched 150 | ext2` +- [x] `100060370575` · L 70 / E 69.80 / Δ -0.20 · `hpcdb17760/gas | cavity wall | (another dwelling` +- [x] `10022972987` · L 11 / E 11.20 / Δ +0.20 · `h691/elec | sandstone as | pitched 200 | ext1,sec:room heaters,whw921` +- [x] `10023219663` · L 78 / E 77.80 / Δ -0.20 · `h301/coal-anth | system built | (another dwelling` +- [x] `100020603440` · L 74 / E 73.80 / Δ -0.20 · `h104/gas | cavity wall | pitched insulated` +- [x] `45040195` · L 75 / E 75.19 / Δ +0.19 · `hpcdb18250/gas | cavity wall | pitched 100` +- [x] `653958` · L 79 / E 78.81 / Δ -0.19 · `hpcdb10071/gas | cavity wall | pitched 250` +- [x] `10096575045` · L 44 / E 44.19 / Δ +0.19 · `h691/elec | cavity wall | (another dwelling | whw909` +- [x] `217058896` · L 68 / E 67.81 / Δ -0.19 · `h301/coal-anth | solid brick | (another dwelling` +- [x] `100050823534` · L 73 / E 73.19 / Δ +0.19 · `hpcdb18204/gas | cavity wall | pitched 75 | consv2,ext1` +- [x] `100061736655` · L 74 / E 73.81 / Δ -0.19 · `hpcdb18911/gas | cavity wall | pitched 400+ | PV,ext1,mv2` +- [x] `100040006258` · L 74 / E 74.19 / Δ +0.19 · `hpcdb15834/gas | granite or | pitched 300` +- [x] `100070051157` · L 72 / E 72.19 / Δ +0.19 · `hpcdb17998/gas | solid brick | pitched 75` +- [x] `100050722945` · L 67 / E 66.81 / Δ -0.19 · `hpcdb19158/gas | cavity wall | pitched insulated | ext2,sec:room heaters` +- [x] `100110491552` · L 70 / E 70.19 / Δ +0.19 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100061721679` · L 71 / E 71.19 / Δ +0.19 · `hpcdb10462/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `100090243980` · L 68 / E 68.18 / Δ +0.18 · `hpcdb10327/gas | cavity wall | pitched 100 | ext1` +- [x] `100100328304` · L 62 / E 61.82 / Δ -0.18 · `hpcdb18768/gas | cavity wall | pitched 270 | ext1` +- [x] `10001131873` · L 79 / E 78.82 / Δ -0.18 · `h402/elec | granite or | (another dwelling | sec:portable electric,whw903` +- [x] `63123708` · L 64 / E 63.82 / Δ -0.18 · `hpcdb16977/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +- [x] `90100875` · L 57 / E 56.82 / Δ -0.18 · `hpcdb17507/gas | solid brick | pitched insulated | ext2,sec:room heaters` +- [x] `128012524` · L 56 / E 56.18 / Δ +0.18 · `hpcdb10265/gas | cavity wall | pitched insulated | ext1,sec:room heaters` +- [x] `100010830948` · L 69 / E 68.82 / Δ -0.18 · `hpcdb18559/gas | cavity wall | pitched 150 | consv3` +- [x] `21060468` · L 67 / E 67.18 / Δ +0.18 · `hpcdb10112/gas | system built | pitched 270 | mv2` +- [x] `200004250345` · L 72 / E 72.18 / Δ +0.18 · `hpcdb4035/gas | cavity wall | pitched unknown | ext1,sec:room heaters` +- [x] `11038944` · L 68 / E 67.83 / Δ -0.17 · `h104/gas | cavity wall | pitched insulated` +- [x] `100090656436` · L 72 / E 72.17 / Δ +0.17 · `h104/gas | cavity wall | pitched unknown | ext2` +- [x] `100121044742` · L 72 / E 72.17 / Δ +0.17 · `hpcdb17505/gas | cavity wall | pitched 100 | ext1` +- [x] `100031540900` · L 68 / E 68.17 / Δ +0.17 · `hpcdb17501/gas | cavity wall | pitched 250` +- [x] `50010028` · L 87 / E 87.17 / Δ +0.17 · `hpcdb16987/gas | cavity wall | pitched 250 | PV,ext2` +- [x] `100061741005` · L 74 / E 73.83 / Δ -0.17 · `hpcdb16210/gas | cavity wall | pitched 200 | RR,ext1` +- [x] `100110589642` · L 72 / E 72.17 / Δ +0.17 · `hpcdb16137/gas | cavity wall | pitched 200` +- [x] `100041131293` · L 76 / E 76.17 / Δ +0.17 · `hpcdb15502/gas | cavity wall | (another dwelling` +- [x] `21072798` · L 72 / E 71.83 / Δ -0.17 · `hpcdb19007/gas | cavity wall | (another dwelling` +- [x] `10009830624` · L 78 / E 77.83 / Δ -0.17 · `hpcdb15706/gas | cavity wall | pitched 300` +- [x] `line768` · L 57 / E 56.83 / Δ -0.17 · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` +- [x] `39023204` · L 68 / E 68.17 / Δ +0.17 · `hpcdb18155/gas | solid brick | pitched insulated | ext2` +- [x] `100060428487` · L 71 / E 71.17 / Δ +0.17 · `hpcdb18496/gas | cavity wall | pitched 100 | consv2,ext1` +- [x] `100121053407` · L 73 / E 72.83 / Δ -0.17 · `hpcdb16919/gas | cavity wall | pitched 300 | consv3` +- [x] `202229245` · L 67 / E 66.83 / Δ -0.17 · `hpcdb18224/gas | solid brick | pitched unknown | ext1` +- [x] `10000208277` · L 75 / E 75.17 / Δ +0.17 · `hpcdb16135/gas | cavity wall | pitched 225 | consv2` +- [x] `100040411293` · L 64 / E 64.16 / Δ +0.16 · `hpcdb16986/gas | cavity wall | pitched 150` +- [x] `200003712915` · L 73 / E 72.84 / Δ -0.16 · `hpcdb16396/gas | cavity wall | pitched 400+ | mv2` +- [x] `4510002139` · L 73 / E 72.84 / Δ -0.16 · `hpcdb18204/gas | solid brick | pitched insulated | RR,ext2` +- [x] `200000920341` · L 69 / E 69.16 / Δ +0.16 · `h104/gas | cavity wall | pitched 270` +- [x] `100021038893` · L 92 / E 91.84 / Δ -0.16 · `hpcdb18907/gas | cavity wall | pitched 300 | PV` +- [x] `100020435702` · L 64 / E 64.16 / Δ +0.16 · `hpcdb10328/gas | cavity wall | pitched insulated` +- [x] `200004517412` · L 74 / E 73.84 / Δ -0.16 · `hpcdb18560/gas | cavity wall | pitched 400+ | sec:room heaters` +- [x] `100020443300` · L 69 / E 68.84 / Δ -0.16 · `hpcdb17507/gas | cavity wall | pitched 100 | ext1` +- [x] `200000387611` · L 71 / E 71.16 / Δ +0.16 · `hpcdb15019/gas | cavity wall | pitched 100 | consv3,sec:room heaters` +- [x] `5870031233` · L 75 / E 74.84 / Δ -0.16 · `h401/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +- [x] `100120733015` · L 65 / E 65.16 / Δ +0.16 · `hpcdb16093/gas | solid brick | pitched 125 | ext1,sec:room heaters` +- [x] `100120629168` · L 70 / E 70.16 / Δ +0.16 · `hpcdb9897/gas | cavity wall | pitched 100 | consv2,ext2` +- [x] `100100713371` · L 65 / E 65.16 / Δ +0.16 · `hpcdb17507/gas | cavity wall | pitched 125 | consv4` +- [x] `10033058144` · L 65 / E 65.16 / Δ +0.16 · `hpcdb18560/gas | cavity wall | pitched 200 | ext1` +- [x] `100031351512` · L 65 / E 64.84 / Δ -0.16 · `hpcdb10265/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` +- [x] `148007532` · L 61 / E 60.84 / Δ -0.16 · `hpcdb1396/gas | solid brick | pitched insulated | RR,consv2,ext1` +- [x] `100010043608` · L 56 / E 56.16 / Δ +0.16 · `h401/elec | cavity wall | pitched 200 | PV,RR,consv2,ext1,sec:room heaters,whw903` +- [x] `100022232588` · L 56 / E 56.16 / Δ +0.16 · `h102/gas | solid brick | pitched 25 | ext1` +- [x] `100110450961` · L 69 / E 68.84 / Δ -0.16 · `h104/gas | sandstone as | pitched 250 | ext1` +- [x] `10014540481` · L 81 / E 81.15 / Δ +0.15 · `hpcdb16400/gas | timber frame | roof room(s) | RR` +- [x] `100061860491` · L 69 / E 68.85 / Δ -0.15 · `hpcdb18824/gas | cavity wall | pitched 250 | consv3` +- [x] `100121065133` · L 81 / E 80.85 / Δ -0.15 · `hpcdb17511/gas | cavity wall | (another dwelling` +- [x] `231757` · L 73 / E 73.15 / Δ +0.15 · `hpcdb17505/gas | sandstone as | pitched 75 | ext1` +- [x] `200001694377` · L 45 / E 44.85 / Δ -0.15 · `hpcdb18429/fuel28 | granite or | pitched 250 | ext3,sec:room heaters` +- [x] `100062331529` · L 81 / E 81.15 / Δ +0.15 · `hpcdb18908/gas | cavity wall | (another dwelling` +- [x] `10033267429` · L 57 / E 56.85 / Δ -0.15 · `h691/elec | system built | (another dwelling | whw903` +- [x] `100090372586` · L 71 / E 71.15 / Δ +0.15 · `h102/gas | cavity wall | pitched 300 | PV,consv3` +- [x] `100060587363` · L 62 / E 62.15 / Δ +0.15 · `hpcdb10462/gas | solid brick | pitched 250 | consv2,ext2,sec:room heaters` +- [x] `207037318` · L 59 / E 58.85 / Δ -0.15 · `h699/fuel0 | cavity wall | (another dwelling | sec:portable electric,whw903` +- [x] `100051048523` · L 67 / E 67.15 / Δ +0.15 · `hpcdb17507/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `551000` · L 72 / E 72.15 / Δ +0.15 · `h104/gas | cavity wall | pitched 150` +- [x] `202137997` · L 69 / E 68.85 / Δ -0.15 · `hpcdb10443/gas | cavity wall | (another dwelling` +- [x] `5870106813` · L 78 / E 78.15 / Δ +0.15 · `hpcdb17505/gas | solid brick | pitched 300` +- [x] `100000056169` · L 62 / E 61.85 / Δ -0.15 · `hpcdb18559/gas | cavity wall | pitched 150 | consv2,ext1` +- [x] `21029519` · L 67 / E 66.85 / Δ -0.15 · `hpcdb17983/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100110469288` · L 67 / E 67.15 / Δ +0.15 · `hpcdb18155/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `10022949096` · L 74 / E 73.85 / Δ -0.15 · `hpcdb17507/gas | cavity wall | pitched 200` +- [x] `100000341714` · L 64 / E 64.15 / Δ +0.15 · `hpcdb15709/gas | system built | pitched 270` +- [x] `100021046998` · L 69 / E 69.15 / Δ +0.15 · `hpcdb10327/gas | solid brick | pitched 100 | ext1` +- [x] `30523770` · L 72 / E 71.85 / Δ -0.15 · `hpcdb8191/fuel28 | granite or | pitched 200 | sec:room heaters` +- [x] `100080902546` · L 79 / E 78.85 / Δ -0.15 · `hpcdb17696/gas | solid brick | pitched insulated | RR,ext1` +- [x] `100021286876` · L 66 / E 66.15 / Δ +0.15 · `hpcdb17503/gas | solid brick | pitched insulated` +- [x] `100070056707` · L 72 / E 72.14 / Δ +0.14 · `hpcdb17505/gas | system built | (another dwelling` +- [x] `72513535` · L 70 / E 70.14 / Δ +0.14 · `h691/elec | system built | (another dwelling | whw903` +- [x] `100080166923` · L 68 / E 67.86 / Δ -0.14 · `hpcdb18826/gas | cavity wall | pitched 75 | consv3,ext1` +- [x] `100023483089` · L 77 / E 76.86 / Δ -0.14 · `h409/elec | system built | (another dwelling | sec:portable electric,whw903` +- [x] `10096537371` · L 37 / E 37.14 / Δ +0.14 · `h691/elec | solid brick | pitched 200 | ext1,whw909` +- [x] `100011476438` · L 57 / E 56.86 / Δ -0.14 · `h402/elec | cavity wall | pitched 125 | sec:room heaters,whw903` +- [x] `10003800267` · L 72 / E 71.86 / Δ -0.14 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100060412840` · L 66 / E 66.14 / Δ +0.14 · `h102/gas | cavity wall | pitched 50 | ext1` +- [x] `2465082925` · L 66 / E 66.14 / Δ +0.14 · `hpcdb16848/gas | cavity wall | pitched 250` +- [x] `100030001912` · L 69 / E 68.86 / Δ -0.14 · `hpcdb19080/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100010757788` · L 68 / E 68.14 / Δ +0.14 · `hpcdb18119/gas | cavity wall | pitched 100 | sec:portable electric` +- [x] `200001601290` · L 61 / E 60.86 / Δ -0.14 · `hpcdb16394/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100100085877` · L 72 / E 72.14 / Δ +0.14 · `hpcdb10122/gas | cavity wall | pitched 270 | ext2,sec:room heaters` +- [x] `10002473454` · L 74 / E 73.86 / Δ -0.14 · `hpcdb19006/gas | cavity wall | pitched 300` +- [x] `100121097651` · L 72 / E 72.14 / Δ +0.14 · `hpcdb18433/gas | cavity wall | pitched 350 | sec:room heaters` +- [x] `100040638671` · L 80 / E 80.14 / Δ +0.14 · `hpcdb10356/gas | cavity wall | pitched 200 | PV,ext4,sec:room heaters` +- [x] `10002096859` · L 79 / E 79.14 / Δ +0.14 · `hpcdb16835/gas | cavity wall | pitched 300 | ext2` +- [x] `100071033049` · L 62 / E 61.86 / Δ -0.14 · `hpcdb18908/gas | cavity wall | pitched 150 | sec:room heaters` +- [x] `100022619802` · L 79 / E 79.13 / Δ +0.13 · `hpcdb16375/gas | cavity wall | flat insulated` +- [x] `100081154129` · L 65 / E 64.87 / Δ -0.13 · `h408/elec | cavity wall | pitched 100 | consv2,whw903` +- [x] `1710040599` · L 70 / E 70.13 / Δ +0.13 · `h102/gas | cavity wall | pitched 100 | RR,sec:room heaters` +- [x] `100050824478` · L 72 / E 71.87 / Δ -0.13 · `hpcdb17615/gas | cavity wall | pitched 200 | ext1` +- [x] `100060005933` · L 71 / E 70.87 / Δ -0.13 · `h102/gas | cavity wall | pitched 175` +- [x] `100080706341` · L 62 / E 61.87 / Δ -0.13 · `hpcdb18045/gas | system built | pitched 75` +- [x] `46083795` · L 78 / E 78.13 / Δ +0.13 · `hpcdb16930/gas | cavity wall | (another dwelling` +- [x] `10090342779` · L 81 / E 80.87 / Δ -0.13 · `hpcdb10327/gas | timber frame | pitched 300` +- [x] `77068182` · L 68 / E 68.13 / Δ +0.13 · `hpcdb10242/gas | cavity wall | pitched 75 | ext2` +- [x] `11077408` · L 67 / E 67.13 / Δ +0.13 · `hpcdb10356/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `100100869589` · L 62 / E 62.13 / Δ +0.13 · `hpcdb17983/gas | cavity wall | pitched 270 | mv5,sec:room heaters` +- [x] `77018431` · L 65 / E 64.87 / Δ -0.13 · `hpcdb17987/gas | cavity wall | pitched insulated | ext1` +- [x] `63064761` · L 72 / E 72.13 / Δ +0.13 · `hpcdb18907/gas | cavity wall | (another dwelling` +- [x] `100011790131` · L 60 / E 60.13 / Δ +0.13 · `hpcdb15709/gas | solid brick | pitched 270 | ext1,sec:room heaters` +- [x] `100011756441` · L 73 / E 73.13 / Δ +0.13 · `hpcdb18511/gas | cavity wall | pitched 75` +- [x] `202028377` · L 66 / E 66.13 / Δ +0.13 · `hpcdb17548/gas | solid brick | pitched 75` +- [x] `100090533643` · L 85 / E 85.13 / Δ +0.13 · `hpcdb17507/gas | cavity wall | pitched insulated | PV,ext1` +- [x] `100090335261` · L 70 / E 70.13 / Δ +0.13 · `hpcdb17974/gas | cavity wall | (another dwelling` +- [x] `100061898123` · L 70 / E 70.13 / Δ +0.13 · `hpcdb17511/gas | solid brick | pitched 100` +- [x] `38149813` · L 74 / E 73.87 / Δ -0.13 · `h104/gas | solid brick | pitched 350 | ext1` +- [x] `10014619006` · L 77 / E 77.13 / Δ +0.13 · `hpcdb17045/gas | cavity wall | pitched 350 | mv2` +- [x] `100091201592` · L 71 / E 70.87 / Δ -0.13 · `hpcdb10464/gas | cavity wall | pitched 150` +- [x] `100040888018` · L 75 / E 75.12 / Δ +0.12 · `hpcdb10265/gas | cavity wall | pitched 250` +- [x] `100030350883` · L 72 / E 72.12 / Δ +0.12 · `hpcdb17660/gas | solid brick | pitched 300 | ext1` +- [x] `12151106` · L 71 / E 70.88 / Δ -0.12 · `hpcdb17929/gas | solid brick | (another dwelling | ext1` +- [x] `22151573` · L 69 / E 68.88 / Δ -0.12 · `hpcdb17991/gas | solid brick | (another dwelling | ext1,sec:room heaters` +- [x] `10008151417` · L 75 / E 75.12 / Δ +0.12 · `hpcdb18619/gas | cavity wall | pitched 225 | ext1,sec:room heaters` +- [x] `100031658267` · L 67 / E 66.88 / Δ -0.12 · `hpcdb19019/gas | cavity wall | pitched 300` +- [x] `100010155093` · L 72 / E 71.88 / Δ -0.12 · `hpcdb15884/gas | cavity wall | pitched 200` +- [x] `10023692117` · L 71 / E 70.88 / Δ -0.12 · `hpcdb9228/gas | system built | flat insulated | ext3,mv3` +- [x] `36046440` · L 78 / E 77.88 / Δ -0.12 · `hpcdb16327/gas | cavity wall | pitched 250` +- [x] `10012226756` · L 79 / E 79.12 / Δ +0.12 · `hpcdb16682/gas | cavity wall | pitched 250` +- [x] `77068828` · L 69 / E 69.12 / Δ +0.12 · `hpcdb10265/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +- [x] `100031461590` · L 62 / E 62.12 / Δ +0.12 · `hpcdb2038/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `261969` · L 75 / E 75.12 / Δ +0.12 · `hpcdb17683/gas | solid brick | (another dwelling | ext1` +- [x] `100090986049` · L 65 / E 65.12 / Δ +0.12 · `hpcdb18830/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `10003926370` · L 62 / E 62.12 / Δ +0.12 · `hpcdb860/fuel28 | cavity wall | pitched 100 | PV,consv2,sec:room heaters` +- [x] `37015003` · L 69 / E 69.11 / Δ +0.11 · `hpcdb18218/gas | cavity wall | pitched unknown | ext1` +- [x] `4510733560` · L 77 / E 76.89 / Δ -0.11 · `h113/gas | cavity wall | (another dwelling` +- [x] `303001209` · L 70 / E 69.89 / Δ -0.11 · `h301/coal-anth | cavity wall | pitched 225` +- [x] `217041293` · L 83 / E 83.11 / Δ +0.11 · `h404/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +- [x] `100030534734` · L 5 / E 4.89 / Δ -0.11 · `h631/LPG | sandstone as | pitched insulated | RR,ext1,sec:portable electric,whw903` +- [x] `10008651218` · L 78 / E 78.11 / Δ +0.11 · `hpcdb10243/gas | cavity wall | pitched 250` +- [x] `100091151352` · L 72 / E 71.89 / Δ -0.11 · `hpcdb10122/gas | solid brick | pitched 270 | ext1` +- [x] `452029430` · L 72 / E 71.89 / Δ -0.11 · `hpcdb10241/gas | cavity wall | pitched 100` +- [x] `100050435392` · L 69 / E 68.89 / Δ -0.11 · `hpcdb18047/gas | cavity wall | pitched 200 | ext1` +- [x] `100060864327` · L 75 / E 75.11 / Δ +0.11 · `hpcdb19006/gas | cavity wall | (another dwelling` +- [x] `100011385976` · L 71 / E 71.11 / Δ +0.11 · `hpcdb16839/gas | cavity wall | pitched 300` +- [x] `10090929166` · L 64 / E 63.89 / Δ -0.11 · `h691/elec | cavity wall | pitched insulated | whw909` +- [x] `100062012` · L 72 / E 72.11 / Δ +0.11 · `hpcdb17117/gas | solid brick | (another dwelling` +- [x] `100030293609` · L 60 / E 59.89 / Δ -0.11 · `hpcdb10328/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `100011764055` · L 72 / E 72.11 / Δ +0.11 · `hpcdb15823/gas | cavity wall | pitched 200 | ext4,sec:room heaters` +- [x] `200164795` · L 82 / E 81.89 / Δ -0.11 · `hpcdb16400/gas | cavity wall | pitched insulated | PV,RR,ext1` +- [x] `100022628872` · L 74 / E 74.11 / Δ +0.11 · `hpcdb18908/gas | cavity wall | (another dwelling` +- [x] `10014460343` · L 79 / E 78.89 / Δ -0.11 · `hpcdb15754/gas | cavity wall | pitched 250` +- [x] `10001142950` · L 69 / E 69.11 / Δ +0.11 · `h301/coal-anth | sandstone as | (another dwelling` +- [x] `38137278` · L 69 / E 69.11 / Δ +0.11 · `hpcdb18907/gas | cavity wall | pitched 400+ | ext2,mv2,sec:room heaters` +- [x] `100040565259` · L 66 / E 66.11 / Δ +0.11 · `hpcdb18221/gas | cavity wall | pitched 300 | ext1` +- [x] `100110437510` · L 87 / E 87.11 / Δ +0.11 · `hpcdb15709/gas | cavity wall | pitched 270 | PV,ext1,mv2,sec:room heaters` +- [x] `100051116259` · L 70 / E 70.11 / Δ +0.11 · `hpcdb15520/gas | cavity wall | pitched insulated | consv4,ext1,sec:room heaters` +- [x] `100031466637` · L 52 / E 51.89 / Δ -0.11 · `h409/elec | solid brick | pitched no | ext3,sec:room heaters,whw903` +- [x] `100060052603` · L 58 / E 57.89 / Δ -0.11 · `hpcdb17553/gas | cavity wall | pitched 100 | consv2,sec:room heaters` +- [x] `100031245724` · L 69 / E 68.90 / Δ -0.10 · `hpcdb17660/gas | cavity wall | pitched 200` +- [x] `24029210` · L 75 / E 75.10 / Δ +0.10 · `hpcdb15704/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `217079598` · L 77 / E 77.10 / Δ +0.10 · `hpcdb18821/gas | system built | (another dwelling` +- [x] `100120820445` · L 72 / E 72.10 / Δ +0.10 · `hpcdb10267/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +- [x] `10008290975` · L 79 / E 79.10 / Δ +0.10 · `hpcdb17973/gas | cavity wall | (another dwelling` +- [x] `100040140820` · L 61 / E 61.10 / Δ +0.10 · `hpcdb1768/fuel28 | cavity wall | pitched 225 | ext1` +- [x] `100090121779` · L 73 / E 73.10 / Δ +0.10 · `hpcdb18089/gas | cavity wall | pitched 125` +- [x] `42180235` · L 77 / E 77.10 / Δ +0.10 · `hpcdb18559/gas | cavity wall | (another dwelling` +- [x] `100061414159` · L 65 / E 65.10 / Δ +0.10 · `hpcdb17313/gas | solid brick | pitched 100 | RR,consv4,ext4` +- [x] `207156543` · L 69 / E 69.10 / Δ +0.10 · `hpcdb18773/gas | solid brick | pitched insulated` +- [x] `10071154302` · L 78 / E 77.90 / Δ -0.10 · `h301/coal-anth | system built | (another dwelling` +- [x] `10004779730` · L 67 / E 67.10 / Δ +0.10 · `hpcdb16398/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `10001005083` · L 65 / E 65.10 / Δ +0.10 · `hpcdb16840/gas | solid brick | (another dwelling` +- [x] `100040960726` · L 89 / E 88.90 / Δ -0.10 · `hpcdb16212/gas | cavity wall | pitched 250 | PV,consv3,ext4,sec:room heaters` +- [x] `100100694586` · L 69 / E 68.90 / Δ -0.10 · `hpcdb10315/gas | solid brick | pitched 75 | ext1` +- [x] `100061607458` · L 69 / E 68.90 / Δ -0.10 · `hpcdb18909/gas | cavity wall | pitched 100` +- [x] `10023410348` · L 68 / E 68.10 / Δ +0.10 · `h301/coal-anth | cavity wall | flat limited` +- [x] `207104025` · L 78 / E 78.10 / Δ +0.10 · `h104/gas | solid brick | pitched unknown` +- [x] `1775077083` · L 72 / E 72.10 / Δ +0.10 · `hpcdb17974/gas | cavity wall | pitched insulated | ext1` +- [x] `100120918121` · L 83 / E 83.10 / Δ +0.10 · `hpcdb18618/gas | cavity wall | pitched 200 | PV,ext1` +- [x] `200000766345` · L 70 / E 70.10 / Δ +0.10 · `hpcdb18827/gas | sandstone as | pitched 270 | ext1,sec:room heaters` +- [x] `100021531772` · L 68 / E 68.10 / Δ +0.10 · `hpcdb18560/gas | solid brick | pitched 100 | ext1` +- [x] `100020596099` · L 50 / E 49.90 / Δ -0.10 · `hpcdb17550/gas | solid brick | pitched insulated | sec:room heaters` +- [x] `38191704` · L 73 / E 73.10 / Δ +0.10 · `hpcdb18107/gas | cavity wall | pitched 125 | consv3` +- [x] `10014478958` · L 77 / E 76.91 / Δ -0.09 · `hpcdb16137/gas | timber frame | pitched 250` +- [x] `100051276007` · L 63 / E 63.09 / Δ +0.09 · `hpcdb16212/gas | cavity wall | pitched 225 | sec:room heaters` +- [x] `100021503967` · L 68 / E 67.91 / Δ -0.09 · `hpcdb18509/gas | solid brick | pitched 100 | ext1` +- [x] `100080331733` · L 72 / E 71.91 / Δ -0.09 · `hpcdb17816/gas | cavity wall | pitched 100 | ext1` +- [x] `100100480670` · L 67 / E 67.09 / Δ +0.09 · `h104/gas | sandstone as | pitched 300` +- [x] `23014695` · L 78 / E 77.91 / Δ -0.09 · `hpcdb18560/gas | system built | pitched 250` +- [x] `10003971523` · L 78 / E 78.09 / Δ +0.09 · `hpcdb17683/gas | cavity wall | flat insulated` +- [x] `523424` · L 23 / E 22.91 / Δ -0.09 · `h104/biogas | sandstone as | pitched insulated | ext1,sec:portable electric` +- [x] `10023385904` · L 77 / E 76.91 / Δ -0.09 · `hpcdb15239/gas | cavity wall | pitched 300 | consv2` +- [x] `100070621229` · L 72 / E 71.91 / Δ -0.09 · `hpcdb15709/gas | solid brick | pitched unknown` +- [x] `5870046999` · L 73 / E 73.09 / Δ +0.09 · `hpcdb17973/gas | cavity wall | (another dwelling` +- [x] `100010384681` · L 75 / E 74.91 / Δ -0.09 · `hpcdb19080/gas | cavity wall | pitched 400+ | PV,ext1,sec:room heaters` +- [x] `100022536385` · L 71 / E 70.92 / Δ -0.08 · `hpcdb17505/gas | solid brick | pitched 300` +- [x] `1710029098` · L 69 / E 69.08 / Δ +0.08 · `hpcdb17958/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100040884417` · L 70 / E 70.08 / Δ +0.08 · `hpcdb10328/gas | cavity wall | (another dwelling` +- [x] `100080706339` · L 65 / E 65.08 / Δ +0.08 · `hpcdb16396/gas | system built | pitched 250` +- [x] `10090018805` · L 77 / E 76.92 / Δ -0.08 · `hpcdb15017/gas | cavity wall | pitched 250` +- [x] `100034336` · L 60 / E 60.08 / Δ +0.08 · `hpcdb17815/gas | solid brick | pitched 100` +- [x] `100051237659` · L 65 / E 65.08 / Δ +0.08 · `hpcdb18560/gas | sandstone as | pitched insulated | sec:room heaters` +- [x] `line979` · L 71 / E 71.08 / Δ +0.08 · `hpcdb15710/gas | cavity wall | pitched insulated` +- [x] `100070431508` · L 64 / E 63.92 / Δ -0.08 · `hpcdb18119/gas | solid brick | pitched insulated | sec:room heaters` +- [x] `100110515214` · L 73 / E 72.92 / Δ -0.08 · `hpcdb17741/gas | cavity wall | pitched 400+ | mv2` +- [x] `100100415869` · L 67 / E 67.08 / Δ +0.08 · `h104/gas | cavity wall | pitched 270` +- [x] `1775078613` · L 72 / E 71.92 / Δ -0.08 · `h104/gas | cavity wall | pitched 150` +- [x] `100091367939` · L 62 / E 62.08 / Δ +0.08 · `h102/gas | cavity wall | pitched 150 | ext2,sec:room heaters` +- [x] `100110175491` · L 74 / E 74.08 / Δ +0.08 · `h102/gas | cavity wall | pitched 150 | ext1` +- [x] `10011830488` · L 75 / E 75.08 / Δ +0.08 · `h102/gas | cavity wall | pitched insulated | consv2` +- [x] `11063823` · L 66 / E 66.07 / Δ +0.07 · `hpcdb17507/gas | cavity wall | pitched unknown` +- [x] `21093278` · L 73 / E 72.93 / Δ -0.07 · `hpcdb16573/gas | cavity wall | pitched 100` +- [x] `100010835776` · L 69 / E 68.93 / Δ -0.07 · `hpcdb17942/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `10090019843` · L 76 / E 75.93 / Δ -0.07 · `hpcdb17615/gas | cavity wall | pitched 100` +- [x] `10013351333` · L 70 / E 69.93 / Δ -0.07 · `hpcdb18759/gas | cavity wall | pitched insulated | consv4` +- [x] `100080359994` · L 72 / E 72.07 / Δ +0.07 · `hpcdb15462/gas | cavity wall | pitched insulated | ext1` +- [x] `100080794353` · L 73 / E 73.07 / Δ +0.07 · `hpcdb19027/gas | cavity wall | pitched 200 | ext1` +- [x] `100080985468` · L 71 / E 71.07 / Δ +0.07 · `hpcdb17505/gas | cavity wall | pitched 125` +- [x] `32067719` · L 67 / E 66.93 / Δ -0.07 · `h104/gas | cavity wall | pitched 150 | consv2,ext1` +- [x] `100011465293` · L 47 / E 46.93 / Δ -0.07 · `h115/gas | cavity wall | pitched insulated | ext1` +- [x] `line77` · L 76 / E 76.07 / Δ +0.07 · `h401/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +- [x] `100061690837` · L 75 / E 75.07 / Δ +0.07 · `hpcdb18862/gas | cavity wall | pitched 50` +- [x] `6077577` · L 83 / E 82.93 / Δ -0.07 · `hpcdb16840/gas | cavity wall | (another dwelling` +- [x] `48102004` · L 71 / E 70.94 / Δ -0.06 · `hpcdb17501/gas | solid brick | pitched insulated` +- [x] `10032999260` · L 76 / E 76.06 / Δ +0.06 · `hpcdb18619/gas | cavity wall | pitched 150` +- [x] `100061778601` · L 68 / E 67.94 / Δ -0.06 · `hpcdb18861/gas | cavity wall | pitched 200 | ext2,mv5` +- [x] `10034910386` · L 74 / E 74.06 / Δ +0.06 · `h113/gas | solid brick | (another dwelling` +- [x] `5039119` · L 70 / E 70.06 / Δ +0.06 · `h409/elec | system built | (another dwelling | sec:portable electric,whw903` +- [x] `50034918` · L 77 / E 77.06 / Δ +0.06 · `hpcdb16777/gas | cavity wall | pitched 200` +- [x] `100061621130` · L 25 / E 24.94 / Δ -0.06 · `h102/fuel27 | timber frame | pitched 100 | RR,ext2,sec:room heaters` +- [x] `100121228675` · L 60 / E 60.06 / Δ +0.06 · `h301/coal-anth | sandstone as | (another dwelling` +- [x] `100051275257` · L 61 / E 61.06 / Δ +0.06 · `hpcdb19007/gas | sandstone as | pitched insulated | RR,ext1` +- [x] `100040663826` · L 67 / E 66.95 / Δ -0.05 · `hpcdb17001/gas | cavity wall | pitched 200` +- [x] `100110441268` · L 75 / E 75.05 / Δ +0.05 · `hpcdb10444/gas | solid brick | pitched 200` +- [x] `310012948` · L 74 / E 74.05 / Δ +0.05 · `hpcdb16454/gas | cavity wall | pitched 200` +- [x] `100010129331` · L 70 / E 69.95 / Δ -0.05 · `hpcdb17843/gas | solid brick | pitched insulated | ext2` +- [x] `10090880711` · L 75 / E 74.95 / Δ -0.05 · `hpcdb16138/gas | cavity wall | pitched 200 | consv4` +- [x] `100070333776` · L 74 / E 73.95 / Δ -0.05 · `hpcdb19082/gas | cavity wall | (another dwelling` +- [x] `100040882044` · L 73 / E 72.95 / Δ -0.05 · `hpcdb16839/gas | system built | pitched 200` +- [x] `207102835` · L 64 / E 64.05 / Δ +0.05 · `hpcdb18908/gas | solid brick | pitched 125 | ext2` +- [x] `83122910` · L 60 / E 59.95 / Δ -0.05 · `hpcdb17985/gas | sandstone as | pitched 100 | sec:room heaters` +- [x] `100050869764` · L 71 / E 70.95 / Δ -0.05 · `hpcdb10315/gas | cavity wall | pitched 150` +- [x] `64107249` · L 66 / E 66.05 / Δ +0.05 · `hpcdb15706/gas | cavity wall | (another dwelling | consv2,ext1,sec:room heaters` +- [x] `200003644880` · L 59 / E 59.05 / Δ +0.05 · `hpcdb15290/gas | solid brick | pitched insulated | ext2,sec:room heaters` +- [x] `10012785474` · L 75 / E 74.96 / Δ -0.04 · `hpcdb10243/gas | solid brick | (another dwelling` +- [x] `100062342550` · L 62 / E 61.96 / Δ -0.04 · `h301/elec10hr | cavity wall | pitched 350` +- [x] `10008919006` · L 51 / E 51.04 / Δ +0.04 · `hpcdb17055/gas | granite or | pitched no | ext1` +- [x] `83166253` · L 72 / E 72.04 / Δ +0.04 · `hpcdb18119/gas | cavity wall | pitched 150` +- [x] `100121099490` · L 75 / E 74.96 / Δ -0.04 · `hpcdb19016/gas | cavity wall | pitched 250` +- [x] `100031412745` · L 62 / E 61.96 / Δ -0.04 · `hpcdb18251/gas | solid brick | pitched 200 | ext2` +- [x] `3040036578` · L 64 / E 64.04 / Δ +0.04 · `hpcdb17553/gas | solid brick | pitched 250 | ext2` +- [x] `100031665275` · L 63 / E 63.04 / Δ +0.04 · `hpcdb17932/gas | solid brick | pitched 50 | ext4,sec:room heaters` +- [x] `1775039958` · L 71 / E 70.96 / Δ -0.04 · `hpcdb16841/gas | cavity wall | pitched 200` +- [x] `10034692050` · L 82 / E 82.04 / Δ +0.04 · `hpcdb18250/gas | sandstone as | pitched 350 | PV,ext2,sec:room heaters` +- [x] `100100694867` · L 62 / E 62.04 / Δ +0.04 · `h119/gas | cavity wall | pitched insulated` +- [x] `100031723834` · L 54 / E 53.96 / Δ -0.04 · `hpcdb18560/gas | cavity wall | pitched 100 | consv2,ext1,sec:room heaters` +- [x] `10008662860` · L 69 / E 69.04 / Δ +0.04 · `hpcdb17505/gas | solid brick | pitched 100` +- [x] `100061845289` · L 68 / E 67.96 / Δ -0.04 · `h409/elec | cavity wall | pitched 350 | sec:portable electric,whw903` +- [x] `14046362` · L 77 / E 77.04 / Δ +0.04 · `h104/gas | cavity wall | (another dwelling` +- [x] `100036648` · L 60 / E 60.04 / Δ +0.04 · `h104/gas | solid brick | pitched 100 | ext1` +- [x] `5072574` · L 66 / E 65.96 / Δ -0.04 · `hpcdb16840/gas | cavity wall | flat no` +- [x] `15041433` · L 70 / E 69.96 / Δ -0.04 · `hpcdb17507/gas | cavity wall | pitched 300` +- [x] `10096767959` · L 73 / E 73.04 / Δ +0.04 · `h421/elec | cavity wall | pitched 300 | sec:portable electric,whw903` +- [x] `100100357016` · L 75 / E 74.96 / Δ -0.04 · `hpcdb17507/gas | cavity wall | pitched 250` +- [x] `100060926936` · L 44 / E 44.04 / Δ +0.04 · `hpcdb1135/gas | cavity wall | pitched unknown` +- [x] `100031375565` · L 70 / E 69.97 / Δ -0.03 · `hpcdb18907/gas | cavity wall | pitched 300` +- [x] `100050859732` · L 57 / E 57.03 / Δ +0.03 · `h104/gas | solid brick | pitched insulated | ext3` +- [x] `100010663631` · L 67 / E 67.03 / Δ +0.03 · `hpcdb17974/gas | cavity wall | pitched 100 | RR,consv4` +- [x] `100031288765` · L 62 / E 61.97 / Δ -0.03 · `hpcdb18203/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +- [x] `10013290770` · L 54 / E 53.97 / Δ -0.03 · `h691/elec | cavity wall | (another dwelling | whw903` +- [x] `100080918720` · L 69 / E 68.97 / Δ -0.03 · `h104/gas | cavity wall | pitched 250` +- [x] `4510035778` · L 71 / E 71.03 / Δ +0.03 · `hpcdb15705/gas | cavity wall | pitched 250` +- [x] `100071152554` · L 72 / E 71.97 / Δ -0.03 · `hpcdb18559/gas | solid brick | pitched 100 | ext1,sec:room heaters` +- [x] `100110568321` · L 72 / E 71.97 / Δ -0.03 · `hpcdb15030/gas | cavity wall | pitched 270 | ext1` +- [x] `100021283678` · L 70 / E 69.97 / Δ -0.03 · `h102/gas | solid brick | pitched insulated | RR,ext1` +- [x] `100031023432` · L 65 / E 65.03 / Δ +0.03 · `hpcdb10200/gas | cavity wall | pitched 50 | ext1` +- [x] `100080699036` · L 67 / E 67.03 / Δ +0.03 · `hpcdb19014/gas | system built | pitched 300` +- [x] `43049701` · L 70 / E 69.97 / Δ -0.03 · `hpcdb19110/gas | cavity wall | pitched 350` +- [x] `100030742978` · L 14 / E 14.03 / Δ +0.03 · `h699/fuel0 | solid brick | pitched 300 | consv2,ext2,sec:portable electric,whw903` +- [x] `24113231` · L 74 / E 73.98 / Δ -0.02 · `hpcdb8787/gas | cavity wall | pitched 250` +- [x] `100120472369` · L 69 / E 68.98 / Δ -0.02 · `hpcdb16453/gas | cavity wall | pitched 75` +- [x] `100020394076` · L 71 / E 70.98 / Δ -0.02 · `hpcdb17115/gas | cavity wall | pitched 150` +- [x] `100061141934` · L 72 / E 71.98 / Δ -0.02 · `hpcdb18433/gas | cavity wall | pitched 100 | consv2` +- [x] `83159875` · L 74 / E 74.02 / Δ +0.02 · `hpcdb10328/gas | cavity wall | pitched 250 | PV,sec:room heaters` +- [x] `15042002` · L 62 / E 61.98 / Δ -0.02 · `hpcdb10327/gas | cavity wall | pitched 125 | ext1,sec:room heaters` +- [x] `1775087633` · L 72 / E 72.02 / Δ +0.02 · `h104/gas | cavity wall | (another dwelling` +- [x] `362182` · L 77 / E 77.02 / Δ +0.02 · `hpcdb17501/gas | sandstone with | pitched 200 | ext1` +- [x] `100050737075` · L 69 / E 69.02 / Δ +0.02 · `hpcdb16841/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `10003500583` · L 70 / E 69.98 / Δ -0.02 · `hpcdb18042/gas | cavity wall | pitched 250 | consv3,ext1,sec:room heaters` +- [x] `100051199928` · L 67 / E 66.98 / Δ -0.02 · `hpcdb19094/gas | cavity wall | pitched 300` +- [x] `100031526911` · L 71 / E 71.02 / Δ +0.02 · `hpcdb15502/gas | solid brick | pitched 250 | consv3,ext1,sec:room heaters` +- [x] `100060516940` · L 68 / E 67.98 / Δ -0.02 · `hpcdb9587/gas | cavity wall | pitched 200` +- [x] `100050345781` · L 66 / E 65.99 / Δ -0.01 · `hpcdb17985/gas | cavity wall | pitched 200 | ext2` +- [x] `100031601615` · L 73 / E 73.01 / Δ +0.01 · `hpcdb19080/gas | cavity wall | pitched insulated | RR,ext1` +- [x] `100032122827` · L 65 / E 64.99 / Δ -0.01 · `hpcdb18432/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `15068830` · L 74 / E 73.99 / Δ -0.01 · `hpcdb18768/gas | cavity wall | pitched 50 | sec:room heaters` +- [x] `32015803` · L 75 / E 75.01 / Δ +0.01 · `hpcdb18155/gas | cavity wall | (another dwelling` +- [x] `43002062` · L 72 / E 72.01 / Δ +0.01 · `hpcdb15707/gas | sandstone as | pitched 200` +- [x] `40057815` · L 78 / E 77.99 / Δ -0.01 · `hpcdb18225/gas | timber frame | pitched 175 | ext1` +- [x] `28052680` · L 76 / E 75.99 / Δ -0.01 · `hpcdb19080/gas | cavity wall | pitched 400+` +- [x] `77163938` · L 69 / E 68.99 / Δ -0.01 · `hpcdb17683/gas | solid brick | pitched insulated | ext1` +- [x] `100110766495` · L 79 / E 79.01 / Δ +0.01 · `hpcdb16839/gas | cavity wall | (another dwelling` +- [x] `100040446690` · L 72 / E 71.99 / Δ -0.01 · `h104/gas | system built | pitched 400+ | ext1,sec:room heaters` +- [x] `10033241196` · L 78 / E 78.01 / Δ +0.01 · `h691/elec | solid brick | pitched 100 | whw909` +- [x] `100061583852` · L 71 / E 71.01 / Δ +0.01 · `hpcdb17507/gas | cavity wall | pitched 300` +- [x] `10009446250` · L 43 / E 42.99 / Δ -0.01 · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +- [x] `line996` · L 75 / E 74.99 / Δ -0.01 · `h104/gas | cavity wall | flat insulated` +- [x] `10014235074` · L 76 / E 75.99 / Δ -0.01 · `hpcdb18516/gas | cavity wall | pitched 200 | ext1` +- [x] `83182597` · L 71 / E 71.00 / Δ +0.00 · `hpcdb18225/gas | cavity wall | (another dwelling` +- [x] `100100122657` · L 61 / E 61.00 / Δ -0.00 · `hpcdb1514/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +- [x] `10007364829` · L 74 / E 74.00 / Δ +0.00 · `hpcdb18432/gas | cavity wall | pitched 200` +- [x] `4510136787` · L 76 / E 76.00 / Δ +0.00 · `h409/elec | solid brick | (another dwelling | whw903` +- [x] `422000111926` · L 1 / E 1.00 / Δ +0.00 · `h699/fuel0 | solid brick | pitched no | sec:portable electric,whw999` + +
diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index 2bce02247..a925e88dd 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -699,6 +699,31 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="0018-2049-6232-4431-6934", sap_score=54, ), + # UPRN 4510053280 (corpus-1000 C001; the corpus doc lodges no cert number). + # RdSAP-Schema-21.0.1 native — GROUND-FLOOR FLAT 47 m², band B, solid brick + # 520 mm uninsulated (+ 8.12 m² sheltered alternative wall), roof "(another + # dwelling above)", ASHP radiators PCDB 100053 (Mitsubishi Ecodan 5 kW, + # 2010 record: PSR table 0.2–2.0, η_space 332.8% @ 2.0, η_water 187.5%, + # duration "24"), no cylinder, electric room-heater secondary, no PV. + # Lodged 51 / engine 74.94 (Δ +23.9, the corpus' worst cert). Dwelling PSR + # = 4.62 kW / (94.0 W/K × 24.2 K) = 2.031, just past the record's largest + # 2.0 → SAP 10.2 N2 (PDF p.101 footnotes 44/45) heat-pump extension: + # reciprocal-interpolate η_space toward 100% at PSR 4.0 → 321% × 0.95 = + # 305%. That is what the engine does, and what accredited Elmhurst did on + # the SAME record family / same PSR shape (golden case 56, record 100061, + # PSR 3.107 → 139.66%). The LODGED software instead treated the + # out-of-range record as invalid and billed direct electric: forcing + # η_space = η_water = 100% + the standard 9-h schedule reproduces the + # lodged CO2 to 1% (0.808 vs 0.800 t) and PE within 6% (178 vs 190), + # whereas the engine's spec path gives 0.444 t / 98.8. A lodged-software + # methodology gap (worklist ⚠), NOT an engine bug — do not tune. PINNED to + # the observed engine 75. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_4510053280", + cert_num="uprn-4510053280", + sap_score=75, + ), ) From c380377948f3c90a9ab6addaae284b01718cdaf8 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 19:06:26 +0000 Subject: [PATCH 02/84] test(accuracy): ratchet 74.2% -> 75.5% via 'insulated (assumed)' roof Table-18 fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RdSAP 10 §5.11.4: a pitched roof lodging thickness "NI" with description "...insulated (assumed)" was billed at the §5.11.4 observed-retrofit 50 mm row (U 0.68) while the SAME description lodged with "ND" fell through to the Table 18 age-band default (0.40 for bands A-G). The ND-vs-NI sentinel is lodging-software noise; "(assumed)" means the insulation PRESENCE is an age-band assumption, not an observed retrofit, so Table 18's "thickness cannot be determined" clause governs both forms. The bare "insulated" description (observed retrofit, no qualifier) keeps the 50 mm row. Evidence: the 27-cert loc4+NI corpus cohort was systematically under-rated (~-1 SAP; zero positive movers among "(assumed)" certs), vs the 102-cert loc4+ND cohort already on Table 18 at ~0 bias. Gauge: within-0.5 74.2% -> 75.5%, SAP MAE 0.721 -> 0.708, CO2 MAE 0.09 -> 0.074, PE MAE 3.5 -> 3.2 (floors ratcheted). Unit-pinned in test_rdsap_uvalues (assumed -> Table 18; bare-insulated -> 0.68 regression guard); integration pin in test_heat_transmission updated; RealCertExpectation pinned for 10094975827 (66 = lodged, was -1.87). Ledger: C002 103001004 deferred pending Elmhurst arbitration (single-immersion off-peak pricing + declared cylinder loss vs Table-2); C006 quadruplet marked ⚠ (LIG-21.0 software honours lodged 0 extract fans literally vs the Elmhurst-validated 0=unknown->default convention, worksheet case 46). Co-Authored-By: Claude Fable 5 --- .../uprn_10094975827/epc.json | 366 +++++++++++++ .../uprn_103001004/epc.json | 321 +++++++++++ domain/sap10_ml/rdsap_uvalues.py | 25 +- domain/sap10_ml/tests/test_rdsap_uvalues.py | 57 +- scripts/corpus_1000/worklist.md | 502 +++++++++--------- .../test_real_cert_sap_accuracy.py | 15 + .../worksheet/test_heat_transmission.py | 23 +- .../epc_client/test_sap_accuracy_corpus.py | 19 +- 8 files changed, 1032 insertions(+), 296 deletions(-) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10094975827/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_103001004/epc.json diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10094975827/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10094975827/epc.json new file mode 100644 index 000000000..5b68ee3b0 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10094975827/epc.json @@ -0,0 +1,366 @@ +{ + "uprn": 10094975827, + "roofs": [ + { + "description": "Pitched, insulated (assumed)", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "description": "Solid brick, as built, no insulation (assumed)", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "floors": [ + { + "description": "(other premises below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "B8 2NG", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BIRMINGHAM", + "psv_count": 0, + "built_form": 3, + "created_at": "2026-05-14 13:27:59", + "door_count": 1, + "region_code": 6, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "N", + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 1, + "main_heating_number": 1, + "main_heating_control": 2107, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 18559 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": { + "value": 1.01, + "quantity": "m" + }, + "window_height": { + "value": 1.61, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": { + "value": 1.66, + "quantity": "m" + }, + "window_height": { + "value": 1.46, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 3, + "window_type": 1, + "glazing_type": 3, + "window_width": { + "value": 1.09, + "quantity": "m" + }, + "window_height": { + "value": 1.29, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 3, + "window_type": 1, + "glazing_type": 3, + "window_width": { + "value": 1.09, + "quantity": "m" + }, + "window_height": { + "value": 1.55, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 3, + "window_type": 1, + "glazing_type": 3, + "window_width": { + "value": 1.79, + "quantity": "m" + }, + "window_height": { + "value": 1.92, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Top-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "Flat 2", + "address_line_2": "874 Washwood Heath Road", + "assessment_type": "RdSAP", + "completion_date": "2026-05-14", + "inspection_date": "2026-05-13", + "extensions_count": 0, + "measurement_type": 1, + "open_flues_count": 0, + "sap_flat_details": { + "level": 3, + "top_storey": "N", + "storey_count": 2, + "flat_location": 1, + "heat_loss_corridor": 0 + }, + "total_floor_area": 78, + "transaction_type": 8, + "conservatory_type": 1, + "heated_room_count": 3, + "other_flues_count": 0, + "registration_date": "2026-05-14", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 3, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 0, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 340, + "floor_heat_loss": 3, + "roof_construction": 4, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.44, + "total_floor_area": 77.87, + "party_wall_length": 11.57, + "heat_loss_perimeter": 25.03 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "B", + "party_wall_construction": 1, + "wall_thickness_measured": "Y", + "roof_insulation_location": 4, + "roof_insulation_thickness": "NI", + "wall_insulation_thickness": "NI" + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 952, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 3.2, + "energy_rating_average": 60, + "energy_rating_current": 66, + "lighting_cost_current": { + "value": 56, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, TRVs and bypass", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "blocked_chimneys_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 735, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 197, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "schema_version_current": "LIG-21.0", + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 171, + "indicative_cost": "\u00a37,500 - \u00a311,000", + "improvement_type": "Q", + "improvement_details": { + "improvement_number": 7 + }, + "improvement_category": 5, + "energy_performance_rating": 70, + "environmental_impact_rating": 70 + }, + { + "sequence": 2, + "typical_saving": 45, + "indicative_cost": "\u00a3220 - \u00a3250", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 14 + }, + "improvement_category": 5, + "energy_performance_rating": 72, + "environmental_impact_rating": 71 + } + ], + "co2_emissions_potential": 2.6, + "energy_rating_potential": 72, + "lighting_cost_potential": { + "value": 56, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0", + "hot_water_cost_potential": { + "value": 198, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2548.95, + "space_heating_existing_dwelling": 10093.12 + }, + "draughtproofed_door_count": 1, + "energy_consumption_current": 227, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "10.2.2.0", + "energy_consumption_potential": 181, + "environmental_impact_current": 64, + "cfl_fixed_lighting_bulbs_count": 0, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 71, + "led_fixed_lighting_bulbs_count": 8, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 41, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_103001004/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_103001004/epc.json new file mode 100644 index 000000000..8897cb84d --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_103001004/epc.json @@ -0,0 +1,321 @@ +{ + "uprn": 103001004, + "roofs": [ + { + "description": "Pitched, Unknown loft insulation", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "description": "Cavity wall, filled cavity", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 2, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "lighting": { + "description": "Good lighting efficiency", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "NE33 1TN", + "hot_water": { + "description": "Electric immersion, off-peak", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 4 + }, + "post_town": "SOUTH SHIELDS", + "built_form": "NR", + "created_at": "2026-04-16 10:25:37", + "door_count": 0, + "region_code": 1, + "report_type": 2, + "sap_heating": { + "number_baths": 0, + "cylinder_size": 3, + "shower_outlets": [ + { + "shower_outlet": { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + } + ], + "cylinder_heat_loss": 1.8, + "number_baths_wwhrs": 0, + "water_heating_code": 903, + "water_heating_fuel": 29, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 20, + "heat_emitter_type": 0, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2307, + "main_heating_category": 6, + "main_heating_fraction": 1, + "sap_main_heating_code": 301, + "main_heating_data_source": 2, + "community_heat_distribution_type": 6 + } + ], + "immersion_heating_type": 2, + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "glazing_gap": 12, + "orientation": 7, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.21, + "window_height": 1.44, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": 12, + "orientation": 7, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.77, + "window_height": 1.14, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Community scheme", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Ground-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "3 Julius Court", + "address_line_2": "Mile End Road", + "assessment_type": "RdSAP", + "completion_date": "2026-04-16", + "inspection_date": "2026-04-16", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 1, + "top_storey": "N", + "storey_count": 1, + "flat_location": 0, + "heat_loss_corridor": 1 + }, + "total_floor_area": 31, + "transaction_type": 8, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 2, + "registration_date": "2026-04-16", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 1, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "extract_fans_count": 2, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.37, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 30.55, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 16.75, + "quantity": "metres" + }, + "floor_construction": 1, + "heat_loss_perimeter": { + "value": 5.37, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 2, + "construction_age_band": "F", + "party_wall_construction": 0, + "wall_thickness_measured": "N", + "roof_insulation_location": 2, + "roof_insulation_thickness": "NI", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 2, + "heating_cost_current": { + "value": 251, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 1.2, + "energy_rating_average": 60, + "energy_rating_current": 50, + "lighting_cost_current": { + "value": 29, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Flat rate charging, TRVs", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 313, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 1054, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 35, + "currency": "GBP" + }, + "indicative_cost": "\u00a3900 - \u00a31,200", + "improvement_type": "A", + "improvement_details": { + "improvement_number": 5 + }, + "improvement_category": 5, + "energy_performance_rating": 52, + "environmental_impact_rating": 81 + }, + { + "sequence": 2, + "typical_saving": { + "value": 598, + "currency": "GBP" + }, + "indicative_cost": "\u00a320 - \u00a340", + "improvement_type": "C", + "improvement_details": { + "improvement_number": 1 + }, + "improvement_category": 5, + "energy_performance_rating": 68, + "environmental_impact_rating": 83 + }, + { + "sequence": 3, + "typical_saving": { + "value": 51, + "currency": "GBP" + }, + "indicative_cost": "\u00a3600 - \u00a31,500", + "improvement_type": "Y", + "improvement_details": { + "improvement_number": 49 + }, + "improvement_category": 5, + "energy_performance_rating": 70, + "environmental_impact_rating": 83 + } + ], + "co2_emissions_potential": 1.0, + "energy_rating_potential": 70, + "lighting_cost_potential": { + "value": 29, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 308, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 5719.21, + "space_heating_existing_dwelling": 1270.63 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 367, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0342", + "energy_consumption_potential": 214, + "environmental_impact_current": 78, + "current_energy_efficiency_band": "E", + "environmental_impact_potential": 83, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 41, + "low_energy_fixed_lighting_bulbs_count": 5, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/domain/sap10_ml/rdsap_uvalues.py b/domain/sap10_ml/rdsap_uvalues.py index 6687491f0..9b7a8c509 100644 --- a/domain/sap10_ml/rdsap_uvalues.py +++ b/domain/sap10_ml/rdsap_uvalues.py @@ -998,13 +998,30 @@ def u_roof( # (band J = 0.16), matching the cohort's "ND" (thickness None) # vaulted roofs which already reach col (1) by falling through. return _ROOF_BY_AGE.get(age_band.upper(), 0.4) + if ( + age_band is not None + and insulation_thickness_mm == 0 + and _described_as_insulated(description) + and description is not None + and "(assumed)" in description.lower() + ): + # RdSAP renders "insulated (assumed)" when insulation PRESENCE is + # itself assumed (age-band / as-built assumption), not an observed + # retrofit — so the §5.11.4 50 mm footnote (below) does not apply; + # the thickness "cannot be determined" and the Table 18 age-band + # default governs (§5.11.4 opening clause). Identical + # "Pitched, insulated (assumed)" corpus dwellings lodge thickness + # "ND" (None → Table 18 by fallthrough) or "NI" (0 → previously the + # 50 mm row) purely per lodging software; both take Table 18. + table_18 = _FLAT_ROOF_BY_AGE if is_flat_roof else roof_by_age + return table_18.get(age_band.upper(), 0.4) if insulation_thickness_mm == 0 and _described_as_insulated(description): # Spec §5.11.4 (page 44 footnote): "If retrofit insulation # present of unknown thickness use 50 mm". The cert encodes - # "thickness unknown but retrofit insulation present" as the - # "NI" sentinel which `_parse_thickness_mm` parses to 0. Without - # this override the Table 16 row-0 lookup below returns the - # uninsulated 2.30 W/m²K. + # "thickness unknown but OBSERVED retrofit insulation" as the + # "NI" sentinel (parsed to 0) + an unqualified "insulated" + # description (no "(assumed)"). Without this override the Table + # 16 row-0 lookup below returns the uninsulated 2.30 W/m²K. return 0.68 # Table 16 row 50, "Insulation at joists at ceiling level" if insulation_thickness_mm is not None: # nearest tabulated thickness <= supplied (Table 16 column (1) diff --git a/domain/sap10_ml/tests/test_rdsap_uvalues.py b/domain/sap10_ml/tests/test_rdsap_uvalues.py index 4fb51f422..e6019befa 100644 --- a/domain/sap10_ml/tests/test_rdsap_uvalues.py +++ b/domain/sap10_ml/tests/test_rdsap_uvalues.py @@ -1059,16 +1059,41 @@ def test_u_roof_description_with_measured_transmittance_returns_parsed_value() - assert result == pytest.approx(0.11, abs=0.001) -def test_u_roof_ni_thickness_with_insulated_description_applies_50mm_per_section_5_11_4() -> None: - # Arrange — 346 corpus certs lodge roof_insulation_thickness="NI" - # (Not Indicated, parsed to 0 by _parse_thickness_mm). When the - # description also signals retrofit insulation ("Pitched, insulated - # (assumed)" / "Flat, insulated" / "Roof room(s), insulated - # (assumed)"), RdSAP 10 §5.11.4 (page 44) footnote applies: +def test_u_roof_ni_thickness_with_observed_insulated_description_applies_50mm_per_section_5_11_4() -> None: + # Arrange — a roof lodging thickness "NI" (parsed to 0) whose + # description signals OBSERVED insulation without the "(assumed)" + # qualifier ("Pitched, insulated" — RdSAP renders the bare form when + # the assessor saw the insulation but not its depth). RdSAP 10 + # §5.11.4 (page 44) footnote applies: # "If retrofit insulation present of unknown thickness use 50 mm". # That maps to Table 16 row "50 mm at joists at ceiling level" = 0.68 - # W/m²K — vs the current 2.30 we return when thickness=0 hits the - # Table 16 row-0 lookup. + # W/m²K — vs the 2.30 the Table 16 row-0 lookup would give. + + # Act + result = u_roof( + country=Country.ENG, + age_band="C", + insulation_thickness_mm=0, # parsed from "NI" + description="Pitched, insulated", + ) + + # Assert + assert result == pytest.approx(0.68, abs=0.01) + + +def test_u_roof_ni_thickness_with_assumed_insulated_description_uses_table18_default() -> None: + # Arrange — RdSAP renders "insulated (assumed)" when insulation + # presence is ASSUMED (age-band / as-built assumption), not an + # observed retrofit — so the §5.11.4 "retrofit insulation present of + # unknown thickness use 50 mm" footnote does NOT apply; the thickness + # "cannot be determined" and Table 18's age-band default governs + # (§5.11.4 opening clause). The corpus lodges the SAME description + # with thickness "ND" (102 certs → already Table 18 via the + # thickness-None fallthrough) or "NI" (27 certs → previously took the + # 50 mm row 0.68), purely per lodging software; both must land on the + # same Table 18 value (band C pitched → 0.40). The loc-4 NI cohort + # was systematically under-rated by ~1 SAP before this (e.g. corpus + # cert 10094975827 band B: Δ −1.87). # Act result = u_roof( @@ -1078,8 +1103,8 @@ def test_u_roof_ni_thickness_with_insulated_description_applies_50mm_per_section description="Pitched, insulated (assumed)", ) - # Assert - assert result == pytest.approx(0.68, abs=0.01) + # Assert — Table 18 column (1) band C. + assert result == pytest.approx(0.40, abs=0.01) def test_u_roof_ni_thickness_with_no_insulation_description_stays_at_2_30() -> None: @@ -1324,18 +1349,20 @@ def test_u_roof_vaulted_ni_unknown_band_j_uses_col1_age_band_not_50mm() -> None: assert abs(result - 0.16) <= 1e-4 -def test_u_roof_normal_pitched_ni_insulated_still_returns_50mm_per_5_11_4() -> None: +def test_u_roof_normal_pitched_ni_observed_insulated_still_returns_50mm_per_5_11_4() -> None: # Arrange — regression guard: the is_sloping_ceiling flag defaults - # False, so a NORMAL pitched roof (with loft) lodged NI + "insulated - # (assumed)" must STILL hit the §5.11.4 retrofit-50 mm row (U=0.68). - # Same inputs as the sloping test above minus is_sloping_ceiling. + # False, so a NORMAL pitched roof (with loft) lodged NI + an + # unqualified "insulated" description (observed retrofit, no + # "(assumed)") must STILL hit the §5.11.4 retrofit-50 mm row + # (U=0.68). The "(assumed)" form routes to Table 18 instead — see + # test_u_roof_ni_thickness_with_assumed_insulated_description_uses_table18_default. # Act result = u_roof( country=Country.ENG, age_band="J", insulation_thickness_mm=0, - description="Pitched, insulated (assumed)", + description="Pitched, insulated", ) # Assert diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index 09bd7e96a..88a9e2626 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -1,16 +1,16 @@ # RdSAP-21.0.1 corpus campaign ledger -**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **74.2%** · MAE = **0.721** (floors in test_sap_accuracy_corpus.py) +**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **75.5%** · MAE = **0.708** (floors in test_sap_accuracy_corpus.py) Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail engine bug · ⛔ unbuildable. Line: `uprn · lodged L / eng E / Δ · signature`. Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` (preserves statuses & `<-` notes). -## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 258 certs in 249 clusters +## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 245 certs in 237 clusters ### C001 · Σ|Δ| 23.9 · 1 certs · `hpcdb100053/elec | solid brick | (another dwelling | sec:room heaters` - ⚠ `4510053280` · L 51 / E 74.94 / Δ +23.94 <- lodged software billed out-of-range-PSR (2.031 > 2.0) PCDB 100053 as 100% direct electric; engine follows SAP10.2 N2 extension (305%), Elmhurst-validated on case 56. Pinned engine 75 in test_real_cert_sap_accuracy. ### C002 · Σ|Δ| 19.7 · 1 certs · `h301/coal-anth | cavity wall | pitched unknown | whw903` -- [ ] `103001004` · L 50 / E 69.69 / Δ +19.69 +- [ ] `103001004` · L 50 / E 69.69 / Δ +19.69 <- needs Elmhurst arbitration: lodged hw £1054 vs ours £113 (single-immersion on-peak fraction + cylinder declared-loss 1.8 kWh/day vs Table-2-sized loss); register data can't decompose. Other 14 declared-loss certs match lodged; only sibling outlier is 100121325434 (C008). ### C003 · Σ|Δ| 15.2 · 1 certs · `h117/gas | cavity wall | pitched 200 | ext2,sec:room heaters` - [ ] `100050355518` · L 36 / E 20.82 / Δ -15.18 @@ -22,10 +22,10 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [ ] `12109191` · L 58 / E 71.10 / Δ +13.10 ### C006 · Σ|Δ| 10.3 · 4 certs · `h691/elec | cavity wall | (another dwelling | whw909` -- [ ] `line279` · L 81 / E 78.44 / Δ -2.56 -- [ ] `line301` · L 81 / E 78.44 / Δ -2.56 -- [ ] `line318` · L 81 / E 78.44 / Δ -2.56 -- [ ] `10093237426` · L 81 / E 78.44 / Δ -2.56 +- ⚠ `line279` · L 81 / E 78.44 / Δ -2.56 <- same as 10093237426 +- ⚠ `line301` · L 81 / E 78.44 / Δ -2.56 <- same as 10093237426 +- ⚠ `line318` · L 81 / E 78.44 / Δ -2.56 <- same as 10093237426 +- ⚠ `10093237426` · L 81 / E 78.44 / Δ -2.56 <- LIG-21.0 software (calc 10.2.2.0) honours lodged 0 extract fans literally; Elmhurst-validated convention (case 46) treats 0 as unknown -> Table 5 default. Fans-as-0 experiment closes 1.42 of 2.56; residual -1.14 unexplained, same-software quadruplet. ### C007 · Σ|Δ| 10.1 · 1 certs · `h691/elec | granite or | pitched 175 | RR,ext1,whw903` - [ ] `100040550095` · L 40 / E 29.87 / Δ -10.13 @@ -109,8 +109,8 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C033 · Σ|Δ| 4.0 · 1 certs · `h191/elec | cavity wall | (another dwelling` - [ ] `10002272664` · L 79 / E 74.96 / Δ -4.04 -### C034 · Σ|Δ| 3.6 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` -- [ ] `72351021` · L 64 / E 60.45 / Δ -3.55 +### C034 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` +- [ ] `100040767294` · L 43 / E 47.04 / Δ +4.04 ### C035 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` - [ ] `39066537` · L 78 / E 81.49 / Δ +3.49 @@ -121,15 +121,15 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C037 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100080122910` · L 60 / E 63.45 / Δ +3.45 -### C038 · Σ|Δ| 3.4 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` -- [ ] `100040767294` · L 43 / E 46.38 / Δ +3.38 - -### C039 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` +### C038 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` - [ ] `452010022` · L 42 / E 38.67 / Δ -3.33 -### C040 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` +### C039 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` - [ ] `200004818752` · L 34 / E 30.73 / Δ -3.27 +### C040 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` +- [ ] `72351021` · L 64 / E 60.85 / Δ -3.15 + ### C041 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` - [ ] `22077224` · L 37 / E 33.90 / Δ -3.10 @@ -142,627 +142,590 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C044 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` - [ ] `10011740578` · L 70 / E 67.00 / Δ -3.00 -### C045 · Σ|Δ| 2.9 · 2 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` -- [ ] `22027335` · L 76 / E 73.77 / Δ -2.23 -- [ ] `200002819281` · L 72 / E 71.29 / Δ -0.71 - -### C046 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +### C045 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` - [ ] `100110680822` · L 79 / E 76.07 / Δ -2.93 -### C047 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` +### C046 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` - [ ] `452032915` · L 75 / E 72.09 / Δ -2.91 -### C048 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` +### C047 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` - [ ] `100071306639` · L 73 / E 70.14 / Δ -2.86 -### C049 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` +### C048 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` - [ ] `100061346049` · L 55 / E 52.15 / Δ -2.85 -### C050 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` +### C049 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` - [ ] `10013008238` · L 41 / E 38.26 / Δ -2.74 -### C051 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` +### C050 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` - [ ] `10033187652` · L 70 / E 71.21 / Δ +1.21 - [ ] `200002730` · L 65 / E 64.13 / Δ -0.87 - [ ] `10023328117` · L 78 / E 78.64 / Δ +0.64 -### C052 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` +### C051 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` - [ ] `10004873253` · L 65 / E 62.29 / Δ -2.71 -### C053 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` +### C052 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` - [ ] `10090793715` · L 73 / E 75.71 / Δ +2.71 -### C054 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` +### C053 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100120745600` · L 65 / E 67.69 / Δ +2.69 -### C055 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` +### C054 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` - [ ] `100051178830` · L 63 / E 65.66 / Δ +2.66 -### C056 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` +### C055 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` - [ ] `100120018282` · L 64 / E 61.36 / Δ -2.64 -### C057 · Σ|Δ| 2.6 · 1 certs · `hpcdb10599/fuel28 | sandstone as | pitched insulated | ext2,sec:room heaters` -- [ ] `666329` · L 69 / E 66.39 / Δ -2.61 - -### C058 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +### C056 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` - [ ] `83035979` · L 65 / E 67.60 / Δ +2.60 -### C059 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` +### C057 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` - [ ] `10014073761` · L 75 / E 72.52 / Δ -2.48 -### C060 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` +### C058 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` +- [ ] `100050964834` · L 60 / E 62.47 / Δ +2.47 + +### C059 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` - [ ] `100120752995` · L 71 / E 73.42 / Δ +2.42 -### C061 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` +### C060 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` - [ ] `100032230128` · L 55 / E 52.60 / Δ -2.40 -### C062 · Σ|Δ| 2.4 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` +### C061 · Σ|Δ| 2.4 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` - [ ] `100012368622` · L 39 / E 41.40 / Δ +2.40 -### C063 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` +### C062 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` - [ ] `100000034023` · L 73 / E 70.71 / Δ -2.29 -### C064 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` +### C063 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` - [ ] `100020377671` · L 62 / E 64.23 / Δ +2.23 +### C064 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` +- [ ] `22027335` · L 76 / E 73.77 / Δ -2.23 + ### C065 · Σ|Δ| 2.2 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` - [ ] `80838` · L 41 / E 43.19 / Δ +2.19 -### C066 · Σ|Δ| 2.1 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` -- [ ] `100050964834` · L 60 / E 62.13 / Δ +2.13 - -### C067 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` +### C066 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` - [ ] `48056153` · L 65 / E 62.89 / Δ -2.11 -### C068 · Σ|Δ| 2.0 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` +### C067 · Σ|Δ| 2.0 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` - [ ] `100070295212` · L 75 / E 77.01 / Δ +2.01 -### C069 · Σ|Δ| 2.0 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` +### C068 · Σ|Δ| 2.0 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` - [ ] `100100274789` · L 60 / E 62.00 / Δ +2.00 -### C070 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` +### C069 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` - [ ] `100021924710` · L 63 / E 65.00 / Δ +2.00 -### C071 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` +### C070 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` - [ ] `100031270375` · L 69 / E 70.93 / Δ +1.93 -### C072 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` +### C071 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` - [ ] `10001118522` · L 80 / E 78.07 / Δ -1.93 -### C073 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` +### C072 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` - [ ] `10010234711` · L 81 / E 79.08 / Δ -1.92 -### C074 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` +### C073 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` - [ ] `100031768368` · L 61 / E 59.12 / Δ -1.88 -### C075 · Σ|Δ| 1.9 · 1 certs · `hpcdb18559/gas | solid brick | pitched insulated` -- [ ] `10094975827` · L 66 / E 64.13 / Δ -1.87 - -### C076 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` +### C074 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` - [ ] `4510729926` · L 73 / E 71.15 / Δ -1.85 -### C077 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` +### C075 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` - [ ] `100091329112` · L 49 / E 50.82 / Δ +1.82 -### C078 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` +### C076 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` - [ ] `100061275133` · L 76 / E 77.24 / Δ +1.24 - [ ] `207032630` · L 74 / E 73.47 / Δ -0.53 -### C079 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` +### C077 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` - [ ] `10011797347` · L 47 / E 48.77 / Δ +1.77 -### C080 · Σ|Δ| 1.8 · 1 certs · `hpcdb17679/gas | solid brick | pitched insulated` -- [ ] `line621` · L 78 / E 76.24 / Δ -1.76 - -### C081 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` +### C078 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` - [ ] `100022668387` · L 68 / E 66.25 / Δ -1.75 -### C082 · Σ|Δ| 1.8 · 1 certs · `hpcdb17803/gas | timber frame | pitched 100` +### C079 · Σ|Δ| 1.8 · 1 certs · `hpcdb17803/gas | timber frame | pitched 100` - [ ] `200004017091` · L 71 / E 72.75 / Δ +1.75 -### C083 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` +### C080 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` - [ ] `100100892216` · L 69 / E 67.28 / Δ -1.72 -### C084 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` +### C081 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100060878876` · L 49 / E 50.71 / Δ +1.71 -### C085 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` +### C082 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` - [ ] `22032926` · L 61 / E 62.71 / Δ +1.71 -### C086 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` +### C083 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100010942905` · L 72 / E 73.70 / Δ +1.70 -### C087 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` +### C084 · Σ|Δ| 1.6 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` +- [ ] `10091707271` · L 41 / E 42.64 / Δ +1.64 + +### C085 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` - [ ] `100030307976` · L 71 / E 69.37 / Δ -1.63 -### C088 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` +### C086 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` - [ ] `100061404488` · L 70 / E 68.38 / Δ -1.62 -### C089 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` +### C087 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` - [ ] `21067296` · L 67 / E 68.60 / Δ +1.60 -### C090 · Σ|Δ| 1.6 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` -- [ ] `100050477371` · L 65 / E 63.40 / Δ -1.60 - -### C091 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` +### C088 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` - [ ] `5870047440` · L 58 / E 59.58 / Δ +1.58 -### C092 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` +### C089 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` - [ ] `100070450818` · L 65 / E 63.43 / Δ -1.57 -### C093 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` +### C090 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` - [ ] `100050881708` · L 70 / E 71.55 / Δ +1.55 -### C094 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` +### C091 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` - [ ] `10010254955` · L 79 / E 77.46 / Δ -1.54 -### C095 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` +### C092 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` - [ ] `3455011834` · L 69 / E 67.48 / Δ -1.52 -### C096 · Σ|Δ| 1.5 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` +### C093 · Σ|Δ| 1.5 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` - [ ] `100051109723` · L 60 / E 61.52 / Δ +1.52 -### C097 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` +### C094 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` - [ ] `100050852755` · L 65 / E 66.49 / Δ +1.49 -### C098 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` +### C095 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` - [ ] `100021326422` · L 70 / E 68.51 / Δ -1.49 -### C099 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` +### C096 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100050988345` · L 61 / E 59.51 / Δ -1.49 -### C100 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` +### C097 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` - [ ] `100030285758` · L 54 / E 55.48 / Δ +1.48 -### C101 · Σ|Δ| 1.5 · 1 certs · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` +### C098 · Σ|Δ| 1.5 · 1 certs · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` - [ ] `100090536443` · L 86 / E 84.52 / Δ -1.48 -### C102 · Σ|Δ| 1.5 · 1 certs · `h158/heatnet+2mains | solid brick | pitched insulated | ext4,sec:room heaters,whw903` -- [ ] `100120881623` · L 53 / E 51.55 / Δ -1.45 - -### C103 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` +### C099 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` - [ ] `line80` · L 72 / E 70.56 / Δ -1.44 -### C104 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` +### C100 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` - [ ] `100080518673` · L 57 / E 58.42 / Δ +1.42 -### C105 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` +### C101 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` - [ ] `235025284` · L 69 / E 67.59 / Δ -1.41 -### C106 · Σ|Δ| 1.4 · 1 certs · `hpcdb16401/gas | cavity wall | pitched insulated | mv2` -- [ ] `10093200879` · L 71 / E 69.59 / Δ -1.41 - -### C107 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` +### C102 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` - [ ] `250063088` · L 73 / E 71.60 / Δ -1.40 -### C108 · Σ|Δ| 1.4 · 1 certs · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` +### C103 · Σ|Δ| 1.4 · 1 certs · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` - [ ] `100050048691` · L 58 / E 59.39 / Δ +1.39 -### C109 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` +### C104 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` - [ ] `100110097281` · L 64 / E 65.37 / Δ +1.37 -### C110 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` +### C105 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` - [ ] `10091630692` · L 58 / E 56.63 / Δ -1.37 -### C111 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` +### C106 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` - [ ] `100031433810` · L 70 / E 68.63 / Δ -1.37 -### C112 · Σ|Δ| 1.4 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` -- [ ] `100051051866` · L 70 / E 68.64 / Δ -1.36 - -### C113 · Σ|Δ| 1.3 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` +### C107 · Σ|Δ| 1.3 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` - [ ] `10002945522` · L 61 / E 62.32 / Δ +1.32 -### C114 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +### C108 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` - [ ] `90077194` · L 65 / E 63.69 / Δ -1.31 -### C115 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` +### C109 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` - [ ] `100031461986` · L 70 / E 71.29 / Δ +1.29 -### C116 · Σ|Δ| 1.3 · 1 certs · `hpcdb15100/gas | cavity wall | pitched insulated | consv2,sec:room heaters` -- [ ] `100031193650` · L 70 / E 68.73 / Δ -1.27 - -### C117 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` +### C110 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` - [ ] `30095054` · L 46 / E 44.74 / Δ -1.26 -### C118 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` +### C111 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` - [ ] `100100055589` · L 58 / E 59.26 / Δ +1.26 -### C119 · Σ|Δ| 1.3 · 1 certs · `hpcdb15049/gas | cavity wall | pitched insulated` -- [ ] `565298` · L 68 / E 66.75 / Δ -1.25 - -### C120 · Σ|Δ| 1.2 · 1 certs · `hpcdb108793/elec | solid brick | pitched insulated | ext2` -- [ ] `100120850835` · L 59 / E 57.77 / Δ -1.23 - -### C121 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` +### C112 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` - [ ] `100091435353` · L 65 / E 66.23 / Δ +1.23 -### C122 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` +### C113 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` - [ ] `10091070164` · L 69 / E 69.60 / Δ +0.60 - [ ] `10090927185` · L 79 / E 79.60 / Δ +0.60 -### C123 · Σ|Δ| 1.2 · 1 certs · `hpcdb16842/gas | cavity wall | pitched no | ext1,sec:room heaters` +### C114 · Σ|Δ| 1.2 · 1 certs · `hpcdb16842/gas | cavity wall | pitched no | ext1,sec:room heaters` - [ ] `100090834242` · L 53 / E 54.20 / Δ +1.20 -### C124 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` +### C115 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` - [ ] `100100614412` · L 53 / E 51.81 / Δ -1.19 -### C125 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` +### C116 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` - [ ] `217091901` · L 62 / E 60.82 / Δ -1.18 -### C126 · Σ|Δ| 1.2 · 1 certs · `hpcdb17978/gas | solid brick | pitched 200 | ext1,sec:room heaters` +### C117 · Σ|Δ| 1.2 · 1 certs · `hpcdb17978/gas | solid brick | pitched 200 | ext1,sec:room heaters` - [ ] `10034812814` · L 65 / E 66.16 / Δ +1.16 -### C127 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` +### C118 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` - [ ] `217061895` · L 61 / E 59.84 / Δ -1.16 -### C128 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C119 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `10002349227` · L 76 / E 77.14 / Δ +1.14 -### C129 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` +### C120 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` - [ ] `200001634005` · L 66 / E 67.11 / Δ +1.11 -### C130 · Σ|Δ| 1.1 · 1 certs · `hpcdb18250/gas | solid brick | pitched insulated` -- [ ] `5128014` · L 67 / E 65.91 / Δ -1.09 - -### C131 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +### C121 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [ ] `100071059081` · L 63 / E 64.09 / Δ +1.09 -### C132 · Σ|Δ| 1.1 · 1 certs · `hpcdb19020/gas | solid brick | pitched insulated | RR,sec:room heaters` +### C122 · Σ|Δ| 1.1 · 1 certs · `hpcdb19020/gas | solid brick | pitched insulated | RR,sec:room heaters` - [ ] `100050567367` · L 64 / E 65.07 / Δ +1.07 -### C133 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` +### C123 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` - [ ] `100011820199` · L 55 / E 56.06 / Δ +1.06 -### C134 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` +### C124 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` - [ ] `90214753` · L 83 / E 81.95 / Δ -1.05 -### C135 · Σ|Δ| 1.0 · 1 certs · `hpcdb18759/gas | sandstone with | pitched 150 | ext1,mv5,sec:room heaters` +### C125 · Σ|Δ| 1.0 · 1 certs · `hpcdb18759/gas | sandstone with | pitched 150 | ext1,mv5,sec:room heaters` - [ ] `10010159639` · L 65 / E 66.05 / Δ +1.05 -### C136 · Σ|Δ| 1.0 · 1 certs · `hpcdb19038/gas | cavity wall | pitched insulated | sec:room heaters` -- [ ] `100051248025` · L 57 / E 55.96 / Δ -1.04 +### C126 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` +- [ ] `100051051866` · L 70 / E 71.04 / Δ +1.04 -### C137 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` +### C127 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` - [ ] `10013836852` · L 100 / E 98.97 / Δ -1.03 -### C138 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` +### C128 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` - [ ] `line899` · L 73 / E 71.97 / Δ -1.03 -### C139 · Σ|Δ| 1.0 · 1 certs · `hpcdb15921/fuel28 | cavity wall | pitched 200 | sec:room heaters` +### C129 · Σ|Δ| 1.0 · 1 certs · `hpcdb15921/fuel28 | cavity wall | pitched 200 | sec:room heaters` - [ ] `100120765933` · L 57 / E 58.03 / Δ +1.03 -### C140 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` +### C130 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` - [ ] `40037847` · L 81 / E 79.98 / Δ -1.02 -### C141 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` +### C131 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` - [ ] `10070056075` · L 80 / E 78.99 / Δ -1.01 -### C142 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` +### C132 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` - [ ] `200131078` · L 86 / E 85.00 / Δ -1.00 -### C143 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` +### C133 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` - [ ] `10000245212` · L 101 / E 100.00 / Δ -1.00 -### C144 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` +### C134 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` - [ ] `15129162` · L 62 / E 61.00 / Δ -1.00 -### C145 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` +### C135 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` - [ ] `23032873` · L 73 / E 72.00 / Δ -1.00 -### C146 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` +### C136 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` - [ ] `45019020` · L 62 / E 61.01 / Δ -0.99 -### C147 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` +### C137 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` - [ ] `42065028` · L 59 / E 58.02 / Δ -0.98 -### C148 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` +### C138 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` - [ ] `10032928147` · L 77 / E 76.04 / Δ -0.96 -### C149 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` +### C139 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` - [ ] `10010678937` · L 78 / E 77.04 / Δ -0.96 -### C150 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` +### C140 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` - [ ] `100011010151` · L 62 / E 62.96 / Δ +0.96 -### C151 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` +### C141 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` +- [ ] `100050477371` · L 65 / E 64.04 / Δ -0.96 + +### C142 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` - [ ] `10032957680` · L 45 / E 45.94 / Δ +0.94 -### C152 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` +### C143 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` - [ ] `2465057465` · L 81 / E 81.93 / Δ +0.93 -### C153 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` +### C144 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` +- [ ] `100090616327` · L 63 / E 63.93 / Δ +0.93 + +### C145 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` - [ ] `100012753833` · L 74 / E 73.07 / Δ -0.93 -### C154 · Σ|Δ| 0.9 · 1 certs · `hpcdb17505/gas | cavity wall | pitched 200 | sec:room heaters` +### C146 · Σ|Δ| 0.9 · 1 certs · `hpcdb17505/gas | cavity wall | pitched 200 | sec:room heaters` - [ ] `200002626191` · L 63 / E 63.92 / Δ +0.92 -### C155 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` +### C147 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` - [ ] `100031269525` · L 53 / E 53.91 / Δ +0.91 -### C156 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` +### C148 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` - [ ] `200003725358` · L 75 / E 74.09 / Δ -0.91 -### C157 · Σ|Δ| 0.9 · 1 certs · `hpcdb18435/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +### C149 · Σ|Δ| 0.9 · 1 certs · `hpcdb18435/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` - [ ] `100060109253` · L 62 / E 62.91 / Δ +0.91 -### C158 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` +### C150 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` - [ ] `100050986162` · L 62 / E 61.10 / Δ -0.90 -### C159 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` +### C151 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` - [ ] `5300000141` · L 78 / E 77.10 / Δ -0.90 -### C160 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` +### C152 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` - [ ] `100050618404` · L 73 / E 73.89 / Δ +0.89 -### C161 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` +### C153 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` - [ ] `100090476016` · L 81 / E 81.89 / Δ +0.89 -### C162 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` +### C154 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` - [ ] `10012119141` · L 45 / E 45.89 / Δ +0.89 -### C163 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` +### C155 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` - [ ] `100040938206` · L 75 / E 75.89 / Δ +0.89 -### C164 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` +### C156 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `38188474` · L 76 / E 76.87 / Δ +0.87 -### C165 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +### C157 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100061194957` · L 69 / E 69.87 / Δ +0.87 -### C166 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` +### C158 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` - [ ] `100021236527` · L 72 / E 71.13 / Δ -0.87 -### C167 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` +### C159 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` - [ ] `100040193752` · L 71 / E 71.86 / Δ +0.86 -### C168 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` +### C160 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` - [ ] `100060701552` · L 74 / E 74.86 / Δ +0.86 -### C169 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` +### C161 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` - [ ] `10070396146` · L 61 / E 60.14 / Δ -0.86 -### C170 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` +### C162 · Σ|Δ| 0.8 · 1 certs · `hpcdb15290/gas | solid brick | pitched insulated | ext2,sec:room heaters` +- [x] `200003644880` · L 59 / E 59.85 / Δ +0.85 + +### C163 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` - [ ] `100030528930` · L 74 / E 73.16 / Δ -0.84 -### C171 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` +### C164 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` - [ ] `100020982570` · L 72 / E 71.17 / Δ -0.83 -### C172 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` +### C165 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` - [ ] `394024487` · L 75 / E 74.17 / Δ -0.83 -### C173 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` +### C166 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` - [ ] `217070698` · L 78 / E 78.83 / Δ +0.83 -### C174 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` +### C167 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` - [ ] `77022508` · L 69 / E 68.18 / Δ -0.82 -### C175 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched 270 | ext1,sec:room heaters` +### C168 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched 270 | ext1,sec:room heaters` - [ ] `10024298029` · L 72 / E 72.82 / Δ +0.82 -### C176 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` +### C169 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` - [ ] `100040259104` · L 68 / E 68.82 / Δ +0.82 -### C177 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` +### C170 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` - [ ] `100031399026` · L 70 / E 70.81 / Δ +0.81 -### C178 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` +### C171 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` - [ ] `10009645698` · L 67 / E 67.81 / Δ +0.81 -### C179 · Σ|Δ| 0.8 · 1 certs · `hpcdb16136/gas | cavity wall | pitched insulated` -- [ ] `100011594820` · L 70 / E 69.19 / Δ -0.81 - -### C180 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` +### C172 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` - [ ] `100080818887` · L 56 / E 55.19 / Δ -0.81 -### C181 · Σ|Δ| 0.8 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | sec:room heaters` +### C173 · Σ|Δ| 0.8 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | sec:room heaters` - [ ] `72103702` · L 70 / E 70.80 / Δ +0.80 -### C182 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` +### C174 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100012374381` · L 69 / E 69.80 / Δ +0.80 -### C183 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` +### C175 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` - [ ] `100012350270` · L 78 / E 77.20 / Δ -0.80 -### C184 · Σ|Δ| 0.8 · 1 certs · `hpcdb17956/gas | sandstone as | pitched insulated` -- [ ] `100010434688` · L 72 / E 71.20 / Δ -0.80 - -### C185 · Σ|Δ| 0.8 · 1 certs · `h104/gas | sandstone as | pitched insulated | ext1` -- [ ] `100050413774` · L 63 / E 62.21 / Δ -0.79 - -### C186 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` +### C176 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` - [ ] `100061616915` · L 63 / E 62.22 / Δ -0.78 -### C187 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` +### C177 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` - [ ] `line71` · L 74 / E 74.77 / Δ +0.77 -### C188 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` +### C178 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` - [ ] `100011603934` · L 72 / E 71.23 / Δ -0.77 -### C189 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` +### C179 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` - [ ] `24030987` · L 73 / E 73.76 / Δ +0.76 -### C190 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` +### C180 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` - [ ] `100010866608` · L 71 / E 70.24 / Δ -0.76 -### C191 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` +### C181 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` - [ ] `100090399615` · L 67 / E 67.75 / Δ +0.75 -### C192 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` +### C182 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` - [ ] `100062174575` · L 46 / E 46.75 / Δ +0.75 -### C193 · Σ|Δ| 0.7 · 1 certs · `hpcdb19082/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +### C183 · Σ|Δ| 0.7 · 1 certs · `hpcdb19082/gas | cavity wall | pitched 300 | ext1,sec:room heaters` - [ ] `63015070` · L 69 / E 69.74 / Δ +0.74 -### C194 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` +### C184 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `10012341135` · L 79 / E 79.73 / Δ +0.73 -### C195 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +### C185 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` - [ ] `100091005853` · L 70 / E 69.27 / Δ -0.73 -### C196 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` +### C186 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` - [ ] `100021533514` · L 71 / E 71.73 / Δ +0.73 -### C197 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` +### C187 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` - [ ] `5062075` · L 69 / E 69.72 / Δ +0.72 -### C198 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` +### C188 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100040813308` · L 62 / E 62.72 / Δ +0.72 -### C199 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` +### C189 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` - [ ] `38105600` · L 68 / E 67.28 / Δ -0.72 -### C200 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` +### C190 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` - [ ] `line255` · L 72 / E 71.29 / Δ -0.71 -### C201 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` +### C191 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` - [ ] `5300047580` · L 69 / E 68.30 / Δ -0.70 -### C202 · Σ|Δ| 0.7 · 1 certs · `hpcdb18559/gas | cavity wall | pitched 75 | consv2,sec:room heaters` +### C192 · Σ|Δ| 0.7 · 1 certs · `hpcdb18559/gas | cavity wall | pitched 75 | consv2,sec:room heaters` - [ ] `10010610915` · L 69 / E 69.69 / Δ +0.69 -### C203 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` +### C193 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` - [ ] `100110433403` · L 69 / E 68.32 / Δ -0.68 -### C204 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` +### C194 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` - [ ] `10093416558` · L 79 / E 78.32 / Δ -0.68 -### C205 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` +### C195 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` - [ ] `100050958217` · L 68 / E 68.68 / Δ +0.68 -### C206 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` +### C196 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` - [ ] `100022667797` · L 68 / E 67.32 / Δ -0.68 -### C207 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C197 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100030528925` · L 78 / E 78.65 / Δ +0.65 -### C208 · Σ|Δ| 0.6 · 1 certs · `h691/elec | timber frame | pitched insulated | ext1,sec:room heaters,whw909` +### C198 · Σ|Δ| 0.6 · 1 certs · `h691/elec | timber frame | pitched insulated | ext1,sec:room heaters,whw909` - [ ] `10094257000` · L 55 / E 55.65 / Δ +0.65 -### C209 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` +### C199 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` - [ ] `100110300037` · L 74 / E 73.35 / Δ -0.65 -### C210 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` +### C200 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` - [ ] `217092450` · L 52 / E 52.64 / Δ +0.64 -### C211 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` +### C201 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` - [ ] `100061164545` · L 72 / E 71.36 / Δ -0.64 -### C212 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` +### C202 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` - [ ] `100051075936` · L 71 / E 70.36 / Δ -0.64 -### C213 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` +### C203 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` - [ ] `100011565830` · L 72 / E 72.64 / Δ +0.64 -### C214 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` +### C204 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` - [ ] `61010956` · L 75 / E 74.37 / Δ -0.63 -### C215 · Σ|Δ| 0.6 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` -- [ ] `10091707271` · L 41 / E 41.63 / Δ +0.63 - -### C216 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` +### C205 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` - [ ] `100110752514` · L 67 / E 67.62 / Δ +0.62 -### C217 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` +### C206 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` - [ ] `100012534027` · L 65 / E 64.38 / Δ -0.62 -### C218 · Σ|Δ| 0.6 · 1 certs · `hpcdb19094/gas | sandstone as | pitched 270 | ext2,sec:room heaters` +### C207 · Σ|Δ| 0.6 · 1 certs · `hpcdb19094/gas | sandstone as | pitched 270 | ext2,sec:room heaters` - [ ] `10070089948` · L 64 / E 64.60 / Δ +0.60 -### C219 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` +### C208 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` - [ ] `34080035` · L 77 / E 76.41 / Δ -0.59 -### C220 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` +### C209 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` - [ ] `21032732` · L 69 / E 69.59 / Δ +0.59 -### C221 · Σ|Δ| 0.6 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` -- [ ] `100090616327` · L 63 / E 63.59 / Δ +0.59 - -### C222 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` +### C210 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100060562056` · L 66 / E 65.41 / Δ -0.59 -### C223 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` +### C211 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` - [ ] `100091086558` · L 79 / E 79.58 / Δ +0.58 -### C224 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` +### C212 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` - [ ] `line599` · L 74 / E 73.42 / Δ -0.58 -### C225 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` +### C213 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` - [ ] `100020407741` · L 72 / E 71.42 / Δ -0.58 -### C226 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` +### C214 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` - [ ] `100050839457` · L 70 / E 70.57 / Δ +0.57 -### C227 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` +### C215 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` - [ ] `42105250` · L 59 / E 59.57 / Δ +0.57 -### C228 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` +### C216 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` - [ ] `77200509` · L 69 / E 69.57 / Δ +0.57 -### C229 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` +### C217 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` - [ ] `200040534` · L 65 / E 65.56 / Δ +0.56 -### C230 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` +### C218 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` - [ ] `100062527568` · L 61 / E 61.56 / Δ +0.56 -### C231 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` +### C219 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` - [ ] `100100268900` · L 69 / E 69.56 / Δ +0.56 -### C232 · Σ|Δ| 0.6 · 1 certs · `hpcdb15100/gas | cavity wall | pitched unknown | sec:room heaters` +### C220 · Σ|Δ| 0.6 · 1 certs · `hpcdb15100/gas | cavity wall | pitched unknown | sec:room heaters` - [ ] `100031166296` · L 58 / E 58.55 / Δ +0.55 -### C233 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` +### C221 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` - [ ] `90036914` · L 60 / E 60.55 / Δ +0.55 -### C234 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` +### C222 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` - [ ] `10004742671` · L 70 / E 69.46 / Δ -0.54 -### C235 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` +### C223 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` - [ ] `100010657450` · L 75 / E 75.54 / Δ +0.54 -### C236 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` +### C224 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` - [ ] `100061834344` · L 71 / E 70.46 / Δ -0.54 -### C237 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` +### C225 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` - [ ] `4510097194` · L 70 / E 70.53 / Δ +0.53 -### C238 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` +### C226 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` - [ ] `100010913220` · L 72 / E 72.53 / Δ +0.53 -### C239 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` +### C227 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` - [ ] `43074051` · L 63 / E 62.48 / Δ -0.52 -### C240 · Σ|Δ| 0.5 · 1 certs · `h104/gas | cavity wall | pitched 300` +### C228 · Σ|Δ| 0.5 · 1 certs · `h104/gas | cavity wall | pitched 300` - [ ] `100010723814` · L 69 / E 69.52 / Δ +0.52 -### C241 · Σ|Δ| 0.5 · 1 certs · `hpcdb16137/gas | cavity wall | (another dwelling` +### C229 · Σ|Δ| 0.5 · 1 certs · `hpcdb16137/gas | cavity wall | (another dwelling` - [ ] `100020955792` · L 77 / E 77.52 / Δ +0.52 -### C242 · Σ|Δ| 0.5 · 1 certs · `hpcdb19079/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +### C230 · Σ|Δ| 0.5 · 1 certs · `hpcdb19079/gas | cavity wall | pitched 200 | ext1,sec:room heaters` - [ ] `77172223` · L 65 / E 65.52 / Δ +0.52 -### C243 · Σ|Δ| 0.5 · 1 certs · `hpcdb10242/gas | granite or | pitched insulated | RR,sec:room heaters` +### C231 · Σ|Δ| 0.5 · 1 certs · `hpcdb10242/gas | granite or | pitched insulated | RR,sec:room heaters` - [ ] `100051245439` · L 62 / E 61.48 / Δ -0.52 -### C244 · Σ|Δ| 0.5 · 1 certs · `hpcdb10328/gas | cavity wall | (another dwelling` +### C232 · Σ|Δ| 0.5 · 1 certs · `hpcdb10328/gas | cavity wall | (another dwelling` - [ ] `100012553958` · L 67 / E 66.48 / Δ -0.52 -### C245 · Σ|Δ| 0.5 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` +### C233 · Σ|Δ| 0.5 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` - [ ] `200004522639` · L 37 / E 36.48 / Δ -0.52 -### C246 · Σ|Δ| 0.5 · 1 certs · `hpcdb10033/gas | cavity wall | pitched 200 | ext2,sec:room heaters` +### C234 · Σ|Δ| 0.5 · 1 certs · `hpcdb10033/gas | cavity wall | pitched 200 | ext2,sec:room heaters` - [ ] `100110108632` · L 63 / E 63.51 / Δ +0.51 -### C247 · Σ|Δ| 0.5 · 1 certs · `h109/gas | cavity wall | pitched 270 | consv2,ext1,sec:room heaters` +### C235 · Σ|Δ| 0.5 · 1 certs · `h109/gas | cavity wall | pitched 270 | consv2,ext1,sec:room heaters` - [ ] `100091102581` · L 65 / E 65.51 / Δ +0.51 -### C248 · Σ|Δ| 0.5 · 1 certs · `hpcdb19008/gas | cavity wall | pitched 150 | ext1,sec:room heaters` +### C236 · Σ|Δ| 0.5 · 1 certs · `hpcdb19008/gas | cavity wall | pitched 150 | ext1,sec:room heaters` - [ ] `10002326688` · L 69 / E 68.50 / Δ -0.50 -### C249 · Σ|Δ| 0.5 · 1 certs · `h129/fuel28 | granite or | pitched 200 | ext2,sec:room heaters` +### C237 · Σ|Δ| 0.5 · 1 certs · `h129/fuel28 | granite or | pitched 200 | ext2,sec:room heaters` - [ ] `10023132869` · L 46 / E 45.50 / Δ -0.50 -## Resolved ≤0.5 (742 certs — no action) +## Resolved ≤0.5 (755 certs — no action)
expand @@ -786,7 +749,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `28012066` · L 71 / E 71.48 / Δ +0.48 · `hpcdb16212/gas | cavity wall | pitched 400+` - [x] `74057326` · L 73 / E 72.52 / Δ -0.48 · `h691/elec | solid brick | pitched 270 | whw909` - [x] `34087745` · L 68 / E 67.52 / Δ -0.48 · `hpcdb10243/gas | solid brick | (another dwelling | ext1` -- [x] `61016813` · L 72 / E 71.52 / Δ -0.48 · `hpcdb17590/gas | sandstone as | pitched insulated` - [x] `33042105` · L 54 / E 54.48 / Δ +0.48 · `h691/elec | cavity wall | pitched 100 | whw903` - [x] `100040286465` · L 65 / E 64.52 / Δ -0.48 · `hpcdb16210/gas | cavity wall | pitched 175 | ext2,sec:room heaters` - [x] `10034663764` · L 74 / E 74.48 / Δ +0.48 · `h104/gas | cavity wall | pitched 350 | ext1` @@ -822,7 +784,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100071073344` · L 73 / E 73.46 / Δ +0.46 · `hpcdb10244/gas | cavity wall | (another dwelling | sec:room heaters` - [x] `100091287350` · L 67 / E 67.46 / Δ +0.46 · `hpcdb17507/gas | solid brick | pitched insulated` - [x] `10023324935` · L 72 / E 72.46 / Δ +0.46 · `h104/gas | cavity wall | pitched insulated` -- [x] `12027355` · L 70 / E 69.54 / Δ -0.46 · `hpcdb1838/gas | solid brick | pitched insulated | ext1` - [x] `1775072187` · L 70 / E 69.54 / Δ -0.46 · `hpcdb15273/gas | timber frame | flat limited` - [x] `5870069932` · L 73 / E 72.54 / Δ -0.46 · `hpcdb17483/gas | cavity wall | pitched insulated | PV` - [x] `10033057673` · L 77 / E 76.54 / Δ -0.46 · `hpcdb18204/gas | cavity wall | pitched 250` @@ -857,7 +818,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `50101945` · L 75 / E 74.56 / Δ -0.44 · `hpcdb10243/gas | timber frame | (another dwelling | ext1` - [x] `10032778242` · L 65 / E 65.44 / Δ +0.44 · `hpcdb9209/gas | sandstone as | pitched 100` - [x] `40002036` · L 64 / E 63.56 / Δ -0.44 · `hpcdb17904/gas | cavity wall | pitched no` -- [x] `200004695006` · L 69 / E 68.56 / Δ -0.44 · `hpcdb10243/gas | sandstone as | pitched insulated` - [x] `100010170141` · L 61 / E 61.44 / Δ +0.44 · `hpcdb4045/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [x] `100090412407` · L 71 / E 70.56 / Δ -0.44 · `hpcdb18908/gas | cavity wall | pitched 200` - [x] `10070623452` · L 84 / E 84.44 / Δ +0.44 · `hpcdb18616/gas | cavity wall | (another dwelling` @@ -870,6 +830,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `39036600` · L 72 / E 72.43 / Δ +0.43 · `hpcdb18225/gas | cavity wall | pitched 400 | mv2` - [x] `100021219619` · L 69 / E 68.57 / Δ -0.43 · `hpcdb18559/gas | solid brick | pitched 100` - [x] `100100579892` · L 71 / E 71.43 / Δ +0.43 · `hpcdb10244/gas | cavity wall | pitched 400+` +- [x] `5128014` · L 67 / E 66.57 / Δ -0.43 · `hpcdb18250/gas | solid brick | pitched insulated` - [x] `200000795879` · L 58 / E 57.57 / Δ -0.43 · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` - [x] `39096576` · L 82 / E 81.57 / Δ -0.43 · `hpcdb17617/gas | timber frame | pitched 400+` - [x] `1775045933` · L 69 / E 69.43 / Δ +0.43 · `hpcdb8180/gas | cavity wall | pitched 150` @@ -887,6 +848,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `10023449405` · L 59 / E 58.58 / Δ -0.42 · `hpcdb18219/gas | granite or | pitched insulated | consv3,ext1,sec:room heaters` - [x] `47237825` · L 79 / E 79.42 / Δ +0.42 · `hpcdb15707/gas | cavity wall | (another dwelling` - [x] `100010265441` · L 69 / E 69.42 / Δ +0.42 · `hpcdb16839/gas | cavity wall | pitched 200` +- [x] `666329` · L 69 / E 69.42 / Δ +0.42 · `hpcdb10599/fuel28 | sandstone as | pitched insulated | ext2,sec:room heaters` - [x] `100010197780` · L 65 / E 65.42 / Δ +0.42 · `hpcdb1839/gas | cavity wall | pitched 75 | sec:room heaters` - [x] `100100991435` · L 74 / E 74.42 / Δ +0.42 · `hpcdb18907/gas | cavity wall | (another dwelling` - [x] `100070537860` · L 91 / E 91.42 / Δ +0.42 · `hpcdb18225/gas | cavity wall | pitched 400+ | PV,sec:room heaters` @@ -1014,6 +976,8 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100110515241` · L 64 / E 63.66 / Δ -0.34 · `hpcdb18559/gas | solid brick | pitched insulated | ext1,sec:room heaters` - [x] `100010779964` · L 72 / E 72.34 / Δ +0.34 · `hpcdb17683/gas | sandstone as | pitched 75` - [x] `64106486` · L 72 / E 71.66 / Δ -0.34 · `hpcdb17926/fuel27 | timber frame | pitched 270 | ext1` +- [x] `200002819281` · L 72 / E 71.66 / Δ -0.34 · `h104/gas | solid brick | pitched insulated | RR,ext1` +- [x] `12027355` · L 70 / E 70.33 / Δ +0.33 · `hpcdb1838/gas | solid brick | pitched insulated | ext1` - [x] `100120926050` · L 71 / E 70.67 / Δ -0.33 · `hpcdb18514/gas | cavity wall | pitched 175 | ext2` - [x] `100012548450` · L 74 / E 74.33 / Δ +0.33 · `hpcdb10338/gas | cavity wall | (another dwelling` - [x] `10012184174` · L 75 / E 74.67 / Δ -0.33 · `hpcdb19006/gas | solid brick | pitched insulated` @@ -1040,6 +1004,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `21082835` · L 78 / E 77.69 / Δ -0.31 · `hpcdb16137/gas | system built | pitched 270` - [x] `100070126788` · L 58 / E 57.69 / Δ -0.31 · `hpcdb18090/gas | system built | pitched 75 | sec:room heaters` - [x] `100010997844` · L 71 / E 71.31 / Δ +0.31 · `hpcdb18651/gas | cavity wall | pitched insulated` +- [x] `100051275257` · L 61 / E 61.31 / Δ +0.31 · `hpcdb19007/gas | sandstone as | pitched insulated | RR,ext1` - [x] `72207515` · L 71 / E 70.69 / Δ -0.31 · `hpcdb17973/gas | cavity wall | (another dwelling | sec:room heaters` - [x] `100070312027` · L 72 / E 71.69 / Δ -0.31 · `hpcdb18908/gas | solid brick | pitched 270 | ext2,sec:room heaters` - [x] `100071105301` · L 72 / E 72.31 / Δ +0.31 · `hpcdb10312/gas | solid brick | pitched 150` @@ -1047,6 +1012,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100110174472` · L 74 / E 74.31 / Δ +0.31 · `hpcdb8368/gas | solid brick | pitched 175 | ext2,mv5` - [x] `100071450760` · L 55 / E 54.69 / Δ -0.31 · `h691/elec | cavity wall | (another dwelling | whw903` - [x] `207096040` · L 69 / E 69.31 / Δ +0.31 · `hpcdb18219/gas | solid brick | pitched insulated | ext1` +- [x] `200004695006` · L 69 / E 69.31 / Δ +0.31 · `hpcdb10243/gas | sandstone as | pitched insulated` - [x] `100100800577` · L 64 / E 64.31 / Δ +0.31 · `h301/coal-anth | system built | pitched 200 | whw903` - [x] `100110234047` · L 71 / E 70.70 / Δ -0.30 · `hpcdb16136/gas | cavity wall | pitched 300` - [x] `10007966883` · L 64 / E 64.30 / Δ +0.30 · `hpcdb17785/gas | solid brick | pitched 100 | ext1` @@ -1065,7 +1031,9 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100021754159` · L 57 / E 57.30 / Δ +0.30 · `hpcdb17503/gas | solid brick | pitched 100 | consv2,ext1,sec:room heaters` - [x] `200000323155` · L 74 / E 74.30 / Δ +0.30 · `hpcdb17974/gas | timber frame | pitched 100 | consv2,ext1` - [x] `422000091523` · L 71 / E 70.70 / Δ -0.30 · `hpcdb18767/gas | solid brick | pitched 50` +- [x] `100031351512` · L 65 / E 65.30 / Δ +0.30 · `hpcdb10265/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` - [x] `100040531566` · L 70 / E 69.71 / Δ -0.29 · `hpcdb15706/gas | cavity wall | pitched 75` +- [x] `100120850835` · L 59 / E 59.29 / Δ +0.29 · `hpcdb108793/elec | solid brick | pitched insulated | ext2` - [x] `100010159140` · L 77 / E 77.29 / Δ +0.29 · `hpcdb17688/gas | cavity wall | pitched 300 | PV,ext1,sec:room heaters` - [x] `77110396` · L 76 / E 75.71 / Δ -0.29 · `hpcdb18737/gas | cavity wall | pitched 200` - [x] `100080908496` · L 81 / E 80.71 / Δ -0.29 · `hpcdb19006/gas | cavity wall | (another dwelling` @@ -1082,6 +1050,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `10001235167` · L 74 / E 73.71 / Δ -0.29 · `hpcdb17645/gas | solid brick | pitched 225` - [x] `100080531660` · L 64 / E 63.71 / Δ -0.29 · `hpcdb16408/gas | cavity wall | pitched 50 | ext1` - [x] `100110515199` · L 91 / E 91.28 / Δ +0.28 · `hpcdb17741/gas | cavity wall | pitched 400+ | PV` +- [x] `61016813` · L 72 / E 72.28 / Δ +0.28 · `hpcdb17590/gas | sandstone as | pitched insulated` - [x] `200001186113` · L 82 / E 82.28 / Δ +0.28 · `h409/elec | cavity wall | pitched 270 | PV,mv2,sec:room heaters,whw903` - [x] `3040022036` · L 69 / E 69.28 / Δ +0.28 · `hpcdb17986/gas | cavity wall | (another dwelling` - [x] `100070536189` · L 75 / E 75.28 / Δ +0.28 · `hpcdb10244/gas | cavity wall | pitched insulated | PV` @@ -1102,6 +1071,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100110136322` · L 66 / E 66.27 / Δ +0.27 · `hpcdb16882/gas | cavity wall | pitched insulated | RR,ext1` - [x] `100022243530` · L 61 / E 61.27 / Δ +0.27 · `hpcdb17959/gas | solid brick | pitched 250 | sec:room heaters` - [x] `83159458` · L 77 / E 76.73 / Δ -0.27 · `hpcdb17683/gas | system built | pitched 250 | sec:room heaters` +- [x] `100031193650` · L 70 / E 69.73 / Δ -0.27 · `hpcdb15100/gas | cavity wall | pitched insulated | consv2,sec:room heaters` - [x] `100110435186` · L 75 / E 74.73 / Δ -0.27 · `hpcdb15709/gas | cavity wall | pitched 300 | PV,ext1,mv2,sec:room heaters` - [x] `38327244` · L 81 / E 80.73 / Δ -0.27 · `hpcdb17507/gas | timber frame | pitched 300 | ext1` - [x] `100031388370` · L 71 / E 71.27 / Δ +0.27 · `hpcdb16931/gas | solid brick | pitched 300 | ext2` @@ -1207,6 +1177,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100050722945` · L 67 / E 66.81 / Δ -0.19 · `hpcdb19158/gas | cavity wall | pitched insulated | ext2,sec:room heaters` - [x] `100110491552` · L 70 / E 70.19 / Δ +0.19 · `h301/coal-anth | cavity wall | (another dwelling` - [x] `100061721679` · L 71 / E 71.19 / Δ +0.19 · `hpcdb10462/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `565298` · L 68 / E 67.82 / Δ -0.18 · `hpcdb15049/gas | cavity wall | pitched insulated` - [x] `100090243980` · L 68 / E 68.18 / Δ +0.18 · `hpcdb10327/gas | cavity wall | pitched 100 | ext1` - [x] `100100328304` · L 62 / E 61.82 / Δ -0.18 · `hpcdb18768/gas | cavity wall | pitched 270 | ext1` - [x] `10001131873` · L 79 / E 78.82 / Δ -0.18 · `h402/elec | granite or | (another dwelling | sec:portable electric,whw903` @@ -1225,6 +1196,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100110589642` · L 72 / E 72.17 / Δ +0.17 · `hpcdb16137/gas | cavity wall | pitched 200` - [x] `100041131293` · L 76 / E 76.17 / Δ +0.17 · `hpcdb15502/gas | cavity wall | (another dwelling` - [x] `21072798` · L 72 / E 71.83 / Δ -0.17 · `hpcdb19007/gas | cavity wall | (another dwelling` +- [x] `10094975827` · L 66 / E 65.83 / Δ -0.17 · `hpcdb18559/gas | solid brick | pitched insulated` - [x] `10009830624` · L 78 / E 77.83 / Δ -0.17 · `hpcdb15706/gas | cavity wall | pitched 300` - [x] `line768` · L 57 / E 56.83 / Δ -0.17 · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` - [x] `39023204` · L 68 / E 68.17 / Δ +0.17 · `hpcdb18155/gas | solid brick | pitched insulated | ext2` @@ -1246,7 +1218,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100120629168` · L 70 / E 70.16 / Δ +0.16 · `hpcdb9897/gas | cavity wall | pitched 100 | consv2,ext2` - [x] `100100713371` · L 65 / E 65.16 / Δ +0.16 · `hpcdb17507/gas | cavity wall | pitched 125 | consv4` - [x] `10033058144` · L 65 / E 65.16 / Δ +0.16 · `hpcdb18560/gas | cavity wall | pitched 200 | ext1` -- [x] `100031351512` · L 65 / E 64.84 / Δ -0.16 · `hpcdb10265/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` - [x] `148007532` · L 61 / E 60.84 / Δ -0.16 · `hpcdb1396/gas | solid brick | pitched insulated | RR,consv2,ext1` - [x] `100010043608` · L 56 / E 56.16 / Δ +0.16 · `h401/elec | cavity wall | pitched 200 | PV,RR,consv2,ext1,sec:room heaters,whw903` - [x] `100022232588` · L 56 / E 56.16 / Δ +0.16 · `h102/gas | solid brick | pitched 25 | ext1` @@ -1264,6 +1235,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100051048523` · L 67 / E 67.15 / Δ +0.15 · `hpcdb17507/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [x] `551000` · L 72 / E 72.15 / Δ +0.15 · `h104/gas | cavity wall | pitched 150` - [x] `202137997` · L 69 / E 68.85 / Δ -0.15 · `hpcdb10443/gas | cavity wall | (another dwelling` +- [x] `100120881623` · L 53 / E 53.15 / Δ +0.15 · `h158/heatnet+2mains | solid brick | pitched insulated | ext4,sec:room heaters,whw903` - [x] `5870106813` · L 78 / E 78.15 / Δ +0.15 · `hpcdb17505/gas | solid brick | pitched 300` - [x] `100000056169` · L 62 / E 61.85 / Δ -0.15 · `hpcdb18559/gas | cavity wall | pitched 150 | consv2,ext1` - [x] `21029519` · L 67 / E 66.85 / Δ -0.15 · `hpcdb17983/gas | cavity wall | pitched 270 | sec:room heaters` @@ -1375,6 +1347,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `1775077083` · L 72 / E 72.10 / Δ +0.10 · `hpcdb17974/gas | cavity wall | pitched insulated | ext1` - [x] `100120918121` · L 83 / E 83.10 / Δ +0.10 · `hpcdb18618/gas | cavity wall | pitched 200 | PV,ext1` - [x] `200000766345` · L 70 / E 70.10 / Δ +0.10 · `hpcdb18827/gas | sandstone as | pitched 270 | ext1,sec:room heaters` +- [x] `100050413774` · L 63 / E 63.10 / Δ +0.10 · `h104/gas | sandstone as | pitched insulated | ext1` - [x] `100021531772` · L 68 / E 68.10 / Δ +0.10 · `hpcdb18560/gas | solid brick | pitched 100 | ext1` - [x] `100020596099` · L 50 / E 49.90 / Δ -0.10 · `hpcdb17550/gas | solid brick | pitched insulated | sec:room heaters` - [x] `38191704` · L 73 / E 73.10 / Δ +0.10 · `hpcdb18107/gas | cavity wall | pitched 125 | consv3` @@ -1405,6 +1378,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100091367939` · L 62 / E 62.08 / Δ +0.08 · `h102/gas | cavity wall | pitched 150 | ext2,sec:room heaters` - [x] `100110175491` · L 74 / E 74.08 / Δ +0.08 · `h102/gas | cavity wall | pitched 150 | ext1` - [x] `10011830488` · L 75 / E 75.08 / Δ +0.08 · `h102/gas | cavity wall | pitched insulated | consv2` +- [x] `line621` · L 78 / E 78.07 / Δ +0.07 · `hpcdb17679/gas | solid brick | pitched insulated` - [x] `11063823` · L 66 / E 66.07 / Δ +0.07 · `hpcdb17507/gas | cavity wall | pitched unknown` - [x] `21093278` · L 73 / E 72.93 / Δ -0.07 · `hpcdb16573/gas | cavity wall | pitched 100` - [x] `100010835776` · L 69 / E 68.93 / Δ -0.07 · `hpcdb17942/gas | cavity wall | pitched 270 | sec:room heaters` @@ -1417,6 +1391,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100011465293` · L 47 / E 46.93 / Δ -0.07 · `h115/gas | cavity wall | pitched insulated | ext1` - [x] `line77` · L 76 / E 76.07 / Δ +0.07 · `h401/elec | cavity wall | (another dwelling | sec:portable electric,whw903` - [x] `100061690837` · L 75 / E 75.07 / Δ +0.07 · `hpcdb18862/gas | cavity wall | pitched 50` +- [x] `100010434688` · L 72 / E 72.07 / Δ +0.07 · `hpcdb17956/gas | sandstone as | pitched insulated` - [x] `6077577` · L 83 / E 82.93 / Δ -0.07 · `hpcdb16840/gas | cavity wall | (another dwelling` - [x] `48102004` · L 71 / E 70.94 / Δ -0.06 · `hpcdb17501/gas | solid brick | pitched insulated` - [x] `10032999260` · L 76 / E 76.06 / Δ +0.06 · `hpcdb18619/gas | cavity wall | pitched 150` @@ -1426,7 +1401,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `50034918` · L 77 / E 77.06 / Δ +0.06 · `hpcdb16777/gas | cavity wall | pitched 200` - [x] `100061621130` · L 25 / E 24.94 / Δ -0.06 · `h102/fuel27 | timber frame | pitched 100 | RR,ext2,sec:room heaters` - [x] `100121228675` · L 60 / E 60.06 / Δ +0.06 · `h301/coal-anth | sandstone as | (another dwelling` -- [x] `100051275257` · L 61 / E 61.06 / Δ +0.06 · `hpcdb19007/gas | sandstone as | pitched insulated | RR,ext1` +- [x] `100051248025` · L 57 / E 56.94 / Δ -0.06 · `hpcdb19038/gas | cavity wall | pitched insulated | sec:room heaters` - [x] `100040663826` · L 67 / E 66.95 / Δ -0.05 · `hpcdb17001/gas | cavity wall | pitched 200` - [x] `100110441268` · L 75 / E 75.05 / Δ +0.05 · `hpcdb10444/gas | solid brick | pitched 200` - [x] `310012948` · L 74 / E 74.05 / Δ +0.05 · `hpcdb16454/gas | cavity wall | pitched 200` @@ -1438,7 +1413,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `83122910` · L 60 / E 59.95 / Δ -0.05 · `hpcdb17985/gas | sandstone as | pitched 100 | sec:room heaters` - [x] `100050869764` · L 71 / E 70.95 / Δ -0.05 · `hpcdb10315/gas | cavity wall | pitched 150` - [x] `64107249` · L 66 / E 66.05 / Δ +0.05 · `hpcdb15706/gas | cavity wall | (another dwelling | consv2,ext1,sec:room heaters` -- [x] `200003644880` · L 59 / E 59.05 / Δ +0.05 · `hpcdb15290/gas | solid brick | pitched insulated | ext2,sec:room heaters` - [x] `10012785474` · L 75 / E 74.96 / Δ -0.04 · `hpcdb10243/gas | solid brick | (another dwelling` - [x] `100062342550` · L 62 / E 61.96 / Δ -0.04 · `h301/elec10hr | cavity wall | pitched 350` - [x] `10008919006` · L 51 / E 51.04 / Δ +0.04 · `hpcdb17055/gas | granite or | pitched no | ext1` @@ -1463,6 +1437,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100031375565` · L 70 / E 69.97 / Δ -0.03 · `hpcdb18907/gas | cavity wall | pitched 300` - [x] `100050859732` · L 57 / E 57.03 / Δ +0.03 · `h104/gas | solid brick | pitched insulated | ext3` - [x] `100010663631` · L 67 / E 67.03 / Δ +0.03 · `hpcdb17974/gas | cavity wall | pitched 100 | RR,consv4` +- [x] `100011594820` · L 70 / E 69.97 / Δ -0.03 · `hpcdb16136/gas | cavity wall | pitched insulated` - [x] `100031288765` · L 62 / E 61.97 / Δ -0.03 · `hpcdb18203/gas | cavity wall | pitched 100 | ext1,sec:room heaters` - [x] `10013290770` · L 54 / E 53.97 / Δ -0.03 · `h691/elec | cavity wall | (another dwelling | whw903` - [x] `100080918720` · L 69 / E 68.97 / Δ -0.03 · `h104/gas | cavity wall | pitched 250` @@ -1483,6 +1458,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `1775087633` · L 72 / E 72.02 / Δ +0.02 · `h104/gas | cavity wall | (another dwelling` - [x] `362182` · L 77 / E 77.02 / Δ +0.02 · `hpcdb17501/gas | sandstone with | pitched 200 | ext1` - [x] `100050737075` · L 69 / E 69.02 / Δ +0.02 · `hpcdb16841/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `10093200879` · L 71 / E 70.98 / Δ -0.02 · `hpcdb16401/gas | cavity wall | pitched insulated | mv2` - [x] `10003500583` · L 70 / E 69.98 / Δ -0.02 · `hpcdb18042/gas | cavity wall | pitched 250 | consv3,ext1,sec:room heaters` - [x] `100051199928` · L 67 / E 66.98 / Δ -0.02 · `hpcdb19094/gas | cavity wall | pitched 300` - [x] `100031526911` · L 71 / E 71.02 / Δ +0.02 · `hpcdb15502/gas | solid brick | pitched 250 | consv3,ext1,sec:room heaters` diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index a925e88dd..5c3afb4e9 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -724,6 +724,21 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-4510053280", sap_score=75, ), + # UPRN 10094975827 (corpus; no cert number lodged). RdSAP-Schema-21.0.1 + # native — TOP-FLOOR FLAT, band B, solid brick, pitched roof lodged + # thickness "NI" + description "Pitched, insulated (assumed)", electric + # room heaters. The "insulated (assumed)" Table-18 cert: presence-assumed + # insulation is NOT the §5.11.4 observed-retrofit 50 mm row (0.68) — it + # takes the Table 18 age-band default (band B pitched → 0.40), the same + # value the "ND" lodgement of this description reaches. Was engine 64.13 + # (Δ −1.87 vs lodged 66); the fix lands 65.83 → rounds to 66 = lodged. + # PINNED to the observed engine 66 = lodged. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_10094975827", + cert_num="uprn-10094975827", + sap_score=66, + ), ) diff --git a/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py b/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py index 213bf2ffb..d0bb7bacc 100644 --- a/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py +++ b/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py @@ -245,15 +245,18 @@ def test_part_geometry_floorless_part_honours_full_key_contract() -> None: assert early["cantilever_floor_area_m2"] == 0.0 -def test_roof_insulated_assumed_with_ni_thickness_uses_50mm_per_section_5_11_4() -> None: - # Arrange — 346 corpus certs lodge roof_insulation_thickness="NI" - # with descriptions like "Pitched, insulated (assumed)". The - # retrofit-insulation signal in the description must flow from - # epc.roofs[0].description through heat_transmission_from_cert - # into u_roof so the 50 mm assumption fires per RdSAP 10 §5.11.4. - # Geometry: 100 m² ground floor → top floor area also 100 m² → - # roof_area = 100 m². roof_w_per_k expected = 0.68 × 100 = 68 - # W/K (vs uninsulated 2.30 × 100 = 230 W/K). +def test_roof_insulated_assumed_with_ni_thickness_uses_table18_default() -> None: + # Arrange — corpus certs lodge roof_insulation_thickness="NI" with + # descriptions like "Pitched, insulated (assumed)". The description + # must flow from epc.roofs[0].description through + # heat_transmission_from_cert into u_roof, where "(assumed)" + # (presence assumed, not observed retrofit) routes to the Table 18 + # age-band default per RdSAP 10 §5.11.4 — band C pitched → 0.40 — + # matching the "ND" lodgement of the same description. (The bare + # "insulated" form keeps the §5.11.4 50 mm row; unit-pinned in + # test_rdsap_uvalues.) Geometry: 100 m² ground floor → top floor + # area also 100 m² → roof_area = 100 m². roof_w_per_k expected = + # 0.40 × 100 = 40 W/K (vs uninsulated 2.30 × 100 = 230 W/K). main = make_building_part( identifier="Main Dwelling", construction_age_band="C", @@ -287,7 +290,7 @@ def test_roof_insulated_assumed_with_ni_thickness_uses_50mm_per_section_5_11_4() result = heat_transmission_from_cert(epc) # Assert - assert result.roof_w_per_k == pytest.approx(68.0, abs=2.0) + assert result.roof_w_per_k == pytest.approx(40.0, abs=2.0) def test_roof_insulation_location_rafters_drives_table16_column_2_api_int_path() -> None: diff --git a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py index 20a0eeae8..567479cf0 100644 --- a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py +++ b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py @@ -196,7 +196,18 @@ _CORPUS = Path( # 0.74 -> 0.742 via the heat-pump water-heating 100% floor (App N3.7): cert # 100110101713 moves inside +-0.5 (|err| 4.97 -> 0.49). See the _MAX_SAP_MAE # log below for the paired space-heating PSR-extension + water-floor slices. -_MIN_WITHIN_HALF_SAP = 0.742 +# 0.742 -> 0.755 (MAE 0.722 -> 0.708, CO2 0.09 -> 0.075, PE 3.5 -> 3.2) via +# the "insulated (assumed)" roof Table-18 fix (RdSAP 10 §5.11.4): a pitched +# roof lodging thickness "NI" + description "insulated (assumed)" was hitting +# the §5.11.4 retrofit-50 mm row (0.68) while the SAME description lodged +# with "ND" fell through to the Table 18 age-band default (e.g. 0.40 A-G) — +# the sentinel choice is lodging-software noise, and "(assumed)" means the +# insulation PRESENCE is an age-band assumption, not an observed retrofit, +# so Table 18's "thickness cannot be determined" clause governs both forms. +# The bare "insulated" description (observed retrofit) keeps the 50 mm row. +# The 27-cert loc4+NI cohort was systematically under-rated ~1 SAP (e.g. +# 10094975827 band B -1.87 -> inside). Unit-pinned in test_rdsap_uvalues. +_MIN_WITHIN_HALF_SAP = 0.755 # 0.793 -> 0.789 via the §12 Unknown-meter + dual-electric-immersion off-peak # trigger (RdSAP 10 PDF p.62): Apartment 241 (main 691 + 903 dual immersion) # -5.38 -> -1.05. Worksheet-validated on "simulated case 48" (Elmhurst SAP 57, @@ -266,9 +277,9 @@ _MIN_WITHIN_HALF_SAP = 0.742 # oversized-PSR water eff 0.60 x 128.55% = 77.13% is floored to 100% (= # accredited Elmhurst (216)), taking the cert 68.03 -> 72.51 (|err| 4.97 -> # 0.49, now inside +-0.5). In-range heat pumps keep their > 100% water COP. -_MAX_SAP_MAE = 0.722 -_MAX_CO2_MAE_TONNES = 0.09 # t CO2 / yr vs co2_emissions_current -_MAX_PE_PER_M2_MAE = 3.5 # kWh / m2 / yr vs energy_consumption_current +_MAX_SAP_MAE = 0.708 +_MAX_CO2_MAE_TONNES = 0.075 # t CO2 / yr vs co2_emissions_current +_MAX_PE_PER_M2_MAE = 3.2 # kWh / m2 / yr vs energy_consumption_current def _load_corpus() -> list[dict[str, Any]]: From a11b10f42758ccb92ff7425a8fca4c7d1094aeaf Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 19:12:48 +0000 Subject: [PATCH 03/84] docs(skill): bank corpus-1000 findings (cost triangulation, software divergences, assumed-roof rule) Co-Authored-By: Claude Fable 5 --- .../expand-sap-accuracy-corpus/SKILL.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.claude/skills/expand-sap-accuracy-corpus/SKILL.md b/.claude/skills/expand-sap-accuracy-corpus/SKILL.md index 954264e70..25769ad4e 100644 --- a/.claude/skills/expand-sap-accuracy-corpus/SKILL.md +++ b/.claude/skills/expand-sap-accuracy-corpus/SKILL.md @@ -169,6 +169,34 @@ Pattern: `with E.session() as (ctx,page): E.goto(...); E.set_text/set_select(... lines 17/18). This drove the first campaign mapper fix — see Banked findings. ## Banked findings (fold new ones in here as the corpus grows) +- **Register cost-triangulation (no Elmhurst needed):** the register lodges + `heating_cost_current` / `hot_water_cost_current` / `lighting_cost_current` + at RETAIL prices — absolute £ never match SAP Table-12 spec prices, but for + same-fuel end-uses the RATIOS localize a divergence without a worksheet. + Normalize by lighting: `(lodged_hw/lodged_light) / (our_hw/our_light)` ≈ 1 + means our water cascade agrees with the lodging software; »1 flags the + divergent end-use. CAVEAT: the register's "hot water cost" INCLUDES the + SAP (64a) electric-shower electricity — add `instant_shower` cost to our + hw bucket before comparing on any electric-shower cert, else every + shower-outlet-type-2 cert false-positives at ratio ~2 (corpus-1000 band + triage, 36 certs, mean ratio 2.0 → 1.04 after adding (64a)). +- **Lodging-software conventions diverge from Elmhurst on two known axes** + (mark such corpus certs ⚠, don't tune): (a) out-of-range-PSR database + heat pumps — SAP 10.2 N2 footnotes 44/45 mandate the reciprocal extension + toward 100% at 2× the record's largest PSR (Elmhurst does this, golden + case 56); at least one software bills 100% direct electric + standard + schedule instead (corpus 4510053280, lodged 51 vs engine/Elmhurst-method + 75). (b) a lodged 0 extract fans — Elmhurst renders 0 as "unknown" → + Table 5 age-band default (worksheet case 46); LIG-21.0 lodgements + (calculation_software_version 10.2.2.0) honour the 0 literally (corpus + quadruplet at Δ −2.56, fans account for 1.42). +- **"insulated (assumed)" roof ≠ observed retrofit:** RdSAP renders + "(assumed)" when insulation PRESENCE is an age-band assumption — Table 18 + age default governs, for BOTH the "ND" and "NI" thickness sentinels + (which are lodging-software noise). The §5.11.4 50 mm row (U 0.68) is + only for the bare "insulated" description (observed retrofit, depth + unknown). Fixed in u_roof (corpus 74.2% → 75.5%); unit-pinned in + test_rdsap_uvalues. - **MAPPER GAP — cylinder insulation thickness dropped (RdSAP-17.0+):** the mapper carries `cylinder_size` + `cylinder_insulation_type` but NOT `cylinder_insulation_thickness` → `EpcPropertyData.sap_heating.cylinder_ From 06a2c413f56332a5604a428ae0537c7a9ee9ebb8 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 19:43:31 +0000 Subject: [PATCH 04/84] test(accuracy): ratchet 75.5% -> 77.0% via secondary-fuel collision fix on cost path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The gov-API `secondary_fuel_type` enums 5 (anthracite) / 9 (dual fuel) / 33 (coal) collide in VALUE with same-valued RdSAP-10 Table-32 codes for OTHER fuels (5=bulk LPG, 9=LPG SC11F, 33=elec 10h-low). The main-fuel boundary and the CO2/display `_secondary_fuel_cost_gbp_per_kwh` already canonicalise these via `canonical_fuel_code`, but the SAP-DRIVING `_fuel_cost` cascade had a SEPARATE inline secondary rate that passed the raw enum straight to the price lookup — so the two paths diverged and the cost path silently mis-priced. Anthracite (enum 5) was billed at the bulk-LPG code-5 rate 12.19 p/kWh instead of 3.64 — a 3x over-cost on the secondary that under-rated every solid-fuel-secondary dwelling. Worst: corpus cert 100050355518 (semi, 2 extensions, anthracite room-heater secondary) lodged 36 / engine 20.8 -> 35.5. Its CO2/PE already matched lodged (the demand cascade was right) — a pure cost-side gap, which is what localised it. Fix: canonicalise `secondary_fuel` before the Table-32 lookup in `_fuel_cost`, mirroring the main-fuel boundary. 55 corpus certs carry a colliding secondary. Gauge: within-0.5 75.5% -> 77.0%, SAP MAE 0.708 -> 0.668 (floors ratcheted). The prior enum-9 test only guarded the display helper; new test_fuel_cost_secondary_colliding_fuel_priced_at_canonical_rate pins the _fuel_cost cost path directly. RealCertExpectation pinned for 100050355518 (36 = lodged). Co-Authored-By: Claude Fable 5 --- .../uprn_100050355518/epc.json | 700 ++++++++++++++++++ .../sap10_calculator/rdsap/cert_to_inputs.py | 11 +- scripts/corpus_1000/worklist.md | 572 +++++++------- .../rdsap/test_cert_to_inputs.py | 40 + .../test_real_cert_sap_accuracy.py | 17 + .../epc_client/test_sap_accuracy_corpus.py | 15 +- 6 files changed, 1051 insertions(+), 304 deletions(-) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050355518/epc.json diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050355518/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050355518/epc.json new file mode 100644 index 000000000..1b70bbe6c --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050355518/epc.json @@ -0,0 +1,700 @@ +{ + "uprn": 100050355518, + "roofs": [ + { + "description": "Pitched, 200 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + { + "description": "Pitched, limited insulation", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "walls": [ + { + "description": "Cavity wall, as built, no insulation (assumed)", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "floors": [ + { + "description": "Suspended, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Partial double glazing", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + }, + "addendum": { + "addendum_numbers": [ + 15 + ], + "cavity_fill_recommended": "true" + }, + "lighting": { + "description": "Below average lighting efficiency", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "postcode": "BD23 1BG", + "hot_water": { + "description": "From main system, no cylinder thermostat", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "post_town": "SKIPTON", + "psv_count": 0, + "built_form": 2, + "created_at": "2026-05-18 08:00:25", + "door_count": 1, + "region_code": 7, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 2, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 2 + }, + { + "shower_wwhrs": 1, + "shower_outlet_type": 2 + } + ], + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "N", + "secondary_fuel_type": 5, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "N", + "heat_emitter_type": 1, + "main_heating_number": 1, + "main_heating_control": 2102, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 117, + "central_heating_pump_age": 0, + "main_heating_data_source": 2 + } + ], + "immersion_heating_type": "NA", + "secondary_heating_type": 631, + "cylinder_insulation_type": 2, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 80 + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 0.4, + "window_height": 1.18, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 5.03, + "window_height": 1.72, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.19, + "window_height": 1, + "draught_proofed": "false", + "window_location": 2, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.74, + "window_height": 2.05, + "draught_proofed": "false", + "window_location": 2, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 2, + "glazing_type": 3, + "window_width": 0.6, + "window_height": 0.9, + "draught_proofed": "false", + "window_location": 2, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 2, + "glazing_type": 3, + "window_width": 0.6, + "window_height": 0.9, + "draught_proofed": "false", + "window_location": 2, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 2.34, + "window_height": 1.18, + "draught_proofed": "false", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.79, + "window_height": 2.06, + "draught_proofed": "false", + "window_location": 2, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 5.03, + "window_height": 1.23, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 1.11, + "window_height": 1.17, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.19, + "window_height": 1, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.18, + "window_height": 1.15, + "draught_proofed": "false", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.1, + "window_height": 1, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.66, + "window_height": 1.17, + "draught_proofed": "false", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Semi-detached house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "26 Regent Crescent", + "assessment_type": "RdSAP", + "completion_date": "2026-05-18", + "inspection_date": "2026-05-15", + "extensions_count": 2, + "measurement_type": 1, + "open_flues_count": 0, + "total_floor_area": 122, + "transaction_type": 15, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 5, + "other_flues_count": 0, + "registration_date": "2026-05-18", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_diverter": "false", + "pv_connection": 0, + "pv_battery_count": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false", + "is_hydro_output_connected_to_dwelling_meter": "false" + }, + "secondary_heating": { + "description": "Room heaters, anthracite", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 1, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 230, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.53, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 35.63, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 6.09, + "quantity": "metres" + }, + "floor_construction": 2, + "heat_loss_perimeter": { + "value": 7.95, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.38, + "quantity": "metres" + }, + "total_floor_area": { + "value": 35.63, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 6.09, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 13.37, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "C", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm", + "wall_insulation_thickness": "NI" + }, + { + "identifier": "Extension 1", + "wall_dry_lined": "N", + "wall_thickness": 320, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.29, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 15.62, + "quantity": "square metres" + }, + "party_wall_length": 0, + "floor_construction": 2, + "heat_loss_perimeter": { + "value": 7.95, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.24, + "quantity": "metres" + }, + "total_floor_area": { + "value": 15.62, + "quantity": "square metres" + }, + "party_wall_length": 0, + "heat_loss_perimeter": { + "value": 11.19, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "C", + "party_wall_construction": "NA", + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm", + "wall_insulation_thickness": "NI" + }, + { + "identifier": "Extension 2", + "wall_dry_lined": "N", + "wall_thickness": 320, + "floor_heat_loss": 7, + "roof_construction": 8, + "wall_construction": 4, + "building_part_number": 3, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.86, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 19.28, + "quantity": "square metres" + }, + "party_wall_length": 0, + "floor_construction": 2, + "heat_loss_perimeter": { + "value": 12.66, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "C", + "party_wall_construction": "NA", + "wall_thickness_measured": "Y", + "roof_insulation_location": 7, + "wall_insulation_thickness": "NI", + "sloping_ceiling_insulation_thickness": "AB" + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 5, + "heating_cost_current": { + "value": 3523, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 12, + "energy_rating_average": 60, + "energy_rating_current": 36, + "lighting_cost_current": { + "value": 84, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, no room thermostat", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "blocked_chimneys_count": 1, + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 1387, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 574, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 260, + "indicative_cost": "\u00a3900 - \u00a31,200", + "improvement_type": "A2", + "improvement_details": { + "improvement_number": 45 + }, + "improvement_category": 5, + "energy_performance_rating": 39, + "environmental_impact_rating": 30 + }, + { + "sequence": 2, + "typical_saving": 606, + "indicative_cost": "\u00a3900 - \u00a31,500", + "improvement_type": "B", + "improvement_details": { + "improvement_number": 6 + }, + "improvement_category": 5, + "energy_performance_rating": 47, + "environmental_impact_rating": 38 + }, + { + "sequence": 3, + "typical_saving": 251, + "indicative_cost": "\u00a35,000 - \u00a310,000", + "improvement_type": "W1", + "improvement_details": { + "improvement_number": 57 + }, + "improvement_category": 5, + "energy_performance_rating": 51, + "environmental_impact_rating": 42 + }, + { + "sequence": 4, + "typical_saving": 134, + "indicative_cost": "\u00a3150 - \u00a3250", + "improvement_type": "D", + "improvement_details": { + "improvement_number": 10 + }, + "improvement_category": 5, + "energy_performance_rating": 53, + "environmental_impact_rating": 44 + }, + { + "sequence": 5, + "typical_saving": 276, + "indicative_cost": "\u00a3220 - \u00a3250", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 12 + }, + "improvement_category": 5, + "energy_performance_rating": 57, + "environmental_impact_rating": 49 + }, + { + "sequence": 6, + "typical_saving": 629, + "indicative_cost": "\u00a32,200 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 5, + "energy_performance_rating": 67, + "environmental_impact_rating": 61 + }, + { + "sequence": 7, + "typical_saving": 197, + "indicative_cost": "\u00a34,500 - \u00a36,000", + "improvement_type": "O", + "improvement_details": { + "improvement_number": 8 + }, + "improvement_category": 5, + "energy_performance_rating": 70, + "environmental_impact_rating": 66 + }, + { + "sequence": 8, + "typical_saving": 233, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 74, + "environmental_impact_rating": 67 + } + ], + "co2_emissions_potential": 4.6, + "energy_rating_potential": 74, + "lighting_cost_potential": { + "value": 84, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0.1", + "alternative_improvements": [ + { + "sequence": 1, + "typical_saving": 172, + "improvement_type": "Q2", + "improvement_details": { + "improvement_number": 55 + }, + "improvement_category": 6, + "energy_performance_rating": 50, + "environmental_impact_rating": 40 + }, + { + "sequence": 2, + "typical_saving": 774, + "improvement_type": "J2", + "improvement_details": { + "improvement_number": 54 + }, + "improvement_category": 6, + "energy_performance_rating": 64, + "environmental_impact_rating": 82 + }, + { + "sequence": 3, + "typical_saving": 828, + "improvement_type": "Z3", + "improvement_details": { + "improvement_number": 53 + }, + "improvement_category": 6, + "energy_performance_rating": 69, + "environmental_impact_rating": 66 + } + ], + "flueless_gas_fires_count": 0, + "hot_water_cost_potential": { + "value": 358, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 3736.92, + "space_heating_existing_dwelling": 24523.93 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 466, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 52, + "calculation_software_version": "4.3.74", + "energy_consumption_potential": 170, + "environmental_impact_current": 27, + "current_energy_efficiency_band": "F", + "environmental_impact_potential": 67, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 98, + "low_energy_fixed_lighting_bulbs_count": 17, + "incandescent_fixed_lighting_bulbs_count": 4 +} \ No newline at end of file diff --git a/domain/sap10_calculator/rdsap/cert_to_inputs.py b/domain/sap10_calculator/rdsap/cert_to_inputs.py index 22d379c32..104f736e4 100644 --- a/domain/sap10_calculator/rdsap/cert_to_inputs.py +++ b/domain/sap10_calculator/rdsap/cert_to_inputs.py @@ -7517,8 +7517,17 @@ def _fuel_cost( secondary_fuel = ( epc.sap_heating.secondary_fuel_type if epc.sap_heating else None ) + # Canonicalise the colliding gov-API secondary fuel enums (5 anthracite / + # 9 dual fuel / 33 coal — `_GOV_API_COLLISION_FUELS`) BEFORE the price + # lookup, exactly as the main-fuel boundary and the CO2/display + # `_secondary_fuel_cost_gbp_per_kwh` already do. Without this the raw + # same-value Table-32 lookup mis-priced e.g. anthracite (enum 5) at the + # bulk-LPG code-5 rate (12.19 vs 3.64 p/kWh) — a 3× over-cost that sank + # cert 100050355518 (lodged 36, engine 20.8). This inline cost path had + # diverged from the already-canonicalised display helper. secondary_high_rate_gbp_per_kwh = ( - table_32_unit_price_p_per_kwh(secondary_fuel) * _PENCE_TO_GBP + table_32_unit_price_p_per_kwh(canonical_fuel_code(secondary_fuel)) + * _PENCE_TO_GBP if secondary_fuel is not None else other_uses_gbp_per_kwh ) diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index 88a9e2626..24784b658 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -1,10 +1,10 @@ # RdSAP-21.0.1 corpus campaign ledger -**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **75.5%** · MAE = **0.708** (floors in test_sap_accuracy_corpus.py) +**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.0%** · MAE = **0.668** (floors in test_sap_accuracy_corpus.py) Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail engine bug · ⛔ unbuildable. Line: `uprn · lodged L / eng E / Δ · signature`. Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` (preserves statuses & `<-` notes). -## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 245 certs in 237 clusters +## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 230 certs in 222 clusters ### C001 · Σ|Δ| 23.9 · 1 certs · `hpcdb100053/elec | solid brick | (another dwelling | sec:room heaters` - ⚠ `4510053280` · L 51 / E 74.94 / Δ +23.94 <- lodged software billed out-of-range-PSR (2.031 > 2.0) PCDB 100053 as 100% direct electric; engine follows SAP10.2 N2 extension (305%), Elmhurst-validated on case 56. Pinned engine 75 in test_real_cert_sap_accuracy. @@ -12,724 +12,680 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C002 · Σ|Δ| 19.7 · 1 certs · `h301/coal-anth | cavity wall | pitched unknown | whw903` - [ ] `103001004` · L 50 / E 69.69 / Δ +19.69 <- needs Elmhurst arbitration: lodged hw £1054 vs ours £113 (single-immersion on-peak fraction + cylinder declared-loss 1.8 kWh/day vs Table-2-sized loss); register data can't decompose. Other 14 declared-loss certs match lodged; only sibling outlier is 100121325434 (C008). -### C003 · Σ|Δ| 15.2 · 1 certs · `h117/gas | cavity wall | pitched 200 | ext2,sec:room heaters` -- [ ] `100050355518` · L 36 / E 20.82 / Δ -15.18 - -### C004 · Σ|Δ| 14.5 · 1 certs · `h195/elec | system built | (another dwelling` +### C003 · Σ|Δ| 14.5 · 1 certs · `h195/elec | system built | (another dwelling` - [ ] `10012334488` · L 72 / E 86.47 / Δ +14.47 -### C005 · Σ|Δ| 13.1 · 1 certs · `hpcdb10326/gas | solid brick | pitched 75 | ext1,sec:room heaters` +### C004 · Σ|Δ| 13.1 · 1 certs · `hpcdb10326/gas | solid brick | pitched 75 | ext1,sec:room heaters` - [ ] `12109191` · L 58 / E 71.10 / Δ +13.10 -### C006 · Σ|Δ| 10.3 · 4 certs · `h691/elec | cavity wall | (another dwelling | whw909` +### C005 · Σ|Δ| 10.3 · 4 certs · `h691/elec | cavity wall | (another dwelling | whw909` - ⚠ `line279` · L 81 / E 78.44 / Δ -2.56 <- same as 10093237426 - ⚠ `line301` · L 81 / E 78.44 / Δ -2.56 <- same as 10093237426 - ⚠ `line318` · L 81 / E 78.44 / Δ -2.56 <- same as 10093237426 - ⚠ `10093237426` · L 81 / E 78.44 / Δ -2.56 <- LIG-21.0 software (calc 10.2.2.0) honours lodged 0 extract fans literally; Elmhurst-validated convention (case 46) treats 0 as unknown -> Table 5 default. Fans-as-0 experiment closes 1.42 of 2.56; residual -1.14 unexplained, same-software quadruplet. -### C007 · Σ|Δ| 10.1 · 1 certs · `h691/elec | granite or | pitched 175 | RR,ext1,whw903` +### C006 · Σ|Δ| 10.1 · 1 certs · `h691/elec | granite or | pitched 175 | RR,ext1,whw903` - [ ] `100040550095` · L 40 / E 29.87 / Δ -10.13 -### C008 · Σ|Δ| 8.7 · 1 certs · `h125/fuel28 | cavity wall | pitched 250 | consv2,sec:room heaters` +### C007 · Σ|Δ| 8.7 · 1 certs · `h125/fuel28 | cavity wall | pitched 250 | consv2,sec:room heaters` - [ ] `100121325434` · L 48 / E 56.75 / Δ +8.75 -### C009 · Σ|Δ| 8.1 · 1 certs · `hpcdb17958/gas | system built | pitched 300 | PV,ext1,mv1` +### C008 · Σ|Δ| 8.1 · 1 certs · `hpcdb17958/gas | system built | pitched 300 | PV,ext1,mv1` - [ ] `100022294004` · L 75 / E 83.13 / Δ +8.13 -### C010 · Σ|Δ| 8.0 · 1 certs · `hpcdb18760/gas | solid brick | pitched 100 | RR,ext2,sec:room heaters` -- [ ] `100010391723` · L 66 / E 57.96 / Δ -8.04 - -### C011 · Σ|Δ| 7.8 · 1 certs · `h195/elec | cavity wall | (another dwelling` +### C009 · Σ|Δ| 7.8 · 1 certs · `h195/elec | cavity wall | (another dwelling` - [ ] `10091578598` · L 71 / E 78.81 / Δ +7.81 -### C012 · Σ|Δ| 7.7 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` +### C010 · Σ|Δ| 7.7 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` - [ ] `74061136` · L 73 / E 80.72 / Δ +7.72 -### C013 · Σ|Δ| 7.1 · 1 certs · `h408/elec | cavity wall | (another dwelling | whw941` +### C011 · Σ|Δ| 7.1 · 1 certs · `h408/elec | cavity wall | (another dwelling | whw941` - [ ] `200000322700` · L 58 / E 65.05 / Δ +7.05 -### C014 · Σ|Δ| 6.7 · 1 certs · `h691/elec | solid brick | pitched 100 | RR,ext1,whw909` +### C012 · Σ|Δ| 6.7 · 1 certs · `h691/elec | solid brick | pitched 100 | RR,ext1,whw909` - [ ] `100032223878` · L 11 / E 17.67 / Δ +6.67 -### C015 · Σ|Δ| 6.6 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` +### C013 · Σ|Δ| 6.6 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` - [ ] `200004296092` · L 71 / E 64.35 / Δ -6.65 -### C016 · Σ|Δ| 6.5 · 1 certs · `h408/elec | granite or | (another dwelling | sec:portable electric,whw903` +### C014 · Σ|Δ| 6.5 · 1 certs · `h408/elec | granite or | (another dwelling | sec:portable electric,whw903` - [ ] `100121397382` · L 69 / E 75.49 / Δ +6.49 -### C017 · Σ|Δ| 6.5 · 1 certs · `h691/elec | solid brick | (another dwelling | ext1,sec:room heaters,whw903` +### C015 · Σ|Δ| 6.5 · 1 certs · `h691/elec | solid brick | (another dwelling | ext1,sec:room heaters,whw903` - [ ] `100062100640` · L 54 / E 47.51 / Δ -6.49 -### C018 · Σ|Δ| 6.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 225` +### C016 · Σ|Δ| 6.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 225` - [ ] `100050844968` · L 71 / E 65.02 / Δ -5.98 -### C019 · Σ|Δ| 5.8 · 1 certs · `hpcdb17777/gas+2mains | cavity wall | pitched insulated | ext1,sec:room heaters,whw914` +### C017 · Σ|Δ| 5.8 · 1 certs · `hpcdb17777/gas+2mains | cavity wall | pitched insulated | ext1,sec:room heaters,whw914` - [ ] `line804` · L 52 / E 57.76 / Δ +5.76 -### C020 · Σ|Δ| 5.7 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` +### C018 · Σ|Δ| 5.7 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` - [ ] `200049463` · L 69 / E 63.28 / Δ -5.72 -### C021 · Σ|Δ| 5.6 · 2 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` +### C019 · Σ|Δ| 5.6 · 2 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` - [ ] `11071248` · L 78 / E 81.86 / Δ +3.86 - [ ] `12126160` · L 69 / E 70.71 / Δ +1.71 -### C022 · Σ|Δ| 5.5 · 1 certs · `hpcdb17033/gas | cavity wall | pitched insulated | RR,ext3,sec:room heaters` -- [ ] `10090368756` · L 80 / E 74.52 / Δ -5.48 - -### C023 · Σ|Δ| 4.6 · 1 certs · `hpcdb18560/gas | solid brick | pitched no | RR` +### C020 · Σ|Δ| 4.6 · 1 certs · `hpcdb18560/gas | solid brick | pitched no | RR` - [ ] `100051233481` · L 65 / E 69.64 / Δ +4.64 -### C024 · Σ|Δ| 4.5 · 1 certs · `h691/elec | timber frame | pitched limited | RR,ext2,whw903` +### C021 · Σ|Δ| 4.5 · 1 certs · `h691/elec | timber frame | pitched limited | RR,ext2,whw903` - [ ] `100061646773` · L 68 / E 63.46 / Δ -4.54 -### C025 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` +### C022 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` - [ ] `100071010014` · L 55 / E 50.47 / Δ -4.53 -### C026 · Σ|Δ| 4.5 · 1 certs · `hpcdb17815/gas | cavity wall | flat insulated` +### C023 · Σ|Δ| 4.5 · 1 certs · `hpcdb17815/gas | cavity wall | flat insulated` - [ ] `47084930` · L 74 / E 69.51 / Δ -4.49 -### C027 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` +### C024 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` - [ ] `10093342182` · L 82 / E 77.51 / Δ -4.49 -### C028 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` +### C025 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` - [ ] `5117280` · L 76 / E 71.56 / Δ -4.44 -### C029 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` +### C026 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` - [ ] `217060420` · L 42 / E 37.58 / Δ -4.42 -### C030 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` +### C027 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` - [ ] `72399971` · L 69 / E 64.60 / Δ -4.40 -### C031 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` +### C028 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` - [ ] `10007016314` · L 57 / E 52.64 / Δ -4.36 -### C032 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` +### C029 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` - [ ] `100052159386` · L 56 / E 51.92 / Δ -4.08 -### C033 · Σ|Δ| 4.0 · 1 certs · `h191/elec | cavity wall | (another dwelling` +### C030 · Σ|Δ| 4.0 · 1 certs · `h191/elec | cavity wall | (another dwelling` - [ ] `10002272664` · L 79 / E 74.96 / Δ -4.04 -### C034 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` +### C031 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` - [ ] `100040767294` · L 43 / E 47.04 / Δ +4.04 -### C035 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` +### C032 · Σ|Δ| 3.6 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` +- [ ] `10002188054` · L 68 / E 64.42 / Δ -3.58 + +### C033 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` - [ ] `39066537` · L 78 / E 81.49 / Δ +3.49 -### C036 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` +### C034 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` - [ ] `100100137438` · L 69 / E 72.48 / Δ +3.48 -### C037 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C035 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100080122910` · L 60 / E 63.45 / Δ +3.45 -### C038 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` +### C036 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` - [ ] `452010022` · L 42 / E 38.67 / Δ -3.33 -### C039 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` +### C037 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` - [ ] `200004818752` · L 34 / E 30.73 / Δ -3.27 -### C040 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` +### C038 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` - [ ] `72351021` · L 64 / E 60.85 / Δ -3.15 -### C041 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` +### C039 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` - [ ] `22077224` · L 37 / E 33.90 / Δ -3.10 -### C042 · Σ|Δ| 3.1 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` -- [ ] `10002188054` · L 68 / E 64.93 / Δ -3.07 - -### C043 · Σ|Δ| 3.1 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` +### C040 · Σ|Δ| 3.1 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` - [ ] `100032043038` · L 74 / E 77.06 / Δ +3.06 -### C044 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` +### C041 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` - [ ] `10011740578` · L 70 / E 67.00 / Δ -3.00 -### C045 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +### C042 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` - [ ] `100110680822` · L 79 / E 76.07 / Δ -2.93 -### C046 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` +### C043 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` - [ ] `452032915` · L 75 / E 72.09 / Δ -2.91 -### C047 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` +### C044 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` - [ ] `100071306639` · L 73 / E 70.14 / Δ -2.86 -### C048 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` +### C045 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` - [ ] `100061346049` · L 55 / E 52.15 / Δ -2.85 -### C049 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` +### C046 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` - [ ] `10013008238` · L 41 / E 38.26 / Δ -2.74 -### C050 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` +### C047 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` - [ ] `10033187652` · L 70 / E 71.21 / Δ +1.21 - [ ] `200002730` · L 65 / E 64.13 / Δ -0.87 - [ ] `10023328117` · L 78 / E 78.64 / Δ +0.64 -### C051 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` +### C048 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` - [ ] `10004873253` · L 65 / E 62.29 / Δ -2.71 -### C052 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` +### C049 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` - [ ] `10090793715` · L 73 / E 75.71 / Δ +2.71 -### C053 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` +### C050 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100120745600` · L 65 / E 67.69 / Δ +2.69 -### C054 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` +### C051 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` - [ ] `100051178830` · L 63 / E 65.66 / Δ +2.66 -### C055 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` +### C052 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` - [ ] `100120018282` · L 64 / E 61.36 / Δ -2.64 -### C056 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +### C053 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` - [ ] `83035979` · L 65 / E 67.60 / Δ +2.60 -### C057 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` +### C054 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` - [ ] `10014073761` · L 75 / E 72.52 / Δ -2.48 -### C058 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` +### C055 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` - [ ] `100050964834` · L 60 / E 62.47 / Δ +2.47 -### C059 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` +### C056 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` - [ ] `100120752995` · L 71 / E 73.42 / Δ +2.42 -### C060 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` +### C057 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` - [ ] `100032230128` · L 55 / E 52.60 / Δ -2.40 -### C061 · Σ|Δ| 2.4 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` -- [ ] `100012368622` · L 39 / E 41.40 / Δ +2.40 - -### C062 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` +### C058 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` - [ ] `100000034023` · L 73 / E 70.71 / Δ -2.29 -### C063 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` +### C059 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` - [ ] `100020377671` · L 62 / E 64.23 / Δ +2.23 -### C064 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` +### C060 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` - [ ] `22027335` · L 76 / E 73.77 / Δ -2.23 -### C065 · Σ|Δ| 2.2 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` +### C061 · Σ|Δ| 2.2 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` - [ ] `80838` · L 41 / E 43.19 / Δ +2.19 -### C066 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` +### C062 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` - [ ] `48056153` · L 65 / E 62.89 / Δ -2.11 -### C067 · Σ|Δ| 2.0 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` +### C063 · Σ|Δ| 2.0 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` - [ ] `100070295212` · L 75 / E 77.01 / Δ +2.01 -### C068 · Σ|Δ| 2.0 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` -- [ ] `100100274789` · L 60 / E 62.00 / Δ +2.00 - -### C069 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` +### C064 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` - [ ] `100021924710` · L 63 / E 65.00 / Δ +2.00 -### C070 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` +### C065 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` - [ ] `100031270375` · L 69 / E 70.93 / Δ +1.93 -### C071 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` +### C066 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` - [ ] `10001118522` · L 80 / E 78.07 / Δ -1.93 -### C072 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` +### C067 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` - [ ] `10010234711` · L 81 / E 79.08 / Δ -1.92 -### C073 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` +### C068 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` - [ ] `100031768368` · L 61 / E 59.12 / Δ -1.88 -### C074 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` +### C069 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` - [ ] `4510729926` · L 73 / E 71.15 / Δ -1.85 -### C075 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` +### C070 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` - [ ] `100091329112` · L 49 / E 50.82 / Δ +1.82 -### C076 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` +### C071 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` - [ ] `100061275133` · L 76 / E 77.24 / Δ +1.24 - [ ] `207032630` · L 74 / E 73.47 / Δ -0.53 -### C077 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` +### C072 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` - [ ] `10011797347` · L 47 / E 48.77 / Δ +1.77 -### C078 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` +### C073 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` - [ ] `100022668387` · L 68 / E 66.25 / Δ -1.75 -### C079 · Σ|Δ| 1.8 · 1 certs · `hpcdb17803/gas | timber frame | pitched 100` +### C074 · Σ|Δ| 1.8 · 1 certs · `hpcdb17803/gas | timber frame | pitched 100` - [ ] `200004017091` · L 71 / E 72.75 / Δ +1.75 -### C080 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` +### C075 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` - [ ] `100100892216` · L 69 / E 67.28 / Δ -1.72 -### C081 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` +### C076 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100060878876` · L 49 / E 50.71 / Δ +1.71 -### C082 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` +### C077 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` - [ ] `22032926` · L 61 / E 62.71 / Δ +1.71 -### C083 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` +### C078 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100010942905` · L 72 / E 73.70 / Δ +1.70 -### C084 · Σ|Δ| 1.6 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` -- [ ] `10091707271` · L 41 / E 42.64 / Δ +1.64 - -### C085 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` +### C079 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` - [ ] `100030307976` · L 71 / E 69.37 / Δ -1.63 -### C086 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` +### C080 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` - [ ] `100061404488` · L 70 / E 68.38 / Δ -1.62 -### C087 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` +### C081 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` - [ ] `21067296` · L 67 / E 68.60 / Δ +1.60 -### C088 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` +### C082 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` - [ ] `5870047440` · L 58 / E 59.58 / Δ +1.58 -### C089 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` +### C083 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` - [ ] `100070450818` · L 65 / E 63.43 / Δ -1.57 -### C090 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` +### C084 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` - [ ] `100050881708` · L 70 / E 71.55 / Δ +1.55 -### C091 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` +### C085 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` - [ ] `10010254955` · L 79 / E 77.46 / Δ -1.54 -### C092 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` +### C086 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` - [ ] `3455011834` · L 69 / E 67.48 / Δ -1.52 -### C093 · Σ|Δ| 1.5 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` -- [ ] `100051109723` · L 60 / E 61.52 / Δ +1.52 +### C087 · Σ|Δ| 1.5 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` +- [ ] `100100274789` · L 60 / E 61.51 / Δ +1.51 -### C094 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` +### C088 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` - [ ] `100050852755` · L 65 / E 66.49 / Δ +1.49 -### C095 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` +### C089 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` - [ ] `100021326422` · L 70 / E 68.51 / Δ -1.49 -### C096 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` +### C090 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100050988345` · L 61 / E 59.51 / Δ -1.49 -### C097 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` +### C091 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` - [ ] `100030285758` · L 54 / E 55.48 / Δ +1.48 -### C098 · Σ|Δ| 1.5 · 1 certs · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` +### C092 · Σ|Δ| 1.5 · 1 certs · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` - [ ] `100090536443` · L 86 / E 84.52 / Δ -1.48 -### C099 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` +### C093 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` - [ ] `line80` · L 72 / E 70.56 / Δ -1.44 -### C100 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` +### C094 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` - [ ] `100080518673` · L 57 / E 58.42 / Δ +1.42 -### C101 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` +### C095 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` - [ ] `235025284` · L 69 / E 67.59 / Δ -1.41 -### C102 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` +### C096 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` - [ ] `250063088` · L 73 / E 71.60 / Δ -1.40 -### C103 · Σ|Δ| 1.4 · 1 certs · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` +### C097 · Σ|Δ| 1.4 · 1 certs · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` - [ ] `100050048691` · L 58 / E 59.39 / Δ +1.39 -### C104 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` +### C098 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` - [ ] `100110097281` · L 64 / E 65.37 / Δ +1.37 -### C105 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` +### C099 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` - [ ] `10091630692` · L 58 / E 56.63 / Δ -1.37 -### C106 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` +### C100 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` - [ ] `100031433810` · L 70 / E 68.63 / Δ -1.37 -### C107 · Σ|Δ| 1.3 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` -- [ ] `10002945522` · L 61 / E 62.32 / Δ +1.32 +### C101 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` +- [ ] `100012368622` · L 39 / E 40.32 / Δ +1.32 -### C108 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +### C102 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` - [ ] `90077194` · L 65 / E 63.69 / Δ -1.31 -### C109 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` +### C103 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` - [ ] `100031461986` · L 70 / E 71.29 / Δ +1.29 -### C110 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` +### C104 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` - [ ] `30095054` · L 46 / E 44.74 / Δ -1.26 -### C111 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` +### C105 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` - [ ] `100100055589` · L 58 / E 59.26 / Δ +1.26 -### C112 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` +### C106 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` - [ ] `100091435353` · L 65 / E 66.23 / Δ +1.23 -### C113 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` +### C107 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` - [ ] `10091070164` · L 69 / E 69.60 / Δ +0.60 - [ ] `10090927185` · L 79 / E 79.60 / Δ +0.60 -### C114 · Σ|Δ| 1.2 · 1 certs · `hpcdb16842/gas | cavity wall | pitched no | ext1,sec:room heaters` -- [ ] `100090834242` · L 53 / E 54.20 / Δ +1.20 - -### C115 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` +### C108 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` - [ ] `100100614412` · L 53 / E 51.81 / Δ -1.19 -### C116 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` +### C109 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` - [ ] `217091901` · L 62 / E 60.82 / Δ -1.18 -### C117 · Σ|Δ| 1.2 · 1 certs · `hpcdb17978/gas | solid brick | pitched 200 | ext1,sec:room heaters` -- [ ] `10034812814` · L 65 / E 66.16 / Δ +1.16 +### C110 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` +- [x] `line768` · L 57 / E 55.84 / Δ -1.16 -### C118 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` +### C111 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` - [ ] `217061895` · L 61 / E 59.84 / Δ -1.16 -### C119 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C112 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `10002349227` · L 76 / E 77.14 / Δ +1.14 -### C120 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` +### C113 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` - [ ] `200001634005` · L 66 / E 67.11 / Δ +1.11 -### C121 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +### C114 · Σ|Δ| 1.1 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` +- [ ] `200004522639` · L 37 / E 35.89 / Δ -1.11 + +### C115 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [ ] `100071059081` · L 63 / E 64.09 / Δ +1.09 -### C122 · Σ|Δ| 1.1 · 1 certs · `hpcdb19020/gas | solid brick | pitched insulated | RR,sec:room heaters` -- [ ] `100050567367` · L 64 / E 65.07 / Δ +1.07 - -### C123 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` +### C116 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` - [ ] `100011820199` · L 55 / E 56.06 / Δ +1.06 -### C124 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` +### C117 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` - [ ] `90214753` · L 83 / E 81.95 / Δ -1.05 -### C125 · Σ|Δ| 1.0 · 1 certs · `hpcdb18759/gas | sandstone with | pitched 150 | ext1,mv5,sec:room heaters` -- [ ] `10010159639` · L 65 / E 66.05 / Δ +1.05 - -### C126 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` +### C118 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` - [ ] `100051051866` · L 70 / E 71.04 / Δ +1.04 -### C127 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` +### C119 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` - [ ] `10013836852` · L 100 / E 98.97 / Δ -1.03 -### C128 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` +### C120 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` - [ ] `line899` · L 73 / E 71.97 / Δ -1.03 -### C129 · Σ|Δ| 1.0 · 1 certs · `hpcdb15921/fuel28 | cavity wall | pitched 200 | sec:room heaters` -- [ ] `100120765933` · L 57 / E 58.03 / Δ +1.03 - -### C130 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` +### C121 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` - [ ] `40037847` · L 81 / E 79.98 / Δ -1.02 -### C131 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` +### C122 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` - [ ] `10070056075` · L 80 / E 78.99 / Δ -1.01 -### C132 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` +### C123 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` - [ ] `200131078` · L 86 / E 85.00 / Δ -1.00 -### C133 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` +### C124 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` - [ ] `10000245212` · L 101 / E 100.00 / Δ -1.00 -### C134 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` +### C125 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` - [ ] `15129162` · L 62 / E 61.00 / Δ -1.00 -### C135 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` +### C126 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` - [ ] `23032873` · L 73 / E 72.00 / Δ -1.00 -### C136 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` +### C127 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` - [ ] `45019020` · L 62 / E 61.01 / Δ -0.99 -### C137 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` +### C128 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` - [ ] `42065028` · L 59 / E 58.02 / Δ -0.98 -### C138 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` +### C129 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` - [ ] `10032928147` · L 77 / E 76.04 / Δ -0.96 -### C139 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` +### C130 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` - [ ] `10010678937` · L 78 / E 77.04 / Δ -0.96 -### C140 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` +### C131 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` - [ ] `100011010151` · L 62 / E 62.96 / Δ +0.96 -### C141 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` +### C132 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` - [ ] `100050477371` · L 65 / E 64.04 / Δ -0.96 -### C142 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` +### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` +- [ ] `10002945522` · L 61 / E 61.94 / Δ +0.94 + +### C134 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` - [ ] `10032957680` · L 45 / E 45.94 / Δ +0.94 -### C143 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` +### C135 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` - [ ] `2465057465` · L 81 / E 81.93 / Δ +0.93 -### C144 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` +### C136 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` - [ ] `100090616327` · L 63 / E 63.93 / Δ +0.93 -### C145 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` +### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` - [ ] `100012753833` · L 74 / E 73.07 / Δ -0.93 -### C146 · Σ|Δ| 0.9 · 1 certs · `hpcdb17505/gas | cavity wall | pitched 200 | sec:room heaters` -- [ ] `200002626191` · L 63 / E 63.92 / Δ +0.92 - -### C147 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` +### C138 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` - [ ] `100031269525` · L 53 / E 53.91 / Δ +0.91 -### C148 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` +### C139 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` - [ ] `200003725358` · L 75 / E 74.09 / Δ -0.91 -### C149 · Σ|Δ| 0.9 · 1 certs · `hpcdb18435/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` -- [ ] `100060109253` · L 62 / E 62.91 / Δ +0.91 - -### C150 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` +### C140 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` - [ ] `100050986162` · L 62 / E 61.10 / Δ -0.90 -### C151 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` +### C141 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` - [ ] `5300000141` · L 78 / E 77.10 / Δ -0.90 -### C152 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` +### C142 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` - [ ] `100050618404` · L 73 / E 73.89 / Δ +0.89 -### C153 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` +### C143 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` - [ ] `100090476016` · L 81 / E 81.89 / Δ +0.89 -### C154 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` +### C144 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` - [ ] `10012119141` · L 45 / E 45.89 / Δ +0.89 -### C155 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` +### C145 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` - [ ] `100040938206` · L 75 / E 75.89 / Δ +0.89 -### C156 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` +### C146 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `38188474` · L 76 / E 76.87 / Δ +0.87 -### C157 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +### C147 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100061194957` · L 69 / E 69.87 / Δ +0.87 -### C158 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` +### C148 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` - [ ] `100021236527` · L 72 / E 71.13 / Δ -0.87 -### C159 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` +### C149 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` - [ ] `100040193752` · L 71 / E 71.86 / Δ +0.86 -### C160 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` +### C150 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` - [ ] `100060701552` · L 74 / E 74.86 / Δ +0.86 -### C161 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` +### C151 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` - [ ] `10070396146` · L 61 / E 60.14 / Δ -0.86 -### C162 · Σ|Δ| 0.8 · 1 certs · `hpcdb15290/gas | solid brick | pitched insulated | ext2,sec:room heaters` -- [x] `200003644880` · L 59 / E 59.85 / Δ +0.85 - -### C163 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` +### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` - [ ] `100030528930` · L 74 / E 73.16 / Δ -0.84 -### C164 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` +### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` - [ ] `100020982570` · L 72 / E 71.17 / Δ -0.83 -### C165 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` +### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` - [ ] `394024487` · L 75 / E 74.17 / Δ -0.83 -### C166 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` +### C155 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` - [ ] `217070698` · L 78 / E 78.83 / Δ +0.83 -### C167 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` +### C156 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` - [ ] `77022508` · L 69 / E 68.18 / Δ -0.82 -### C168 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched 270 | ext1,sec:room heaters` -- [ ] `10024298029` · L 72 / E 72.82 / Δ +0.82 - -### C169 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` +### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` - [ ] `100040259104` · L 68 / E 68.82 / Δ +0.82 -### C170 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` +### C158 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` - [ ] `100031399026` · L 70 / E 70.81 / Δ +0.81 -### C171 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` +### C159 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` - [ ] `10009645698` · L 67 / E 67.81 / Δ +0.81 -### C172 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` +### C160 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` - [ ] `100080818887` · L 56 / E 55.19 / Δ -0.81 -### C173 · Σ|Δ| 0.8 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | sec:room heaters` -- [ ] `72103702` · L 70 / E 70.80 / Δ +0.80 - -### C174 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` +### C161 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100012374381` · L 69 / E 69.80 / Δ +0.80 -### C175 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` +### C162 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` - [ ] `100012350270` · L 78 / E 77.20 / Δ -0.80 -### C176 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` +### C163 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` +- [ ] `100051109723` · L 60 / E 60.78 / Δ +0.78 + +### C164 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` - [ ] `100061616915` · L 63 / E 62.22 / Δ -0.78 -### C177 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` +### C165 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` - [ ] `line71` · L 74 / E 74.77 / Δ +0.77 -### C178 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` +### C166 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` - [ ] `100011603934` · L 72 / E 71.23 / Δ -0.77 -### C179 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` +### C167 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` - [ ] `24030987` · L 73 / E 73.76 / Δ +0.76 -### C180 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` +### C168 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` - [ ] `100010866608` · L 71 / E 70.24 / Δ -0.76 -### C181 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` +### C169 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` - [ ] `100090399615` · L 67 / E 67.75 / Δ +0.75 -### C182 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` +### C170 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` - [ ] `100062174575` · L 46 / E 46.75 / Δ +0.75 -### C183 · Σ|Δ| 0.7 · 1 certs · `hpcdb19082/gas | cavity wall | pitched 300 | ext1,sec:room heaters` -- [ ] `63015070` · L 69 / E 69.74 / Δ +0.74 - -### C184 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` +### C171 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `10012341135` · L 79 / E 79.73 / Δ +0.73 -### C185 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +### C172 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` - [ ] `100091005853` · L 70 / E 69.27 / Δ -0.73 -### C186 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` +### C173 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` - [ ] `100021533514` · L 71 / E 71.73 / Δ +0.73 -### C187 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` +### C174 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` - [ ] `5062075` · L 69 / E 69.72 / Δ +0.72 -### C188 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` +### C175 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100040813308` · L 62 / E 62.72 / Δ +0.72 -### C189 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` +### C176 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` - [ ] `38105600` · L 68 / E 67.28 / Δ -0.72 -### C190 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` +### C177 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` - [ ] `line255` · L 72 / E 71.29 / Δ -0.71 -### C191 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` +### C178 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` - [ ] `5300047580` · L 69 / E 68.30 / Δ -0.70 -### C192 · Σ|Δ| 0.7 · 1 certs · `hpcdb18559/gas | cavity wall | pitched 75 | consv2,sec:room heaters` -- [ ] `10010610915` · L 69 / E 69.69 / Δ +0.69 - -### C193 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` +### C179 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` - [ ] `100110433403` · L 69 / E 68.32 / Δ -0.68 -### C194 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` +### C180 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` - [ ] `10093416558` · L 79 / E 78.32 / Δ -0.68 -### C195 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` +### C181 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` - [ ] `100050958217` · L 68 / E 68.68 / Δ +0.68 -### C196 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` +### C182 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` - [ ] `100022667797` · L 68 / E 67.32 / Δ -0.68 -### C197 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C183 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100030528925` · L 78 / E 78.65 / Δ +0.65 -### C198 · Σ|Δ| 0.6 · 1 certs · `h691/elec | timber frame | pitched insulated | ext1,sec:room heaters,whw909` -- [ ] `10094257000` · L 55 / E 55.65 / Δ +0.65 - -### C199 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` +### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` - [ ] `100110300037` · L 74 / E 73.35 / Δ -0.65 -### C200 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` +### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` - [ ] `217092450` · L 52 / E 52.64 / Δ +0.64 -### C201 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` +### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` - [ ] `100061164545` · L 72 / E 71.36 / Δ -0.64 -### C202 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` +### C187 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` - [ ] `100051075936` · L 71 / E 70.36 / Δ -0.64 -### C203 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` +### C188 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` - [ ] `100011565830` · L 72 / E 72.64 / Δ +0.64 -### C204 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` +### C189 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` - [ ] `61010956` · L 75 / E 74.37 / Δ -0.63 -### C205 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` +### C190 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` - [ ] `100110752514` · L 67 / E 67.62 / Δ +0.62 -### C206 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` +### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` - [ ] `100012534027` · L 65 / E 64.38 / Δ -0.62 -### C207 · Σ|Δ| 0.6 · 1 certs · `hpcdb19094/gas | sandstone as | pitched 270 | ext2,sec:room heaters` -- [ ] `10070089948` · L 64 / E 64.60 / Δ +0.60 +### C192 · Σ|Δ| 0.6 · 1 certs · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` +- [x] `10009812472` · L 40 / E 39.40 / Δ -0.60 -### C208 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` +### C193 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` - [ ] `34080035` · L 77 / E 76.41 / Δ -0.59 -### C209 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` +### C194 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` - [ ] `21032732` · L 69 / E 69.59 / Δ +0.59 -### C210 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` +### C195 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100060562056` · L 66 / E 65.41 / Δ -0.59 -### C211 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` +### C196 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` - [ ] `100091086558` · L 79 / E 79.58 / Δ +0.58 -### C212 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` +### C197 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` - [ ] `line599` · L 74 / E 73.42 / Δ -0.58 -### C213 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` +### C198 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` - [ ] `100020407741` · L 72 / E 71.42 / Δ -0.58 -### C214 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` +### C199 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` - [ ] `100050839457` · L 70 / E 70.57 / Δ +0.57 -### C215 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` +### C200 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` - [ ] `42105250` · L 59 / E 59.57 / Δ +0.57 -### C216 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` +### C201 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` - [ ] `77200509` · L 69 / E 69.57 / Δ +0.57 -### C217 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` +### C202 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` - [ ] `200040534` · L 65 / E 65.56 / Δ +0.56 -### C218 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` +### C203 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` - [ ] `100062527568` · L 61 / E 61.56 / Δ +0.56 -### C219 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` +### C204 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` - [ ] `100100268900` · L 69 / E 69.56 / Δ +0.56 -### C220 · Σ|Δ| 0.6 · 1 certs · `hpcdb15100/gas | cavity wall | pitched unknown | sec:room heaters` -- [ ] `100031166296` · L 58 / E 58.55 / Δ +0.55 +### C205 · Σ|Δ| 0.6 · 1 certs · `hpcdb17004/fuel27+2mains | sandstone as | pitched no | ext3,sec:room heaters` +- [x] `200003110548` · L 29 / E 28.45 / Δ -0.55 -### C221 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` +### C206 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` - [ ] `90036914` · L 60 / E 60.55 / Δ +0.55 -### C222 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` +### C207 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` - [ ] `10004742671` · L 70 / E 69.46 / Δ -0.54 -### C223 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` +### C208 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` - [ ] `100010657450` · L 75 / E 75.54 / Δ +0.54 -### C224 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` +### C209 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` - [ ] `100061834344` · L 71 / E 70.46 / Δ -0.54 -### C225 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` +### C210 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` - [ ] `4510097194` · L 70 / E 70.53 / Δ +0.53 -### C226 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` +### C211 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` - [ ] `100010913220` · L 72 / E 72.53 / Δ +0.53 -### C227 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` +### C212 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` - [ ] `43074051` · L 63 / E 62.48 / Δ -0.52 -### C228 · Σ|Δ| 0.5 · 1 certs · `h104/gas | cavity wall | pitched 300` +### C213 · Σ|Δ| 0.5 · 1 certs · `h104/gas | cavity wall | pitched 300` - [ ] `100010723814` · L 69 / E 69.52 / Δ +0.52 -### C229 · Σ|Δ| 0.5 · 1 certs · `hpcdb16137/gas | cavity wall | (another dwelling` +### C214 · Σ|Δ| 0.5 · 1 certs · `hpcdb16137/gas | cavity wall | (another dwelling` - [ ] `100020955792` · L 77 / E 77.52 / Δ +0.52 -### C230 · Σ|Δ| 0.5 · 1 certs · `hpcdb19079/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +### C215 · Σ|Δ| 0.5 · 1 certs · `hpcdb19079/gas | cavity wall | pitched 200 | ext1,sec:room heaters` - [ ] `77172223` · L 65 / E 65.52 / Δ +0.52 -### C231 · Σ|Δ| 0.5 · 1 certs · `hpcdb10242/gas | granite or | pitched insulated | RR,sec:room heaters` +### C216 · Σ|Δ| 0.5 · 1 certs · `hpcdb10242/gas | granite or | pitched insulated | RR,sec:room heaters` - [ ] `100051245439` · L 62 / E 61.48 / Δ -0.52 -### C232 · Σ|Δ| 0.5 · 1 certs · `hpcdb10328/gas | cavity wall | (another dwelling` +### C217 · Σ|Δ| 0.5 · 1 certs · `hpcdb10328/gas | cavity wall | (another dwelling` - [ ] `100012553958` · L 67 / E 66.48 / Δ -0.52 -### C233 · Σ|Δ| 0.5 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` -- [ ] `200004522639` · L 37 / E 36.48 / Δ -0.52 - -### C234 · Σ|Δ| 0.5 · 1 certs · `hpcdb10033/gas | cavity wall | pitched 200 | ext2,sec:room heaters` +### C218 · Σ|Δ| 0.5 · 1 certs · `hpcdb10033/gas | cavity wall | pitched 200 | ext2,sec:room heaters` - [ ] `100110108632` · L 63 / E 63.51 / Δ +0.51 -### C235 · Σ|Δ| 0.5 · 1 certs · `h109/gas | cavity wall | pitched 270 | consv2,ext1,sec:room heaters` +### C219 · Σ|Δ| 0.5 · 1 certs · `h109/gas | cavity wall | pitched 270 | consv2,ext1,sec:room heaters` - [ ] `100091102581` · L 65 / E 65.51 / Δ +0.51 -### C236 · Σ|Δ| 0.5 · 1 certs · `hpcdb19008/gas | cavity wall | pitched 150 | ext1,sec:room heaters` +### C220 · Σ|Δ| 0.5 · 1 certs · `hpcdb19008/gas | cavity wall | pitched 150 | ext1,sec:room heaters` - [ ] `10002326688` · L 69 / E 68.50 / Δ -0.50 -### C237 · Σ|Δ| 0.5 · 1 certs · `h129/fuel28 | granite or | pitched 200 | ext2,sec:room heaters` +### C221 · Σ|Δ| 0.5 · 1 certs · `h129/fuel28 | granite or | pitched 200 | ext2,sec:room heaters` - [ ] `10023132869` · L 46 / E 45.50 / Δ -0.50 -## Resolved ≤0.5 (755 certs — no action) +### C222 · Σ|Δ| 0.5 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` +- [ ] `10091707271` · L 41 / E 41.50 / Δ +0.50 + +## Resolved ≤0.5 (770 certs — no action)
expand - [x] `100090733462` · L 67 / E 67.50 / Δ +0.50 · `hpcdb17974/gas | solid brick | pitched insulated | ext1` +- [x] `100050567367` · L 64 / E 64.50 / Δ +0.50 · `hpcdb19020/gas | solid brick | pitched insulated | RR,sec:room heaters` - [x] `10034815294` · L 78 / E 77.51 / Δ -0.49 · `hpcdb18559/gas | timber frame | pitched 125` - [x] `100110206000` · L 57 / E 56.51 / Δ -0.49 · `h111/gas | cavity wall | pitched 175 | ext1,sec:room heaters` - [x] `100090478973` · L 86 / E 86.49 / Δ +0.49 · `hpcdb18907/gas | cavity wall | pitched 150 | PV` @@ -745,6 +701,8 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100052163521` · L 73 / E 72.51 / Δ -0.49 · `h104/gas | cavity wall | pitched 300` - [x] `202030317` · L 74 / E 74.49 / Δ +0.49 · `hpcdb18820/gas | solid brick | (another dwelling` - [x] `10022829122` · L 82 / E 82.49 / Δ +0.49 · `hpcdb104568/elec | cavity wall | (another dwelling` +- [x] `10034812814` · L 65 / E 65.49 / Δ +0.49 · `hpcdb17978/gas | solid brick | pitched 200 | ext1,sec:room heaters` +- [x] `72103702` · L 70 / E 70.48 / Δ +0.48 · `hpcdb18759/gas | sandstone as | pitched insulated | sec:room heaters` - [x] `100091572782` · L 74 / E 74.48 / Δ +0.48 · `hpcdb19168/gas | cavity wall | pitched 100 | ext1` - [x] `28012066` · L 71 / E 71.48 / Δ +0.48 · `hpcdb16212/gas | cavity wall | pitched 400+` - [x] `74057326` · L 73 / E 72.52 / Δ -0.48 · `h691/elec | solid brick | pitched 270 | whw909` @@ -758,7 +716,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100070365977` · L 78 / E 77.52 / Δ -0.48 · `hpcdb19001/gas | solid brick | pitched 400+ | PV` - [x] `100080323739` · L 67 / E 67.48 / Δ +0.48 · `hpcdb10327/gas | cavity wall | pitched 150` - [x] `100100840201` · L 60 / E 60.48 / Δ +0.48 · `hpcdb10244/gas | granite or | pitched 100 | ext1` -- [x] `100061125812` · L 75 / E 75.48 / Δ +0.48 · `hpcdb17983/gas | solid brick | pitched 50 | PV,ext2,sec:room heaters` - [x] `100071135609` · L 68 / E 68.48 / Δ +0.48 · `hpcdb18229/gas | solid brick | pitched 200 | ext2` - [x] `100121043224` · L 77 / E 77.48 / Δ +0.48 · `hpcdb1758/gas | cavity wall | pitched 300` - [x] `30025401` · L 70 / E 69.52 / Δ -0.48 · `hpcdb18433/gas | cavity wall | pitched 270 | ext2` @@ -766,6 +723,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `10013778285` · L 80 / E 79.52 / Δ -0.48 · `hpcdb16138/gas | cavity wall | (another dwelling` - [x] `100010348502` · L 76 / E 75.52 / Δ -0.48 · `hpcdb16839/gas | cavity wall | pitched 175` - [x] `100040227808` · L 58 / E 58.48 / Δ +0.48 · `hpcdb15502/gas | solid brick | pitched 270 | sec:room heaters` +- [x] `100050355518` · L 36 / E 35.53 / Δ -0.47 · `h117/gas | cavity wall | pitched 200 | ext2,sec:room heaters` - [x] `100051118081` · L 73 / E 73.47 / Δ +0.47 · `hpcdb18907/gas | cavity wall | pitched 300 | PV` - [x] `100110190943` · L 67 / E 66.53 / Δ -0.47 · `hpcdb16777/gas | cavity wall | pitched 200` - [x] `545523` · L 59 / E 59.47 / Δ +0.47 · `hpcdb16840/gas | cavity wall | pitched 100` @@ -813,12 +771,10 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `10002589494` · L 70 / E 70.44 / Δ +0.44 · `hpcdb8642/gas | cavity wall | pitched 200` - [x] `100010460076` · L 67 / E 66.56 / Δ -0.44 · `hpcdb17515/gas | cavity wall | pitched 100` - [x] `100051178837` · L 63 / E 63.44 / Δ +0.44 · `h104/gas | sandstone as | pitched no | RR` -- [x] `10014526109` · L 59 / E 59.44 / Δ +0.44 · `h126/fuel28 | solid brick | flat insulated | consv2,ext1,sec:room heaters` - [x] `63017340` · L 74 / E 73.56 / Δ -0.44 · `hpcdb17956/gas | solid brick | pitched insulated` - [x] `50101945` · L 75 / E 74.56 / Δ -0.44 · `hpcdb10243/gas | timber frame | (another dwelling | ext1` - [x] `10032778242` · L 65 / E 65.44 / Δ +0.44 · `hpcdb9209/gas | sandstone as | pitched 100` - [x] `40002036` · L 64 / E 63.56 / Δ -0.44 · `hpcdb17904/gas | cavity wall | pitched no` -- [x] `100010170141` · L 61 / E 61.44 / Δ +0.44 · `hpcdb4045/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [x] `100090412407` · L 71 / E 70.56 / Δ -0.44 · `hpcdb18908/gas | cavity wall | pitched 200` - [x] `10070623452` · L 84 / E 84.44 / Δ +0.44 · `hpcdb18616/gas | cavity wall | (another dwelling` - [x] `100000059044` · L 73 / E 72.56 / Δ -0.44 · `hpcdb17983/gas | cavity wall | (another dwelling` @@ -836,13 +792,13 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `1775045933` · L 69 / E 69.43 / Δ +0.43 · `hpcdb8180/gas | cavity wall | pitched 150` - [x] `83105081` · L 67 / E 67.43 / Δ +0.43 · `hpcdb18119/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [x] `21072782` · L 66 / E 65.57 / Δ -0.43 · `hpcdb18045/gas | cavity wall | pitched 175 | sec:room heaters` -- [x] `100090106879` · L 70 / E 70.43 / Δ +0.43 · `hpcdb16836/gas | cavity wall | pitched 300 | sec:room heaters` - [x] `100031468327` · L 69 / E 69.43 / Δ +0.43 · `hpcdb19083/gas | cavity wall | pitched 300 | consv2` - [x] `100100253270` · L 71 / E 71.43 / Δ +0.43 · `hpcdb18496/gas | cavity wall | pitched 250 | ext1` - [x] `100071116347` · L 62 / E 62.43 / Δ +0.43 · `h104/gas | solid brick | pitched 150` - [x] `422000030203` · L 75 / E 75.42 / Δ +0.42 · `hpcdb10328/gas | cavity wall | pitched 225` - [x] `100010399776` · L 63 / E 63.42 / Δ +0.42 · `hpcdb10462/gas | cavity wall | pitched 270 | RR,ext1,sec:room heaters` - [x] `100080945063` · L 70 / E 70.42 / Δ +0.42 · `hpcdb10326/gas | cavity wall | (another dwelling | ext1` +- [x] `10034692050` · L 82 / E 81.58 / Δ -0.42 · `hpcdb18250/gas | sandstone as | pitched 350 | PV,ext2,sec:room heaters` - [x] `100100284086` · L 69 / E 69.42 / Δ +0.42 · `hpcdb17983/gas | cavity wall | pitched 300 | sec:room heaters` - [x] `100031674118` · L 66 / E 66.42 / Δ +0.42 · `hpcdb17986/gas | cavity wall | pitched 125 | consv2,sec:room heaters` - [x] `10023449405` · L 59 / E 58.58 / Δ -0.42 · `hpcdb18219/gas | granite or | pitched insulated | consv3,ext1,sec:room heaters` @@ -865,14 +821,15 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `10070086972` · L 18 / E 17.59 / Δ -0.41 · `hpcdb710/fuel28+2mains | sandstone as | pitched insulated | RR,ext4,sec:room heaters` - [x] `100050397944` · L 65 / E 64.59 / Δ -0.41 · `hpcdb17681/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [x] `63105357` · L 74 / E 74.41 / Δ +0.41 · `hpcdb17507/gas | cavity wall | pitched 270 | sec:room heaters` -- [x] `10009812472` · L 40 / E 40.41 / Δ +0.41 · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` - [x] `100090989765` · L 70 / E 70.41 / Δ +0.41 · `hpcdb16408/gas | timber frame | pitched 300 | consv3,ext1,sec:room heaters` +- [x] `30523770` · L 72 / E 71.60 / Δ -0.40 · `hpcdb8191/fuel28 | granite or | pitched 200 | sec:room heaters` - [x] `200004700463` · L 65 / E 65.40 / Δ +0.40 · `hpcdb18559/gas | sandstone as | pitched 75` - [x] `100020675575` · L 60 / E 60.40 / Δ +0.40 · `h102/gas | cavity wall | pitched 12` - [x] `100110694244` · L 72 / E 72.40 / Δ +0.40 · `hpcdb18512/gas | granite or | pitched 200 | sec:room heaters` - [x] `10003910753` · L 64 / E 63.60 / Δ -0.40 · `h409/elec | granite or | pitched 300 | sec:room heaters,whw903` - [x] `100040881207` · L 73 / E 73.40 / Δ +0.40 · `hpcdb16839/gas | solid brick | pitched 100 | ext1` - [x] `100070601575` · L 68 / E 68.40 / Δ +0.40 · `hpcdb18560/gas | solid brick | pitched 250` +- [x] `100061125812` · L 75 / E 74.60 / Δ -0.40 · `hpcdb17983/gas | solid brick | pitched 50 | PV,ext2,sec:room heaters` - [x] `100010596378` · L 67 / E 67.40 / Δ +0.40 · `hpcdb16839/gas | cavity wall | pitched 350 | RR,consv3,ext1,sec:room heaters` - [x] `100051185130` · L 67 / E 66.60 / Δ -0.40 · `hpcdb18156/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [x] `38198539` · L 80 / E 80.40 / Δ +0.40 · `hpcdb18229/gas | cavity wall | (another dwelling` @@ -883,7 +840,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100071356612` · L 69 / E 68.61 / Δ -0.39 · `h301/coal-anth | solid brick | (another dwelling` - [x] `74041417` · L 79 / E 79.39 / Δ +0.39 · `hpcdb17507/gas | cavity wall | pitched 300 | PV` - [x] `100022607800` · L 73 / E 72.61 / Δ -0.39 · `hpcdb18119/gas | solid brick | pitched 270` -- [x] `100040268694` · L 58 / E 58.39 / Δ +0.39 · `h127/fuel28 | granite or | pitched insulated | RR,ext1,sec:room heaters` - [x] `100022277442` · L 58 / E 58.39 / Δ +0.39 · `h409/elec | cavity wall | pitched insulated | whw903` - [x] `250029611` · L 73 / E 72.61 / Δ -0.39 · `hpcdb17553/gas | cavity wall | pitched 250 | consv2,ext1` - [x] `100022887979` · L 72 / E 72.39 / Δ +0.39 · `hpcdb18861/gas | solid brick | (another dwelling` @@ -902,11 +858,8 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `10096536318` · L 66 / E 65.62 / Δ -0.38 · `h301/coal-anth | cavity wall | (another dwelling` - [x] `100030585620` · L 59 / E 59.38 / Δ +0.38 · `h102/gas | cavity wall | pitched insulated | ext4,sec:room heaters` - [x] `10008325030` · L 82 / E 81.62 / Δ -0.38 · `h301/coal-anth | system built | (another dwelling` -- [x] `100060061070` · L 70 / E 70.38 / Δ +0.38 · `hpcdb17986/gas | cavity wall | pitched 300 | ext1,sec:room heaters` - [x] `100050869353` · L 75 / E 74.62 / Δ -0.38 · `hpcdb10547/gas | solid brick | pitched 300` - [x] `45034352` · L 70 / E 70.38 / Δ +0.38 · `hpcdb18684/gas | cavity wall | pitched 250 | ext1` -- [x] `10009274535` · L 31 / E 31.38 / Δ +0.38 · `h126/fuel28 | sandstone as | pitched 50 | consv4,ext2,sec:room heaters` -- [x] `1710007756` · L 76 / E 76.38 / Δ +0.38 · `h104/gas | cavity wall | pitched 250 | RR,ext1,sec:room heaters` - [x] `72274934` · L 66 / E 66.38 / Δ +0.38 · `hpcdb17985/gas | cavity wall | pitched 300 | ext1,sec:room heaters` - [x] `100030893211` · L 70 / E 69.62 / Δ -0.38 · `hpcdb17546/gas | cavity wall | pitched 200 | ext1` - [x] `21018821` · L 67 / E 67.38 / Δ +0.38 · `hpcdb19014/gas | cavity wall | pitched 200 | sec:room heaters` @@ -914,6 +867,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100021434831` · L 74 / E 74.38 / Δ +0.38 · `h102/gas | cavity wall | pitched insulated | RR,ext1` - [x] `100090160202` · L 78 / E 77.62 / Δ -0.38 · `hpcdb18120/gas | cavity wall | pitched 300 | PV` - [x] `100000001899` · L 70 / E 70.38 / Δ +0.38 · `hpcdb17507/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `63015070` · L 69 / E 69.38 / Δ +0.38 · `hpcdb19082/gas | cavity wall | pitched 300 | ext1,sec:room heaters` - [x] `100032207872` · L 71 / E 71.38 / Δ +0.38 · `hpcdb17505/gas | cavity wall | (another dwelling` - [x] `90089745` · L 62 / E 61.62 / Δ -0.38 · `hpcdb10243/gas | solid brick | pitched 150` - [x] `100090379526` · L 67 / E 66.62 / Δ -0.38 · `hpcdb17992/gas | cavity wall | pitched 150 | ext2` @@ -942,11 +896,13 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100090373553` · L 50 / E 49.64 / Δ -0.36 · `h102/gas | cavity wall | pitched insulated | ext1` - [x] `100110122381` · L 70 / E 70.36 / Δ +0.36 · `hpcdb18119/gas | solid brick | pitched 300 | ext1` - [x] `100110084287` · L 69 / E 68.64 / Δ -0.36 · `hpcdb17513/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `10010610915` · L 69 / E 69.36 / Δ +0.36 · `hpcdb18559/gas | cavity wall | pitched 75 | consv2,sec:room heaters` - [x] `100050858546` · L 58 / E 58.36 / Δ +0.36 · `hpcdb19030/gas | cavity wall | pitched 150 | sec:room heaters` - [x] `100061152006` · L 66 / E 66.36 / Δ +0.36 · `hpcdb17503/gas | cavity wall | pitched 270 | ext1,sec:room heaters` - [x] `100070649980` · L 69 / E 68.64 / Δ -0.36 · `hpcdb17505/gas | solid brick | pitched 200` - [x] `100121236760` · L 58 / E 58.36 / Δ +0.36 · `hpcdb18044/gas | sandstone as | pitched insulated | RR,ext3,sec:room heaters` - [x] `64024859` · L 54 / E 53.64 / Δ -0.36 · `hpcdb8358/gas | cavity wall | pitched 125 | consv3,ext1,sec:room heaters` +- [x] `100031166296` · L 58 / E 57.64 / Δ -0.36 · `hpcdb15100/gas | cavity wall | pitched unknown | sec:room heaters` - [x] `100110061827` · L 71 / E 70.64 / Δ -0.36 · `hpcdb16688/gas | cavity wall | pitched 150 | ext2` - [x] `100110394521` · L 73 / E 72.64 / Δ -0.36 · `hpcdb10328/gas | cavity wall | pitched 300 | ext1,sec:room heaters` - [x] `10023253242` · L 72 / E 72.36 / Δ +0.36 · `h104/gas | cavity wall | pitched insulated` @@ -972,11 +928,12 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100050971905` · L 46 / E 46.34 / Δ +0.34 · `hpcdb19059/fuel27 | cavity wall | flat limited` - [x] `50120779` · L 76 / E 75.66 / Δ -0.34 · `hpcdb16848/gas | solid brick | (another dwelling` - [x] `23018106` · L 66 / E 66.34 / Δ +0.34 · `hpcdb18250/gas | cavity wall | pitched 150 | sec:room heaters` -- [x] `100090866399` · L 79 / E 79.34 / Δ +0.34 · `hpcdb18435/gas | cavity wall | pitched 200 | PV,ext2,sec:room heaters` - [x] `100110515241` · L 64 / E 63.66 / Δ -0.34 · `hpcdb18559/gas | solid brick | pitched insulated | ext1,sec:room heaters` - [x] `100010779964` · L 72 / E 72.34 / Δ +0.34 · `hpcdb17683/gas | sandstone as | pitched 75` - [x] `64106486` · L 72 / E 71.66 / Δ -0.34 · `hpcdb17926/fuel27 | timber frame | pitched 270 | ext1` +- [x] `100060109253` · L 62 / E 62.34 / Δ +0.34 · `hpcdb18435/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` - [x] `200002819281` · L 72 / E 71.66 / Δ -0.34 · `h104/gas | solid brick | pitched insulated | RR,ext1` +- [x] `100051237659` · L 65 / E 64.67 / Δ -0.33 · `hpcdb18560/gas | sandstone as | pitched insulated | sec:room heaters` - [x] `12027355` · L 70 / E 70.33 / Δ +0.33 · `hpcdb1838/gas | solid brick | pitched insulated | ext1` - [x] `100120926050` · L 71 / E 70.67 / Δ -0.33 · `hpcdb18514/gas | cavity wall | pitched 175 | ext2` - [x] `100012548450` · L 74 / E 74.33 / Δ +0.33 · `hpcdb10338/gas | cavity wall | (another dwelling` @@ -999,6 +956,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100031318648` · L 79 / E 78.68 / Δ -0.32 · `hpcdb18907/gas | timber frame | pitched 400+ | PV,sec:room heaters` - [x] `21089432` · L 64 / E 63.68 / Δ -0.32 · `hpcdb18045/gas | cavity wall | pitched no | ext1` - [x] `93099` · L 63 / E 63.32 / Δ +0.32 · `hpcdb18250/gas | solid brick | pitched 200 | ext2` +- [x] `100120765933` · L 57 / E 57.32 / Δ +0.32 · `hpcdb15921/fuel28 | cavity wall | pitched 200 | sec:room heaters` - [x] `100051053673` · L 66 / E 66.32 / Δ +0.32 · `hpcdb17660/gas | cavity wall | pitched 300 | ext1,sec:room heaters` - [x] `200002919291` · L 59 / E 59.32 / Δ +0.32 · `h691/elec | system built | (another dwelling | whw903` - [x] `21082835` · L 78 / E 77.69 / Δ -0.31 · `hpcdb16137/gas | system built | pitched 270` @@ -1017,11 +975,13 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100110234047` · L 71 / E 70.70 / Δ -0.30 · `hpcdb16136/gas | cavity wall | pitched 300` - [x] `10007966883` · L 64 / E 64.30 / Δ +0.30 · `hpcdb17785/gas | solid brick | pitched 100 | ext1` - [x] `100091292858` · L 59 / E 59.30 / Δ +0.30 · `h691/elec | solid brick | (another dwelling | whw903` +- [x] `100120820445` · L 72 / E 71.70 / Δ -0.30 · `hpcdb10267/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` - [x] `100010719461` · L 56 / E 56.30 / Δ +0.30 · `hpcdb16930/gas | cavity wall | pitched no` - [x] `100070487183` · L 66 / E 66.30 / Δ +0.30 · `h691/elec | timber frame | pitched 150 | whw909` - [x] `116895` · L 73 / E 72.70 / Δ -0.30 · `hpcdb18119/gas | cavity wall | pitched 250 | sec:room heaters` - [x] `10008031947` · L 79 / E 78.70 / Δ -0.30 · `hpcdb16406/gas+2mains | cavity wall | pitched 250 | ext2` - [x] `100050834171` · L 73 / E 72.70 / Δ -0.30 · `hpcdb10547/gas | cavity wall | pitched 100` +- [x] `10010159639` · L 65 / E 65.30 / Δ +0.30 · `hpcdb18759/gas | sandstone with | pitched 150 | ext1,mv5,sec:room heaters` - [x] `100110455808` · L 67 / E 66.70 / Δ -0.30 · `hpcdb10242/gas | cavity wall | pitched no` - [x] `100070968292` · L 72 / E 71.70 / Δ -0.30 · `h104/gas | cavity wall | pitched insulated` - [x] `100011754031` · L 69 / E 69.30 / Δ +0.30 · `hpcdb16839/gas | cavity wall | pitched 150 | ext1` @@ -1045,7 +1005,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `32049938` · L 63 / E 62.71 / Δ -0.29 · `hpcdb17983/gas | solid brick | pitched 350 | sec:room heaters` - [x] `100110433442` · L 70 / E 69.71 / Δ -0.29 · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1` - [x] `100070532674` · L 76 / E 76.29 / Δ +0.29 · `hpcdb17983/gas | cavity wall | pitched insulated` -- [x] `200003110548` · L 29 / E 29.29 / Δ +0.29 · `hpcdb17004/fuel27+2mains | sandstone as | pitched no | ext3,sec:room heaters` +- [x] `10024298029` · L 72 / E 72.29 / Δ +0.29 · `hpcdb17503/gas | solid brick | pitched 270 | ext1,sec:room heaters` - [x] `5079850` · L 39 / E 39.29 / Δ +0.29 · `h301/coal-anth | system built | (another dwelling | ext1,whw903` - [x] `10001235167` · L 74 / E 73.71 / Δ -0.29 · `hpcdb17645/gas | solid brick | pitched 225` - [x] `100080531660` · L 64 / E 63.71 / Δ -0.29 · `hpcdb16408/gas | cavity wall | pitched 50 | ext1` @@ -1077,6 +1037,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100031388370` · L 71 / E 71.27 / Δ +0.27 · `hpcdb16931/gas | solid brick | pitched 300 | ext2` - [x] `45115812` · L 75 / E 74.73 / Δ -0.27 · `h304/elec | system built | (another dwelling` - [x] `207084872` · L 60 / E 59.74 / Δ -0.26 · `h114/gas | solid brick | pitched 75 | ext1` +- [x] `100060061070` · L 70 / E 69.74 / Δ -0.26 · `hpcdb17986/gas | cavity wall | pitched 300 | ext1,sec:room heaters` - [x] `100021026327` · L 72 / E 71.74 / Δ -0.26 · `hpcdb15502/gas | solid brick | (another dwelling` - [x] `50016716` · L 62 / E 62.26 / Δ +0.26 · `hpcdb18431/gas | cavity wall | pitched 100` - [x] `100040724662` · L 73 / E 73.26 / Δ +0.26 · `hpcdb18229/gas | cavity wall | pitched insulated | ext1` @@ -1105,6 +1066,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100120874299` · L 72 / E 71.75 / Δ -0.25 · `hpcdb107234/elec | cavity wall | pitched 200 | mv2` - [x] `100030332130` · L 51 / E 50.76 / Δ -0.24 · `h402/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` - [x] `100060721835` · L 68 / E 67.76 / Δ -0.24 · `hpcdb16841/gas | system built | pitched 250` +- [x] `100011764055` · L 72 / E 71.76 / Δ -0.24 · `hpcdb15823/gas | cavity wall | pitched 200 | ext4,sec:room heaters` - [x] `5067734` · L 67 / E 67.24 / Δ +0.24 · `hpcdb17726/gas | solid brick | (another dwelling` - [x] `100021942272` · L 69 / E 69.24 / Δ +0.24 · `hpcdb17501/gas | solid brick | pitched insulated | RR` - [x] `100050587694` · L 70 / E 70.24 / Δ +0.24 · `hpcdb18516/gas | cavity wall | pitched 270` @@ -1128,7 +1090,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100062014047` · L 76 / E 75.77 / Δ -0.23 · `hpcdb10547/gas | cavity wall | pitched 200` - [x] `14003893` · L 69 / E 69.22 / Δ +0.22 · `hpcdb16931/gas | cavity wall | pitched 150` - [x] `6721183` · L 82 / E 81.78 / Δ -0.22 · `h301/coal-anth | system built | (another dwelling` -- [x] `100051035527` · L 74 / E 74.22 / Δ +0.22 · `hpcdb16842/gas | cavity wall | pitched 300 | sec:room heaters` - [x] `100040914059` · L 72 / E 72.22 / Δ +0.22 · `hpcdb10244/gas | solid brick | pitched 400+` - [x] `10034523788` · L 69 / E 69.22 / Δ +0.22 · `hpcdb10459/gas+2mains | cavity wall | pitched 250 | RR,ext4,sec:room heaters,whw914` - [x] `41223299` · L 76 / E 76.22 / Δ +0.22 · `h301/coal-anth | cavity wall | (another dwelling` @@ -1159,6 +1120,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `6007002` · L 76 / E 76.20 / Δ +0.20 · `hpcdb17702/gas | system built | (another dwelling` - [x] `100040926648` · L 70 / E 69.80 / Δ -0.20 · `hpcdb10244/gas | cavity wall | pitched 250 | ext1` - [x] `100100299483` · L 67 / E 66.80 / Δ -0.20 · `hpcdb17507/gas | granite or | pitched 50 | ext3` +- [x] `100010391723` · L 66 / E 66.20 / Δ +0.20 · `hpcdb18760/gas | solid brick | pitched 100 | RR,ext2,sec:room heaters` - [x] `100110431858` · L 84 / E 83.80 / Δ -0.20 · `hpcdb18119/gas | cavity wall | pitched 400+ | PV` - [x] `30102683` · L 78 / E 77.80 / Δ -0.20 · `hpcdb9969/gas | cavity wall | roof room(s) | RR,consv2` - [x] `200000800903` · L 75 / E 74.80 / Δ -0.20 · `hpcdb2040/gas | timber frame | pitched 150 | ext2` @@ -1198,12 +1160,12 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `21072798` · L 72 / E 71.83 / Δ -0.17 · `hpcdb19007/gas | cavity wall | (another dwelling` - [x] `10094975827` · L 66 / E 65.83 / Δ -0.17 · `hpcdb18559/gas | solid brick | pitched insulated` - [x] `10009830624` · L 78 / E 77.83 / Δ -0.17 · `hpcdb15706/gas | cavity wall | pitched 300` -- [x] `line768` · L 57 / E 56.83 / Δ -0.17 · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` - [x] `39023204` · L 68 / E 68.17 / Δ +0.17 · `hpcdb18155/gas | solid brick | pitched insulated | ext2` - [x] `100060428487` · L 71 / E 71.17 / Δ +0.17 · `hpcdb18496/gas | cavity wall | pitched 100 | consv2,ext1` - [x] `100121053407` · L 73 / E 72.83 / Δ -0.17 · `hpcdb16919/gas | cavity wall | pitched 300 | consv3` - [x] `202229245` · L 67 / E 66.83 / Δ -0.17 · `hpcdb18224/gas | solid brick | pitched unknown | ext1` - [x] `10000208277` · L 75 / E 75.17 / Δ +0.17 · `hpcdb16135/gas | cavity wall | pitched 225 | consv2` +- [x] `10094257000` · L 55 / E 55.16 / Δ +0.16 · `h691/elec | timber frame | pitched insulated | ext1,sec:room heaters,whw909` - [x] `100040411293` · L 64 / E 64.16 / Δ +0.16 · `hpcdb16986/gas | cavity wall | pitched 150` - [x] `200003712915` · L 73 / E 72.84 / Δ -0.16 · `hpcdb16396/gas | cavity wall | pitched 400+ | mv2` - [x] `4510002139` · L 73 / E 72.84 / Δ -0.16 · `hpcdb18204/gas | solid brick | pitched insulated | RR,ext2` @@ -1218,6 +1180,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100120629168` · L 70 / E 70.16 / Δ +0.16 · `hpcdb9897/gas | cavity wall | pitched 100 | consv2,ext2` - [x] `100100713371` · L 65 / E 65.16 / Δ +0.16 · `hpcdb17507/gas | cavity wall | pitched 125 | consv4` - [x] `10033058144` · L 65 / E 65.16 / Δ +0.16 · `hpcdb18560/gas | cavity wall | pitched 200 | ext1` +- [x] `200002626191` · L 63 / E 63.16 / Δ +0.16 · `hpcdb17505/gas | cavity wall | pitched 200 | sec:room heaters` - [x] `148007532` · L 61 / E 60.84 / Δ -0.16 · `hpcdb1396/gas | solid brick | pitched insulated | RR,consv2,ext1` - [x] `100010043608` · L 56 / E 56.16 / Δ +0.16 · `h401/elec | cavity wall | pitched 200 | PV,RR,consv2,ext1,sec:room heaters,whw903` - [x] `100022232588` · L 56 / E 56.16 / Δ +0.16 · `h102/gas | solid brick | pitched 25 | ext1` @@ -1235,6 +1198,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100051048523` · L 67 / E 67.15 / Δ +0.15 · `hpcdb17507/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [x] `551000` · L 72 / E 72.15 / Δ +0.15 · `h104/gas | cavity wall | pitched 150` - [x] `202137997` · L 69 / E 68.85 / Δ -0.15 · `hpcdb10443/gas | cavity wall | (another dwelling` +- [x] `10090368756` · L 80 / E 79.85 / Δ -0.15 · `hpcdb17033/gas | cavity wall | pitched insulated | RR,ext3,sec:room heaters` - [x] `100120881623` · L 53 / E 53.15 / Δ +0.15 · `h158/heatnet+2mains | solid brick | pitched insulated | ext4,sec:room heaters,whw903` - [x] `5870106813` · L 78 / E 78.15 / Δ +0.15 · `hpcdb17505/gas | solid brick | pitched 300` - [x] `100000056169` · L 62 / E 61.85 / Δ -0.15 · `hpcdb18559/gas | cavity wall | pitched 150 | consv2,ext1` @@ -1243,7 +1207,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `10022949096` · L 74 / E 73.85 / Δ -0.15 · `hpcdb17507/gas | cavity wall | pitched 200` - [x] `100000341714` · L 64 / E 64.15 / Δ +0.15 · `hpcdb15709/gas | system built | pitched 270` - [x] `100021046998` · L 69 / E 69.15 / Δ +0.15 · `hpcdb10327/gas | solid brick | pitched 100 | ext1` -- [x] `30523770` · L 72 / E 71.85 / Δ -0.15 · `hpcdb8191/fuel28 | granite or | pitched 200 | sec:room heaters` - [x] `100080902546` · L 79 / E 78.85 / Δ -0.15 · `hpcdb17696/gas | solid brick | pitched insulated | RR,ext1` - [x] `100021286876` · L 66 / E 66.15 / Δ +0.15 · `hpcdb17503/gas | solid brick | pitched insulated` - [x] `100070056707` · L 72 / E 72.14 / Δ +0.14 · `hpcdb17505/gas | system built | (another dwelling` @@ -1252,6 +1215,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100023483089` · L 77 / E 76.86 / Δ -0.14 · `h409/elec | system built | (another dwelling | sec:portable electric,whw903` - [x] `10096537371` · L 37 / E 37.14 / Δ +0.14 · `h691/elec | solid brick | pitched 200 | ext1,whw909` - [x] `100011476438` · L 57 / E 56.86 / Δ -0.14 · `h402/elec | cavity wall | pitched 125 | sec:room heaters,whw903` +- [x] `100090106879` · L 70 / E 69.86 / Δ -0.14 · `hpcdb16836/gas | cavity wall | pitched 300 | sec:room heaters` - [x] `10003800267` · L 72 / E 71.86 / Δ -0.14 · `h301/coal-anth | cavity wall | (another dwelling` - [x] `100060412840` · L 66 / E 66.14 / Δ +0.14 · `h102/gas | cavity wall | pitched 50 | ext1` - [x] `2465082925` · L 66 / E 66.14 / Δ +0.14 · `hpcdb16848/gas | cavity wall | pitched 250` @@ -1266,10 +1230,12 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100071033049` · L 62 / E 61.86 / Δ -0.14 · `hpcdb18908/gas | cavity wall | pitched 150 | sec:room heaters` - [x] `100022619802` · L 79 / E 79.13 / Δ +0.13 · `hpcdb16375/gas | cavity wall | flat insulated` - [x] `100081154129` · L 65 / E 64.87 / Δ -0.13 · `h408/elec | cavity wall | pitched 100 | consv2,whw903` +- [x] `10009274535` · L 31 / E 30.87 / Δ -0.13 · `h126/fuel28 | sandstone as | pitched 50 | consv4,ext2,sec:room heaters` - [x] `1710040599` · L 70 / E 70.13 / Δ +0.13 · `h102/gas | cavity wall | pitched 100 | RR,sec:room heaters` - [x] `100050824478` · L 72 / E 71.87 / Δ -0.13 · `hpcdb17615/gas | cavity wall | pitched 200 | ext1` - [x] `100060005933` · L 71 / E 70.87 / Δ -0.13 · `h102/gas | cavity wall | pitched 175` - [x] `100080706341` · L 62 / E 61.87 / Δ -0.13 · `hpcdb18045/gas | system built | pitched 75` +- [x] `200003644880` · L 59 / E 58.87 / Δ -0.13 · `hpcdb15290/gas | solid brick | pitched insulated | ext2,sec:room heaters` - [x] `46083795` · L 78 / E 78.13 / Δ +0.13 · `hpcdb16930/gas | cavity wall | (another dwelling` - [x] `10090342779` · L 81 / E 80.87 / Δ -0.13 · `hpcdb10327/gas | timber frame | pitched 300` - [x] `77068182` · L 68 / E 68.13 / Δ +0.13 · `hpcdb10242/gas | cavity wall | pitched 75 | ext2` @@ -1315,21 +1281,23 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `10090929166` · L 64 / E 63.89 / Δ -0.11 · `h691/elec | cavity wall | pitched insulated | whw909` - [x] `100062012` · L 72 / E 72.11 / Δ +0.11 · `hpcdb17117/gas | solid brick | (another dwelling` - [x] `100030293609` · L 60 / E 59.89 / Δ -0.11 · `hpcdb10328/gas | cavity wall | pitched 200 | sec:room heaters` -- [x] `100011764055` · L 72 / E 72.11 / Δ +0.11 · `hpcdb15823/gas | cavity wall | pitched 200 | ext4,sec:room heaters` - [x] `200164795` · L 82 / E 81.89 / Δ -0.11 · `hpcdb16400/gas | cavity wall | pitched insulated | PV,RR,ext1` - [x] `100022628872` · L 74 / E 74.11 / Δ +0.11 · `hpcdb18908/gas | cavity wall | (another dwelling` - [x] `10014460343` · L 79 / E 78.89 / Δ -0.11 · `hpcdb15754/gas | cavity wall | pitched 250` - [x] `10001142950` · L 69 / E 69.11 / Δ +0.11 · `h301/coal-anth | sandstone as | (another dwelling` +- [x] `10014526109` · L 59 / E 59.11 / Δ +0.11 · `h126/fuel28 | solid brick | flat insulated | consv2,ext1,sec:room heaters` - [x] `38137278` · L 69 / E 69.11 / Δ +0.11 · `hpcdb18907/gas | cavity wall | pitched 400+ | ext2,mv2,sec:room heaters` - [x] `100040565259` · L 66 / E 66.11 / Δ +0.11 · `hpcdb18221/gas | cavity wall | pitched 300 | ext1` - [x] `100110437510` · L 87 / E 87.11 / Δ +0.11 · `hpcdb15709/gas | cavity wall | pitched 270 | PV,ext1,mv2,sec:room heaters` - [x] `100051116259` · L 70 / E 70.11 / Δ +0.11 · `hpcdb15520/gas | cavity wall | pitched insulated | consv4,ext1,sec:room heaters` - [x] `100031466637` · L 52 / E 51.89 / Δ -0.11 · `h409/elec | solid brick | pitched no | ext3,sec:room heaters,whw903` +- [x] `10070089948` · L 64 / E 64.11 / Δ +0.11 · `hpcdb19094/gas | sandstone as | pitched 270 | ext2,sec:room heaters` +- [x] `100090866399` · L 79 / E 78.89 / Δ -0.11 · `hpcdb18435/gas | cavity wall | pitched 200 | PV,ext2,sec:room heaters` - [x] `100060052603` · L 58 / E 57.89 / Δ -0.11 · `hpcdb17553/gas | cavity wall | pitched 100 | consv2,sec:room heaters` +- [x] `100010170141` · L 61 / E 60.89 / Δ -0.11 · `hpcdb4045/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [x] `100031245724` · L 69 / E 68.90 / Δ -0.10 · `hpcdb17660/gas | cavity wall | pitched 200` - [x] `24029210` · L 75 / E 75.10 / Δ +0.10 · `hpcdb15704/gas | cavity wall | pitched 250 | sec:room heaters` - [x] `217079598` · L 77 / E 77.10 / Δ +0.10 · `hpcdb18821/gas | system built | (another dwelling` -- [x] `100120820445` · L 72 / E 72.10 / Δ +0.10 · `hpcdb10267/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` - [x] `10008290975` · L 79 / E 79.10 / Δ +0.10 · `hpcdb17973/gas | cavity wall | (another dwelling` - [x] `100040140820` · L 61 / E 61.10 / Δ +0.10 · `hpcdb1768/fuel28 | cavity wall | pitched 225 | ext1` - [x] `100090121779` · L 73 / E 73.10 / Δ +0.10 · `hpcdb18089/gas | cavity wall | pitched 125` @@ -1369,7 +1337,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100080706339` · L 65 / E 65.08 / Δ +0.08 · `hpcdb16396/gas | system built | pitched 250` - [x] `10090018805` · L 77 / E 76.92 / Δ -0.08 · `hpcdb15017/gas | cavity wall | pitched 250` - [x] `100034336` · L 60 / E 60.08 / Δ +0.08 · `hpcdb17815/gas | solid brick | pitched 100` -- [x] `100051237659` · L 65 / E 65.08 / Δ +0.08 · `hpcdb18560/gas | sandstone as | pitched insulated | sec:room heaters` - [x] `line979` · L 71 / E 71.08 / Δ +0.08 · `hpcdb15710/gas | cavity wall | pitched insulated` - [x] `100070431508` · L 64 / E 63.92 / Δ -0.08 · `hpcdb18119/gas | solid brick | pitched insulated | sec:room heaters` - [x] `100110515214` · L 73 / E 72.92 / Δ -0.08 · `hpcdb17741/gas | cavity wall | pitched 400+ | mv2` @@ -1381,11 +1348,13 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `line621` · L 78 / E 78.07 / Δ +0.07 · `hpcdb17679/gas | solid brick | pitched insulated` - [x] `11063823` · L 66 / E 66.07 / Δ +0.07 · `hpcdb17507/gas | cavity wall | pitched unknown` - [x] `21093278` · L 73 / E 72.93 / Δ -0.07 · `hpcdb16573/gas | cavity wall | pitched 100` +- [x] `100051035527` · L 74 / E 73.93 / Δ -0.07 · `hpcdb16842/gas | cavity wall | pitched 300 | sec:room heaters` - [x] `100010835776` · L 69 / E 68.93 / Δ -0.07 · `hpcdb17942/gas | cavity wall | pitched 270 | sec:room heaters` - [x] `10090019843` · L 76 / E 75.93 / Δ -0.07 · `hpcdb17615/gas | cavity wall | pitched 100` - [x] `10013351333` · L 70 / E 69.93 / Δ -0.07 · `hpcdb18759/gas | cavity wall | pitched insulated | consv4` - [x] `100080359994` · L 72 / E 72.07 / Δ +0.07 · `hpcdb15462/gas | cavity wall | pitched insulated | ext1` - [x] `100080794353` · L 73 / E 73.07 / Δ +0.07 · `hpcdb19027/gas | cavity wall | pitched 200 | ext1` +- [x] `1710007756` · L 76 / E 76.07 / Δ +0.07 · `h104/gas | cavity wall | pitched 250 | RR,ext1,sec:room heaters` - [x] `100080985468` · L 71 / E 71.07 / Δ +0.07 · `hpcdb17505/gas | cavity wall | pitched 125` - [x] `32067719` · L 67 / E 66.93 / Δ -0.07 · `h104/gas | cavity wall | pitched 150 | consv2,ext1` - [x] `100011465293` · L 47 / E 46.93 / Δ -0.07 · `h115/gas | cavity wall | pitched insulated | ext1` @@ -1422,7 +1391,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `3040036578` · L 64 / E 64.04 / Δ +0.04 · `hpcdb17553/gas | solid brick | pitched 250 | ext2` - [x] `100031665275` · L 63 / E 63.04 / Δ +0.04 · `hpcdb17932/gas | solid brick | pitched 50 | ext4,sec:room heaters` - [x] `1775039958` · L 71 / E 70.96 / Δ -0.04 · `hpcdb16841/gas | cavity wall | pitched 200` -- [x] `10034692050` · L 82 / E 82.04 / Δ +0.04 · `hpcdb18250/gas | sandstone as | pitched 350 | PV,ext2,sec:room heaters` - [x] `100100694867` · L 62 / E 62.04 / Δ +0.04 · `h119/gas | cavity wall | pitched insulated` - [x] `100031723834` · L 54 / E 53.96 / Δ -0.04 · `hpcdb18560/gas | cavity wall | pitched 100 | consv2,ext1,sec:room heaters` - [x] `10008662860` · L 69 / E 69.04 / Δ +0.04 · `hpcdb17505/gas | solid brick | pitched 100` @@ -1437,6 +1405,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100031375565` · L 70 / E 69.97 / Δ -0.03 · `hpcdb18907/gas | cavity wall | pitched 300` - [x] `100050859732` · L 57 / E 57.03 / Δ +0.03 · `h104/gas | solid brick | pitched insulated | ext3` - [x] `100010663631` · L 67 / E 67.03 / Δ +0.03 · `hpcdb17974/gas | cavity wall | pitched 100 | RR,consv4` +- [x] `100040268694` · L 58 / E 57.97 / Δ -0.03 · `h127/fuel28 | granite or | pitched insulated | RR,ext1,sec:room heaters` - [x] `100011594820` · L 70 / E 69.97 / Δ -0.03 · `hpcdb16136/gas | cavity wall | pitched insulated` - [x] `100031288765` · L 62 / E 61.97 / Δ -0.03 · `hpcdb18203/gas | cavity wall | pitched 100 | ext1,sec:room heaters` - [x] `10013290770` · L 54 / E 53.97 / Δ -0.03 · `h691/elec | cavity wall | (another dwelling | whw903` @@ -1474,6 +1443,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `77163938` · L 69 / E 68.99 / Δ -0.01 · `hpcdb17683/gas | solid brick | pitched insulated | ext1` - [x] `100110766495` · L 79 / E 79.01 / Δ +0.01 · `hpcdb16839/gas | cavity wall | (another dwelling` - [x] `100040446690` · L 72 / E 71.99 / Δ -0.01 · `h104/gas | system built | pitched 400+ | ext1,sec:room heaters` +- [x] `100090834242` · L 53 / E 52.99 / Δ -0.01 · `hpcdb16842/gas | cavity wall | pitched no | ext1,sec:room heaters` - [x] `10033241196` · L 78 / E 78.01 / Δ +0.01 · `h691/elec | solid brick | pitched 100 | whw909` - [x] `100061583852` · L 71 / E 71.01 / Δ +0.01 · `hpcdb17507/gas | cavity wall | pitched 300` - [x] `10009446250` · L 43 / E 42.99 / Δ -0.01 · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` diff --git a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py index c8836a92b..9ceaeea51 100644 --- a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py +++ b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py @@ -2686,6 +2686,46 @@ def test_dual_fuel_secondary_api_enum_9_prices_as_dual_fuel_not_lpg() -> None: assert secondary_factor_code == 10 +def test_fuel_cost_secondary_colliding_fuel_priced_at_canonical_rate() -> None: + # Arrange — the SAP-DRIVING `_fuel_cost` cascade prices the secondary + # via its own inline `secondary_high_rate_gbp_per_kwh`, distinct from + # the CO2/display `_secondary_fuel_cost_gbp_per_kwh`. It must apply the + # SAME `_GOV_API_COLLISION_FUELS` canonicalisation, else an ANTHRACITE + # secondary (gov-API `secondary_fuel_type=5`) resolves to the same-value + # Table-32 code 5 = bulk LPG (12.19 p/kWh) instead of anthracite + # (3.64 p/kWh) — a 3× over-cost that sank corpus cert 100050355518 + # (lodged 36, engine 20.8). Anthracite room-heater secondary on a + # mains-gas boiler main. + gas_boiler_main = MainHeatingDetail( + has_fghrs=False, main_fuel_type=26, heat_emitter_type=1, + emitter_temperature=1, main_heating_control=2106, + main_heating_category=2, sap_main_heating_code=102, + ) + anthracite_secondary_epc = make_minimal_sap10_epc( + total_floor_area_m2=_TYPICAL_TFA_M2, + habitable_rooms_count=4, + country_code="ENG", + sap_building_parts=[make_building_part(construction_age_band="D")], + sap_heating=make_sap_heating( + main_heating_details=[gas_boiler_main], + secondary_fuel_type=5, # gov-API enum: anthracite + secondary_heating_type=631, # room heater + ), + ) + + # Act + inputs = cert_to_inputs(anthracite_secondary_epc) + result = Sap10Calculator().calculate(anthracite_secondary_epc) + fc = inputs.fuel_cost + secondary_kwh = result.secondary_heating_fuel_kwh_per_yr + + # Assert — anthracite 3.64 p/kWh (0.0364), NOT the collision LPG + # 12.19 p/kWh the raw same-value Table-32 lookup returns. + assert secondary_kwh > 0.0 + assert abs(fc.secondary_total_cost_gbp - secondary_kwh * 0.0364) <= 1e-6 + assert abs(fc.secondary_total_cost_gbp - secondary_kwh * 0.1219) > 1.0 + + def test_is_electric_water_dual_fuel_table_32_code_10_is_not_electric() -> None: # Arrange — same API/Table 32 collision as `_is_electric_main` per # S0380.136 docstring. diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index 5c3afb4e9..67fc8153f 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -739,6 +739,23 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-10094975827", sap_score=66, ), + # UPRN 100050355518 (corpus C003; no cert number lodged). RdSAP-21.0.1 + # native — SEMI-DETACHED HOUSE, 122 m², 2 extensions (3 building parts), + # mains-gas boiler main (SAP 117) + ANTHRACITE room-heater secondary + # (gov-API secondary_fuel_type=5, SAP 631). The secondary-fuel collision + # cert: enum 5 collides with Table-32 code 5 (bulk LPG 12.19 p/kWh); the + # SAP-driving _fuel_cost path priced the anthracite secondary at the LPG + # rate instead of anthracite 3.64 p/kWh — a 3× over-cost on ~1431 kWh + # (+£100/yr → ECF 6.24 vs 4.67). Engine was 20.8 (Δ −15.2 vs lodged 36); + # canonicalising the secondary fuel lands 35.5 = lodged 36. CO2/PE + # already matched lodged (0.055 t / 1.7 kWh) — a pure cost-side gap, the + # signature that localised it. PINNED to the observed engine 36 = lodged. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_100050355518", + cert_num="uprn-100050355518", + sap_score=36, + ), ) diff --git a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py index 567479cf0..9a41d9e8a 100644 --- a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py +++ b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py @@ -207,7 +207,18 @@ _CORPUS = Path( # The bare "insulated" description (observed retrofit) keeps the 50 mm row. # The 27-cert loc4+NI cohort was systematically under-rated ~1 SAP (e.g. # 10094975827 band B -1.87 -> inside). Unit-pinned in test_rdsap_uvalues. -_MIN_WITHIN_HALF_SAP = 0.755 +# 0.755 -> 0.770 (MAE 0.708 -> 0.668) via the secondary-fuel collision fix +# on the SAP-DRIVING cost path (`_fuel_cost`): the gov-API secondary fuel +# enums 5 (anthracite) / 9 (dual fuel) / 33 (coal) collide with same-valued +# Table-32 codes for OTHER fuels, and `_fuel_cost`'s inline secondary rate +# passed the raw enum to the price lookup (unlike the already-canonicalised +# main-fuel boundary + CO2/display helper). Anthracite priced at the bulk-LPG +# code-5 rate (12.19 vs 3.64 p/kWh) 3x over-cost the secondary -> under-rate. +# Worst: cert 100050355518 (2 extensions, anthracite room-heater 2ndary) +# lodged 36 / engine 20.8 -> 35.9. 55 corpus certs carry a colliding +# secondary. Unit-pinned in test_cert_to_inputs (fuel_cost cost path, not +# just the display helper the prior enum-9 test guarded). +_MIN_WITHIN_HALF_SAP = 0.770 # 0.793 -> 0.789 via the §12 Unknown-meter + dual-electric-immersion off-peak # trigger (RdSAP 10 PDF p.62): Apartment 241 (main 691 + 903 dual immersion) # -5.38 -> -1.05. Worksheet-validated on "simulated case 48" (Elmhurst SAP 57, @@ -277,7 +288,7 @@ _MIN_WITHIN_HALF_SAP = 0.755 # oversized-PSR water eff 0.60 x 128.55% = 77.13% is floored to 100% (= # accredited Elmhurst (216)), taking the cert 68.03 -> 72.51 (|err| 4.97 -> # 0.49, now inside +-0.5). In-range heat pumps keep their > 100% water COP. -_MAX_SAP_MAE = 0.708 +_MAX_SAP_MAE = 0.669 _MAX_CO2_MAE_TONNES = 0.075 # t CO2 / yr vs co2_emissions_current _MAX_PE_PER_M2_MAE = 3.2 # kWh / m2 / yr vs energy_consumption_current From 928ce293d0a70a147b6ed3aa738be5893ce02d9a Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 19:48:10 +0000 Subject: [PATCH 05/84] docs(ledger): re-rank at 77.0% + triage electric-tariff & fabric tail Co-Authored-By: Claude Fable 5 --- .../uprn_100040550095/epc.json | 510 ++++++++++++++++++ scripts/corpus_1000/worklist.md | 8 +- 2 files changed, 514 insertions(+), 4 deletions(-) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100040550095/epc.json diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100040550095/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100040550095/epc.json new file mode 100644 index 000000000..98b566cf4 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100040550095/epc.json @@ -0,0 +1,510 @@ +{ + "uprn": 100040550095, + "roofs": [ + { + "description": "Pitched, 175 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Granite or whin, as built, no insulation (assumed)", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + }, + { + "description": "Solid brick, as built, no insulation (assumed)", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "floors": [ + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "addendum": { + "stone_walls": "true" + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "TQ1 2BW", + "hot_water": { + "description": "Electric immersion, standard tariff", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 5 + }, + "post_town": "TORQUAY", + "built_form": 4, + "created_at": "2026-05-20 13:21:34", + "door_count": 2, + "region_code": 15, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 2, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 2 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 903, + "water_heating_fuel": 29, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 29, + "heat_emitter_type": 0, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2603, + "main_heating_category": 10, + "main_heating_fraction": 1, + "sap_main_heating_code": 691, + "main_heating_data_source": 2 + } + ], + "immersion_heating_type": 2, + "cylinder_insulation_type": 2, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 38 + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 0.91, + "window_height": 1.64, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 0.91, + "window_height": 1.64, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 0.62, + "window_height": 0.91, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.2, + "window_height": 0.88, + "draught_proofed": "true", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.02, + "window_height": 0.82, + "draught_proofed": "true", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 0.6, + "window_height": 1.14, + "draught_proofed": "true", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Room heaters, electric", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 5 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Mid-terrace house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "11 Meadfoot Lane", + "assessment_type": "RdSAP", + "completion_date": "2026-05-20", + "inspection_date": "2026-05-20", + "extensions_count": 1, + "measurement_type": 1, + "total_floor_area": 59, + "transaction_type": 8, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2026-05-20", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "extract_fans_count": 1, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 510, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 1, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.31, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 17.29, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 7.27, + "quantity": "metres" + }, + "floor_construction": 1, + "heat_loss_perimeter": { + "value": 4.72, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.35, + "quantity": "metres" + }, + "total_floor_area": { + "value": 17.29, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 7.27, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 4.72, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "A", + "party_wall_construction": 1, + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "175mm", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + }, + { + "identifier": "Extension 1", + "wall_dry_lined": "N", + "wall_thickness": 185, + "floor_heat_loss": 7, + "sap_room_in_roof": { + "floor_area": 12.24, + "room_in_roof_type_2": { + "gable_wall_type_1": 1, + "gable_wall_type_2": 3, + "gable_wall_height_1": 2.5, + "gable_wall_height_2": 2.5, + "gable_wall_length_1": 7.39, + "gable_wall_length_2": 7.39, + "common_wall_height_1": 1.5, + "common_wall_height_2": 1.5, + "common_wall_length_1": 1.4, + "common_wall_length_2": 1.4 + }, + "construction_age_band": "A" + }, + "roof_construction": 5, + "wall_construction": 3, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.27, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 12.24, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 7.39, + "quantity": "metres" + }, + "floor_construction": 1, + "heat_loss_perimeter": { + "value": 2.8, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "A", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 4, + "roof_insulation_thickness": "ND", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 1266, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 1.1, + "energy_rating_average": 60, + "energy_rating_current": 40, + "lighting_cost_current": { + "value": 43, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer and appliance thermostats", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 366, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 679, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 449, + "currency": "GBP" + }, + "indicative_cost": "\u00a37,500 - \u00a311,000", + "improvement_type": "Q", + "improvement_details": { + "improvement_number": 7 + }, + "improvement_category": 5, + "energy_performance_rating": 55, + "environmental_impact_rating": 88 + }, + { + "sequence": 2, + "typical_saving": { + "value": 57, + "currency": "GBP" + }, + "indicative_cost": "\u00a35,000 - \u00a310,000", + "improvement_type": "W2", + "improvement_details": { + "improvement_number": 58 + }, + "improvement_category": 5, + "energy_performance_rating": 56, + "environmental_impact_rating": 89 + }, + { + "sequence": 3, + "typical_saving": { + "value": 100, + "currency": "GBP" + }, + "indicative_cost": "\u00a320 - \u00a340", + "improvement_type": "C", + "improvement_details": { + "improvement_number": 2 + }, + "improvement_category": 5, + "energy_performance_rating": 59, + "environmental_impact_rating": 89 + }, + { + "sequence": 4, + "typical_saving": { + "value": 671, + "currency": "GBP" + }, + "indicative_cost": "\u00a33,500 - \u00a310,000", + "improvement_type": "T", + "improvement_details": { + "improvement_number": 29 + }, + "improvement_category": 5, + "energy_performance_rating": 76, + "environmental_impact_rating": 83 + }, + { + "sequence": 5, + "typical_saving": { + "value": 220, + "currency": "GBP" + }, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 81, + "environmental_impact_rating": 84 + } + ], + "co2_emissions_potential": 1.1, + "energy_rating_potential": 81, + "lighting_cost_potential": { + "value": 43, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "alternative_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 822, + "currency": "GBP" + }, + "improvement_type": "J2", + "improvement_details": { + "improvement_number": 54 + }, + "improvement_category": 6, + "energy_performance_rating": 79, + "environmental_impact_rating": 96 + }, + { + "sequence": 2, + "typical_saving": { + "value": 524, + "currency": "GBP" + }, + "improvement_type": "Z3", + "improvement_details": { + "improvement_number": 53 + }, + "improvement_category": 6, + "energy_performance_rating": 71, + "environmental_impact_rating": 74 + } + ], + "hot_water_cost_potential": { + "value": 301, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2452.35, + "space_heating_existing_dwelling": 4576.09 + }, + "draughtproofed_door_count": 2, + "energy_consumption_current": 189, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 102, + "environmental_impact_current": 84, + "current_energy_efficiency_band": "E", + "environmental_impact_potential": 84, + "led_fixed_lighting_bulbs_count": 7, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 18, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index 24784b658..e40d688f2 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -25,7 +25,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - ⚠ `10093237426` · L 81 / E 78.44 / Δ -2.56 <- LIG-21.0 software (calc 10.2.2.0) honours lodged 0 extract fans literally; Elmhurst-validated convention (case 46) treats 0 as unknown -> Table 5 default. Fans-as-0 experiment closes 1.42 of 2.56; residual -1.14 unexplained, same-software quadruplet. ### C006 · Σ|Δ| 10.1 · 1 certs · `h691/elec | granite or | pitched 175 | RR,ext1,whw903` -- [ ] `100040550095` · L 40 / E 29.87 / Δ -10.13 +- [ ] `100040550095` · L 40 / E 29.87 / Δ -10.13 <- needs Elmhurst arbitration: PE+39/CO2+0.20 both over -> demand/fabric over-count (granite+solid-brick mixed walls + simplified RR type-2), not a cost bug ### C007 · Σ|Δ| 8.7 · 1 certs · `h125/fuel28 | cavity wall | pitched 250 | consv2,sec:room heaters` - [ ] `100121325434` · L 48 / E 56.75 / Δ +8.75 @@ -34,13 +34,13 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [ ] `100022294004` · L 75 / E 83.13 / Δ +8.13 ### C009 · Σ|Δ| 7.8 · 1 certs · `h195/elec | cavity wall | (another dwelling` -- [ ] `10091578598` · L 71 / E 78.81 / Δ +7.81 +- [ ] `10091578598` · L 71 / E 78.81 / Δ +7.81 <- electric-main off-peak tariff cohort: cost-only signature, storage/electric E7 high-rate-fraction split needs Elmhurst per-config arbitration (fixing blind regresses in-band storage certs) ### C010 · Σ|Δ| 7.7 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` -- [ ] `74061136` · L 73 / E 80.72 / Δ +7.72 +- [ ] `74061136` · L 73 / E 80.72 / Δ +7.72 <- electric storage cat7 E7: over-rate = off-peak rate/fraction too generous; needs Elmhurst tariff arbitration ### C011 · Σ|Δ| 7.1 · 1 certs · `h408/elec | cavity wall | (another dwelling | whw941` -- [ ] `200000322700` · L 58 / E 65.05 / Δ +7.05 +- [ ] `200000322700` · L 58 / E 65.05 / Δ +7.05 <- electric storage cat7 E7 over-rate; see 74061136 ### C012 · Σ|Δ| 6.7 · 1 certs · `h691/elec | solid brick | pitched 100 | RR,ext1,whw909` - [ ] `100032223878` · L 11 / E 17.67 / Δ +6.67 From cb089a630cc35a264180648d94b54f0aba798864 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 20:04:58 +0000 Subject: [PATCH 06/84] test(accuracy): ratchet SAP MAE 0.668 -> 0.658 via instantaneous-electric-DHW off-peak fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An instantaneous point-of-use electric water heater (WHC 907/909, no cylinder) on an off-peak tariff was billed 100% at the off-peak LOW rate by the generic electric-off-peak else-branch. But SAP 10.2 §12 (PDF line 2680) computes the off-peak on-peak HW proportion via Table 13, "dependent on the total floor area and the CYLINDER size" — it presumes a stored-water cylinder charged overnight. An instantaneous heater has NO cylinder, heats on demand, and cannot shift to the off-peak window, so 100% of its consumption bills at the HIGH rate (Table 12a WH high-rate fraction 1.0). Both the SAP-cost rate (`_hot_water_fuel_cost_gbp_per_kwh`) and the ADR-0014 / CO2-PE fraction (`_hot_water_high_rate_fraction`) fixed consistently (low-rate scalar -> 7-hour high rate; fraction 0.0 -> 1.0). Localised by deep-diving corpus cert 74061136 (HHR-storage mid-floor flat, WHC 909): PE matched lodged (+1.6, roof+floor zero-loss) while SAP over-rated +7.72 — the cost-only signature. Its DHW was ours £59 vs lodged £344 (5.8x); the tariff was the whole gap. Fix: +7.72 -> -1.25 (residual is separate small fabric). 7 corpus certs carry electric-instantaneous DHW on off-peak; the 3 outside 0.5 all move sharply inward (MAE the win, not within-0.5 crossings). RdSAP 10 §12 tariff routing confirmed spec-correct (Unknown meter + storage 409 -> off-peak 7-hour, Rule 2) — the bug was the DHW rate, not the tariff. Unit-pinned in test_cert_to_inputs; RealCertExpectation 74061136 = 72. Co-Authored-By: Claude Fable 5 --- .../uprn_74061136/epc.json | 315 +++++++++++++++ .../sap10_calculator/rdsap/cert_to_inputs.py | 14 + scripts/corpus_1000/worklist.md | 376 +++++++++--------- .../rdsap/test_cert_to_inputs.py | 36 ++ .../test_real_cert_sap_accuracy.py | 18 + .../epc_client/test_sap_accuracy_corpus.py | 9 +- 6 files changed, 579 insertions(+), 189 deletions(-) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_74061136/epc.json diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_74061136/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_74061136/epc.json new file mode 100644 index 000000000..86bc6b0c2 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_74061136/epc.json @@ -0,0 +1,315 @@ +{ + "uprn": 74061136, + "roofs": [ + { + "description": "(another dwelling above)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "walls": [ + { + "description": "Solid brick, with internal insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + { + "description": "Timber frame, with additional insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "(other premises below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "S41 7TP", + "hot_water": { + "description": "Electric instantaneous at point of use", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 5 + }, + "post_town": "Chesterfield,", + "psv_count": 0, + "built_form": 4, + "created_at": "2026-05-20 13:45:13", + "door_count": 1, + "region_code": 6, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 909, + "water_heating_fuel": 29, + "cylinder_thermostat": "N", + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 29, + "storage_heaters": [ + { + "index_number": 230002, + "number_of_heaters": 1, + "high_heat_retention": "true" + } + ], + "fan_flue_present": "Y", + "heat_emitter_type": 0, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2404, + "main_heating_category": 7, + "main_heating_fraction": 50, + "sap_main_heating_code": 409, + "main_heating_data_source": 2 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.6, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.6, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Address Matched", + "country_code": "ENG", + "main_heating": [ + { + "description": "Electric storage heaters", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 5 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Mid-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "Flat 3,", + "address_line_2": "14-20 Corporation Street,", + "assessment_type": "RdSAP", + "completion_date": "2026-05-20", + "inspection_date": "2026-05-20", + "extensions_count": 0, + "measurement_type": 1, + "open_flues_count": 0, + "sap_flat_details": { + "level": 2, + "top_storey": "N", + "storey_count": 3, + "flat_location": 1, + "heat_loss_corridor": 2, + "unheated_corridor_length": 6 + }, + "total_floor_area": 24, + "transaction_type": 1, + "conservatory_type": 2, + "heated_room_count": 1, + "other_flues_count": 0, + "registration_date": "2026-05-20", + "sap_energy_source": { + "mains_gas": "N", + "meter_type": 3, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "Portable electric heaters (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 0, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 300, + "floor_heat_loss": 3, + "roof_construction": 3, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.4, + "total_floor_area": 24, + "party_wall_length": 8, + "heat_loss_perimeter": 12 + } + ], + "wall_insulation_type": 3, + "construction_age_band": "B", + "sap_alternative_wall_1": { + "wall_area": 14.4, + "sheltered_wall": "Y", + "wall_dry_lined": "N", + "wall_thickness": 150, + "wall_construction": 5, + "wall_insulation_type": 3, + "wall_thickness_measured": "Y", + "wall_insulation_thickness": "NI" + }, + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": "ND", + "roof_insulation_thickness": "ND", + "wall_insulation_thickness": "measured", + "wall_insulation_thickness_measured": 25, + "wall_insulation_thermal_conductivity": 3 + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 1, + "heating_cost_current": { + "value": 348, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 0.4, + "energy_rating_average": 60, + "energy_rating_current": 73, + "lighting_cost_current": { + "value": 23, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Controls for high heat retention storage heaters", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "blocked_chimneys_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 348, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 344, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "schema_version_current": "LIG-21.0", + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 66, + "indicative_cost": "\u00a3600 - \u00a31,500", + "improvement_type": "Y", + "improvement_details": { + "improvement_number": 49 + }, + "improvement_category": 5, + "energy_performance_rating": 76, + "environmental_impact_rating": 92 + } + ], + "co2_emissions_potential": 0.4, + "energy_rating_potential": 76, + "lighting_cost_potential": { + "value": 23, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0", + "hot_water_cost_potential": { + "value": 278, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 1079.39, + "space_heating_existing_dwelling": 2013.05 + }, + "draughtproofed_door_count": 1, + "energy_consumption_current": 200, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "10.2.2.0", + "energy_consumption_potential": 187, + "environmental_impact_current": 91, + "cfl_fixed_lighting_bulbs_count": 0, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 92, + "led_fixed_lighting_bulbs_count": 6, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 19, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/domain/sap10_calculator/rdsap/cert_to_inputs.py b/domain/sap10_calculator/rdsap/cert_to_inputs.py index 104f736e4..262c54f42 100644 --- a/domain/sap10_calculator/rdsap/cert_to_inputs.py +++ b/domain/sap10_calculator/rdsap/cert_to_inputs.py @@ -2888,6 +2888,15 @@ def _hot_water_fuel_cost_gbp_per_kwh( ) blended = high_frac * high_rate + (1.0 - high_frac) * low_rate return blended * _PENCE_TO_GBP + if water_heating_code in _INSTANTANEOUS_WATER_CODES: + # SAP 10.2 §12 (PDF line 2680): the Table-13 off-peak on-peak HW + # split is keyed on the CYLINDER size — it presumes stored water + # charged overnight. An instantaneous point-of-use heater (WHC + # 907/909, no cylinder) heats on demand and cannot shift to the + # off-peak window, so 100% bills at the HIGH rate (Table 12a WH + # high-rate fraction 1.0), not the off-peak low rate. + high_rate, _low = _tariff_high_low_rates_p_per_kwh(tariff) + return high_rate * _PENCE_TO_GBP return _off_peak_low_rate_gbp_per_kwh(tariff) if water_heating_fuel is not None: return prices.unit_price_p_per_kwh(water_heating_fuel) * _PENCE_TO_GBP @@ -2942,6 +2951,11 @@ def _hot_water_high_rate_fraction( single_immersion=effective_single, tariff=tariff, ) + if water_heating_code in _INSTANTANEOUS_WATER_CODES: + # Instantaneous point-of-use electric DHW (WHC 907/909) has no + # cylinder to charge overnight — it heats on demand, wholly at the + # high/day rate (see `_hot_water_fuel_cost_gbp_per_kwh`). + return 1.0 return 0.0 diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index e40d688f2..4f8a9a5dd 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -1,6 +1,6 @@ # RdSAP-21.0.1 corpus campaign ledger -**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.0%** · MAE = **0.668** (floors in test_sap_accuracy_corpus.py) +**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.0%** · MAE = **0.658** (floors in test_sap_accuracy_corpus.py) Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail engine bug · ⛔ unbuildable. Line: `uprn · lodged L / eng E / Δ · signature`. Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` (preserves statuses & `<-` notes). @@ -36,554 +36,554 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C009 · Σ|Δ| 7.8 · 1 certs · `h195/elec | cavity wall | (another dwelling` - [ ] `10091578598` · L 71 / E 78.81 / Δ +7.81 <- electric-main off-peak tariff cohort: cost-only signature, storage/electric E7 high-rate-fraction split needs Elmhurst per-config arbitration (fixing blind regresses in-band storage certs) -### C010 · Σ|Δ| 7.7 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` -- [ ] `74061136` · L 73 / E 80.72 / Δ +7.72 <- electric storage cat7 E7: over-rate = off-peak rate/fraction too generous; needs Elmhurst tariff arbitration - -### C011 · Σ|Δ| 7.1 · 1 certs · `h408/elec | cavity wall | (another dwelling | whw941` +### C010 · Σ|Δ| 7.1 · 1 certs · `h408/elec | cavity wall | (another dwelling | whw941` - [ ] `200000322700` · L 58 / E 65.05 / Δ +7.05 <- electric storage cat7 E7 over-rate; see 74061136 -### C012 · Σ|Δ| 6.7 · 1 certs · `h691/elec | solid brick | pitched 100 | RR,ext1,whw909` +### C011 · Σ|Δ| 6.7 · 1 certs · `h691/elec | solid brick | pitched 100 | RR,ext1,whw909` - [ ] `100032223878` · L 11 / E 17.67 / Δ +6.67 -### C013 · Σ|Δ| 6.6 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` +### C012 · Σ|Δ| 6.6 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` - [ ] `200004296092` · L 71 / E 64.35 / Δ -6.65 -### C014 · Σ|Δ| 6.5 · 1 certs · `h408/elec | granite or | (another dwelling | sec:portable electric,whw903` +### C013 · Σ|Δ| 6.5 · 1 certs · `h408/elec | granite or | (another dwelling | sec:portable electric,whw903` - [ ] `100121397382` · L 69 / E 75.49 / Δ +6.49 -### C015 · Σ|Δ| 6.5 · 1 certs · `h691/elec | solid brick | (another dwelling | ext1,sec:room heaters,whw903` +### C014 · Σ|Δ| 6.5 · 1 certs · `h691/elec | solid brick | (another dwelling | ext1,sec:room heaters,whw903` - [ ] `100062100640` · L 54 / E 47.51 / Δ -6.49 -### C016 · Σ|Δ| 6.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 225` +### C015 · Σ|Δ| 6.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 225` - [ ] `100050844968` · L 71 / E 65.02 / Δ -5.98 -### C017 · Σ|Δ| 5.8 · 1 certs · `hpcdb17777/gas+2mains | cavity wall | pitched insulated | ext1,sec:room heaters,whw914` +### C016 · Σ|Δ| 5.8 · 1 certs · `hpcdb17777/gas+2mains | cavity wall | pitched insulated | ext1,sec:room heaters,whw914` - [ ] `line804` · L 52 / E 57.76 / Δ +5.76 -### C018 · Σ|Δ| 5.7 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` +### C017 · Σ|Δ| 5.7 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` - [ ] `200049463` · L 69 / E 63.28 / Δ -5.72 -### C019 · Σ|Δ| 5.6 · 2 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` +### C018 · Σ|Δ| 5.6 · 2 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` - [ ] `11071248` · L 78 / E 81.86 / Δ +3.86 - [ ] `12126160` · L 69 / E 70.71 / Δ +1.71 -### C020 · Σ|Δ| 4.6 · 1 certs · `hpcdb18560/gas | solid brick | pitched no | RR` +### C019 · Σ|Δ| 4.6 · 1 certs · `hpcdb18560/gas | solid brick | pitched no | RR` - [ ] `100051233481` · L 65 / E 69.64 / Δ +4.64 -### C021 · Σ|Δ| 4.5 · 1 certs · `h691/elec | timber frame | pitched limited | RR,ext2,whw903` +### C020 · Σ|Δ| 4.5 · 1 certs · `h691/elec | timber frame | pitched limited | RR,ext2,whw903` - [ ] `100061646773` · L 68 / E 63.46 / Δ -4.54 -### C022 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` +### C021 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` - [ ] `100071010014` · L 55 / E 50.47 / Δ -4.53 -### C023 · Σ|Δ| 4.5 · 1 certs · `hpcdb17815/gas | cavity wall | flat insulated` +### C022 · Σ|Δ| 4.5 · 1 certs · `hpcdb17815/gas | cavity wall | flat insulated` - [ ] `47084930` · L 74 / E 69.51 / Δ -4.49 -### C024 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` +### C023 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` - [ ] `10093342182` · L 82 / E 77.51 / Δ -4.49 -### C025 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` +### C024 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` - [ ] `5117280` · L 76 / E 71.56 / Δ -4.44 -### C026 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` +### C025 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` - [ ] `217060420` · L 42 / E 37.58 / Δ -4.42 -### C027 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` +### C026 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` - [ ] `72399971` · L 69 / E 64.60 / Δ -4.40 -### C028 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` +### C027 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` - [ ] `10007016314` · L 57 / E 52.64 / Δ -4.36 -### C029 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` +### C028 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` - [ ] `100052159386` · L 56 / E 51.92 / Δ -4.08 -### C030 · Σ|Δ| 4.0 · 1 certs · `h191/elec | cavity wall | (another dwelling` +### C029 · Σ|Δ| 4.0 · 1 certs · `h191/elec | cavity wall | (another dwelling` - [ ] `10002272664` · L 79 / E 74.96 / Δ -4.04 -### C031 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` +### C030 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` - [ ] `100040767294` · L 43 / E 47.04 / Δ +4.04 -### C032 · Σ|Δ| 3.6 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` +### C031 · Σ|Δ| 3.6 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` - [ ] `10002188054` · L 68 / E 64.42 / Δ -3.58 -### C033 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` +### C032 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` - [ ] `39066537` · L 78 / E 81.49 / Δ +3.49 -### C034 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` +### C033 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` - [ ] `100100137438` · L 69 / E 72.48 / Δ +3.48 -### C035 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C034 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100080122910` · L 60 / E 63.45 / Δ +3.45 -### C036 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` +### C035 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` - [ ] `452010022` · L 42 / E 38.67 / Δ -3.33 -### C037 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` +### C036 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` - [ ] `200004818752` · L 34 / E 30.73 / Δ -3.27 -### C038 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` +### C037 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` - [ ] `72351021` · L 64 / E 60.85 / Δ -3.15 -### C039 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` +### C038 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` - [ ] `22077224` · L 37 / E 33.90 / Δ -3.10 -### C040 · Σ|Δ| 3.1 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` -- [ ] `100032043038` · L 74 / E 77.06 / Δ +3.06 - -### C041 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` +### C039 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` - [ ] `10011740578` · L 70 / E 67.00 / Δ -3.00 -### C042 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +### C040 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` - [ ] `100110680822` · L 79 / E 76.07 / Δ -2.93 -### C043 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` +### C041 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` - [ ] `452032915` · L 75 / E 72.09 / Δ -2.91 -### C044 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` +### C042 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` - [ ] `100071306639` · L 73 / E 70.14 / Δ -2.86 -### C045 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` +### C043 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` - [ ] `100061346049` · L 55 / E 52.15 / Δ -2.85 -### C046 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` +### C044 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` - [ ] `10013008238` · L 41 / E 38.26 / Δ -2.74 -### C047 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` +### C045 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` - [ ] `10033187652` · L 70 / E 71.21 / Δ +1.21 - [ ] `200002730` · L 65 / E 64.13 / Δ -0.87 - [ ] `10023328117` · L 78 / E 78.64 / Δ +0.64 -### C048 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` +### C046 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` - [ ] `10004873253` · L 65 / E 62.29 / Δ -2.71 -### C049 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` +### C047 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` - [ ] `10090793715` · L 73 / E 75.71 / Δ +2.71 -### C050 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` +### C048 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100120745600` · L 65 / E 67.69 / Δ +2.69 -### C051 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` +### C049 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` - [ ] `100051178830` · L 63 / E 65.66 / Δ +2.66 -### C052 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` +### C050 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` - [ ] `100120018282` · L 64 / E 61.36 / Δ -2.64 -### C053 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +### C051 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` - [ ] `83035979` · L 65 / E 67.60 / Δ +2.60 -### C054 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` +### C052 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` - [ ] `10014073761` · L 75 / E 72.52 / Δ -2.48 -### C055 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` +### C053 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` - [ ] `100050964834` · L 60 / E 62.47 / Δ +2.47 -### C056 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` +### C054 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` - [ ] `100120752995` · L 71 / E 73.42 / Δ +2.42 -### C057 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` +### C055 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` - [ ] `100032230128` · L 55 / E 52.60 / Δ -2.40 -### C058 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` +### C056 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` - [ ] `100000034023` · L 73 / E 70.71 / Δ -2.29 -### C059 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` +### C057 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` - [ ] `100020377671` · L 62 / E 64.23 / Δ +2.23 -### C060 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` +### C058 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` - [ ] `22027335` · L 76 / E 73.77 / Δ -2.23 -### C061 · Σ|Δ| 2.2 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` +### C059 · Σ|Δ| 2.2 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` - [ ] `80838` · L 41 / E 43.19 / Δ +2.19 -### C062 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` +### C060 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` - [ ] `48056153` · L 65 / E 62.89 / Δ -2.11 -### C063 · Σ|Δ| 2.0 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` -- [ ] `100070295212` · L 75 / E 77.01 / Δ +2.01 - -### C064 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` +### C061 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` - [ ] `100021924710` · L 63 / E 65.00 / Δ +2.00 -### C065 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` +### C062 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` - [ ] `100031270375` · L 69 / E 70.93 / Δ +1.93 -### C066 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` +### C063 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` - [ ] `10001118522` · L 80 / E 78.07 / Δ -1.93 -### C067 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` +### C064 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` - [ ] `10010234711` · L 81 / E 79.08 / Δ -1.92 -### C068 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` +### C065 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` - [ ] `100031768368` · L 61 / E 59.12 / Δ -1.88 -### C069 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` +### C066 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` - [ ] `4510729926` · L 73 / E 71.15 / Δ -1.85 -### C070 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` +### C067 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` - [ ] `100091329112` · L 49 / E 50.82 / Δ +1.82 -### C071 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` +### C068 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` - [ ] `100061275133` · L 76 / E 77.24 / Δ +1.24 - [ ] `207032630` · L 74 / E 73.47 / Δ -0.53 -### C072 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` +### C069 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` - [ ] `10011797347` · L 47 / E 48.77 / Δ +1.77 -### C073 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` +### C070 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` - [ ] `100022668387` · L 68 / E 66.25 / Δ -1.75 -### C074 · Σ|Δ| 1.8 · 1 certs · `hpcdb17803/gas | timber frame | pitched 100` +### C071 · Σ|Δ| 1.8 · 1 certs · `hpcdb17803/gas | timber frame | pitched 100` - [ ] `200004017091` · L 71 / E 72.75 / Δ +1.75 -### C075 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` +### C072 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` - [ ] `100100892216` · L 69 / E 67.28 / Δ -1.72 -### C076 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` +### C073 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100060878876` · L 49 / E 50.71 / Δ +1.71 -### C077 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` +### C074 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` - [ ] `22032926` · L 61 / E 62.71 / Δ +1.71 -### C078 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` +### C075 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100010942905` · L 72 / E 73.70 / Δ +1.70 -### C079 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` +### C076 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` - [ ] `100030307976` · L 71 / E 69.37 / Δ -1.63 -### C080 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` +### C077 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` - [ ] `100061404488` · L 70 / E 68.38 / Δ -1.62 -### C081 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` +### C078 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` - [ ] `21067296` · L 67 / E 68.60 / Δ +1.60 -### C082 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` +### C079 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` - [ ] `5870047440` · L 58 / E 59.58 / Δ +1.58 -### C083 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` +### C080 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` - [ ] `100070450818` · L 65 / E 63.43 / Δ -1.57 -### C084 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` +### C081 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` - [ ] `100050881708` · L 70 / E 71.55 / Δ +1.55 -### C085 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` +### C082 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` - [ ] `10010254955` · L 79 / E 77.46 / Δ -1.54 -### C086 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` +### C083 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` - [ ] `3455011834` · L 69 / E 67.48 / Δ -1.52 -### C087 · Σ|Δ| 1.5 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` +### C084 · Σ|Δ| 1.5 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` - [ ] `100100274789` · L 60 / E 61.51 / Δ +1.51 -### C088 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` +### C085 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` - [ ] `100050852755` · L 65 / E 66.49 / Δ +1.49 -### C089 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` +### C086 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` - [ ] `100021326422` · L 70 / E 68.51 / Δ -1.49 -### C090 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` +### C087 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100050988345` · L 61 / E 59.51 / Δ -1.49 -### C091 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` +### C088 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` - [ ] `100030285758` · L 54 / E 55.48 / Δ +1.48 -### C092 · Σ|Δ| 1.5 · 1 certs · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` +### C089 · Σ|Δ| 1.5 · 1 certs · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` - [ ] `100090536443` · L 86 / E 84.52 / Δ -1.48 -### C093 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` +### C090 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` - [ ] `line80` · L 72 / E 70.56 / Δ -1.44 -### C094 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` +### C091 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` - [ ] `100080518673` · L 57 / E 58.42 / Δ +1.42 -### C095 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` +### C092 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` - [ ] `235025284` · L 69 / E 67.59 / Δ -1.41 -### C096 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` +### C093 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` - [ ] `250063088` · L 73 / E 71.60 / Δ -1.40 -### C097 · Σ|Δ| 1.4 · 1 certs · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` +### C094 · Σ|Δ| 1.4 · 1 certs · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` - [ ] `100050048691` · L 58 / E 59.39 / Δ +1.39 -### C098 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` +### C095 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` - [ ] `100110097281` · L 64 / E 65.37 / Δ +1.37 -### C099 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` +### C096 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` - [ ] `10091630692` · L 58 / E 56.63 / Δ -1.37 -### C100 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` +### C097 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` - [ ] `100031433810` · L 70 / E 68.63 / Δ -1.37 -### C101 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` +### C098 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` - [ ] `100012368622` · L 39 / E 40.32 / Δ +1.32 -### C102 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +### C099 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` - [ ] `90077194` · L 65 / E 63.69 / Δ -1.31 -### C103 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` +### C100 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` - [ ] `100031461986` · L 70 / E 71.29 / Δ +1.29 -### C104 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` +### C101 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` - [ ] `30095054` · L 46 / E 44.74 / Δ -1.26 -### C105 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` +### C102 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` - [ ] `100100055589` · L 58 / E 59.26 / Δ +1.26 -### C106 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` +### C103 · Σ|Δ| 1.2 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` +- [ ] `74061136` · L 73 / E 71.75 / Δ -1.25 <- electric storage cat7 E7: over-rate = off-peak rate/fraction too generous; needs Elmhurst tariff arbitration + +### C104 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` - [ ] `100091435353` · L 65 / E 66.23 / Δ +1.23 -### C107 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` +### C105 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` - [ ] `10091070164` · L 69 / E 69.60 / Δ +0.60 - [ ] `10090927185` · L 79 / E 79.60 / Δ +0.60 -### C108 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` +### C106 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` - [ ] `100100614412` · L 53 / E 51.81 / Δ -1.19 -### C109 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` +### C107 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` - [ ] `217091901` · L 62 / E 60.82 / Δ -1.18 -### C110 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` +### C108 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` - [x] `line768` · L 57 / E 55.84 / Δ -1.16 -### C111 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` +### C109 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` - [ ] `217061895` · L 61 / E 59.84 / Δ -1.16 -### C112 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C110 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `10002349227` · L 76 / E 77.14 / Δ +1.14 -### C113 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` +### C111 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` - [ ] `200001634005` · L 66 / E 67.11 / Δ +1.11 -### C114 · Σ|Δ| 1.1 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` +### C112 · Σ|Δ| 1.1 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` - [ ] `200004522639` · L 37 / E 35.89 / Δ -1.11 -### C115 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +### C113 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [ ] `100071059081` · L 63 / E 64.09 / Δ +1.09 -### C116 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` +### C114 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` - [ ] `100011820199` · L 55 / E 56.06 / Δ +1.06 -### C117 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` +### C115 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` - [ ] `90214753` · L 83 / E 81.95 / Δ -1.05 -### C118 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` +### C116 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` - [ ] `100051051866` · L 70 / E 71.04 / Δ +1.04 -### C119 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` +### C117 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` - [ ] `10013836852` · L 100 / E 98.97 / Δ -1.03 -### C120 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` +### C118 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` - [ ] `line899` · L 73 / E 71.97 / Δ -1.03 -### C121 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` +### C119 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` - [ ] `40037847` · L 81 / E 79.98 / Δ -1.02 -### C122 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` +### C120 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` - [ ] `10070056075` · L 80 / E 78.99 / Δ -1.01 -### C123 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` +### C121 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` - [ ] `200131078` · L 86 / E 85.00 / Δ -1.00 -### C124 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` +### C122 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` - [ ] `10000245212` · L 101 / E 100.00 / Δ -1.00 -### C125 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` +### C123 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` - [ ] `15129162` · L 62 / E 61.00 / Δ -1.00 -### C126 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` +### C124 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` - [ ] `23032873` · L 73 / E 72.00 / Δ -1.00 -### C127 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` +### C125 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` - [ ] `45019020` · L 62 / E 61.01 / Δ -0.99 -### C128 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` +### C126 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` - [ ] `42065028` · L 59 / E 58.02 / Δ -0.98 -### C129 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` +### C127 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` - [ ] `10032928147` · L 77 / E 76.04 / Δ -0.96 -### C130 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` +### C128 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` - [ ] `10010678937` · L 78 / E 77.04 / Δ -0.96 -### C131 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` +### C129 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` - [ ] `100011010151` · L 62 / E 62.96 / Δ +0.96 -### C132 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` +### C130 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` - [ ] `100050477371` · L 65 / E 64.04 / Δ -0.96 -### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` +### C131 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` - [ ] `10002945522` · L 61 / E 61.94 / Δ +0.94 -### C134 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` +### C132 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` - [ ] `10032957680` · L 45 / E 45.94 / Δ +0.94 -### C135 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` +### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` - [ ] `2465057465` · L 81 / E 81.93 / Δ +0.93 -### C136 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` +### C134 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` - [ ] `100090616327` · L 63 / E 63.93 / Δ +0.93 -### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` +### C135 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` - [ ] `100012753833` · L 74 / E 73.07 / Δ -0.93 -### C138 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` +### C136 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` - [ ] `100031269525` · L 53 / E 53.91 / Δ +0.91 -### C139 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` +### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` - [ ] `200003725358` · L 75 / E 74.09 / Δ -0.91 -### C140 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` +### C138 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` - [ ] `100050986162` · L 62 / E 61.10 / Δ -0.90 -### C141 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` +### C139 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` - [ ] `5300000141` · L 78 / E 77.10 / Δ -0.90 -### C142 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` +### C140 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` - [ ] `100050618404` · L 73 / E 73.89 / Δ +0.89 -### C143 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` +### C141 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` - [ ] `100090476016` · L 81 / E 81.89 / Δ +0.89 -### C144 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` +### C142 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` - [ ] `10012119141` · L 45 / E 45.89 / Δ +0.89 -### C145 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` +### C143 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` - [ ] `100040938206` · L 75 / E 75.89 / Δ +0.89 -### C146 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` +### C144 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `38188474` · L 76 / E 76.87 / Δ +0.87 -### C147 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +### C145 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100061194957` · L 69 / E 69.87 / Δ +0.87 -### C148 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` +### C146 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` - [ ] `100021236527` · L 72 / E 71.13 / Δ -0.87 -### C149 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` +### C147 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` - [ ] `100040193752` · L 71 / E 71.86 / Δ +0.86 -### C150 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` +### C148 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` - [ ] `100060701552` · L 74 / E 74.86 / Δ +0.86 -### C151 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` +### C149 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` - [ ] `10070396146` · L 61 / E 60.14 / Δ -0.86 -### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` +### C150 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` - [ ] `100030528930` · L 74 / E 73.16 / Δ -0.84 -### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` +### C151 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` - [ ] `100020982570` · L 72 / E 71.17 / Δ -0.83 -### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` +### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` - [ ] `394024487` · L 75 / E 74.17 / Δ -0.83 -### C155 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` +### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` - [ ] `217070698` · L 78 / E 78.83 / Δ +0.83 -### C156 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` +### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` - [ ] `77022508` · L 69 / E 68.18 / Δ -0.82 -### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` +### C155 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` - [ ] `100040259104` · L 68 / E 68.82 / Δ +0.82 -### C158 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` +### C156 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` - [ ] `100031399026` · L 70 / E 70.81 / Δ +0.81 -### C159 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` +### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` - [ ] `10009645698` · L 67 / E 67.81 / Δ +0.81 -### C160 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` +### C158 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` - [ ] `100080818887` · L 56 / E 55.19 / Δ -0.81 -### C161 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` +### C159 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100012374381` · L 69 / E 69.80 / Δ +0.80 -### C162 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` +### C160 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` - [ ] `100012350270` · L 78 / E 77.20 / Δ -0.80 -### C163 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` +### C161 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` - [ ] `100051109723` · L 60 / E 60.78 / Δ +0.78 -### C164 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` +### C162 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` - [ ] `100061616915` · L 63 / E 62.22 / Δ -0.78 -### C165 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` +### C163 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` - [ ] `line71` · L 74 / E 74.77 / Δ +0.77 -### C166 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` +### C164 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` - [ ] `100011603934` · L 72 / E 71.23 / Δ -0.77 -### C167 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` +### C165 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` - [ ] `24030987` · L 73 / E 73.76 / Δ +0.76 -### C168 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` +### C166 · Σ|Δ| 0.8 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` +- [ ] `100032043038` · L 74 / E 73.24 / Δ -0.76 + +### C167 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` - [ ] `100010866608` · L 71 / E 70.24 / Δ -0.76 -### C169 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` +### C168 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` - [ ] `100090399615` · L 67 / E 67.75 / Δ +0.75 -### C170 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` +### C169 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` - [ ] `100062174575` · L 46 / E 46.75 / Δ +0.75 -### C171 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` +### C170 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `10012341135` · L 79 / E 79.73 / Δ +0.73 -### C172 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +### C171 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` - [ ] `100091005853` · L 70 / E 69.27 / Δ -0.73 -### C173 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` +### C172 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` - [ ] `100021533514` · L 71 / E 71.73 / Δ +0.73 -### C174 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` +### C173 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` - [ ] `5062075` · L 69 / E 69.72 / Δ +0.72 -### C175 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` +### C174 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100040813308` · L 62 / E 62.72 / Δ +0.72 -### C176 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` +### C175 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` - [ ] `38105600` · L 68 / E 67.28 / Δ -0.72 -### C177 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` +### C176 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` - [ ] `line255` · L 72 / E 71.29 / Δ -0.71 -### C178 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` +### C177 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` - [ ] `5300047580` · L 69 / E 68.30 / Δ -0.70 -### C179 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` +### C178 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` - [ ] `100110433403` · L 69 / E 68.32 / Δ -0.68 -### C180 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` +### C179 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` - [ ] `10093416558` · L 79 / E 78.32 / Δ -0.68 -### C181 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` +### C180 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` - [ ] `100050958217` · L 68 / E 68.68 / Δ +0.68 -### C182 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` +### C181 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` - [ ] `100022667797` · L 68 / E 67.32 / Δ -0.68 -### C183 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C182 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100030528925` · L 78 / E 78.65 / Δ +0.65 -### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` +### C183 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` - [ ] `100110300037` · L 74 / E 73.35 / Δ -0.65 -### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` +### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` - [ ] `217092450` · L 52 / E 52.64 / Δ +0.64 -### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` +### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` - [ ] `100061164545` · L 72 / E 71.36 / Δ -0.64 -### C187 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` +### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` - [ ] `100051075936` · L 71 / E 70.36 / Δ -0.64 -### C188 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` +### C187 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` - [ ] `100011565830` · L 72 / E 72.64 / Δ +0.64 -### C189 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` +### C188 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` - [ ] `61010956` · L 75 / E 74.37 / Δ -0.63 -### C190 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` +### C189 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` - [ ] `100110752514` · L 67 / E 67.62 / Δ +0.62 +### C190 · Σ|Δ| 0.6 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` +- [ ] `100070295212` · L 75 / E 74.38 / Δ -0.62 + ### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` - [ ] `100012534027` · L 65 / E 64.38 / Δ -0.62 diff --git a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py index 9ceaeea51..ded178ade 100644 --- a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py +++ b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py @@ -4931,6 +4931,42 @@ def test_hot_water_from_pcdb_heat_pump_bills_at_app_n_wh_high_rate() -> None: assert abs(rate_immersion - 0.0750) <= 1e-6 +def test_instantaneous_electric_dhw_off_peak_bills_at_high_rate() -> None: + # Arrange — SAP 10.2 §12 (PDF line 2680): the off-peak on-peak HW + # proportion (Table 13) is "dependent on the total floor area and the + # CYLINDER SIZE" — it presumes a stored-water cylinder that can be + # charged overnight. An INSTANTANEOUS point-of-use electric heater + # (WHC 907/909, no cylinder) heats water on demand and CANNOT shift to + # the off-peak window, so 100% of its consumption is at the high rate + # (Table 12a high-rate fraction 1.0). The generic off-peak else-branch + # billed it at 100% off-peak LOW rate (5.50 p/kWh at 7-hour), 3× under- + # costing the DHW and over-rating the dwelling — corpus cert 74061136 + # (HHR-storage flat, WHC 909) lodged 73, engine 80.7. + from domain.sap10_calculator.tables.table_12a import Tariff + from domain.sap10_calculator.rdsap.cert_to_inputs import ( + _hot_water_fuel_cost_gbp_per_kwh, # pyright: ignore[reportPrivateUsage] + _hot_water_high_rate_fraction, # pyright: ignore[reportPrivateUsage] + ) + storage_main = MainHeatingDetail( + has_fghrs=False, main_fuel_type=29, heat_emitter_type=0, + emitter_temperature="NA", main_heating_control=2404, + main_heating_category=7, sap_main_heating_code=409, + ) + + # Act — instantaneous electric DHW (WHC 909) on a 7-hour off-peak tariff. + rate = _hot_water_fuel_cost_gbp_per_kwh( + 29, storage_main, Tariff.SEVEN_HOUR, SAP_10_2_SPEC_PRICES, + water_heating_code=909, + ) + fraction = _hot_water_high_rate_fraction( + 29, storage_main, Tariff.SEVEN_HOUR, water_heating_code=909, + ) + + # Assert — 100% at the 7-hour HIGH rate (15.29 p/kWh), NOT the low 5.50. + assert abs(rate - 0.1529) <= 1e-6 + assert fraction == 1.0 + + def test_heat_pump_water_efficiency_is_floored_at_100pct_per_app_n3_7() -> None: # Arrange — SAP 10.2 Appendix N3.7 ("Thermal efficiency for water # heating – heat pumps", PDF p.109): "multiply the thermal efficiency diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index 67fc8153f..cf5269895 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -756,6 +756,24 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-100050355518", sap_score=36, ), + # UPRN 74061136 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # MID-FLOOR FLAT 24 m², band B, HHR electric storage heaters (SAP 409) on + # an Unknown meter (type 3 → off-peak 7-hour per RdSAP 10 §12 Rule 2), + # INSTANTANEOUS electric point-of-use DHW (WHC 909, no cylinder). The + # instantaneous-DHW off-peak cert: its DHW was billed 100% at the 7-hour + # LOW rate (5.50 p) but SAP 10.2 §12 (Table-13 on-peak split is keyed on + # CYLINDER size) presumes stored water — an instantaneous heater has no + # cylinder, heats on demand, so 100% bills at the HIGH rate (15.29 p). + # Mid-floor flat → roof/floor both zero-loss, so PE matched lodged (+1.6) + # and the +7.72 over-rate isolated cleanly to the DHW tariff. Fix lands + # 71.75 (Δ −1.25 vs lodged 73); the tariff error is gone, the residual is + # a separate small fabric effect. PINNED to the observed engine 72. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_74061136", + cert_num="uprn-74061136", + sap_score=72, + ), ) diff --git a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py index 9a41d9e8a..3841f0c41 100644 --- a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py +++ b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py @@ -288,7 +288,14 @@ _MIN_WITHIN_HALF_SAP = 0.770 # oversized-PSR water eff 0.60 x 128.55% = 77.13% is floored to 100% (= # accredited Elmhurst (216)), taking the cert 68.03 -> 72.51 (|err| 4.97 -> # 0.49, now inside +-0.5). In-range heat pumps keep their > 100% water COP. -_MAX_SAP_MAE = 0.669 +# 0.669 -> 0.659 via the instantaneous-electric-DHW off-peak fix: WHC 907/909 +# (point-of-use, no cylinder) on an off-peak tariff was billed 100% at the +# off-peak LOW rate, but SAP 10.2 §12 (Table 13 on-peak proportion is keyed on +# CYLINDER size) presumes stored water; an instantaneous heater has no cylinder +# and heats on demand -> 100% high rate. Cert 74061136 (HHR-storage flat, +# WHC 909) +7.72 -> -1.25. Both the cost rate and the ADR-0014/CO2-PE fraction +# fixed (fraction 0 -> 1.0). Unit-pinned in test_cert_to_inputs. +_MAX_SAP_MAE = 0.659 _MAX_CO2_MAE_TONNES = 0.075 # t CO2 / yr vs co2_emissions_current _MAX_PE_PER_M2_MAE = 3.2 # kWh / m2 / yr vs energy_consumption_current From 0e784cbb1c47917ec39ed780d109cf59f2521767 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 20:24:56 +0000 Subject: [PATCH 07/84] test(accuracy): ratchet SAP MAE 0.658 -> 0.647 via wall added-insulation unknown-thickness default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A SOLID-BRICK or STONE wall lodging External/Internal insulation (wall_insulation_type 1/3) but no measured insulation thickness (gov-API "NI" -> None) was billed at its UNINSULATED §5.6/Table-6 U-value: the §5.8 added-insulation R-value adjustment gates on `insulation_thickness_mm > 0`, so an unknown thickness fell straight through to the raw solid-wall U (~1.4-1.7). This over-counted wall heat loss and under-rated the dwelling. RdSAP 10 §5.4 (PDF p.32): "the U-value with additional insulation is based on the thickness of insulation of mineral wool type (assume 100 mm if thickness is unknown)". Apply that 100 mm default so the §5.8 Table-14 R-value fires. Scoped to solid brick / stone (the only constructions with a §5.8 R-value path in u_wall) so cavity (composite path) and timber / system-built walls are untouched. Localised by deep-diving corpus cert 200004296092 (end-terrace, solid brick 360 mm "with external insulation", NI): walls 101.7 W/K (U~1.40, HLP 3.46 = absurd for an insulated wall) -> ~0.29; PE +59.6 -> ~0; engine 64.35 (Δ -6.65) -> 71.74 = lodged 71. ~8 solid-brick/stone corpus certs carry this NI-thickness-with-insulation shape. Gauge: within-0.5 held at 77.0%, SAP MAE 0.658 -> 0.647, CO2 0.074 -> 0.073, PE 3.2 -> 3.1 (floor ratcheted). Unit-pinned in test_rdsap_uvalues (brick 360 mm external NI -> 0.29) + RealCertExpectation 200004296092 = 72. Co-Authored-By: Claude Fable 5 --- .../uprn_200004296092/epc.json | 361 ++++++++++++++++ domain/sap10_ml/rdsap_uvalues.py | 27 ++ domain/sap10_ml/tests/test_rdsap_uvalues.py | 28 ++ scripts/corpus_1000/worklist.md | 394 +++++++++--------- .../test_real_cert_sap_accuracy.py | 16 + .../epc_client/test_sap_accuracy_corpus.py | 11 +- 6 files changed, 639 insertions(+), 198 deletions(-) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/epc.json diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/epc.json new file mode 100644 index 000000000..93fe00f70 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/epc.json @@ -0,0 +1,361 @@ +{ + "uprn": 200004296092, + "roofs": [ + { + "description": "Pitched, 150 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Solid brick, with external insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "LL16 3RL", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "DENBIGH", + "psv_count": 0, + "built_form": 3, + "created_at": "2026-05-14 14:33:05", + "door_count": 2, + "region_code": 7, + "report_type": 2, + "sap_heating": { + "number_baths": 0, + "cylinder_size": 1, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 2 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 1, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 16137 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.07, + "quantity": "m" + }, + "window_height": { + "value": 1.34, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.07, + "quantity": "m" + }, + "window_height": { + "value": 1.34, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 0.47, + "quantity": "m" + }, + "window_height": { + "value": 0.85, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 0.47, + "quantity": "m" + }, + "window_height": { + "value": 0.85, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 0.76, + "quantity": "m" + }, + "window_height": { + "value": 0.84, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "WLS", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "End-terrace house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "54 Myddleton Avenue", + "assessment_type": "RdSAP", + "completion_date": "2026-05-14", + "inspection_date": "2026-05-14", + "extensions_count": 0, + "measurement_type": 1, + "open_flues_count": 0, + "total_floor_area": 62, + "transaction_type": 1, + "conservatory_type": 1, + "heated_room_count": 3, + "other_flues_count": 0, + "registration_date": "2026-05-14", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 0, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 360, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.4, + "floor_insulation": 1, + "total_floor_area": 31.16, + "party_wall_length": 6.79, + "floor_construction": 1, + "heat_loss_perimeter": 15.97 + }, + { + "floor": 1, + "room_height": 2.4, + "total_floor_area": 31.16, + "party_wall_length": 6.79, + "heat_loss_perimeter": 15.97 + } + ], + "wall_insulation_type": 1, + "construction_age_band": "B", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "150mm", + "wall_insulation_thickness": "NI" + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 589, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 1.8, + "energy_rating_average": 60, + "energy_rating_current": 71, + "lighting_cost_current": { + "value": 50, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "blocked_chimneys_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 543, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 275, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "schema_version_current": "LIG-21.0", + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 47, + "indicative_cost": "\u00a35,000 - \u00a310,000", + "improvement_type": "W2", + "improvement_details": { + "improvement_number": 58 + }, + "improvement_category": 5, + "energy_performance_rating": 72, + "environmental_impact_rating": 79 + }, + { + "sequence": 2, + "typical_saving": 275, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 84, + "environmental_impact_rating": 81 + } + ], + "co2_emissions_potential": 1.4, + "energy_rating_potential": 84, + "lighting_cost_potential": { + "value": 50, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0", + "hot_water_cost_potential": { + "value": 275, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 1768.31, + "space_heating_existing_dwelling": 5933.75 + }, + "draughtproofed_door_count": 2, + "energy_consumption_current": 169, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "10.2.2.0", + "energy_consumption_potential": 130, + "environmental_impact_current": 77, + "cfl_fixed_lighting_bulbs_count": 0, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 81, + "led_fixed_lighting_bulbs_count": 12, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 29, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/domain/sap10_ml/rdsap_uvalues.py b/domain/sap10_ml/rdsap_uvalues.py index 9b7a8c509..0d2246394 100644 --- a/domain/sap10_ml/rdsap_uvalues.py +++ b/domain/sap10_ml/rdsap_uvalues.py @@ -157,6 +157,11 @@ _WALL_INSULATION_INTERNAL: Final[int] = 3 WALL_INSULATION_CAVITY_PLUS_EXTERNAL: Final[int] = 6 WALL_INSULATION_CAVITY_PLUS_INTERNAL: Final[int] = 7 +# RdSAP 10 §5.4 (PDF p.32): "assume 100 mm if thickness is unknown" — the +# default added-insulation thickness for an External / Internal wall +# insulation lodgement (type 1/3) with no measured thickness. +_WALL_ADDED_INSULATION_UNKNOWN_THICKNESS_MM: Final[int] = 100 + # RdSAP 10 §4-6 (page 73): default thermal conductivity of insulation when # no documentary evidence is available. Used to convert the lodged # `wall_insulation_thickness` (mm) into thermal resistance (m²K/W) via @@ -589,6 +594,28 @@ def u_wall( ctry = country if country is not None else Country.ENG age_idx = _age_index(age_band) band = _AGE_BANDS[age_idx] + # RdSAP 10 §5.4 (PDF p.32): "the U-value with additional insulation is + # based on the thickness of insulation of mineral wool type (assume + # 100 mm if thickness is unknown)". A SOLID-BRICK or STONE wall lodging + # External or Internal insulation (wall_insulation_type 1/3) but no + # measured insulation thickness (gov-API "NI" → None) takes the 100 mm + # default so the §5.8 Table-14 R-value adjustment (brick/stone branches + # below) fires instead of billing the wall at its uninsulated + # §5.6/Table-6 U (over-counting fabric loss → under-rate; corpus cert + # 200004296092, solid brick 360 mm, walls 101.7 W/K → PE +59.6). Scoped + # to brick/stone because only those constructions have a §5.8 added- + # insulation R-value path here — cavity uses the separate + # `WALL_INSULATION_CAVITY_PLUS_*` composite, and timber/system-built + # carry no §5.8 branch, so a thickness default there would be inert or + # mis-routed. + if ( + construction + in (WALL_STONE_GRANITE, WALL_STONE_SANDSTONE, WALL_SOLID_BRICK) + and wall_insulation_type + in (_WALL_INSULATION_EXTERNAL, _WALL_INSULATION_INTERNAL) + and (insulation_thickness_mm is None or insulation_thickness_mm == 0) + ): + insulation_thickness_mm = _WALL_ADDED_INSULATION_UNKNOWN_THICKNESS_MM # RdSAP 10 Tables 6-10 stone rows + footnote (a) (PDF p.33-39), §5.6 # formula (PDF p.40), §5.8 + Table 14 (PDF p.41-42). A documentary wall # thickness (per §5.3) routes stone in age bands A-E off the §5.6 formula, diff --git a/domain/sap10_ml/tests/test_rdsap_uvalues.py b/domain/sap10_ml/tests/test_rdsap_uvalues.py index e6019befa..f7067759c 100644 --- a/domain/sap10_ml/tests/test_rdsap_uvalues.py +++ b/domain/sap10_ml/tests/test_rdsap_uvalues.py @@ -835,6 +835,34 @@ def test_u_wall_stone_granite_with_external_insulation_applies_5_8_table_14_r_va assert abs(result - 0.57) <= 1e-4 +def test_u_wall_solid_brick_external_insulation_unknown_thickness_assumes_100mm() -> None: + # Arrange — RdSAP 10 §5.4 (PDF p.32): "the U-value with additional + # insulation is based on the thickness of insulation of mineral wool + # type (assume 100 mm if thickness is unknown)". A solid brick / stone + # wall lodging External or Internal insulation (wall_insulation_type + # 1/3) but NO measured insulation thickness (gov-API "NI" → parsed to + # None) must take the 100 mm §5.4 default so the §5.8 Table-14 R-value + # fires — NOT fall through to the uninsulated §5.6 U. Corpus cert + # 200004296092 (age-B solid brick 360 mm, "with external insulation", + # thickness NI) was billed at the uninsulated 1.40 (walls 101.7 W/K, + # HLP 3.46) → PE +59.6, SAP −6.65. With 100 mm: U₀(§5.6, 360 mm brick) + # + R(100 mm, λ=0.04 → 2.5) → 0.29. + + # Act + result = u_wall( + country=Country.ENG, + age_band="B", + construction=WALL_SOLID_BRICK, + insulation_thickness_mm=None, # gov-API "NI" — thickness unknown + insulation_present=True, + wall_insulation_type=1, # External + wall_thickness_mm=360, + ) + + # Assert — 100 mm default applied, not the uninsulated 1.40. + assert abs(result - 0.29) <= 1e-4 + + def test_u_wall_stone_granite_age_g_with_wall_thickness_ignores_5_6_formula_per_age_a_to_e_gate() -> None: # Arrange — §5.6 (PDF p.40) heading explicitly scopes the formula # to "age bands A to E". For age F onwards Table 6 gives literal diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index 4f8a9a5dd..07c3cccf3 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -1,6 +1,6 @@ # RdSAP-21.0.1 corpus campaign ledger -**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.0%** · MAE = **0.658** (floors in test_sap_accuracy_corpus.py) +**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.0%** · MAE = **0.647** (floors in test_sap_accuracy_corpus.py) Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail engine bug · ⛔ unbuildable. Line: `uprn · lodged L / eng E / Δ · signature`. Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` (preserves statuses & `<-` notes). @@ -42,584 +42,584 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C011 · Σ|Δ| 6.7 · 1 certs · `h691/elec | solid brick | pitched 100 | RR,ext1,whw909` - [ ] `100032223878` · L 11 / E 17.67 / Δ +6.67 -### C012 · Σ|Δ| 6.6 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` -- [ ] `200004296092` · L 71 / E 64.35 / Δ -6.65 - -### C013 · Σ|Δ| 6.5 · 1 certs · `h408/elec | granite or | (another dwelling | sec:portable electric,whw903` +### C012 · Σ|Δ| 6.5 · 1 certs · `h408/elec | granite or | (another dwelling | sec:portable electric,whw903` - [ ] `100121397382` · L 69 / E 75.49 / Δ +6.49 -### C014 · Σ|Δ| 6.5 · 1 certs · `h691/elec | solid brick | (another dwelling | ext1,sec:room heaters,whw903` +### C013 · Σ|Δ| 6.5 · 1 certs · `h691/elec | solid brick | (another dwelling | ext1,sec:room heaters,whw903` - [ ] `100062100640` · L 54 / E 47.51 / Δ -6.49 -### C015 · Σ|Δ| 6.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 225` +### C014 · Σ|Δ| 6.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 225` - [ ] `100050844968` · L 71 / E 65.02 / Δ -5.98 -### C016 · Σ|Δ| 5.8 · 1 certs · `hpcdb17777/gas+2mains | cavity wall | pitched insulated | ext1,sec:room heaters,whw914` +### C015 · Σ|Δ| 5.8 · 1 certs · `hpcdb17777/gas+2mains | cavity wall | pitched insulated | ext1,sec:room heaters,whw914` - [ ] `line804` · L 52 / E 57.76 / Δ +5.76 -### C017 · Σ|Δ| 5.7 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` -- [ ] `200049463` · L 69 / E 63.28 / Δ -5.72 - -### C018 · Σ|Δ| 5.6 · 2 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` +### C016 · Σ|Δ| 5.6 · 2 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` - [ ] `11071248` · L 78 / E 81.86 / Δ +3.86 - [ ] `12126160` · L 69 / E 70.71 / Δ +1.71 -### C019 · Σ|Δ| 4.6 · 1 certs · `hpcdb18560/gas | solid brick | pitched no | RR` +### C017 · Σ|Δ| 4.6 · 1 certs · `hpcdb18560/gas | solid brick | pitched no | RR` - [ ] `100051233481` · L 65 / E 69.64 / Δ +4.64 -### C020 · Σ|Δ| 4.5 · 1 certs · `h691/elec | timber frame | pitched limited | RR,ext2,whw903` +### C018 · Σ|Δ| 4.5 · 1 certs · `h691/elec | timber frame | pitched limited | RR,ext2,whw903` - [ ] `100061646773` · L 68 / E 63.46 / Δ -4.54 -### C021 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` +### C019 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` - [ ] `100071010014` · L 55 / E 50.47 / Δ -4.53 -### C022 · Σ|Δ| 4.5 · 1 certs · `hpcdb17815/gas | cavity wall | flat insulated` +### C020 · Σ|Δ| 4.5 · 1 certs · `hpcdb17815/gas | cavity wall | flat insulated` - [ ] `47084930` · L 74 / E 69.51 / Δ -4.49 -### C023 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` +### C021 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` - [ ] `10093342182` · L 82 / E 77.51 / Δ -4.49 -### C024 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` +### C022 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` - [ ] `5117280` · L 76 / E 71.56 / Δ -4.44 -### C025 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` +### C023 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` - [ ] `217060420` · L 42 / E 37.58 / Δ -4.42 -### C026 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` +### C024 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` - [ ] `72399971` · L 69 / E 64.60 / Δ -4.40 -### C027 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` +### C025 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` - [ ] `10007016314` · L 57 / E 52.64 / Δ -4.36 -### C028 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` +### C026 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` - [ ] `100052159386` · L 56 / E 51.92 / Δ -4.08 -### C029 · Σ|Δ| 4.0 · 1 certs · `h191/elec | cavity wall | (another dwelling` +### C027 · Σ|Δ| 4.0 · 1 certs · `h191/elec | cavity wall | (another dwelling` - [ ] `10002272664` · L 79 / E 74.96 / Δ -4.04 -### C030 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` +### C028 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` - [ ] `100040767294` · L 43 / E 47.04 / Δ +4.04 -### C031 · Σ|Δ| 3.6 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` +### C029 · Σ|Δ| 3.6 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` - [ ] `10002188054` · L 68 / E 64.42 / Δ -3.58 -### C032 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` +### C030 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` - [ ] `39066537` · L 78 / E 81.49 / Δ +3.49 -### C033 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` +### C031 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` - [ ] `100100137438` · L 69 / E 72.48 / Δ +3.48 -### C034 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C032 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100080122910` · L 60 / E 63.45 / Δ +3.45 -### C035 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` +### C033 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` - [ ] `452010022` · L 42 / E 38.67 / Δ -3.33 -### C036 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` +### C034 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` - [ ] `200004818752` · L 34 / E 30.73 / Δ -3.27 -### C037 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` +### C035 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` - [ ] `72351021` · L 64 / E 60.85 / Δ -3.15 -### C038 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` +### C036 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` - [ ] `22077224` · L 37 / E 33.90 / Δ -3.10 -### C039 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` +### C037 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` - [ ] `10011740578` · L 70 / E 67.00 / Δ -3.00 -### C040 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +### C038 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` - [ ] `100110680822` · L 79 / E 76.07 / Δ -2.93 -### C041 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` +### C039 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` - [ ] `452032915` · L 75 / E 72.09 / Δ -2.91 -### C042 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` +### C040 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` - [ ] `100071306639` · L 73 / E 70.14 / Δ -2.86 -### C043 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` +### C041 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` - [ ] `100061346049` · L 55 / E 52.15 / Δ -2.85 -### C044 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` +### C042 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` - [ ] `10013008238` · L 41 / E 38.26 / Δ -2.74 -### C045 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` +### C043 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` - [ ] `10033187652` · L 70 / E 71.21 / Δ +1.21 - [ ] `200002730` · L 65 / E 64.13 / Δ -0.87 - [ ] `10023328117` · L 78 / E 78.64 / Δ +0.64 -### C046 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` +### C044 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` - [ ] `10004873253` · L 65 / E 62.29 / Δ -2.71 -### C047 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` +### C045 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` - [ ] `10090793715` · L 73 / E 75.71 / Δ +2.71 -### C048 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` +### C046 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100120745600` · L 65 / E 67.69 / Δ +2.69 -### C049 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` +### C047 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` - [ ] `100051178830` · L 63 / E 65.66 / Δ +2.66 -### C050 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` +### C048 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` - [ ] `100120018282` · L 64 / E 61.36 / Δ -2.64 -### C051 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +### C049 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` - [ ] `83035979` · L 65 / E 67.60 / Δ +2.60 -### C052 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` +### C050 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` - [ ] `10014073761` · L 75 / E 72.52 / Δ -2.48 -### C053 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` +### C051 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` - [ ] `100050964834` · L 60 / E 62.47 / Δ +2.47 -### C054 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` +### C052 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` - [ ] `100120752995` · L 71 / E 73.42 / Δ +2.42 -### C055 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` +### C053 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` - [ ] `100032230128` · L 55 / E 52.60 / Δ -2.40 -### C056 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` +### C054 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` - [ ] `100000034023` · L 73 / E 70.71 / Δ -2.29 -### C057 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` +### C055 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` - [ ] `100020377671` · L 62 / E 64.23 / Δ +2.23 -### C058 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` +### C056 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` - [ ] `22027335` · L 76 / E 73.77 / Δ -2.23 -### C059 · Σ|Δ| 2.2 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` +### C057 · Σ|Δ| 2.2 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` - [ ] `80838` · L 41 / E 43.19 / Δ +2.19 -### C060 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` +### C058 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` - [ ] `48056153` · L 65 / E 62.89 / Δ -2.11 -### C061 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` +### C059 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` - [ ] `100021924710` · L 63 / E 65.00 / Δ +2.00 -### C062 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` +### C060 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` - [ ] `100031270375` · L 69 / E 70.93 / Δ +1.93 -### C063 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` +### C061 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` - [ ] `10001118522` · L 80 / E 78.07 / Δ -1.93 -### C064 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` +### C062 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` - [ ] `10010234711` · L 81 / E 79.08 / Δ -1.92 -### C065 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` +### C063 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` - [ ] `100031768368` · L 61 / E 59.12 / Δ -1.88 -### C066 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` +### C064 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` - [ ] `4510729926` · L 73 / E 71.15 / Δ -1.85 -### C067 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` +### C065 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` - [ ] `100091329112` · L 49 / E 50.82 / Δ +1.82 -### C068 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` +### C066 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` - [ ] `100061275133` · L 76 / E 77.24 / Δ +1.24 - [ ] `207032630` · L 74 / E 73.47 / Δ -0.53 -### C069 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` +### C067 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` - [ ] `10011797347` · L 47 / E 48.77 / Δ +1.77 -### C070 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` +### C068 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` - [ ] `100022668387` · L 68 / E 66.25 / Δ -1.75 -### C071 · Σ|Δ| 1.8 · 1 certs · `hpcdb17803/gas | timber frame | pitched 100` +### C069 · Σ|Δ| 1.8 · 1 certs · `hpcdb17803/gas | timber frame | pitched 100` - [ ] `200004017091` · L 71 / E 72.75 / Δ +1.75 -### C072 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` +### C070 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` - [ ] `100100892216` · L 69 / E 67.28 / Δ -1.72 -### C073 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` +### C071 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100060878876` · L 49 / E 50.71 / Δ +1.71 -### C074 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` +### C072 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` - [ ] `22032926` · L 61 / E 62.71 / Δ +1.71 -### C075 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` +### C073 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100010942905` · L 72 / E 73.70 / Δ +1.70 -### C076 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` +### C074 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` - [ ] `100030307976` · L 71 / E 69.37 / Δ -1.63 -### C077 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` +### C075 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` - [ ] `100061404488` · L 70 / E 68.38 / Δ -1.62 -### C078 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` +### C076 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` - [ ] `21067296` · L 67 / E 68.60 / Δ +1.60 -### C079 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` +### C077 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` - [ ] `5870047440` · L 58 / E 59.58 / Δ +1.58 -### C080 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` +### C078 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` - [ ] `100070450818` · L 65 / E 63.43 / Δ -1.57 -### C081 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` +### C079 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` - [ ] `100050881708` · L 70 / E 71.55 / Δ +1.55 -### C082 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` +### C080 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` - [ ] `10010254955` · L 79 / E 77.46 / Δ -1.54 -### C083 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` +### C081 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` - [ ] `3455011834` · L 69 / E 67.48 / Δ -1.52 -### C084 · Σ|Δ| 1.5 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` +### C082 · Σ|Δ| 1.5 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` - [ ] `100100274789` · L 60 / E 61.51 / Δ +1.51 -### C085 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` +### C083 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` - [ ] `100050852755` · L 65 / E 66.49 / Δ +1.49 -### C086 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` +### C084 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` - [ ] `100021326422` · L 70 / E 68.51 / Δ -1.49 -### C087 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` +### C085 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100050988345` · L 61 / E 59.51 / Δ -1.49 -### C088 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` +### C086 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` - [ ] `100030285758` · L 54 / E 55.48 / Δ +1.48 -### C089 · Σ|Δ| 1.5 · 1 certs · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` +### C087 · Σ|Δ| 1.5 · 1 certs · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` - [ ] `100090536443` · L 86 / E 84.52 / Δ -1.48 -### C090 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` +### C088 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` - [ ] `line80` · L 72 / E 70.56 / Δ -1.44 -### C091 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` +### C089 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` - [ ] `100080518673` · L 57 / E 58.42 / Δ +1.42 -### C092 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` +### C090 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` - [ ] `235025284` · L 69 / E 67.59 / Δ -1.41 -### C093 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` +### C091 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` - [ ] `250063088` · L 73 / E 71.60 / Δ -1.40 -### C094 · Σ|Δ| 1.4 · 1 certs · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` +### C092 · Σ|Δ| 1.4 · 1 certs · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` - [ ] `100050048691` · L 58 / E 59.39 / Δ +1.39 -### C095 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` +### C093 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` - [ ] `100110097281` · L 64 / E 65.37 / Δ +1.37 -### C096 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` +### C094 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` - [ ] `10091630692` · L 58 / E 56.63 / Δ -1.37 -### C097 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` +### C095 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` - [ ] `100031433810` · L 70 / E 68.63 / Δ -1.37 -### C098 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` +### C096 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` - [ ] `100012368622` · L 39 / E 40.32 / Δ +1.32 -### C099 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +### C097 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` - [ ] `90077194` · L 65 / E 63.69 / Δ -1.31 -### C100 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` +### C098 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` - [ ] `100031461986` · L 70 / E 71.29 / Δ +1.29 -### C101 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` +### C099 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` - [ ] `30095054` · L 46 / E 44.74 / Δ -1.26 -### C102 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` +### C100 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` - [ ] `100100055589` · L 58 / E 59.26 / Δ +1.26 -### C103 · Σ|Δ| 1.2 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` +### C101 · Σ|Δ| 1.2 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` - [ ] `74061136` · L 73 / E 71.75 / Δ -1.25 <- electric storage cat7 E7: over-rate = off-peak rate/fraction too generous; needs Elmhurst tariff arbitration -### C104 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` +### C102 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` - [ ] `100091435353` · L 65 / E 66.23 / Δ +1.23 -### C105 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` +### C103 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` - [ ] `10091070164` · L 69 / E 69.60 / Δ +0.60 - [ ] `10090927185` · L 79 / E 79.60 / Δ +0.60 -### C106 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` +### C104 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` - [ ] `100100614412` · L 53 / E 51.81 / Δ -1.19 -### C107 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` +### C105 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` - [ ] `217091901` · L 62 / E 60.82 / Δ -1.18 -### C108 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` +### C106 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` - [x] `line768` · L 57 / E 55.84 / Δ -1.16 -### C109 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` +### C107 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` - [ ] `217061895` · L 61 / E 59.84 / Δ -1.16 -### C110 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C108 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `10002349227` · L 76 / E 77.14 / Δ +1.14 -### C111 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` +### C109 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` - [ ] `200001634005` · L 66 / E 67.11 / Δ +1.11 -### C112 · Σ|Δ| 1.1 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` +### C110 · Σ|Δ| 1.1 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` - [ ] `200004522639` · L 37 / E 35.89 / Δ -1.11 -### C113 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +### C111 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [ ] `100071059081` · L 63 / E 64.09 / Δ +1.09 -### C114 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` +### C112 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` - [ ] `100011820199` · L 55 / E 56.06 / Δ +1.06 -### C115 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` +### C113 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` - [ ] `90214753` · L 83 / E 81.95 / Δ -1.05 -### C116 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` +### C114 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` - [ ] `100051051866` · L 70 / E 71.04 / Δ +1.04 -### C117 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` +### C115 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` - [ ] `10013836852` · L 100 / E 98.97 / Δ -1.03 -### C118 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` +### C116 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` - [ ] `line899` · L 73 / E 71.97 / Δ -1.03 -### C119 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` +### C117 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` - [ ] `40037847` · L 81 / E 79.98 / Δ -1.02 -### C120 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` +### C118 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` - [ ] `10070056075` · L 80 / E 78.99 / Δ -1.01 -### C121 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` +### C119 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` - [ ] `200131078` · L 86 / E 85.00 / Δ -1.00 -### C122 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` +### C120 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` - [ ] `10000245212` · L 101 / E 100.00 / Δ -1.00 -### C123 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` +### C121 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` - [ ] `15129162` · L 62 / E 61.00 / Δ -1.00 -### C124 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` +### C122 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` - [ ] `23032873` · L 73 / E 72.00 / Δ -1.00 -### C125 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` +### C123 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` - [ ] `45019020` · L 62 / E 61.01 / Δ -0.99 -### C126 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` +### C124 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` - [ ] `42065028` · L 59 / E 58.02 / Δ -0.98 -### C127 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` +### C125 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` - [ ] `10032928147` · L 77 / E 76.04 / Δ -0.96 -### C128 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` +### C126 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` - [ ] `10010678937` · L 78 / E 77.04 / Δ -0.96 -### C129 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` +### C127 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` - [ ] `100011010151` · L 62 / E 62.96 / Δ +0.96 -### C130 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` +### C128 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` - [ ] `100050477371` · L 65 / E 64.04 / Δ -0.96 -### C131 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` +### C129 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` - [ ] `10002945522` · L 61 / E 61.94 / Δ +0.94 -### C132 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` +### C130 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` - [ ] `10032957680` · L 45 / E 45.94 / Δ +0.94 -### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` +### C131 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` - [ ] `2465057465` · L 81 / E 81.93 / Δ +0.93 -### C134 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` +### C132 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` - [ ] `100090616327` · L 63 / E 63.93 / Δ +0.93 -### C135 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` +### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` - [ ] `100012753833` · L 74 / E 73.07 / Δ -0.93 -### C136 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` +### C134 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` - [ ] `100031269525` · L 53 / E 53.91 / Δ +0.91 -### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` +### C135 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` - [ ] `200003725358` · L 75 / E 74.09 / Δ -0.91 -### C138 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` +### C136 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` - [ ] `100050986162` · L 62 / E 61.10 / Δ -0.90 -### C139 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` +### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` - [ ] `5300000141` · L 78 / E 77.10 / Δ -0.90 -### C140 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` +### C138 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` - [ ] `100050618404` · L 73 / E 73.89 / Δ +0.89 -### C141 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` +### C139 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` - [ ] `100090476016` · L 81 / E 81.89 / Δ +0.89 -### C142 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` +### C140 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` - [ ] `10012119141` · L 45 / E 45.89 / Δ +0.89 -### C143 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` +### C141 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` - [ ] `100040938206` · L 75 / E 75.89 / Δ +0.89 -### C144 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` +### C142 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `38188474` · L 76 / E 76.87 / Δ +0.87 -### C145 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +### C143 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100061194957` · L 69 / E 69.87 / Δ +0.87 -### C146 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` +### C144 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` - [ ] `100021236527` · L 72 / E 71.13 / Δ -0.87 -### C147 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` +### C145 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` - [ ] `100040193752` · L 71 / E 71.86 / Δ +0.86 -### C148 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` +### C146 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` - [ ] `100060701552` · L 74 / E 74.86 / Δ +0.86 -### C149 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` +### C147 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` - [ ] `10070396146` · L 61 / E 60.14 / Δ -0.86 -### C150 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` +### C148 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` - [ ] `100030528930` · L 74 / E 73.16 / Δ -0.84 -### C151 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` +### C149 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` - [ ] `100020982570` · L 72 / E 71.17 / Δ -0.83 -### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` +### C150 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` - [ ] `394024487` · L 75 / E 74.17 / Δ -0.83 -### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` +### C151 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` - [ ] `217070698` · L 78 / E 78.83 / Δ +0.83 -### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` +### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` - [ ] `77022508` · L 69 / E 68.18 / Δ -0.82 -### C155 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` +### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` - [ ] `100040259104` · L 68 / E 68.82 / Δ +0.82 -### C156 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` +### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` - [ ] `100031399026` · L 70 / E 70.81 / Δ +0.81 -### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` +### C155 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` - [ ] `10009645698` · L 67 / E 67.81 / Δ +0.81 -### C158 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` +### C156 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` - [ ] `100080818887` · L 56 / E 55.19 / Δ -0.81 -### C159 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` +### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100012374381` · L 69 / E 69.80 / Δ +0.80 -### C160 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` +### C158 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` - [ ] `100012350270` · L 78 / E 77.20 / Δ -0.80 -### C161 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` +### C159 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` - [ ] `100051109723` · L 60 / E 60.78 / Δ +0.78 -### C162 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` +### C160 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` - [ ] `100061616915` · L 63 / E 62.22 / Δ -0.78 -### C163 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` +### C161 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` - [ ] `line71` · L 74 / E 74.77 / Δ +0.77 -### C164 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` +### C162 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` - [ ] `100011603934` · L 72 / E 71.23 / Δ -0.77 -### C165 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` +### C163 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` - [ ] `24030987` · L 73 / E 73.76 / Δ +0.76 -### C166 · Σ|Δ| 0.8 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` +### C164 · Σ|Δ| 0.8 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` - [ ] `100032043038` · L 74 / E 73.24 / Δ -0.76 -### C167 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` +### C165 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` - [ ] `100010866608` · L 71 / E 70.24 / Δ -0.76 -### C168 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` +### C166 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` - [ ] `100090399615` · L 67 / E 67.75 / Δ +0.75 -### C169 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` +### C167 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` - [ ] `100062174575` · L 46 / E 46.75 / Δ +0.75 -### C170 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` +### C168 · Σ|Δ| 0.7 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` +- [ ] `200004296092` · L 71 / E 71.74 / Δ +0.74 + +### C169 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `10012341135` · L 79 / E 79.73 / Δ +0.73 -### C171 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +### C170 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` - [ ] `100091005853` · L 70 / E 69.27 / Δ -0.73 -### C172 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` +### C171 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` - [ ] `100021533514` · L 71 / E 71.73 / Δ +0.73 -### C173 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` +### C172 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` - [ ] `5062075` · L 69 / E 69.72 / Δ +0.72 -### C174 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` +### C173 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100040813308` · L 62 / E 62.72 / Δ +0.72 -### C175 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` +### C174 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` - [ ] `38105600` · L 68 / E 67.28 / Δ -0.72 -### C176 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` +### C175 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` - [ ] `line255` · L 72 / E 71.29 / Δ -0.71 -### C177 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` +### C176 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` - [ ] `5300047580` · L 69 / E 68.30 / Δ -0.70 -### C178 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` +### C177 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` - [ ] `100110433403` · L 69 / E 68.32 / Δ -0.68 -### C179 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` +### C178 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` - [ ] `10093416558` · L 79 / E 78.32 / Δ -0.68 -### C180 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` +### C179 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` - [ ] `100050958217` · L 68 / E 68.68 / Δ +0.68 -### C181 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` +### C180 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` - [ ] `100022667797` · L 68 / E 67.32 / Δ -0.68 -### C182 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C181 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100030528925` · L 78 / E 78.65 / Δ +0.65 -### C183 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` +### C182 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` - [ ] `100110300037` · L 74 / E 73.35 / Δ -0.65 -### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` +### C183 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` - [ ] `217092450` · L 52 / E 52.64 / Δ +0.64 -### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` +### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` - [ ] `100061164545` · L 72 / E 71.36 / Δ -0.64 -### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` +### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` - [ ] `100051075936` · L 71 / E 70.36 / Δ -0.64 -### C187 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` +### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` - [ ] `100011565830` · L 72 / E 72.64 / Δ +0.64 -### C188 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` +### C187 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` - [ ] `61010956` · L 75 / E 74.37 / Δ -0.63 -### C189 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` +### C188 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` - [ ] `100110752514` · L 67 / E 67.62 / Δ +0.62 -### C190 · Σ|Δ| 0.6 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` +### C189 · Σ|Δ| 0.6 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` - [ ] `100070295212` · L 75 / E 74.38 / Δ -0.62 -### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` +### C190 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` - [ ] `100012534027` · L 65 / E 64.38 / Δ -0.62 -### C192 · Σ|Δ| 0.6 · 1 certs · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` +### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` - [x] `10009812472` · L 40 / E 39.40 / Δ -0.60 -### C193 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` +### C192 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` - [ ] `34080035` · L 77 / E 76.41 / Δ -0.59 -### C194 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` +### C193 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` - [ ] `21032732` · L 69 / E 69.59 / Δ +0.59 -### C195 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` +### C194 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100060562056` · L 66 / E 65.41 / Δ -0.59 -### C196 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` +### C195 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` - [ ] `100091086558` · L 79 / E 79.58 / Δ +0.58 -### C197 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` +### C196 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` - [ ] `line599` · L 74 / E 73.42 / Δ -0.58 -### C198 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` +### C197 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` - [ ] `100020407741` · L 72 / E 71.42 / Δ -0.58 -### C199 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` +### C198 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` - [ ] `100050839457` · L 70 / E 70.57 / Δ +0.57 -### C200 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` +### C199 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` - [ ] `42105250` · L 59 / E 59.57 / Δ +0.57 -### C201 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` +### C200 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` - [ ] `77200509` · L 69 / E 69.57 / Δ +0.57 -### C202 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` +### C201 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` - [ ] `200040534` · L 65 / E 65.56 / Δ +0.56 +### C202 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` +- [ ] `200049463` · L 69 / E 69.56 / Δ +0.56 + ### C203 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` - [ ] `100062527568` · L 61 / E 61.56 / Δ +0.56 @@ -839,6 +839,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100050553337` · L 70 / E 69.60 / Δ -0.40 · `hpcdb16839/gas | cavity wall | pitched 270 | sec:room heaters` - [x] `100071356612` · L 69 / E 68.61 / Δ -0.39 · `h301/coal-anth | solid brick | (another dwelling` - [x] `74041417` · L 79 / E 79.39 / Δ +0.39 · `hpcdb17507/gas | cavity wall | pitched 300 | PV` +- [x] `100110452552` · L 67 / E 67.39 / Δ +0.39 · `hpcdb15068/gas | cavity wall | pitched 175 | mv2,sec:room heaters` - [x] `100022607800` · L 73 / E 72.61 / Δ -0.39 · `hpcdb18119/gas | solid brick | pitched 270` - [x] `100022277442` · L 58 / E 58.39 / Δ +0.39 · `h409/elec | cavity wall | pitched insulated | whw903` - [x] `250029611` · L 73 / E 72.61 / Δ -0.39 · `hpcdb17553/gas | cavity wall | pitched 250 | consv2,ext1` @@ -885,7 +886,6 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `1775087250` · L 75 / E 74.63 / Δ -0.37 · `hpcdb18861/gas | cavity wall | pitched 250 | ext1` - [x] `100061253556` · L 60 / E 59.63 / Δ -0.37 · `hpcdb18907/gas | cavity wall | pitched 100 | sec:room heaters` - [x] `6083595` · L 76 / E 76.37 / Δ +0.37 · `hpcdb17685/gas | cavity wall | pitched insulated` -- [x] `100110452552` · L 67 / E 66.64 / Δ -0.36 · `hpcdb15068/gas | cavity wall | pitched 175 | mv2,sec:room heaters` - [x] `200033141` · L 76 / E 75.64 / Δ -0.36 · `hpcdb16738/gas | cavity wall | flat insulated` - [x] `100030357741` · L 72 / E 72.36 / Δ +0.36 · `hpcdb18560/gas | cavity wall | pitched 300 | consv2,ext1` - [x] `100080707176` · L 72 / E 71.64 / Δ -0.36 · `hpcdb10243/gas | cavity wall | pitched 100` diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index cf5269895..d7e22cd64 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -774,6 +774,22 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-74061136", sap_score=72, ), + # UPRN 200004296092 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # END-TERRACE HOUSE, TFA 62, age B, mains-gas COMBI (PCDB 16137), SOLID + # BRICK 360 mm "with external insulation" (wall_insulation_type 1) but + # thickness lodged "NI" (unknown). The wall added-insulation unknown- + # thickness cert: the §5.8 R-value gate needs thickness > 0, so the + # externally-insulated wall fell through to its UNINSULATED §5.6 U (1.40, + # walls 101.7 W/K, HLP 3.46) → PE +59.6, engine 64.35 (Δ −6.65 vs lodged + # 71). RdSAP 10 §5.4 (PDF p.32) "assume 100 mm if thickness is unknown" + # applies the 100 mm §5.8 default → U ~0.29, engine 71.74 = lodged. PINNED + # to the observed engine 72. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_200004296092", + cert_num="uprn-200004296092", + sap_score=72, + ), ) diff --git a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py index 3841f0c41..36ea16c3a 100644 --- a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py +++ b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py @@ -295,7 +295,16 @@ _MIN_WITHIN_HALF_SAP = 0.770 # and heats on demand -> 100% high rate. Cert 74061136 (HHR-storage flat, # WHC 909) +7.72 -> -1.25. Both the cost rate and the ADR-0014/CO2-PE fraction # fixed (fraction 0 -> 1.0). Unit-pinned in test_cert_to_inputs. -_MAX_SAP_MAE = 0.659 +# 0.659 -> 0.648 via the wall added-insulation unknown-thickness fix: a +# SOLID-BRICK/STONE wall lodging External/Internal insulation (type 1/3) with +# thickness "NI" (unknown) was billed UNINSULATED (§5.8 R-value gate needs a +# thickness > 0), over-counting wall heat loss. RdSAP 10 §5.4 (PDF p.32): +# "assume 100 mm if thickness is unknown" -> apply the 100 mm §5.8 default. +# Cert 200004296092 (age-B solid brick 360 mm + external, NI): walls 101.7 W/K +# (U~1.4) -> ~0.29, PE +59.6 -> ~0, SAP 64.35 -> 71.74 (lodged 71). Scoped to +# brick/stone (the only §5.8 R-value path); within-0.5 held at 77.0%, MAE +# 0.658 -> 0.647, PE 3.2 -> 3.1. Unit-pinned in test_rdsap_uvalues. +_MAX_SAP_MAE = 0.648 _MAX_CO2_MAE_TONNES = 0.075 # t CO2 / yr vs co2_emissions_current _MAX_PE_PER_M2_MAE = 3.2 # kWh / m2 / yr vs energy_consumption_current From 8e487a9bae5eee8077ca2713c4c812ac180fca56 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 20:49:58 +0000 Subject: [PATCH 08/84] docs(elmhurst): validate slice-5 wall fix against accredited Elmhurst worksheet (uprn 200004296092) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Built the cert in accredited Elmhurst RdSAP10-Online on the lodged register inputs; downloaded Input Summary + SAP Worksheets (committed alongside). Confirmed: - Slice 5 DIRECTION validated: the externally-insulated solid-brick wall is billed insulated by both tools (Elmhurst U 0.48, engine U 0.29), far below the uninsulated 1.40 the pre-fix §5.8 gate produced. - ROOF matches EXACTLY (U 0.30, 9.35 W/K). - Engine 71.74 = lodged 71; Elmhurst current SAP 66 (its "unknown external insulation" default is more conservative + this build used a generic combi and no keyed wall thickness, so 66 is not a clean engine-comparison). Follow-up lead (documented in ELMHURST_FINDINGS.md): the engine feeds the UNMEASURED lodged wall_thickness (360 mm, measured=N) into the §5.6 formula, whereas RdSAP §5.3 uses measured thickness / Table-3 default otherwise. The party-wall "difference" is NOT a bug (engine 0.25 is spec-correct, Table 15 row 4). Also adds the build script scripts/hyde/build_200004296092.py. No engine change in this commit. Co-Authored-By: Claude Fable 5 --- .../uprn_200004296092/ELMHURST_FINDINGS.md | 70 + .../uprn_200004296092/elmhurst_summary.pdf | Bin 0 -> 78631 bytes .../uprn_200004296092/elmhurst_worksheet.pdf | Bin 0 -> 44339 bytes .../uprn_200004296092/sum.txt | 254 ++++ .../uprn_200004296092/ws.txt | 1311 +++++++++++++++++ scripts/hyde/build_200004296092.py | 297 ++++ 6 files changed, 1932 insertions(+) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ELMHURST_FINDINGS.md create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_summary.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_worksheet.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/sum.txt create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ws.txt create mode 100644 scripts/hyde/build_200004296092.py diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ELMHURST_FINDINGS.md b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ELMHURST_FINDINGS.md new file mode 100644 index 000000000..165cbe29a --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ELMHURST_FINDINGS.md @@ -0,0 +1,70 @@ +# Elmhurst validation — UPRN 200004296092 (corpus, slice-5 wall fix) + +Built in accredited Elmhurst RdSAP10-Online on the lodged register inputs +(end-terrace house, solid brick + **external insulation, thickness "NI"**, +pitched 150 mm loft, solid ground floor, mains-gas combi, TFA 62). +Artefacts: `elmhurst_summary.pdf` (Input Summary), `elmhurst_worksheet.pdf` +(SAP Worksheets). + +## Headline +- **Lodged SAP 71**; **engine 71.74** (post slice-5 §5.4 100 mm fix, was 64.35); + **accredited Elmhurst current SAP 66** (band D), potential 75. +- Slice 5 is **directionally validated**: the externally-insulated wall must be + billed insulated, not at the uninsulated 1.40 the §5.8 gate produced. Both + Elmhurst (0.48) and the engine (0.29) are far below 1.40. + +## Fabric line-by-line (engine dive vs Elmhurst worksheet) +| Element | Engine | Elmhurst | Note | +|---|---|---|---| +| External wall | 21.1 W/K (U 0.29) | 30.7 W/K (U **0.48**, "SolidWallDensePlaster**200**") | see WALL below | +| Roof | 9.35 W/K (U 0.30) | 9.35 W/K (U 0.30) | **exact match** | +| Ground floor | 21.2 W/K | 22.7 W/K (U 0.73) | close | +| Party wall | **8.57 W/K** | **0.00 W/K** | see PARTY below | +| Windows | 7.96 W/K | ~same area (4.31 + 4×2.89 split) | ~ | + +The wall (engine −9.6) and party wall (engine +8.6) differences nearly cancel, +so the two HTCs are close; the residual SAP gap (71.7 vs 66) is dominated by the +heating system — this build used a GENERIC Post-98 condensing combi, whereas the +engine uses the lodged PCDB 16137 (Ideal Logic combi 30). Not a clean 1e-4 +comparison for that reason. + +## Leads (both partly confounded by an imperfect build — see caveats) +1. **WALL — base thickness on an unmeasured wall.** The cert lodges + `wall_thickness 360` but `wall_thickness_measured = N`. Elmhurst modelled a + **~200 mm** base wall ("SolidWallDensePlaster200") — but note my build did + NOT enter a wall thickness, so Elmhurst used its own default; had I keyed + 360 mm it might match the engine. The open question is genuine though: + RdSAP §5.3 uses the documentary/measured thickness, and when NOT measured + the engine perhaps should fall to the Table-3 default rather than trust the + unmeasured lodged 360 mm. WORTH A DEDICATED CHECK (build with the thickness + keyed both ways). +2. **PARTY WALL — NOT an engine gap.** Elmhurst rendered the party wall as + "Solid, U 0.00", but the engine's **0.25** is SPEC-CORRECT: RdSAP §5.10 + Table 15 row 4 ("unable to determine, house") = 0.25. The cert lodges + `party_wall_construction = 0` (unable to determine), so 0.25 is right; the + Elmhurst 0.00 reflects how my build's party-wall dropdown resolved (a + "Solid" masonry party wall, Table 15 row 1 = 0), not the cert's "unknown". + Build artifact, not a bug. + +## Build caveats (why the 71.7-vs-66 residual isn't cleanly attributable) +- Heating: built a GENERIC Post-98 condensing combi; the engine uses the lodged + PCDB 16137 (Ideal Logic combi 30) — different efficiency. +- Wall thickness: not keyed into Elmhurst (defaulted 200 mm) vs engine's 360 mm. +- Party wall: entered as a resolved type (0.00) vs the cert's "unable to + determine" (engine 0.25). +So this build's clean, confirmed results are: (a) the ROOF matches exactly +(U 0.30, 9.35 W/K), (b) slice 5's DIRECTION is validated (insulated wall, not +the uninsulated 1.40). The wall-thickness question (lead 1) is the one genuine +follow-up. + +## Slice-5 calibration note (banked) +The accredited "External insulation, **Unknown** thickness" selection in Elmhurst +produced U 0.48 (≈ a 50 mm equivalent on its 200 mm base), NOT the 0.29 the +§5.4-literal "assume 100 mm" gives on the engine's 360 mm base. The 100 mm fix +nevertheless matches the LODGED corpus better (MAE 0.658 → 0.647, within held) — +lodged assessors typically knew the real (~100 mm) thickness the register then +flattens to "NI". Per the campaign rule (engine = lodged is the goal; Elmhurst +arbitrates only when lodged can't be explained from register data), the 100 mm +fix STANDS; the lodged-vs-Elmhurst gap here is explained by the register's "NI" +discarding the assessor's thickness knowledge. But the base-thickness and +party-wall leads above are genuine and independent of the insulation default. diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_summary.pdf new file mode 100644 index 0000000000000000000000000000000000000000..2caa620585e51ce1227bc8e5b126082b3b7f2a75 GIT binary patch literal 78631 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 literal 0 HcmV?d00001 diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_worksheet.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3ebe582a3d801be3a4289f974ce21c86f4e0c421 GIT binary patch literal 44339 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 literal 0 HcmV?d00001 diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/sum.txt b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/sum.txt new file mode 100644 index 000000000..25a3346a2 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/sum.txt @@ -0,0 +1,254 @@ + Summary Information +Surveyor: P960-0001 +Name: Richard Matthew Ratcliff Title: Mr. Tel Number: 07760 443 469 +Survey Reference: 001431 My Reference: Khalim-test +Current SAP rating: D 66 Potential SAP rating: C 75 Emissions (t/year): 1.927 tonnes +Current EI rating: C 72 Potential EI rating: C 76 Fuel Bill: £1026 +Property Details: +RdSAP version: RdSAP10 +Reference Number: P960-0001-001431 +My Reference: Khalim-test +Lodgement Required: No +Regs Region: England +EPC Language: English +UPRN: +Postcode: W6 9BF +Region: Thames Valley +House Name: 28 Distillery Wharf +House No: 28 +Street: Distillery Wharf +Locality: +Town: London +County: +Property Tenure: Owner-occupied +Transaction Type: Marketed sale +Inspection Date: 25/06/2025 +Process date: 02/07/2026 +Check for the existence of No +an EPC: +Does an EPC exist at the No +point of carrying out this +energy assessment: +Reason why another energy +assessment needs to be +undertaken: + + RdSAP Inputs + +Property Description: +1.0 Property type: H House + E End-Terrace +2.0 Number of Storeys: 2 + Habitable Rooms: 3 + Heated Habitable Rooms: 3 +3.0 Date Built: Main Property B 1900-1929 + + +4.0 Dimensions: +Dimension type: Internal +Main Property + Floor Room Heat Loss Party Wall + Area Height Wall Perimeter Length + [m2] [m] [m] [m] + + 1st Floor: 31.16 2.40 15.97 6.79 + Lowest Floor: 31.16 2.40 15.97 6.79 No + +5.0 Conservatory: +Is there a conservatory? No +7.0 Walls: + + + + + © Elmhurst Energy Systems Limited Registered Office Unit 16, St Johns Business Park, Lutterworth, Leicestershire LE17 4HB + Summary Information +Main Property + + Type SO Solid Brick + Insulation E External + Insulation Thickness Unknown + Conductivity Known No + Thermal Conductivity Lambda = 0.04 W/m*K + Wall Thickness Unknown No + Wall Thickness 260 mm + U-value Known No + Party Wall Type S Solid masonry / timber / system build +8.0 Roofs: +Main Property + + Type PA Pitched (slates/tiles), access to loft + Insulation J Joists + Insulation Thickness 150 mm + U-value Known No +8.1 Rooms in Roof: +9.0 Floors: +Main Property + + Location G Ground floor + Type S Solid + Insulation A As built + Default U-value 0.73 + U-value Known No +10.0 Doors: + Total Number of Doors 2 + Number of Insulated Doors 0 +11.0 Windows: + Frame Frame Glazing Building U g Draught Permanent +W H Area Glazing Type Location Orient. Data-Source + Type Factor Gap Part value value Proofed Shutters + Double with unknown +4.31 1.00 4.31 PVC 0.70 12 mm Main External wall North Manufacturer 2.80 0.76 Yes None + install date + Double with unknown +2.89 1.00 2.89 PVC 0.70 12 mm Main External wall West Manufacturer 2.80 0.76 Yes None + install date + Double with unknown +2.89 1.00 2.89 PVC 0.70 12 mm Main External wall North Manufacturer 2.80 0.76 Yes None + install date + Double with unknown +2.89 1.00 2.89 PVC 0.70 12 mm Main External wall East Manufacturer 2.80 0.76 Yes None + install date + + Draught Proofing 67 % +12.0 Ventilation & Cooling + No. of open chimneys 0 + No. of open flues 0 + No. of open chimneys/open flues attached to closed fire 0 + No. of flues attached to solid fuel boiler 0 + No. of open flues attached to other heater 0 + No. of blocked chimneys 0 + No. of intermittent extract fans 0 + No. of passive vents 0 + No. of flueless gas fires 0 + Fixed Space Cooling No + Draught Lobby Unable to determine + + + + + © Elmhurst Energy Systems Limited Registered Office Unit 16, St Johns Business Park, Lutterworth, Leicestershire LE17 4HB + Summary Information +12.1 Mechanical Ventilation + Mechanical Ventilation No +12.2 Air Pressure Test + Test Method Not available +13.0 Lighting + Total number of bulbs 6 + Number of LED and CFL Known Yes + Number of LED lights 0 + Number of CFL lights 0 + Total number of Low Energy 0 + Total number of incandescents 6 +14.0 Main Heating1 + PCDF boiler Reference 0 + Main Heating EES Code BGW + Main Heating SAP Code 104 + Heat Emitter Radiators + Heat pump age 2013 or later + Flue Type Balanced + Fan Assisted Flue Yes + Design flow temperature <= 35°C + PCDF Heating Controls 0 + Main Heating Controls EES CBE + Main Heating Controls Sap SAP code 2106, Programmer, room thermostat and TRVs + PCDF Compensator 0 + Percentage of Heat 100 % +14.1 Main Heating2 + PCDF boiler Reference 0 + Main Heating EES Code + Main Heating SAP Code 0 + Percentage of Heat 0% +14.1 Community Heating/Heat Network + Heating Type None +14.2 Meters +Electricity meter type Single +Main gas Yes +Electricity Smart Meter Present No +Gas Smart Meter Present No +15.0 Water Heating + Water Heating Code HWP + Water Heating SapCode 901 + Water Heating Fuel Type Mains gas +15.1 Hot Water Cylinder + Hot Water Cylinder Present No +15.2 Community Hot Water + PCDF boiler Reference 0 +16.0 Solar water heating + Solar Water Heating No +17.0 Waste Water Heat Recovery System + Is WWHRS present in the property? No / Unknown +1x.0 Baths and Showers + Total Number of Baths 2 + Number of Baths Connected 0 + +Description Type Connected + +1 Non-electric shower None + + + + + © Elmhurst Energy Systems Limited Registered Office Unit 16, St Johns Business Park, Lutterworth, Leicestershire LE17 4HB + Summary Information +18.0 Flue Gas Heat Recovery System + Present No +19.0 Photovoltaic Panel + Photovoltaic Panel None + Export capable meter No +20.0 Wind Turbine + Terrain Type Urban + Wind turbine present? No +22.0 Special Features +21.0 Small-Scale Hydro + Electricity generated [kWh/year] 0.00 + + + + + © Elmhurst Energy Systems Limited Registered Office Unit 16, St Johns Business Park, Lutterworth, Leicestershire LE17 4HB + Summary Information + + Recommendations + + Loft insulation (SAP increase too small) + Flat roof insulation (Not applicable) + Room-in-roof insulation (Not applicable) + Cavity wall insulation (Not applicable) + Solid wall insulation (SAP increase too small) + Floor insulation (solid floor) (Recommended) + Hot water cylinder insulation (Not applicable) + Draught proofing (SAP increase too small) + Low energy lighting (Recommended) + Cylinder thermostat (Not applicable) + Heating controls for wet central heating system (Already installed) + Upgrade boiler, same fuel (Already installed) + Change heating to condensing gas condensing boiler (fuel switch) (Not applicable) + Flue gas heat recovery in conjunction with new boiler (Not applicable) + Solar water heating (SAP increase too small) + Heat recovery system for mixer showers (SAP increase too small) + Double glazed windows (Already installed) + Insulated doors (SAP increase too small) + Solar photovoltaic panels (Recommended) + Wind turbine (Not applicable) + PV diverter (Not applicable) + PV battery (Not applicable) + Water heating controls (Not applicable) + + Alternative Recommendations + External wall insulation with cavity insulation (Not applicable) + Biomass boiler (alternative) (Not applicable) + Micro CHP (alternative) (Not applicable) + + Related Party Disclosure + +No related party + + Addenda +When considering the PV installation consider installing PV battery and a PV diverter for water heating + + + + + © Elmhurst Energy Systems Limited Registered Office Unit 16, St Johns Business Park, Lutterworth, Leicestershire LE17 4HB + \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ws.txt b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ws.txt new file mode 100644 index 000000000..20c66e415 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ws.txt @@ -0,0 +1,1311 @@ +---------------------------------------------------------------------------------------------------- + SAP 10.02 Input Data (House) 02/07/2026 +---------------------------------------------------------------------------------------------------- +Full RefNo 001431 +Inspection date 25/06/2025 00:00:00 +Regs Region England +SAP Region Thames Valley +Property address 28 Distillery Wharf, 28 Distillery Wharf London +Postcode W6 9BF +Dwelling Orientation North +Property Type House, End-Terrace +Storeys 2 +Property Age Band B +Sheltered Sides 1 +Sunlight Shade Average or unknown +Measurements Perimeter, Floor Area, Storey Height + 1st Storey: 15.97, 31.16, 2.40 + 2nd Storey: 15.97, 31.16, 2.65 +Living Area 18.7 m2, fraction: 30.0% +Thermal Mass Enter TMP value +Thermal MassValue 250.00 +External Walls Nett Area, Gross Area, Kappa, Element, Construction, Type, ShelterFactor, UValueFinal + External walls Main 63.97, 80.65, 190, SolidWallDensePlaster200, Solid, 0.0, 0.48, Gross +Party Walls Area, Kappa, Element, Construction, Type, ShelterFactor, UValueFinal + Party walls Main 34.29, 0, Other, Solid, 0, 0.00 +External Roofs Nett Area, Gross Area, Kappa, Construction, Element, UValueFinal + External roof Main 31.16, 31.16, 9, Plasterboard, insulated slope, 0.3 +Heat Loss Floors Area, Kappa, Construction, Element, Type, ShelterFactor, UValueFinal + Ground floor Main 31.16, 0.00, Other, Ground Floor - Solid, 0.00, 0.73 +Description Data Source, Type, Glazing, Glazing Gap, Argon Filled, Solar Trans, Frame Type, Frame Factor, U Value + Doors uninsulated 1 Manufacturer, Solid Door, , , , , , , + Windows 1 Manufacturer, Window, Double glazed, , , 0.76, , 0.7, +Openings Opening Type, Location, Orientation, Pitch, Width, Height, Count, Area + Doors uninsulated Solid Door, External walls Main, East, , 3.7, 1, 1, 3.70 + Windows 1(Main) Window, External walls Main, North, , 4.31, 1, 1, 4.31 + Windows 2(Main) Window, External walls Main, West, , 2.89, 1, 1, 2.89 + Windows 2(Main) Window, External walls Main, North, , 2.89, 1, 1, 2.89 + Windows 2(Main) Window, External walls Main, East, , 2.89, 1, 1, 2.89 +Conservatory None +Draught Proofing 67 +Draught Lobby No +Thermal Bridges + Bridging User Input + Y 0.15 + Description RDSAP conversion + List of Bridges Junction with, Bridge Type, Source Type, Imported, Length, Psi, Adjusted, Result, Reference + 0. External wall, E22 Basement floor, Table K1 - Default, No, 1.00, 0.220, 0.220, 0.22, TER +Pressure Test False +Pressure Test Method Blower Door +Designed AP50 15.00 +AsBuilt AP50 0.00 +Property Tested True +Mechanical Ventilation None +Open Chimneys 0 +Open Flues 0 +Chimneys/Flues Attached to Closed Fire0 +Flues Attached to Solid Fuel Boiler0 +Flues Attached to Other Heater0 +Blocked chimneys 0 +Intermittent Fans 0 +Passive Vents 0 +Flueless Gas Fires 0 +Cooling System None +Lightings Name, Power, Efficacy, Capacity, Count + incandescent lights 60, 11.2, 672, 6 +Percentage of LEL Fittings 0.00 +Electricity Tariff Standard +Main Heating 1 + Description + Percentage 100 + FuelType Mains gas + SAP Code 104 + Boiler Efficiency Type SAP Table + Controls by PCDF 0 + MHS Controls 2106 Programmer, room thermostat and TRVs + Boiler Interlock Yes + Compensator 0 + Delayed Start Stat No + Ctrl SAP Code 2106 + Flue Type Balanced + Fan Assisted Flue Yes + Pumped Pump in heated space + Heat Pump Age 2013 or later + Heat Emitter Radiators + Flow Temperature Enter value + Flow Temperature Value 35 + Combi boiler type Standard Combi + Combi keep hot type None +Main Heating 2 None +Smoke Control Area Unknown +Community Heating None +Secondary Heating + Description Electricity Electric Panel, convector or radiant heaters + SAP Code 691 + Efficiency 100 +Water Heating + Type MainHeating1 + WHS 901 From main heating system + Low Water Usage No + SAP Code 901 + Cold Water Source From mains + Total number of baths in property2 + Hot Water Cylinder None +Showers Description, Type, Flow rate, Rated power, Connected, Connected WWHRS + Shower 01 Vented hot water system, 7.00, , No, +Flue Gas Heat Recovery System None +Waste Water Heat Recovery none +PV Unit None +Terrain Type Urban +Wind Turbine None +Small Scale Hydro None +Special Features None +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +SAP 10 WORKSHEET FOR Existing dwelling (SAP) (Version 10.2, February 2022) +CALCULATION OF ENERGY RATING +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +1. Overall dwelling characteristics + ---------------------------------------------------------------------------------------------------- + Area Storey height Volume +Main dwelling (m2) (m) (m3) + Ground floor 31.1600 (1b) x 2.4000 (2b) = 74.7840 (1b) - (3b) + First floor 31.1600 (1c) x 2.6500 (2c) = 82.5740 (1c) - (3c) +Total floor area TFA = (1a)+(1b)+(1c)+(1d)+(1e)...(1n) 62.3200 (4) +Dwelling volume (3a)+(3b)+(3c)+(3d)+(3e)...(3n) = 157.3580 (5) +---------------------------------------------------------------------------------------------------- +2. Ventilation rate +---------------------------------------------------------------------------------------------------- + m3 per hour + +Number of open chimneys 0 * 80 = 0.0000 (6a) +Number of open flues 0 * 20 = 0.0000 (6b) +Number of chimneys / flues attached to closed fire 0 * 10 = 0.0000 (6c) +Number of flues attached to solid fuel boiler 0 * 20 = 0.0000 (6d) +Number of flues attached to other heater 0 * 35 = 0.0000 (6e) +Number of blocked chimneys 0 * 20 = 0.0000 (6f) +Number of intermittent extract fans 0 * 10 = 0.0000 (7a) +Number of passive vents 0 * 10 = 0.0000 (7b) +Number of flueless gas fires 0 * 40 = 0.0000 (7c) + Air changes per hour +Infiltration due to chimneys, flues and fans = (6a)+(6b)+(6c)+(6d)+(6e)+(6f)+(6g)+(7a)+(7b)+(7c) = 0.0000 / (5) = 0.0000 (8) + Number of storeys in the dwelling (ns) 2 (9) + Additional infiltration [(9) - 1] x 0.1 = 0.1000 (10) + Structural infiltration: 0.25 for steel or timber frame or 0.35 for masonry construction 0.3500 (11) + If suspended wooden floor, enter 0.2 (unsealed) or 0.1 (sealed), else enter 0 0.0000 (12) + If no draught lobby, enter 0.05, else enter 0 0.0500 (13) + Percentage of windows and doors draught stripped 67.0000 (14) + Window infiltration 0.25 - [0.2 * (14) / 100] = 0.1160 (15) +Pressure test No +Infiltration rate 0.6160 (18) +Number of sides sheltered 1 (19) +Shelter factor (20) = 1 - [0.075 x (19)] = 0.9250 (20) +Infiltration rate adjusted to include shelter factor (21) = (18) x (20) = 0.5698 (21) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Wind speed 5.1000 5.0000 4.9000 4.4000 4.3000 3.8000 3.8000 3.7000 4.0000 4.3000 4.5000 4.7000 (22) +Wind factor 1.2750 1.2500 1.2250 1.1000 1.0750 0.9500 0.9500 0.9250 1.0000 1.0750 1.1250 1.1750 (22a) +Adj infilt rate + 0.7265 0.7123 0.6980 0.6268 0.6125 0.5413 0.5413 0.5271 0.5698 0.6125 0.6410 0.6695 (22b) +Effective ac 0.7639 0.7537 0.7436 0.6964 0.6876 0.6465 0.6465 0.6389 0.6623 0.6876 0.7055 0.7241 (25) +---------------------------------------------------------------------------------------------------- +3. Heat losses and heat loss parameter +---------------------------------------------------------------------------------------------------- +Element Gross Openings NetArea U-value A x U K-value A x K +Main dwelling m2 m2 m2 W/m2K W/K kJ/m2K kJ/K + Doors uninsulated 1 3.7000 3.0000 11.1000 (26) + Windows 1 12.9800 2.5180 32.6835 (27) + Ground floor Main 31.1600 0.7300 22.7468 (28a) + External walls Main 80.6500 16.6800 63.9700 0.4800 30.7056 (29a) + External roof Main 31.1600 31.1600 0.3000 9.3480 (30) +Total net area of external elements Aum(A, m2) 142.9700 (31) +Fabric heat loss, W/K = Sum (A x U) (26)...(30) + (32) = 106.5839 (33) +Main dwelling + Party walls Main 34.2900 0.0000 0.0000 (32) +Thermal mass parameter (TMP = Cm / TFA) in kJ/m2K 250.0000 (35) +Thermal bridges (User defined value 0.150 * total exposed area) 21.4455 (36) +Point Thermal bridges (36a) = 0.0000 +Total fabric heat loss (33) + (36) + (36a) = 128.0294 (37) +Ventilation heat loss calculated monthly (38)m = 0.33 x (25)m x (5) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(38)m 39.6678 39.1356 38.6140 36.1641 35.7058 33.5720 33.5720 33.1768 34.3939 35.7058 36.6330 37.6025 (38) +Heat transfer coeff + 167.6971 167.1650 166.6434 164.1935 163.7351 161.6013 161.6013 161.2062 162.4232 163.7351 164.6624 165.6318 (39) +Average = Sum(39)m / 12 = 164.1913 + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +HLP 2.6909 2.6824 2.6740 2.6347 2.6273 2.5931 2.5931 2.5867 2.6063 2.6273 2.6422 2.6578 (40) +HLP (average) 2.6346 +Days in mont 31 28 31 30 31 30 31 31 30 31 30 31 +---------------------------------------------------------------------------------------------------- +4. Water heating energy requirements (kWh/year) +---------------------------------------------------------------------------------------------------- +Assumed occupancy 2.0464 (42) +Hot water usage for mixer showers + 51.2148 50.4451 49.3236 47.1777 45.5941 43.8281 42.8243 43.9374 45.1575 47.0536 49.2456 51.0186 (42a) +Hot water usage for baths + 26.6248 26.2294 25.6726 24.6459 23.8771 23.0246 22.5642 23.1171 23.7192 24.6313 25.6791 26.5348 (42b) +Hot water usage for other uses + 37.4603 36.0981 34.7359 33.3737 32.0116 30.6494 30.6494 32.0116 33.3737 34.7359 36.0981 37.4603 (42c) +Average daily hot water use (litres/day) 105.9586 (43) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Daily hot water use + 115.2999 112.7727 109.7321 105.1973 101.4828 97.5021 96.0379 99.0660 102.2504 106.4209 111.0229 115.0137 (44) +Energy conte 182.6069 160.5868 168.6541 144.0099 136.6153 119.8902 116.1495 122.6644 126.0850 144.4121 158.1725 180.0836 (45) +Energy content (annual) Total = Sum(45)m = 1759.9303 +Distribution loss (46)m = 0.15 x (45)m + 27.3910 24.0880 25.2981 21.6015 20.4923 17.9835 17.4224 18.3997 18.9127 21.6618 23.7259 27.0125 (46) +Water storage loss (or HIU loss): +Total storage loss + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (56) +If cylinder contains dedicated solar storage + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (57) +Primary loss 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (59) +Combi loss 50.9589 46.0274 50.9589 49.3151 50.9589 48.0832 48.9398 50.4830 49.3151 50.9589 49.3151 50.9589 (61) +Total heat required for water heating calculated for each month + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (62) +WWHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63a) +PV diverter 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63b) +Solar input 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63c) +FGHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63d) +Output from w/h + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) + Total per year (kWh/year) = Sum(64)m = 2356.2034 (64) +Electric shower(s) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (64a) + Total Energy used by instantaneous electric shower(s) (kWh/year) = Sum(64a)m = 0.0000 (64a) +Heat gains from water heating, kWh/month + 73.4565 64.9019 68.8172 60.2121 58.1643 51.8843 50.8547 53.4067 54.2520 60.7568 64.9211 72.6175 (65) +---------------------------------------------------------------------------------------------------- +5. Internal gains (see Table 5 and 5a) +---------------------------------------------------------------------------------------------------- +Metabolic gains (Table 5), Watts + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(66)m 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 (66) +Lighting gains (calculated in Appendix L, equation L9 or L9a), also see Table 5 + 71.1593 63.2031 51.4002 38.9133 29.0881 24.5574 26.5352 34.4914 46.2943 58.7812 68.6064 73.1371 (67) +Appliances gains (calculated in Appendix L, equation L13 or L13a), also see Table 5 + 266.8027 269.5713 262.5946 247.7419 228.9932 211.3720 199.5999 196.8313 203.8081 218.6607 237.4095 255.0307 (68) +Cooking gains (calculated in Appendix L, equation L15 or L15a), also see Table 5 + 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 (69) +Pumps, fans 3.0000 3.0000 3.0000 3.0000 3.0000 0.0000 0.0000 0.0000 0.0000 3.0000 3.0000 3.0000 (70) +Losses e.g. evaporation (negative values) (Table 5) + -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 (71) +Water heating gains (Table 5) + 98.7319 96.5803 92.4963 83.6279 78.1778 72.0615 68.3530 71.7832 75.3500 81.6623 90.1682 97.6042 (72) +Total internal gains + 529.9471 522.6078 499.7442 463.5362 429.5123 398.2441 384.7412 393.3590 415.7055 452.3574 489.4372 519.0251 (73) +---------------------------------------------------------------------------------------------------- +6. Solar gains +---------------------------------------------------------------------------------------------------- +[Jan] Area Solar flux g FF Access Gains + m2 Table 6a Specific data Specific data factor W + W/m2 or Table 6b or Table 6c Table 6d +---------------------------------------------------------------------------------------------------- +North 7.2000 10.6334 0.7600 0.7000 0.7700 28.2260 (74) +East 2.8900 19.6403 0.7600 0.7000 0.7700 20.9262 (76) +West 2.8900 19.6403 0.7600 0.7000 0.7700 20.9262 (80) +---------------------------------------------------------------------------------------------------- +Solar gains 70.0784 135.8134 226.4912 343.8726 439.3250 459.0195 433.0958 359.0167 267.0192 161.3582 87.0054 57.9479 (83) +Total gains 600.0254 658.4212 726.2353 807.4088 868.8373 857.2635 817.8371 752.3758 682.7247 613.7156 576.4425 576.9730 (84) +---------------------------------------------------------------------------------------------------- +7. Mean internal temperature (heating season) +---------------------------------------------------------------------------------------------------- +Temperature during heating periods in the living area from Table 9, Th1 (C) 21.0000 (85) +Utilisation factor for gains for living area, ni1,m (see Table 9a) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +tau 25.8071 25.8893 25.9703 26.3578 26.4316 26.7806 26.7806 26.8462 26.6451 26.4316 26.2827 26.1289 +alpha 2.7205 2.7260 2.7314 2.7572 2.7621 2.7854 2.7854 2.7897 2.7763 2.7621 2.7522 2.7419 +util living area + 0.9881 0.9836 0.9735 0.9487 0.8963 0.8005 0.6824 0.7308 0.8833 0.9610 0.9831 0.9894 (86) +MIT 18.0348 18.2517 18.6986 19.3471 19.9916 20.5260 20.7917 20.7386 20.2963 19.4913 18.6708 18.0152 (87) +Th 2 18.9125 18.9172 18.9219 18.9438 18.9479 18.9673 18.9673 18.9709 18.9598 18.9479 18.9396 18.9309 (88) +util rest of house + 0.9835 0.9772 0.9621 0.9235 0.8361 0.6608 0.4360 0.4985 0.7860 0.9365 0.9751 0.9853 (89) +MIT 2 16.4138 16.6314 17.0756 17.7205 18.3240 18.7776 18.9318 18.9172 18.6162 17.8743 17.0631 16.4054 (90) +Living area fraction fLA = Living area / (4) = 0.3001 (91) +MIT 16.9002 17.1176 17.5626 18.2086 18.8244 19.3022 19.4899 19.4637 19.1203 18.3595 17.5455 16.8884 (92) +Temperature adjustment 0.0000 +adjusted MIT 16.9002 17.1176 17.5626 18.2086 18.8244 19.3022 19.4899 19.4637 19.1203 18.3595 17.5455 16.8884 (93) +---------------------------------------------------------------------------------------------------- +8. Space heating requirement +---------------------------------------------------------------------------------------------------- + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Utilisation 0.9765 0.9686 0.9509 0.9107 0.8312 0.6900 0.5126 0.5690 0.7966 0.9259 0.9666 0.9789 (94) +Useful gains 585.9077 637.7302 690.5719 735.2903 722.1589 591.5356 419.2138 428.1056 543.8706 568.2557 557.2080 564.7854 (95) +Ext temp. 4.3000 4.9000 6.5000 8.9000 11.7000 14.6000 16.6000 16.4000 14.1000 10.6000 7.1000 4.2000 (96) +Heat loss rate W + 2113.0154 2042.3548 1843.5024 1528.4133 1166.5069 759.8827 467.0161 493.8903 815.4187 1270.5091 1719.9789 2101.6097 (97) +Space heating kWh + 1136.1681 943.9077 857.7803 571.0485 330.5949 0.0000 0.0000 0.0000 0.0000 522.4765 837.1951 1143.3973 (98a) +Space heating requirement - total per year (kWh/year) 6342.5685 +Solar heating kWh + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (98b) +Solar heating contribution - total per year (kWh/year) 0.0000 +Space heating kWh + 1136.1681 943.9077 857.7803 571.0485 330.5949 0.0000 0.0000 0.0000 0.0000 522.4765 837.1951 1143.3973 (98c) +Space heating requirement after solar contribution - total per year (kWh/year) 6342.5685 +Space heating per m2 (98c) / (4) = 101.7742 (99) +---------------------------------------------------------------------------------------------------- +9a. Energy requirements - Individual heating systems, including micro-CHP +---------------------------------------------------------------------------------------------------- +Fraction of space heat from secondary/supplementary system (Table 11) 0.1000 (201) +Fraction of space heat from main system(s) 0.9000 (202) +Efficiency of main space heating system 1 (in %) 84.0000 (206) +Efficiency of main space heating system 2 (in %) 0.0000 (207) +Efficiency of secondary/supplementary heating system, % 100.0000 (208) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Space heating requirement + 1136.1681 943.9077 857.7803 571.0485 330.5949 0.0000 0.0000 0.0000 0.0000 522.4765 837.1951 1143.3973 (98) +Space heating efficiency (main heating system 1) + 84.0000 84.0000 84.0000 84.0000 84.0000 0.0000 0.0000 0.0000 0.0000 84.0000 84.0000 84.0000 (210) +Space heating fuel (main heating system) + 1217.3230 1011.3297 919.0504 611.8377 354.2088 0.0000 0.0000 0.0000 0.0000 559.7963 896.9947 1225.0686 (211) +Space heating efficiency (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (212) +Space heating fuel (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (213) +Space heating fuel (secondary) + 113.6168 94.3908 85.7780 57.1049 33.0595 0.0000 0.0000 0.0000 0.0000 52.2477 83.7195 114.3397 (215) +Water heating +Water heating requirement + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) +Efficiency of water heater 75.0000 (216) +(217)m 82.1666 82.0733 81.8254 81.3322 80.2753 75.0000 75.0000 75.0000 75.0000 81.1419 81.8785 82.1916 (217) +Fuel for water heating, kWh/month + 284.2588 251.7436 268.3923 237.6978 233.6638 223.9646 220.1191 230.8632 233.8667 240.7769 253.4089 281.1024 (219) +Space cooling fuel requirement +(221)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (221) +Pumps and Fa 7.3041 6.5973 7.3041 7.0685 7.3041 7.0685 7.3041 7.3041 7.0685 7.3041 7.0685 7.3041 (231) +Lighting 62.2853 49.9676 44.9903 32.9618 25.4607 20.8016 23.2261 30.1901 39.2140 51.4509 58.1136 64.0164 (232) +Electricity generated by PVs (Appendix M) (negative quantity) +(233a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233a) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234a) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235a) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235c)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235c) +Electricity generated by PVs (Appendix M) (negative quantity) +(233b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233b) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234b) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235b) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235d)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235d) +Annual totals kWh/year +Space heating fuel - main system 1 6795.6091 (211) +Space heating fuel - main system 2 0.0000 (213) +Space heating fuel - secondary 634.2569 (215) +Efficiency of water heater 75.0000 +Water heating fuel used 2959.8582 (219) +Space cooling fuel 0.0000 (221) +Electricity for pumps and fans: + central heating pump 41.0000 (230c) + main heating flue fan 45.0000 (230e) +Total electricity for the above, kWh/year 86.0000 (231) +Electricity for lighting (calculated in Appendix L) 502.6784 (232) + Energy saving/generation technologies (Appendices M ,N and Q) +PV generation 0.0000 (233) +Wind generation 0.0000 (234) +Hydro-electric generation (Appendix N) 0.0000 (235a) +Electricity generated - Micro CHP (Appendix N) 0.0000 (235) +Appendix Q - special features +Energy saved or generated 0.0000 (236) +Energy used 0.0000 (237) +Total delivered energy for all uses 10978.4026 (238) +---------------------------------------------------------------------------------------------------- +10a. Fuel costs - using Table 12 prices +---------------------------------------------------------------------------------------------------- + Fuel Fuel price Fuel cost + kWh/year p/kWh £/year +Space heating - main system 1 6795.6091 3.4800 236.4872 (240) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 634.2569 13.1900 83.6585 (242) +Water heating (other fuel) 2959.8582 3.4800 103.0031 (247) +Energy for instantaneous electric shower(s) 0.0000 13.1900 0.0000 (247a) +Pumps, fans and electric keep-hot 86.0000 13.1900 11.3434 (249) +Energy for lighting 502.6784 13.1900 66.3033 (250) +Additional standing charges 120.0000 (251) +Total energy cost 620.7954 (255) +---------------------------------------------------------------------------------------------------- +11a. SAP rating - Individual heating systems +---------------------------------------------------------------------------------------------------- +Energy cost deflator (Table 12): 0.4200 (256) +Energy cost factor (ECF) [(255) x (256)] / [(4) + 45.0] = 2.4295 (257) +SAP value 66.1085 +SAP rating (Section 12) 66 (258) +SAP band D +---------------------------------------------------------------------------------------------------- +12a. Carbon dioxide emissions - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Emission factor Emissions + kWh/year kg CO2/kWh kg CO2/year +Space heating - main system 1 6795.6091 0.2100 1427.0779 (261) +Total CO2 associated with community systems 0.0000 (373) +Space heating - secondary 634.2569 0.1540 97.6607 (263) +Water heating (other fuel) 2959.8582 0.2100 621.5702 (264) +Space and water heating 2146.3088 (265) +Pumps, fans and electric keep-hot 86.0000 0.1387 11.9293 (267) +Energy for lighting 502.6784 0.1443 72.5520 (268) +Total CO2, kg/year 2230.7901 (272) +CO2 emissions per m2 35.8000 (273) +EI value 72.1463 +EI rating 72 (274) +EI band C +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +SAP 10 WORKSHEET FOR Existing dwelling (SAP) (Version 10.2, February 2022) +CALCULATION OF EPC COSTS, EMISSIONS AND PRIMARY ENERGY +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +1. Overall dwelling characteristics +---------------------------------------------------------------------------------------------------- + Area Storey height Volume +Main dwelling (m2) (m) (m3) + Ground floor 31.1600 (1b) x 2.4000 (2b) = 74.7840 (1b) - (3b) + First floor 31.1600 (1c) x 2.6500 (2c) = 82.5740 (1c) - (3c) +Total floor area TFA = (1a)+(1b)+(1c)+(1d)+(1e)...(1n) 62.3200 (4) +Dwelling volume (3a)+(3b)+(3c)+(3d)+(3e)...(3n) = 157.3580 (5) +---------------------------------------------------------------------------------------------------- +2. Ventilation rate +---------------------------------------------------------------------------------------------------- + m3 per hour + +Number of open chimneys 0 * 80 = 0.0000 (6a) +Number of open flues 0 * 20 = 0.0000 (6b) +Number of chimneys / flues attached to closed fire 0 * 10 = 0.0000 (6c) +Number of flues attached to solid fuel boiler 0 * 20 = 0.0000 (6d) +Number of flues attached to other heater 0 * 35 = 0.0000 (6e) +Number of blocked chimneys 0 * 20 = 0.0000 (6f) +Number of intermittent extract fans 0 * 10 = 0.0000 (7a) +Number of passive vents 0 * 10 = 0.0000 (7b) +Number of flueless gas fires 0 * 40 = 0.0000 (7c) + Air changes per hour +Infiltration due to chimneys, flues and fans = (6a)+(6b)+(6c)+(6d)+(6e)+(6f)+(6g)+(7a)+(7b)+(7c) = 0.0000 / (5) = 0.0000 (8) + Number of storeys in the dwelling (ns) 2 (9) + Additional infiltration [(9) - 1] x 0.1 = 0.1000 (10) + Structural infiltration: 0.25 for steel or timber frame or 0.35 for masonry construction 0.3500 (11) + If suspended wooden floor, enter 0.2 (unsealed) or 0.1 (sealed), else enter 0 0.0000 (12) + If no draught lobby, enter 0.05, else enter 0 0.0500 (13) + Percentage of windows and doors draught stripped 67.0000 (14) + Window infiltration 0.25 - [0.2 * (14) / 100] = 0.1160 (15) +Pressure test No +Infiltration rate 0.6160 (18) +Number of sides sheltered 1 (19) +Shelter factor (20) = 1 - [0.075 x (19)] = 0.9250 (20) +Infiltration rate adjusted to include shelter factor (21) = (18) x (20) = 0.5698 (21) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Wind speed 3.8000 3.7000 3.7000 3.5000 3.5000 3.1000 3.3000 3.0000 3.0000 3.1000 3.1000 3.5000 (22) +Wind factor 0.9500 0.9250 0.9250 0.8750 0.8750 0.7750 0.8250 0.7500 0.7500 0.7750 0.7750 0.8750 (22a) +Adj infilt rate + 0.5413 0.5271 0.5271 0.4986 0.4986 0.4416 0.4701 0.4274 0.4274 0.4416 0.4416 0.4986 (22b) +Effective ac 0.6465 0.6389 0.6389 0.6243 0.6243 0.5975 0.6105 0.5913 0.5913 0.5975 0.5975 0.6243 (25) +---------------------------------------------------------------------------------------------------- +3. Heat losses and heat loss parameter +---------------------------------------------------------------------------------------------------- +Element Gross Openings NetArea U-value A x U K-value A x K +Main dwelling m2 m2 m2 W/m2K W/K kJ/m2K kJ/K + Doors uninsulated 1 3.7000 3.0000 11.1000 (26) + Windows 1 12.9800 2.5180 32.6835 (27) + Ground floor Main 31.1600 0.7300 22.7468 (28a) + External walls Main 80.6500 16.6800 63.9700 0.4800 30.7056 (29a) + External roof Main 31.1600 31.1600 0.3000 9.3480 (30) +Total net area of external elements Aum(A, m2) 142.9700 (31) +Fabric heat loss, W/K = Sum (A x U) (26)...(30) + (32) = 106.5839 (33) +Main dwelling + Party walls Main 34.2900 0.0000 0.0000 (32) +Thermal mass parameter (TMP = Cm / TFA) in kJ/m2K 250.0000 (35) +Thermal bridges (User defined value 0.150 * total exposed area) 21.4455 (36) +Point Thermal bridges (36a) = 0.0000 +Total fabric heat loss (33) + (36) + (36a) = 128.0294 (37) +Ventilation heat loss calculated monthly (38)m = 0.33 x (25)m x (5) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(38)m 33.5720 33.1768 33.1768 32.4181 32.4181 31.0272 31.7016 30.7058 30.7058 31.0272 31.0272 32.4181 (38) +Heat transfer coeff + 161.6013 161.2062 161.2062 160.4475 160.4475 159.0566 159.7310 158.7352 158.7352 159.0566 159.0566 160.4475 (39) +Average = Sum(39)m / 12 = 159.9773 + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +HLP 2.5931 2.5867 2.5867 2.5746 2.5746 2.5523 2.5631 2.5471 2.5471 2.5523 2.5523 2.5746 (40) +HLP (average) 2.5670 +Days in mont 31 28 31 30 31 30 31 31 30 31 30 31 +---------------------------------------------------------------------------------------------------- +4. Water heating energy requirements (kWh/year) +---------------------------------------------------------------------------------------------------- +Assumed occupancy 2.0464 (42) +Hot water usage for mixer showers + 51.2148 50.4451 49.3236 47.1777 45.5941 43.8281 42.8243 43.9374 45.1575 47.0536 49.2456 51.0186 (42a) +Hot water usage for baths + 26.6248 26.2294 25.6726 24.6459 23.8771 23.0246 22.5642 23.1171 23.7192 24.6313 25.6791 26.5348 (42b) +Hot water usage for other uses + 37.4603 36.0981 34.7359 33.3737 32.0116 30.6494 30.6494 32.0116 33.3737 34.7359 36.0981 37.4603 (42c) +Average daily hot water use (litres/day) 105.9586 (43) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Daily hot water use + 115.2999 112.7727 109.7321 105.1973 101.4828 97.5021 96.0379 99.0660 102.2504 106.4209 111.0229 115.0137 (44) +Energy conte 182.6069 160.5868 168.6541 144.0099 136.6153 119.8902 116.1495 122.6644 126.0850 144.4121 158.1725 180.0836 (45) +Energy content (annual) Total = Sum(45)m = 1759.9303 +Distribution loss (46)m = 0.15 x (45)m + 27.3910 24.0880 25.2981 21.6015 20.4923 17.9835 17.4224 18.3997 18.9127 21.6618 23.7259 27.0125 (46) +Water storage loss (or HIU loss): +Total storage loss + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (56) +If cylinder contains dedicated solar storage + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (57) +Primary loss 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (59) +Combi loss 50.9589 46.0274 50.9589 49.3151 50.9589 48.0832 48.9398 50.4830 49.3151 50.9589 49.3151 50.9589 (61) +Total heat required for water heating calculated for each month + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (62) +WWHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63a) +PV diverter 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63b) +Solar input 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63c) +FGHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63d) +Output from w/h + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) + Total per year (kWh/year) = Sum(64)m = 2356.2034 (64) +Electric shower(s) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (64a) + Total Energy used by instantaneous electric shower(s) (kWh/year) = Sum(64a)m = 0.0000 (64a) +Heat gains from water heating, kWh/month + 73.4565 64.9019 68.8172 60.2121 58.1643 51.8843 50.8547 53.4067 54.2520 60.7568 64.9211 72.6175 (65) +---------------------------------------------------------------------------------------------------- +5. Internal gains (see Table 5 and 5a) +---------------------------------------------------------------------------------------------------- +Metabolic gains (Table 5), Watts + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(66)m 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 (66) +Lighting gains (calculated in Appendix L, equation L9 or L9a), also see Table 5 + 71.1593 63.2031 51.4002 38.9133 29.0881 24.5574 26.5352 34.4914 46.2943 58.7812 68.6064 73.1371 (67) +Appliances gains (calculated in Appendix L, equation L13 or L13a), also see Table 5 + 266.8027 269.5713 262.5946 247.7419 228.9932 211.3720 199.5999 196.8313 203.8081 218.6607 237.4095 255.0307 (68) +Cooking gains (calculated in Appendix L, equation L15 or L15a), also see Table 5 + 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 (69) +Pumps, fans 3.0000 3.0000 3.0000 3.0000 3.0000 0.0000 0.0000 0.0000 0.0000 3.0000 3.0000 3.0000 (70) +Losses e.g. evaporation (negative values) (Table 5) + -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 (71) +Water heating gains (Table 5) + 98.7319 96.5803 92.4963 83.6279 78.1778 72.0615 68.3530 71.7832 75.3500 81.6623 90.1682 97.6042 (72) +Total internal gains + 529.9471 522.6078 499.7442 463.5362 429.5123 398.2441 384.7412 393.3590 415.7055 452.3574 489.4372 519.0251 (73) +---------------------------------------------------------------------------------------------------- +6. Solar gains +---------------------------------------------------------------------------------------------------- +[Jan] Area Solar flux g FF Access Gains + m2 Table 6a Specific data Specific data factor W + W/m2 or Table 6b or Table 6c Table 6d +---------------------------------------------------------------------------------------------------- +North 7.2000 11.5683 0.7600 0.7000 0.7700 30.7077 (74) +East 2.8900 21.5704 0.7600 0.7000 0.7700 22.9826 (76) +West 2.8900 21.5704 0.7600 0.7000 0.7700 22.9826 (80) +---------------------------------------------------------------------------------------------------- +Solar gains 76.6730 133.8602 224.7811 352.4577 437.5532 487.5086 459.0611 390.9446 291.1241 173.9501 98.4071 64.8811 (83) +Total gains 606.6201 656.4679 724.5253 815.9939 867.0655 885.7527 843.8023 784.3036 706.8297 626.3075 587.8443 583.9062 (84) +---------------------------------------------------------------------------------------------------- +7. Mean internal temperature (heating season) +---------------------------------------------------------------------------------------------------- +Temperature during heating periods in the living area from Table 9, Th1 (C) 21.0000 (85) +Utilisation factor for gains for living area, ni1,m (see Table 9a) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +tau 26.7806 26.8462 26.8462 26.9732 26.9732 27.2090 27.0942 27.2641 27.2641 27.2090 27.2090 26.9732 +alpha 2.7854 2.7897 2.7897 2.7982 2.7982 2.8139 2.8063 2.8176 2.8176 2.8139 2.8139 2.7982 +util living area + 0.9851 0.9800 0.9656 0.9261 0.8356 0.6366 0.4258 0.4815 0.7985 0.9397 0.9769 0.9865 (86) +MIT 18.4242 18.6244 19.0967 19.7531 20.3898 20.8355 20.9671 20.9519 20.6203 19.8886 19.0627 18.4121 (87) +Th 2 18.9673 18.9709 18.9709 18.9778 18.9778 18.9906 18.9844 18.9935 18.9935 18.9906 18.9906 18.9778 (88) +util rest of house + 0.9789 0.9715 0.9493 0.8856 0.7279 0.3908 0.0727 0.1199 0.6192 0.8964 0.9650 0.9808 (89) +MIT 2 16.8338 17.0336 17.4974 18.1289 18.6833 18.9656 18.9843 18.9933 18.8769 18.2799 17.4816 16.8285 (90) +Living area fraction fLA = Living area / (4) = 0.3001 (91) +MIT 17.3110 17.5110 17.9773 18.6163 19.1954 19.5267 19.5793 19.5810 19.4000 18.7626 17.9560 17.3037 (92) +Temperature adjustment 0.0000 +adjusted MIT 17.3110 17.5110 17.9773 18.6163 19.1954 19.5267 19.5793 19.5810 19.4000 18.7626 17.9560 17.3037 (93) +---------------------------------------------------------------------------------------------------- +8. Space heating requirement +---------------------------------------------------------------------------------------------------- + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Utilisation 0.9710 0.9622 0.9376 0.8756 0.7429 0.4675 0.1840 0.2358 0.6665 0.8892 0.9554 0.9735 (94) +Useful gains 589.0545 631.6483 679.2849 714.4648 644.1081 414.0819 155.2945 184.9239 471.0774 556.9055 561.6531 568.4109 (95) +Ext temp. 5.6000 6.2000 8.0000 10.6000 13.7000 16.7000 18.6000 18.4000 15.7000 12.2000 8.5000 5.6000 (96) +Heat loss rate W + 1892.5112 1823.3964 1608.4000 1286.1922 881.7185 449.6045 156.4215 187.4638 587.3223 1043.8267 1504.0390 1877.8239 (97) +Space heating kWh + 969.7718 800.8547 691.2617 411.6437 176.7821 0.0000 0.0000 0.0000 0.0000 362.2694 678.5179 974.2033 (98a) +Space heating requirement - total per year (kWh/year) 5065.3045 +Solar heating kWh + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (98b) +Solar heating contribution - total per year (kWh/year) 0.0000 +Space heating kWh + 969.7718 800.8547 691.2617 411.6437 176.7821 0.0000 0.0000 0.0000 0.0000 362.2694 678.5179 974.2033 (98c) +Space heating requirement after solar contribution - total per year (kWh/year) 5065.3045 +Space heating per m2 (98c) / (4) = 81.2790 (99) +---------------------------------------------------------------------------------------------------- +9a. Energy requirements - Individual heating systems, including micro-CHP +---------------------------------------------------------------------------------------------------- +Fraction of space heat from secondary/supplementary system (Table 11) 0.1000 (201) + Fraction of space heat from main system(s) 0.9000 (202) +Efficiency of main space heating system 1 (in %) 84.0000 (206) +Efficiency of main space heating system 2 (in %) 0.0000 (207) +Efficiency of secondary/supplementary heating system, % 100.0000 (208) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Space heating requirement + 969.7718 800.8547 691.2617 411.6437 176.7821 0.0000 0.0000 0.0000 0.0000 362.2694 678.5179 974.2033 (98) +Space heating efficiency (main heating system 1) + 84.0000 84.0000 84.0000 84.0000 84.0000 0.0000 0.0000 0.0000 0.0000 84.0000 84.0000 84.0000 (210) +Space heating fuel (main heating system) + 1039.0412 858.0586 740.6375 441.0468 189.4094 0.0000 0.0000 0.0000 0.0000 388.1458 726.9834 1043.7892 (211) +Space heating efficiency (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (212) +Space heating fuel (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (213) +Space heating fuel (secondary) + 96.9772 80.0855 69.1262 41.1644 17.6782 0.0000 0.0000 0.0000 0.0000 36.2269 67.8518 97.4203 (215) +Water heating +Water heating requirement + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) +Efficiency of water heater 75.0000 (216) +(217)m 81.9246 81.8127 81.4500 80.6802 78.8786 75.0000 75.0000 75.0000 75.0000 80.3856 81.5192 81.9491 (217) +Fuel for water heating, kWh/month + 285.0986 252.5452 269.6294 239.6187 237.8011 223.9646 220.1191 230.8632 233.8667 243.0424 254.5261 281.9342 (219) +Space cooling fuel requirement +(221)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (221) +Pumps and Fa 7.3041 6.5973 7.3041 7.0685 7.3041 7.0685 7.3041 7.3041 7.0685 7.3041 7.0685 7.3041 (231) +Lighting 62.2853 49.9676 44.9903 32.9618 25.4607 20.8016 23.2261 30.1901 39.2140 51.4509 58.1136 64.0164 (232) +Electricity generated by PVs (Appendix M) (negative quantity) +(233a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233a) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234a) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235a) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235c)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235c) +Electricity generated by PVs (Appendix M) (negative quantity) +(233b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233b) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234b) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235b) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235d)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235d) +Annual totals kWh/year +Space heating fuel - main system 1 5427.1120 (211) +Space heating fuel - main system 2 0.0000 (213) +Space heating fuel - secondary 506.5305 (215) +Efficiency of water heater 75.0000 +Water heating fuel used 2973.0093 (219) +Space cooling fuel 0.0000 (221) +Electricity for pumps and fans: + central heating pump 41.0000 (230c) + main heating flue fan 45.0000 (230e) +Total electricity for the above, kWh/year 86.0000 (231) +Electricity for lighting (calculated in Appendix L) 502.6784 (232) +Energy saving/generation technologies (Appendices M ,N and Q) +PV generation 0.0000 (233) +Wind generation 0.0000 (234) +Hydro-electric generation (Appendix N) 0.0000 (235a) +Electricity generated - Micro CHP (Appendix N) 0.0000 (235) +Appendix Q - special features +Energy saved or generated 0.0000 (236) +Energy used 0.0000 (237) +Total delivered energy for all uses 9495.3302 (238) +---------------------------------------------------------------------------------------------------- +10a. Fuel costs - using BEDF prices (596) +---------------------------------------------------------------------------------------------------- + Fuel Fuel price Fuel cost + kWh/year p/kWh £/year +Space heating - main system 1 5427.1120 7.3200 397.2646 (240) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 506.5305 27.6700 140.1570 (242) +Water heating (other fuel) 2973.0093 7.3200 217.6243 (247) +Energy for instantaneous electric shower(s) 0.0000 27.6700 0.0000 (247a) +Pumps, fans and electric keep-hot 86.0000 27.6700 23.7962 (249) +Energy for lighting 502.6784 27.6700 139.0911 (250) +Additional standing charges 108.0000 (251) +Total energy cost 1025.9332 (255) +---------------------------------------------------------------------------------------------------- +12a. Carbon dioxide emissions - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Emission factor Emissions + kWh/year kg CO2/kWh kg CO2/year +Space heating - main system 1 5427.1120 0.2100 1139.6935 (261) +Total CO2 associated with community systems 0.0000 (373) +Space heating - secondary 506.5305 0.1549 78.4693 (263) +Water heating (other fuel) 2973.0093 0.2100 624.3320 (264) +Space and water heating 1842.4948 (265) +Pumps, fans and electric keep-hot 86.0000 0.1387 11.9293 (267) +Energy for lighting 502.6784 0.1443 72.5520 (268) +Total CO2, kg/year 1926.9760 (272) +---------------------------------------------------------------------------------------------------- +13a. Primary energy - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Primary energy factor Primary energy + kWh/year kg CO2/kWh kWh/year +Space heating - main system 1 5427.1120 1.1300 6132.6365 (275) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 506.5305 1.5736 797.0530 (277) +Water heating (other fuel) 2973.0093 1.1300 3359.5005 (278) +Space and water heating 10289.1901 (279) +Pumps, fans and electric keep-hot 86.0000 1.5128 130.1008 (281) +Energy for lighting 502.6784 1.5338 771.0249 (282) +Total Primary energy kWh/year 11190.3158 (286) +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +SAP 10 WORKSHEET FOR Existing dwelling (SAP) (Version 10.2, February 2022) +CALCULATION OF ENERGY RATING FOR IMPROVED DWELLING +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +1. Overall dwelling characteristics +---------------------------------------------------------------------------------------------------- + Area Storey height Volume +Main dwelling (m2) (m) (m3) + Ground floor 31.1600 (1b) x 2.4000 (2b) = 74.7840 (1b) - (3b) + First floor 31.1600 (1c) x 2.6500 (2c) = 82.5740 (1c) - (3c) +Total floor area TFA = (1a)+(1b)+(1c)+(1d)+(1e)...(1n) 62.3200 (4) + Dwelling volume (3a)+(3b)+(3c)+(3d)+(3e)...(3n) = 157.3580 (5) +---------------------------------------------------------------------------------------------------- +2. Ventilation rate +---------------------------------------------------------------------------------------------------- + m3 per hour + +Number of open chimneys 0 * 80 = 0.0000 (6a) +Number of open flues 0 * 20 = 0.0000 (6b) +Number of chimneys / flues attached to closed fire 0 * 10 = 0.0000 (6c) +Number of flues attached to solid fuel boiler 0 * 20 = 0.0000 (6d) +Number of flues attached to other heater 0 * 35 = 0.0000 (6e) +Number of blocked chimneys 0 * 20 = 0.0000 (6f) +Number of intermittent extract fans 0 * 10 = 0.0000 (7a) +Number of passive vents 0 * 10 = 0.0000 (7b) +Number of flueless gas fires 0 * 40 = 0.0000 (7c) + Air changes per hour +Infiltration due to chimneys, flues and fans = (6a)+(6b)+(6c)+(6d)+(6e)+(6f)+(6g)+(7a)+(7b)+(7c) = 0.0000 / (5) = 0.0000 (8) + Number of storeys in the dwelling (ns) 2 (9) + Additional infiltration [(9) - 1] x 0.1 = 0.1000 (10) + Structural infiltration: 0.25 for steel or timber frame or 0.35 for masonry construction 0.3500 (11) + If suspended wooden floor, enter 0.2 (unsealed) or 0.1 (sealed), else enter 0 0.0000 (12) + If no draught lobby, enter 0.05, else enter 0 0.0500 (13) + Percentage of windows and doors draught stripped 67.0000 (14) + Window infiltration 0.25 - [0.2 * (14) / 100] = 0.1160 (15) +Pressure test No +Infiltration rate 0.6160 (18) +Number of sides sheltered 1 (19) +Shelter factor (20) = 1 - [0.075 x (19)] = 0.9250 (20) +Infiltration rate adjusted to include shelter factor (21) = (18) x (20) = 0.5698 (21) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Wind speed 5.1000 5.0000 4.9000 4.4000 4.3000 3.8000 3.8000 3.7000 4.0000 4.3000 4.5000 4.7000 (22) +Wind factor 1.2750 1.2500 1.2250 1.1000 1.0750 0.9500 0.9500 0.9250 1.0000 1.0750 1.1250 1.1750 (22a) +Adj infilt rate + 0.7265 0.7123 0.6980 0.6268 0.6125 0.5413 0.5413 0.5271 0.5698 0.6125 0.6410 0.6695 (22b) +Effective ac 0.7639 0.7537 0.7436 0.6964 0.6876 0.6465 0.6465 0.6389 0.6623 0.6876 0.7055 0.7241 (25) +---------------------------------------------------------------------------------------------------- +3. Heat losses and heat loss parameter +---------------------------------------------------------------------------------------------------- +Element Gross Openings NetArea U-value A x U K-value A x K +Main dwelling m2 m2 m2 W/m2K W/K kJ/m2K kJ/K + Doors uninsulated 1 3.7000 3.0000 11.1000 (26) + Windows 1 12.9800 2.5180 32.6835 (27) + Ground floor Main 31.1600 0.2500 7.7900 (28a) + External walls Main 80.6500 16.6800 63.9700 0.4800 30.7056 (29a) + External roof Main 31.1600 31.1600 0.3000 9.3480 (30) +Total net area of external elements Aum(A, m2) 142.9700 (31) +Fabric heat loss, W/K = Sum (A x U) (26)...(30) + (32) = 91.6271 (33) +Main dwelling + Party walls Main 34.2900 0.0000 0.0000 (32) +Thermal mass parameter (TMP = Cm / TFA) in kJ/m2K 250.0000 (35) +Thermal bridges (User defined value 0.150 * total exposed area) 21.4455 (36) +Point Thermal bridges (36a) = 0.0000 +Total fabric heat loss (33) + (36) + (36a) = 113.0726 (37) +Ventilation heat loss calculated monthly (38)m = 0.33 x (25)m x (5) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(38)m 39.6678 39.1356 38.6140 36.1641 35.7058 33.5720 33.5720 33.1768 34.3939 35.7058 36.6330 37.6025 (38) +Heat transfer coeff + 152.7403 152.2082 151.6866 149.2367 148.7783 146.6445 146.6445 146.2494 147.4664 148.7783 149.7056 150.6750 (39) +Average = Sum(39)m / 12 = 149.2345 + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +HLP 2.4509 2.4424 2.4340 2.3947 2.3873 2.3531 2.3531 2.3467 2.3663 2.3873 2.4022 2.4178 (40) +HLP (average) 2.3946 +Days in mont 31 28 31 30 31 30 31 31 30 31 30 31 +---------------------------------------------------------------------------------------------------- +4. Water heating energy requirements (kWh/year) +---------------------------------------------------------------------------------------------------- +Assumed occupancy 2.0464 (42) +Hot water usage for mixer showers + 51.2148 50.4451 49.3236 47.1777 45.5941 43.8281 42.8243 43.9374 45.1575 47.0536 49.2456 51.0186 (42a) +Hot water usage for baths + 26.6248 26.2294 25.6726 24.6459 23.8771 23.0246 22.5642 23.1171 23.7192 24.6313 25.6791 26.5348 (42b) +Hot water usage for other uses + 37.4603 36.0981 34.7359 33.3737 32.0116 30.6494 30.6494 32.0116 33.3737 34.7359 36.0981 37.4603 (42c) +Average daily hot water use (litres/day) 105.9586 (43) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Daily hot water use + 115.2999 112.7727 109.7321 105.1973 101.4828 97.5021 96.0379 99.0660 102.2504 106.4209 111.0229 115.0137 (44) +Energy conte 182.6069 160.5868 168.6541 144.0099 136.6153 119.8902 116.1495 122.6644 126.0850 144.4121 158.1725 180.0836 (45) +Energy content (annual) Total = Sum(45)m = 1759.9303 +Distribution loss (46)m = 0.15 x (45)m + 27.3910 24.0880 25.2981 21.6015 20.4923 17.9835 17.4224 18.3997 18.9127 21.6618 23.7259 27.0125 (46) +Water storage loss (or HIU loss): +Total storage loss + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (56) +If cylinder contains dedicated solar storage + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (57) +Primary loss 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (59) +Combi loss 50.9589 46.0274 50.9589 49.3151 50.9589 48.0832 48.9398 50.4830 49.3151 50.9589 49.3151 50.9589 (61) +Total heat required for water heating calculated for each month + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (62) +WWHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63a) +PV diverter 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63b) +Solar input 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63c) +FGHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63d) +Output from w/h + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) + Total per year (kWh/year) = Sum(64)m = 2356.2034 (64) +Electric shower(s) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (64a) + Total Energy used by instantaneous electric shower(s) (kWh/year) = Sum(64a)m = 0.0000 (64a) +Heat gains from water heating, kWh/month + 73.4565 64.9019 68.8172 60.2121 58.1643 51.8843 50.8547 53.4067 54.2520 60.7568 64.9211 72.6175 (65) +---------------------------------------------------------------------------------------------------- +5. Internal gains (see Table 5 and 5a) +---------------------------------------------------------------------------------------------------- +Metabolic gains (Table 5), Watts + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(66)m 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 (66) +Lighting gains (calculated in Appendix L, equation L9 or L9a), also see Table 5 + 21.4748 19.0737 15.5118 11.7434 8.7783 7.4110 8.0079 10.4090 13.9709 17.7393 20.7043 22.0716 (67) +Appliances gains (calculated in Appendix L, equation L13 or L13a), also see Table 5 + 266.8027 269.5713 262.5946 247.7419 228.9932 211.3720 199.5999 196.8313 203.8081 218.6607 237.4095 255.0307 (68) +Cooking gains (calculated in Appendix L, equation L15 or L15a), also see Table 5 + 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 (69) +Pumps, fans 3.0000 3.0000 3.0000 3.0000 3.0000 0.0000 0.0000 0.0000 0.0000 3.0000 3.0000 3.0000 (70) +Losses e.g. evaporation (negative values) (Table 5) + -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 (71) +Water heating gains (Table 5) + 98.7319 96.5803 92.4963 83.6279 78.1778 72.0615 68.3530 71.7832 75.3500 81.6623 90.1682 97.6042 (72) + Total internal gains + 480.2625 478.4784 463.8557 436.3663 409.2025 381.0977 366.2140 369.2766 383.3821 411.3154 441.5351 467.9596 (73) +---------------------------------------------------------------------------------------------------- +6. Solar gains +---------------------------------------------------------------------------------------------------- +[Jan] Area Solar flux g FF Access Gains + m2 Table 6a Specific data Specific data factor W + W/m2 or Table 6b or Table 6c Table 6d +---------------------------------------------------------------------------------------------------- +North 7.2000 10.6334 0.7600 0.7000 0.7700 28.2260 (74) +East 2.8900 19.6403 0.7600 0.7000 0.7700 20.9262 (76) +West 2.8900 19.6403 0.7600 0.7000 0.7700 20.9262 (80) +---------------------------------------------------------------------------------------------------- +Solar gains 70.0784 135.8134 226.4912 343.8726 439.3250 459.0195 433.0958 359.0167 267.0192 161.3582 87.0054 57.9479 (83) +Total gains 550.3409 614.2918 690.3469 780.2390 848.5275 840.1171 799.3098 728.2933 650.4014 572.6737 528.5405 525.9076 (84) +---------------------------------------------------------------------------------------------------- +7. Mean internal temperature (heating season) +---------------------------------------------------------------------------------------------------- +Temperature during heating periods in the living area from Table 9, Th1 (C) 21.0000 (85) +Utilisation factor for gains for living area, ni1,m (see Table 9a) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +tau 28.3342 28.4333 28.5310 28.9994 29.0888 29.5120 29.5120 29.5918 29.3475 29.0888 28.9086 28.7226 +alpha 2.8889 2.8956 2.9021 2.9333 2.9393 2.9675 2.9675 2.9728 2.9565 2.9393 2.9272 2.9148 +util living area + 0.9906 0.9863 0.9760 0.9497 0.8924 0.7878 0.6632 0.7179 0.8842 0.9654 0.9864 0.9919 (86) +MIT 18.2110 18.4316 18.8731 19.5070 20.1207 20.6096 20.8376 20.7883 20.3770 19.6041 18.8156 18.1916 (87) +Th 2 19.0497 19.0547 19.0597 19.0832 19.0876 19.1083 19.1083 19.1122 19.1003 19.0876 19.0787 19.0694 (88) +util rest of house + 0.9871 0.9810 0.9658 0.9258 0.8333 0.6527 0.4342 0.4999 0.7921 0.9440 0.9801 0.9888 (89) +MIT 2 16.6722 16.8940 17.3333 17.9651 18.5373 18.9492 19.0790 19.0662 18.7874 18.0739 17.2925 16.6652 (90) +Living area fraction fLA = Living area / (4) = 0.3001 (91) +MIT 17.1340 17.3553 17.7953 18.4277 19.0124 19.4474 19.6067 19.5829 19.2644 18.5330 17.7495 17.1232 (92) +Temperature adjustment 0.0000 +adjusted MIT 17.1340 17.3553 17.7953 18.4277 19.0124 19.4474 19.6067 19.5829 19.2644 18.5330 17.7495 17.1232 (93) +---------------------------------------------------------------------------------------------------- +8. Space heating requirement +---------------------------------------------------------------------------------------------------- + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Utilisation 0.9815 0.9738 0.9560 0.9143 0.8302 0.6825 0.5049 0.5658 0.8028 0.9348 0.9733 0.9838 (94) +Useful gains 540.1819 598.2008 659.9997 713.3767 704.4687 573.3873 403.5552 412.0764 522.1727 535.3218 514.4052 517.4024 (95) +Ext temp. 4.3000 4.9000 6.5000 8.9000 11.7000 14.6000 16.6000 16.4000 14.1000 10.6000 7.1000 4.2000 (96) +Heat loss rate W + 1960.2641 1895.8060 1713.3509 1421.8886 1087.9269 710.8496 440.9131 465.4991 761.5729 1180.2651 1594.2946 1947.2023 (97) +Space heating kWh + 1056.5411 871.9907 783.6932 510.1286 285.2929 0.0000 0.0000 0.0000 0.0000 479.8378 777.5204 1063.7711 (98a) +Space heating requirement - total per year (kWh/year) 5828.7758 +Solar heating kWh + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (98b) +Solar heating contribution - total per year (kWh/year) 0.0000 +Space heating kWh + 1056.5411 871.9907 783.6932 510.1286 285.2929 0.0000 0.0000 0.0000 0.0000 479.8378 777.5204 1063.7711 (98c) +Space heating requirement after solar contribution - total per year (kWh/year) 5828.7758 +Space heating per m2 (98c) / (4) = 93.5298 (99) +---------------------------------------------------------------------------------------------------- +9a. Energy requirements - Individual heating systems, including micro-CHP +---------------------------------------------------------------------------------------------------- +Fraction of space heat from secondary/supplementary system (Table 11) 0.1000 (201) +Fraction of space heat from main system(s) 0.9000 (202) +Efficiency of main space heating system 1 (in %) 84.0000 (206) +Efficiency of main space heating system 2 (in %) 0.0000 (207) +Efficiency of secondary/supplementary heating system, % 100.0000 (208) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Space heating requirement + 1056.5411 871.9907 783.6932 510.1286 285.2929 0.0000 0.0000 0.0000 0.0000 479.8378 777.5204 1063.7711 (98) +Space heating efficiency (main heating system 1) + 84.0000 84.0000 84.0000 84.0000 84.0000 0.0000 0.0000 0.0000 0.0000 84.0000 84.0000 84.0000 (210) +Space heating fuel (main heating system) + 1132.0083 934.2758 839.6713 546.5663 305.6709 0.0000 0.0000 0.0000 0.0000 514.1119 833.0576 1139.7547 (211) +Space heating efficiency (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (212) +Space heating fuel (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (213) +Space heating fuel (secondary) + 105.6541 87.1991 78.3693 51.0129 28.5293 0.0000 0.0000 0.0000 0.0000 47.9838 77.7520 106.3771 (215) +Water heating +Water heating requirement + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) +Efficiency of water heater 75.0000 (216) +(217)m 82.0582 81.9505 81.6730 81.1157 79.9500 75.0000 75.0000 75.0000 75.0000 80.9734 81.7563 82.0850 (217) +Fuel for water heating, kWh/month + 284.6342 252.1206 268.8932 238.3322 234.6145 223.9646 220.1191 230.8632 233.8667 241.2782 253.7878 281.4673 (219) +Space cooling fuel requirement +(221)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (221) +Pumps and Fa 7.3041 6.5973 7.3041 7.0685 7.3041 7.0685 7.3041 7.3041 7.0685 7.3041 7.0685 7.3041 (231) +Lighting 18.7968 15.0795 13.5774 9.9474 7.6836 6.2776 7.0093 9.1109 11.8342 15.5271 17.5378 19.3192 (232) +Electricity generated by PVs (Appendix M) (negative quantity) +(233a)m -34.1798 -49.1906 -71.4871 -79.7104 -83.3882 -72.3889 -71.4835 -67.4980 -60.4123 -54.9397 -37.6017 -29.4537 (233a) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234a) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235a) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235c)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235c) +Electricity generated by PVs (Appendix M) (negative quantity) +(233b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233b) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234b) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235b) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235d)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235d) +Annual totals kWh/year +Space heating fuel - main system 1 6245.1169 (211) +Space heating fuel - main system 2 0.0000 (213) +Space heating fuel - secondary 582.8776 (215) +Efficiency of water heater 75.0000 +Water heating fuel used 2963.9416 (219) +Space cooling fuel 0.0000 (221) +Electricity for pumps and fans: + central heating pump 41.0000 (230c) + main heating flue fan 45.0000 (230e) +Total electricity for the above, kWh/year 86.0000 (231) +Electricity for lighting (calculated in Appendix L) 151.7006 (232) +Energy saving/generation technologies (Appendices M ,N and Q) +PV generation -711.7338 (233) +Wind generation 0.0000 (234) +Hydro-electric generation (Appendix N) 0.0000 (235a) +Electricity generated - Micro CHP (Appendix N) 0.0000 (235) +Appendix Q - special features + Energy saved or generated 0.0000 (236) +Energy used 0.0000 (237) +Total delivered energy for all uses 9317.9029 (238) +---------------------------------------------------------------------------------------------------- +10a. Fuel costs - using Table 12 prices +---------------------------------------------------------------------------------------------------- + Fuel Fuel price Fuel cost + kWh/year p/kWh £/year +Space heating - main system 1 6245.1169 3.4800 217.3301 (240) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 582.8776 13.1900 76.8816 (242) +Water heating (other fuel) 2963.9416 3.4800 103.1452 (247) +Energy for instantaneous electric shower(s) 0.0000 13.1900 0.0000 (247a) +Pumps, fans and electric keep-hot 86.0000 13.1900 11.3434 (249) +Energy for lighting 151.7006 13.1900 20.0093 (250) +Additional standing charges 120.0000 (251) +Energy saving/generation technologies +PV Unit electricity used in dwelling -711.7338 13.1900 -93.8777 +PV Unit electricity exported 0.0000 13.1900 0.0000 +Total -93.8777 (252) +Total energy cost 454.8318 (255) +---------------------------------------------------------------------------------------------------- +11a. SAP rating - Individual heating systems +---------------------------------------------------------------------------------------------------- +Energy cost deflator (Table 12): 0.4200 (256) +Energy cost factor (ECF) [(255) x (256)] / [(4) + 45.0] = 1.7800 (257) +SAP value 75.1690 +SAP rating (Section 12) 75 (258) +SAP band C +---------------------------------------------------------------------------------------------------- +12a. Carbon dioxide emissions - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Emission factor Emissions + kWh/year kg CO2/kWh kg CO2/year +Space heating - main system 1 6245.1169 0.2100 1311.4746 (261) +Total CO2 associated with community systems 0.0000 (373) +Space heating - secondary 582.8776 0.1541 89.8305 (263) +Water heating (other fuel) 2963.9416 0.2100 622.4277 (264) +Space and water heating 2023.7328 (265) +Pumps, fans and electric keep-hot 86.0000 0.1387 11.9293 (267) +Energy for lighting 151.7006 0.1443 21.8951 (268) +Energy saving/generation technologies +PV Unit electricity used in dwelling -711.7338 0.1353 -96.2872 +PV Unit electricity exported 0.0000 0.0000 0.0000 +Total -96.2872 (269) +Total CO2, kg/year 1961.2700 (272) +CO2 emissions per m2 31.4700 (273) +EI value 75.5115 +EI rating 76 (274) +EI band C +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +SAP 10 WORKSHEET FOR Existing dwelling (SAP) (Version 10.2, February 2022) +CALCULATION OF EPC COSTS, EMISSIONS AND PRIMARY ENERGY FOR IMPROVED DWELLING +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +1. Overall dwelling characteristics +---------------------------------------------------------------------------------------------------- + Area Storey height Volume +Main dwelling (m2) (m) (m3) + Ground floor 31.1600 (1b) x 2.4000 (2b) = 74.7840 (1b) - (3b) + First floor 31.1600 (1c) x 2.6500 (2c) = 82.5740 (1c) - (3c) +Total floor area TFA = (1a)+(1b)+(1c)+(1d)+(1e)...(1n) 62.3200 (4) +Dwelling volume (3a)+(3b)+(3c)+(3d)+(3e)...(3n) = 157.3580 (5) +---------------------------------------------------------------------------------------------------- +2. Ventilation rate +---------------------------------------------------------------------------------------------------- + m3 per hour + +Number of open chimneys 0 * 80 = 0.0000 (6a) +Number of open flues 0 * 20 = 0.0000 (6b) +Number of chimneys / flues attached to closed fire 0 * 10 = 0.0000 (6c) +Number of flues attached to solid fuel boiler 0 * 20 = 0.0000 (6d) +Number of flues attached to other heater 0 * 35 = 0.0000 (6e) +Number of blocked chimneys 0 * 20 = 0.0000 (6f) +Number of intermittent extract fans 0 * 10 = 0.0000 (7a) +Number of passive vents 0 * 10 = 0.0000 (7b) +Number of flueless gas fires 0 * 40 = 0.0000 (7c) + Air changes per hour +Infiltration due to chimneys, flues and fans = (6a)+(6b)+(6c)+(6d)+(6e)+(6f)+(6g)+(7a)+(7b)+(7c) = 0.0000 / (5) = 0.0000 (8) + Number of storeys in the dwelling (ns) 2 (9) + Additional infiltration [(9) - 1] x 0.1 = 0.1000 (10) + Structural infiltration: 0.25 for steel or timber frame or 0.35 for masonry construction 0.3500 (11) + If suspended wooden floor, enter 0.2 (unsealed) or 0.1 (sealed), else enter 0 0.0000 (12) + If no draught lobby, enter 0.05, else enter 0 0.0500 (13) + Percentage of windows and doors draught stripped 67.0000 (14) + Window infiltration 0.25 - [0.2 * (14) / 100] = 0.1160 (15) +Pressure test No +Infiltration rate 0.6160 (18) +Number of sides sheltered 1 (19) +Shelter factor (20) = 1 - [0.075 x (19)] = 0.9250 (20) +Infiltration rate adjusted to include shelter factor (21) = (18) x (20) = 0.5698 (21) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Wind speed 3.8000 3.7000 3.7000 3.5000 3.5000 3.1000 3.3000 3.0000 3.0000 3.1000 3.1000 3.5000 (22) +Wind factor 0.9500 0.9250 0.9250 0.8750 0.8750 0.7750 0.8250 0.7500 0.7500 0.7750 0.7750 0.8750 (22a) +Adj infilt rate + 0.5413 0.5271 0.5271 0.4986 0.4986 0.4416 0.4701 0.4274 0.4274 0.4416 0.4416 0.4986 (22b) +Effective ac 0.6465 0.6389 0.6389 0.6243 0.6243 0.5975 0.6105 0.5913 0.5913 0.5975 0.5975 0.6243 (25) +---------------------------------------------------------------------------------------------------- +3. Heat losses and heat loss parameter +---------------------------------------------------------------------------------------------------- +Element Gross Openings NetArea U-value A x U K-value A x K +Main dwelling m2 m2 m2 W/m2K W/K kJ/m2K kJ/K + Doors uninsulated 1 3.7000 3.0000 11.1000 (26) + Windows 1 12.9800 2.5180 32.6835 (27) + Ground floor Main 31.1600 0.2500 7.7900 (28a) + External walls Main 80.6500 16.6800 63.9700 0.4800 30.7056 (29a) + External roof Main 31.1600 31.1600 0.3000 9.3480 (30) +Total net area of external elements Aum(A, m2) 142.9700 (31) +Fabric heat loss, W/K = Sum (A x U) (26)...(30) + (32) = 91.6271 (33) +Main dwelling + Party walls Main 34.2900 0.0000 0.0000 (32) +Thermal mass parameter (TMP = Cm / TFA) in kJ/m2K 250.0000 (35) +Thermal bridges (User defined value 0.150 * total exposed area) 21.4455 (36) +Point Thermal bridges (36a) = 0.0000 +Total fabric heat loss (33) + (36) + (36a) = 113.0726 (37) +Ventilation heat loss calculated monthly (38)m = 0.33 x (25)m x (5) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec + (38)m 33.5720 33.1768 33.1768 32.4181 32.4181 31.0272 31.7016 30.7058 30.7058 31.0272 31.0272 32.4181 (38) +Heat transfer coeff + 146.6445 146.2494 146.2494 145.4907 145.4907 144.0998 144.7742 143.7784 143.7784 144.0998 144.0998 145.4907 (39) +Average = Sum(39)m / 12 = 145.0205 + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +HLP 2.3531 2.3467 2.3467 2.3346 2.3346 2.3123 2.3231 2.3071 2.3071 2.3123 2.3123 2.3346 (40) +HLP (average) 2.3270 +Days in mont 31 28 31 30 31 30 31 31 30 31 30 31 +---------------------------------------------------------------------------------------------------- +4. Water heating energy requirements (kWh/year) +---------------------------------------------------------------------------------------------------- +Assumed occupancy 2.0464 (42) +Hot water usage for mixer showers + 51.2148 50.4451 49.3236 47.1777 45.5941 43.8281 42.8243 43.9374 45.1575 47.0536 49.2456 51.0186 (42a) +Hot water usage for baths + 26.6248 26.2294 25.6726 24.6459 23.8771 23.0246 22.5642 23.1171 23.7192 24.6313 25.6791 26.5348 (42b) +Hot water usage for other uses + 37.4603 36.0981 34.7359 33.3737 32.0116 30.6494 30.6494 32.0116 33.3737 34.7359 36.0981 37.4603 (42c) +Average daily hot water use (litres/day) 105.9586 (43) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Daily hot water use + 115.2999 112.7727 109.7321 105.1973 101.4828 97.5021 96.0379 99.0660 102.2504 106.4209 111.0229 115.0137 (44) +Energy conte 182.6069 160.5868 168.6541 144.0099 136.6153 119.8902 116.1495 122.6644 126.0850 144.4121 158.1725 180.0836 (45) +Energy content (annual) Total = Sum(45)m = 1759.9303 +Distribution loss (46)m = 0.15 x (45)m + 27.3910 24.0880 25.2981 21.6015 20.4923 17.9835 17.4224 18.3997 18.9127 21.6618 23.7259 27.0125 (46) +Water storage loss (or HIU loss): +Total storage loss + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (56) +If cylinder contains dedicated solar storage + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (57) +Primary loss 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (59) +Combi loss 50.9589 46.0274 50.9589 49.3151 50.9589 48.0832 48.9398 50.4830 49.3151 50.9589 49.3151 50.9589 (61) +Total heat required for water heating calculated for each month + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (62) +WWHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63a) +PV diverter 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63b) +Solar input 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63c) +FGHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63d) +Output from w/h + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) + Total per year (kWh/year) = Sum(64)m = 2356.2034 (64) +Electric shower(s) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (64a) + Total Energy used by instantaneous electric shower(s) (kWh/year) = Sum(64a)m = 0.0000 (64a) +Heat gains from water heating, kWh/month + 73.4565 64.9019 68.8172 60.2121 58.1643 51.8843 50.8547 53.4067 54.2520 60.7568 64.9211 72.6175 (65) +---------------------------------------------------------------------------------------------------- +5. Internal gains (see Table 5 and 5a) +---------------------------------------------------------------------------------------------------- +Metabolic gains (Table 5), Watts + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(66)m 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 (66) +Lighting gains (calculated in Appendix L, equation L9 or L9a), also see Table 5 + 21.4748 19.0737 15.5118 11.7434 8.7783 7.4110 8.0079 10.4090 13.9709 17.7393 20.7043 22.0716 (67) +Appliances gains (calculated in Appendix L, equation L13 or L13a), also see Table 5 + 266.8027 269.5713 262.5946 247.7419 228.9932 211.3720 199.5999 196.8313 203.8081 218.6607 237.4095 255.0307 (68) +Cooking gains (calculated in Appendix L, equation L15 or L15a), also see Table 5 + 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 (69) +Pumps, fans 3.0000 3.0000 3.0000 3.0000 3.0000 0.0000 0.0000 0.0000 0.0000 3.0000 3.0000 3.0000 (70) +Losses e.g. evaporation (negative values) (Table 5) + -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 (71) +Water heating gains (Table 5) + 98.7319 96.5803 92.4963 83.6279 78.1778 72.0615 68.3530 71.7832 75.3500 81.6623 90.1682 97.6042 (72) +Total internal gains + 480.2625 478.4784 463.8557 436.3663 409.2025 381.0977 366.2140 369.2766 383.3821 411.3154 441.5351 467.9596 (73) +---------------------------------------------------------------------------------------------------- +6. Solar gains +---------------------------------------------------------------------------------------------------- +[Jan] Area Solar flux g FF Access Gains + m2 Table 6a Specific data Specific data factor W + W/m2 or Table 6b or Table 6c Table 6d +---------------------------------------------------------------------------------------------------- +North 7.2000 11.5683 0.7600 0.7000 0.7700 30.7077 (74) +East 2.8900 21.5704 0.7600 0.7000 0.7700 22.9826 (76) +West 2.8900 21.5704 0.7600 0.7000 0.7700 22.9826 (80) +---------------------------------------------------------------------------------------------------- +Solar gains 76.6730 133.8602 224.7811 352.4577 437.5532 487.5086 459.0611 390.9446 291.1241 173.9501 98.4071 64.8811 (83) +Total gains 556.9355 612.3386 688.6368 788.8241 846.7557 868.6063 825.2750 760.2212 674.5063 585.2655 539.9422 532.8408 (84) +---------------------------------------------------------------------------------------------------- +7. Mean internal temperature (heating season) +---------------------------------------------------------------------------------------------------- +Temperature during heating periods in the living area from Table 9, Th1 (C) 21.0000 (85) +Utilisation factor for gains for living area, ni1,m (see Table 9a) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +tau 29.5120 29.5918 29.5918 29.7461 29.7461 30.0332 29.8933 30.1003 30.1003 30.0332 30.0332 29.7461 +alpha 2.9675 2.9728 2.9728 2.9831 2.9831 3.0022 2.9929 3.0067 3.0067 3.0022 3.0022 2.9831 +util living area + 0.9881 0.9831 0.9683 0.9259 0.8265 0.6133 0.4021 0.4603 0.7942 0.9446 0.9810 0.9895 (86) +MIT 18.5901 18.7933 19.2566 19.8925 20.4875 20.8766 20.9779 20.9661 20.6784 19.9847 19.1949 18.5759 (87) +Th 2 19.1083 19.1122 19.1122 19.1196 19.1196 19.1333 19.1266 19.1365 19.1365 19.1333 19.1333 19.1196 (88) +util rest of house + 0.9832 0.9760 0.9536 0.8869 0.7217 0.3874 0.0923 0.1390 0.6247 0.9057 0.9713 0.9851 (89) +MIT 2 17.0860 17.2893 17.7444 18.3557 18.8686 19.1133 19.1266 19.1361 19.0331 18.4675 17.7026 17.0793 (90) +Living area fraction fLA = Living area / (4) = 0.3001 (91) +MIT 17.5373 17.7406 18.1982 18.8168 19.3543 19.6424 19.6821 19.6852 19.5268 18.9228 18.1504 17.5284 (92) +Temperature adjustment 0.0000 +adjusted MIT 17.5373 17.7406 18.1982 18.8168 19.3543 19.6424 19.6821 19.6852 19.5268 18.9228 18.1504 17.5284 (93) +---------------------------------------------------------------------------------------------------- +8. Space heating requirement +---------------------------------------------------------------------------------------------------- + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Utilisation 0.9770 0.9682 0.9433 0.8784 0.7380 0.4574 0.1888 0.2404 0.6697 0.8994 0.9634 0.9794 (94) +Useful gains 544.1060 592.8372 649.5622 692.8756 624.9256 397.2799 155.7782 182.7905 451.6915 526.4023 520.2010 521.8383 (95) +Ext temp. 5.6000 6.2000 8.0000 10.6000 13.7000 16.7000 18.6000 18.4000 15.7000 12.2000 8.5000 5.6000 (96) +Heat loss rate W + 1750.5467 1687.8026 1491.4798 1195.4735 822.6545 423.9972 156.6578 184.7872 550.2136 968.7502 1390.6200 1735.4681 (97) +Space heating kWh + 897.5919 735.8167 626.3867 361.8705 147.1103 0.0000 0.0000 0.0000 0.0000 329.1069 626.7017 902.9406 (98a) +Space heating requirement - total per year (kWh/year) 4627.5252 +Solar heating kWh + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (98b) +Solar heating contribution - total per year (kWh/year) 0.0000 +Space heating kWh + 897.5919 735.8167 626.3867 361.8705 147.1103 0.0000 0.0000 0.0000 0.0000 329.1069 626.7017 902.9406 (98c) +Space heating requirement after solar contribution - total per year (kWh/year) 4627.5252 +Space heating per m2 (98c) / (4) = 74.2543 (99) +---------------------------------------------------------------------------------------------------- +9a. Energy requirements - Individual heating systems, including micro-CHP + ---------------------------------------------------------------------------------------------------- +Fraction of space heat from secondary/supplementary system (Table 11) 0.1000 (201) +Fraction of space heat from main system(s) 0.9000 (202) +Efficiency of main space heating system 1 (in %) 84.0000 (206) +Efficiency of main space heating system 2 (in %) 0.0000 (207) +Efficiency of secondary/supplementary heating system, % 100.0000 (208) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Space heating requirement + 897.5919 735.8167 626.3867 361.8705 147.1103 0.0000 0.0000 0.0000 0.0000 329.1069 626.7017 902.9406 (98) +Space heating efficiency (main heating system 1) + 84.0000 84.0000 84.0000 84.0000 84.0000 0.0000 0.0000 0.0000 0.0000 84.0000 84.0000 84.0000 (210) +Space heating fuel (main heating system) + 961.7056 788.3750 671.1287 387.7184 157.6182 0.0000 0.0000 0.0000 0.0000 352.6145 671.4661 967.4363 (211) +Space heating efficiency (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (212) +Space heating fuel (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (213) +Space heating fuel (secondary) + 89.7592 73.5817 62.6387 36.1870 14.7110 0.0000 0.0000 0.0000 0.0000 32.9107 62.6702 90.2941 (215) +Water heating +Water heating requirement + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) +Efficiency of water heater 75.0000 (216) +(217)m 81.7985 81.6695 81.2661 80.4060 78.4793 75.0000 75.0000 75.0000 75.0000 80.1761 81.3739 81.8263 (217) +Fuel for water heating, kWh/month + 285.5380 252.9883 270.2395 240.4361 239.0111 223.9646 220.1191 230.8632 233.8667 243.6773 254.9804 282.3572 (219) +Space cooling fuel requirement +(221)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (221) +Pumps and Fa 7.3041 6.5973 7.3041 7.0685 7.3041 7.0685 7.3041 7.3041 7.0685 7.3041 7.0685 7.3041 (231) +Lighting 18.7968 15.0795 13.5774 9.9474 7.6836 6.2776 7.0093 9.1109 11.8342 15.5271 17.5378 19.3192 (232) +Electricity generated by PVs (Appendix M) (negative quantity) +(233a)m -36.0565 -47.5984 -69.1347 -78.0275 -80.0163 -73.7910 -72.7946 -69.6016 -62.6000 -55.9069 -40.3706 -31.7267 (233a) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234a) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235a) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235c)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235c) +Electricity generated by PVs (Appendix M) (negative quantity) +(233b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233b) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234b) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235b) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235d)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235d) +Annual totals kWh/year +Space heating fuel - main system 1 4958.0627 (211) +Space heating fuel - main system 2 0.0000 (213) +Space heating fuel - secondary 462.7525 (215) +Efficiency of water heater 75.0000 +Water heating fuel used 2978.0416 (219) +Space cooling fuel 0.0000 (221) +Electricity for pumps and fans: + central heating pump 41.0000 (230c) + main heating flue fan 45.0000 (230e) +Total electricity for the above, kWh/year 86.0000 (231) +Electricity for lighting (calculated in Appendix L) 151.7006 (232) +Energy saving/generation technologies (Appendices M ,N and Q) +PV generation -717.6247 (233) +Wind generation 0.0000 (234) +Hydro-electric generation (Appendix N) 0.0000 (235a) +Electricity generated - Micro CHP (Appendix N) 0.0000 (235) +Appendix Q - special features +Energy saved or generated 0.0000 (236) +Energy used 0.0000 (237) +Total delivered energy for all uses 7918.9327 (238) +---------------------------------------------------------------------------------------------------- +10a. Fuel costs - using BEDF prices (596) +---------------------------------------------------------------------------------------------------- + Fuel Fuel price Fuel cost + kWh/year p/kWh £/year +Space heating - main system 1 4958.0627 7.3200 362.9302 (240) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 462.7525 27.6700 128.0436 (242) +Water heating (other fuel) 2978.0416 7.3200 217.9926 (247) +Energy for instantaneous electric shower(s) 0.0000 27.6700 0.0000 (247a) +Pumps, fans and electric keep-hot 86.0000 27.6700 23.7962 (249) +Energy for lighting 151.7006 27.6700 41.9755 (250) +Additional standing charges 108.0000 (251) +Energy saving/generation technologies +PV Unit electricity used in dwelling -717.6247 27.6700 -198.5668 +PV Unit electricity exported 0.0000 5.8100 0.0000 +Total -198.5668 (252) +Total energy cost 684.1714 (255) +---------------------------------------------------------------------------------------------------- +12a. Carbon dioxide emissions - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Emission factor Emissions + kWh/year kg CO2/kWh kg CO2/year +Space heating - main system 1 4958.0627 0.2100 1041.1932 (261) +Total CO2 associated with community systems 0.0000 (373) +Space heating - secondary 462.7525 0.1551 71.7611 (263) +Water heating (other fuel) 2978.0416 0.2100 625.3887 (264) +Space and water heating 1738.3430 (265) +Pumps, fans and electric keep-hot 86.0000 0.1387 11.9293 (267) +Energy for lighting 151.7006 0.1443 21.8951 (268) +Energy saving/generation technologies +PV Unit electricity used in dwelling -717.6247 0.1352 -97.0291 +PV Unit electricity exported 0.0000 0.0000 0.0000 +Total -97.0291 (269) +Total CO2, kg/year 1675.1383 (272) +---------------------------------------------------------------------------------------------------- +13a. Primary energy - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Primary energy factor Primary energy + kWh/year kg CO2/kWh kWh/year +Space heating - main system 1 4958.0627 1.1300 5602.6109 (275) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 462.7525 1.5741 728.4382 (277) +Water heating (other fuel) 2978.0416 1.1300 3365.1870 (278) +Space and water heating 9696.2361 (279) +Pumps, fans and electric keep-hot 86.0000 1.5128 130.1008 (281) +Energy for lighting 151.7006 1.5338 232.6834 (282) +Energy saving/generation technologies +PV Unit electricity used in dwelling -717.6247 1.4997 -1076.2548 +PV Unit electricity exported 0.0000 0.0000 0.0000 +Total -1076.2548 (283) +Total Primary energy kWh/year 8982.7654 (286) + \ No newline at end of file diff --git a/scripts/hyde/build_200004296092.py b/scripts/hyde/build_200004296092.py new file mode 100644 index 000000000..926b6809c --- /dev/null +++ b/scripts/hyde/build_200004296092.py @@ -0,0 +1,297 @@ +"""Elmhurst build for UPRN 200004296092 (RdSAP-Schema-21.0.1, END-TERRACE HOUSE, +2-storey, band B, SOLID BRICK 360 mm WITH EXTERNAL INSULATION (thickness lodged +"NI" = unknown), pitched 150 mm loft, solid uninsulated ground floor, mains-gas +COMBI (PCDB 16137 Ideal Logic combi 30 ~ generic Post-98 condensing combi), +control 2106 (CBE), double glazed ~4.31 m², 2 doors, TFA ~62, party wall 6.79 m. +Engine 71.74 = lodged 71 AFTER the §5.4 "assume 100 mm if unknown" wall fix +(slice 5); this build validates that against the accredited Elmhurst worksheet. + +The KEY page is `walls`: it prints Elmhurst's insulation dropdown so we can see +how the accredited tool handles External insulation of unknown thickness. Run: + DISPLAY=:99 python scripts/hyde/build_200004296092.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +PWALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelPartyWallMain_WebUserControlPartyWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +WP = "TabContainer_TabPanelWindowsPanel_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" + +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_200004296092") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def _options(page, suffix): + return page.evaluate( + """(id)=>{const s=document.getElementById(id);if(!s)return []; + return Array.from(s.options).map(o=>o.text);}""", f"{E.FP}{suffix}") + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + E.set_select(page, "DropDownListPropertyType1", "H House") + print("built_form ->", _pick(page, "DropDownListPropertyType2", "end-terrace") + or _pick(page, "DropDownListPropertyType2", "end terrace")) + E.set_text(page, "TextBoxStoreys", "2") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1900-1929") + or _pick(page, "DropDownListDateBuiltMain", "1900")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.set_select(page, "DropDownListRoomInRoofMain", "") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "31.16") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "15.97") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "6.79") + E.set_text(page, f"{DIM}TextBoxFloorArea1stFloor", "31.16") + E.set_text(page, f"{DIM}TextBoxRoomHeight1stFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeter1stFloor", "15.97") + E.set_text(page, f"{DIM}TextBoxPartyWallLength1stFloor", "6.79") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + print("WALL TYPE options:", _options(page, f"{WALL}DropDownListType")) + _pick(page, f"{WALL}DropDownListType", "solid brick") \ + or _pick(page, f"{WALL}DropDownListType", "brick") + page.wait_for_timeout(600) + print("INSULATION options:", _options(page, f"{WALL}DropDownListInsulation")) + ins = (_pick(page, f"{WALL}DropDownListInsulation", "external") + or _pick(page, f"{WALL}DropDownListInsulation", "ext")) + print("insulation ->", ins) + page.wait_for_timeout(600) + # If a thickness dropdown appears for external insulation, show it (this is + # the slice-5 question: what does Elmhurst do with UNKNOWN thickness?). + for suf in (f"{WALL}DropDownListInsulationThickness", + f"{WALL}DropDownListExternalInsulationThickness"): + if page.locator(f"#{E.FP}{suf}").count(): + print("INSULATION THICKNESS options:", _options(page, suf), + "current:", page.locator(f"#{E.FP}{suf}").input_value()) + print("party wall ->", + _pick(page, f"{PWALL}DropDownListPartyWallType", "determine") + or _pick(page, f"{PWALL}DropDownListPartyWallType", "masonry")) + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + _pick(page, f"{ROOF}DropDownListType", "access to loft") \ + or _pick(page, f"{ROOF}DropDownListType", "loft") + _pick(page, f"{ROOF}DropDownListInsulationAt", "joists") + E.set_select(page, f"{ROOF}DropDownListThickness", "150 mm") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + E.set_select(page, f"{FLOOR}DropDownListLocation", "G Ground floor") + _pick(page, f"{FLOOR}DropDownListType", "solid") + E.set_select(page, f"{FLOOR}DropDownListInsulation", "A As built") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + _add_window(page, 4.31, "North", _glazing(page)) + _delete_zero_rows(page) + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "2") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + for needle in ("unknown install date", "before 2002", "pre 2002"): + for opt in _options(page, f"{WP}DropDownListExtGlazing"): + low = opt.lower() + if needle in low and "triple" not in low and "single" not in low and "known data" not in low: + return opt + return "Double post or during 2022" + + +def _add_window(page, area, orientation, glazing): + print("glazing ->", glazing) + E.set_select(page, f"{WP}DropDownListExtGlazing", glazing) + page.wait_for_timeout(400) + ft = page.locator(f"#{E.FP}{WP}DropDownListExtFrameType") + if ft.count(): + ft.select_option("PVC") + gg = page.locator(f"#{E.FP}{WP}DropDownListExtGlazingGap") + if gg.count(): + gg.select_option("12 mm") + wid = f"{E.FP}{WP}TextBoxExtWidth" + page.evaluate( + """(a)=>{const e=document.getElementById(a[0]);if(e){e.value=a[1]; + e.dispatchEvent(new Event('input',{bubbles:true})); + e.dispatchEvent(new Event('change',{bubbles:true})); + e.dispatchEvent(new Event('blur',{bubbles:true}));}}""", [wid, str(area)]) + page.locator(f"#{E.FP}{WP}TextBoxExtHeight").fill("1.00") + page.locator(f"#{E.FP}{WP}DropDownListExtOrientation").select_option(orientation) + page.locator(f"#{E.FP}{WP}DropDownListExtBuildingPartId").select_option("Main") + page.locator(f"#{E.FP}{WP}DropDownListExtLocation").select_option("External wall") + page.wait_for_timeout(300) + before = E.window_row_count(page) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}{WP}ButtonAddWindow") + for _ in range(25): + page.wait_for_timeout(200) + if E.window_row_count(page) > before: + break + + +def _grid_rows(page): + return page.evaluate( + """()=>{const t=document.querySelector("[id*=GridViewExtendedWidows]"); + if(!t)return[];return Array.from(t.querySelectorAll('tr')).slice(1) + .map(r=>Array.from(r.querySelectorAll('td')).map(c=>c.innerText.trim()));}""") + + +def _delete_zero_rows(page): + g = 0 + while g < 6 and E.window_row_count(page) > 1: + g += 1 + rows = _grid_rows(page) + bad = next((i for i, c in enumerate(rows) if len(c) > 1 and c[1] in ("0.00", "0", "0.0")), None) + if bad is None: + break + _delete_row(page, bad) + page.wait_for_timeout(400) + + +def _delete_row(page, idx): + before = E.window_row_count(page) + btn = page.evaluate( + """(i)=>{const b=document.querySelectorAll("[id*='GridViewExtendedWidows_DeleteButton_']");return b[i]?b[i].id:null;}""", idx) + if not btn: + return + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", btn) + page.wait_for_selector(f"#{E.FP}DeleteWindowDialog_LinkButtonYes", state="visible", timeout=5000) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}DeleteWindowDialog_LinkButtonYes") + for _ in range(20): + page.wait_for_timeout(200) + if E.window_row_count(page) < before: + break + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "0") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "6") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + # Generic Post-1998 condensing combi (~89% SAP 4b, ≈ PCDB 16137 Ideal Logic + # combi 30). combi vs regular is set on the water page (from primary + no + # cylinder). Control 2106 = CBE (programmer, room thermostat and TRVs). + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "No") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + print("navigating via Recommendations ...") + with page.expect_navigation(wait_until="networkidle", timeout=60_000): + page.click("#ContentBody_buttonActionRecommendations_Link", timeout=15_000) + page.wait_for_timeout(1500) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60_000) as dl: + page.click(f"#{btn}", timeout=15_000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +_ORDER = ["property_description", "dimensions", "walls", "roofs", "floors", + "openings", "ventilation", "space_heating", "water_heating", "download"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_200004296092.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 11a637c6bde2d5b561d7aa99c9c969054268677a Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 23:02:27 +0000 Subject: [PATCH 09/84] test(accuracy): ratchet 77.0% -> 77.3% via unsized-cylinder storage-loss fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A hot-water cylinder lodging gov-API `cylinder_size=0` ("size not determined", with has_hot_water_cylinder=true) resolved to a None volume in `_cylinder_storage_loss_override` (which reads `_cylinder_volume_l_ from_code`, returning None for code 0). The subsequent `if volume_l is None: return None` then DROPPED the cylinder's Table-2 storage loss entirely — under-costing the DHW and over-rating the dwelling. Meanwhile the Table-13 high-rate-fraction path already used `_hot_water_cylinder_ volume_l` (which defaults size 0 to 110 L), so the two DHW paths disagreed on the same cylinder. RdSAP 10 §10.5 Table 28 ("if the actual size is not determined, the size is taken as according to Table 28") makes an unsized present cylinder the 110 L "Normal" baseline, which STILL incurs the storage loss. Fixed by defaulting the storage-loss volume to 110 L for the explicit size-0 case. Gated on the EXPLICIT 0 (not None): a full-SAP cert whose RdSAP cylinder_size is simply unlodged (None, e.g. pinned 10091568921) keeps its own cylinder handling rather than a forced 110 L RdSAP default. 7 corpus certs lodge cylinder_size=0 + has_cylinder=true. Gauge: within 77.0% -> 77.3%, SAP MAE ~flat (0.648), CO2 0.074 -> 0.073, PE 3.2 -> 3.05 (the previously-dropped storage loss now correctly counted in the demand cascade). Unit-pinned in test_cert_to_inputs (storage loss non-None for size 0); RealCertExpectation 200004017091 = 71. Co-Authored-By: Claude Fable 5 --- .../uprn_200004017091/epc.json | 372 +++++++++++++++++ .../sap10_calculator/rdsap/cert_to_inputs.py | 12 + scripts/corpus_1000/worklist.md | 376 +++++++++--------- .../rdsap/test_cert_to_inputs.py | 24 ++ .../test_real_cert_sap_accuracy.py | 15 + .../epc_client/test_sap_accuracy_corpus.py | 15 +- 6 files changed, 621 insertions(+), 193 deletions(-) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004017091/epc.json diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004017091/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004017091/epc.json new file mode 100644 index 000000000..80a987a43 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004017091/epc.json @@ -0,0 +1,372 @@ +{ + "uprn": 200004017091, + "roofs": [ + { + "description": "Pitched, 100 mm loft insulation", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "description": "Timber frame, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "addendum": { + "addendum_numbers": [ + 15 + ] + }, + "lighting": { + "description": "Good lighting efficiency", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "BN14 9EL", + "hot_water": { + "description": "From main system, no cylinder thermostat", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "post_town": "WORTHING", + "built_form": 3, + "created_at": "2026-04-21 13:18:06", + "door_count": 2, + "region_code": 14, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 0, + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 0, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 17803 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.1, + "window_height": 1.2, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.1, + "window_height": 1.2, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.1, + "window_height": 1.2, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 0.8, + "window_height": 0.8, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.5, + "window_height": 0.8, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "End-terrace house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "3 Radbone Close", + "assessment_type": "RdSAP", + "completion_date": "2026-04-21", + "inspection_date": "2026-04-20", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 65, + "transaction_type": 1, + "conservatory_type": 1, + "heated_room_count": 4, + "registration_date": "2026-04-21", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "extract_fans_count": 1, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 280, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 5, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.37, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 32.38, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 7.42, + "quantity": "metres" + }, + "floor_construction": 1, + "heat_loss_perimeter": { + "value": 16.15, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.35, + "quantity": "metres" + }, + "total_floor_area": { + "value": 32.37, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 7.42, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 16.15, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "G", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "100mm", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 4, + "heating_cost_current": { + "value": 556, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 2.2, + "energy_rating_average": 60, + "energy_rating_current": 71, + "lighting_cost_current": { + "value": 51, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 516, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 333, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 71, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 44, + "currency": "GBP" + }, + "indicative_cost": "\u00a35,000 - \u00a310,000", + "improvement_type": "W2", + "improvement_details": { + "improvement_number": 58 + }, + "improvement_category": 5, + "energy_performance_rating": 73, + "environmental_impact_rating": 74 + }, + { + "sequence": 2, + "typical_saving": { + "value": 143, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,000 - \u00a37,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 5, + "energy_performance_rating": 76, + "environmental_impact_rating": 79 + }, + { + "sequence": 3, + "typical_saving": { + "value": 212, + "currency": "GBP" + }, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 81, + "environmental_impact_rating": 80 + } + ], + "co2_emissions_potential": 1.5, + "energy_rating_potential": 81, + "lighting_cost_potential": { + "value": 51, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 186, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 3562.39, + "space_heating_existing_dwelling": 4593.09 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 184, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0342", + "energy_consumption_potential": 118, + "environmental_impact_current": 72, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 80, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 33, + "low_energy_fixed_lighting_bulbs_count": 12, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/domain/sap10_calculator/rdsap/cert_to_inputs.py b/domain/sap10_calculator/rdsap/cert_to_inputs.py index 262c54f42..27451560e 100644 --- a/domain/sap10_calculator/rdsap/cert_to_inputs.py +++ b/domain/sap10_calculator/rdsap/cert_to_inputs.py @@ -7104,6 +7104,18 @@ def _cylinder_storage_loss_override( # 550 kWh/yr). The Table-2b temperature factor still applies (49)→(50). declared_loss = _float_or_none(getattr(sh, "cylinder_heat_loss", None)) volume_l = _cylinder_volume_l_from_code(epc) + if volume_l is None and _int_or_none(sh.cylinder_size) == 0: + # gov-API cylinder_size=0 = "size not determined" for a present + # cylinder (has_hot_water_cylinder=true). RdSAP 10 §10.5 Table 28: + # "If the actual size is not determined, the size ... is taken as + # according to Table 28" → the "Normal" 110 L baseline, which STILL + # incurs a storage loss. Without this the code lookup returned None + # and the `if volume_l is None: return None` below dropped the loss, + # under-costing the DHW (7 corpus certs; e.g. 200004017091 +1.75 -> + # +0.39). Gated on the EXPLICIT 0 so a full-SAP cert whose RdSAP + # cylinder_size is simply unlodged (None, e.g. 10091568921) keeps its + # own cylinder handling rather than a forced 110 L RdSAP default. + volume_l = _CYLINDER_SIZE_NOT_DETERMINED_L if declared_loss is not None: storage_56m = cylinder_storage_loss_monthly_kwh( volume_l=volume_l or 0.0, diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index 07c3cccf3..7f57b370c 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -1,10 +1,10 @@ # RdSAP-21.0.1 corpus campaign ledger -**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.0%** · MAE = **0.647** (floors in test_sap_accuracy_corpus.py) +**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.3%** · MAE = **0.648** (floors in test_sap_accuracy_corpus.py) Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail engine bug · ⛔ unbuildable. Line: `uprn · lodged L / eng E / Δ · signature`. Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` (preserves statuses & `<-` notes). -## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 230 certs in 222 clusters +## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 227 certs in 220 clusters ### C001 · Σ|Δ| 23.9 · 1 certs · `hpcdb100053/elec | solid brick | (another dwelling | sec:room heaters` - ⚠ `4510053280` · L 51 / E 74.94 / Δ +23.94 <- lodged software billed out-of-range-PSR (2.031 > 2.0) PCDB 100053 as 100% direct electric; engine follows SAP10.2 N2 extension (305%), Elmhurst-validated on case 56. Pinned engine 75 in test_real_cert_sap_accuracy. @@ -12,8 +12,8 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C002 · Σ|Δ| 19.7 · 1 certs · `h301/coal-anth | cavity wall | pitched unknown | whw903` - [ ] `103001004` · L 50 / E 69.69 / Δ +19.69 <- needs Elmhurst arbitration: lodged hw £1054 vs ours £113 (single-immersion on-peak fraction + cylinder declared-loss 1.8 kWh/day vs Table-2-sized loss); register data can't decompose. Other 14 declared-loss certs match lodged; only sibling outlier is 100121325434 (C008). -### C003 · Σ|Δ| 14.5 · 1 certs · `h195/elec | system built | (another dwelling` -- [ ] `10012334488` · L 72 / E 86.47 / Δ +14.47 +### C003 · Σ|Δ| 13.2 · 1 certs · `h195/elec | system built | (another dwelling` +- [ ] `10012334488` · L 72 / E 85.20 / Δ +13.20 ### C004 · Σ|Δ| 13.1 · 1 certs · `hpcdb10326/gas | solid brick | pitched 75 | ext1,sec:room heaters` - [ ] `12109191` · L 58 / E 71.10 / Δ +13.10 @@ -42,55 +42,54 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C011 · Σ|Δ| 6.7 · 1 certs · `h691/elec | solid brick | pitched 100 | RR,ext1,whw909` - [ ] `100032223878` · L 11 / E 17.67 / Δ +6.67 -### C012 · Σ|Δ| 6.5 · 1 certs · `h408/elec | granite or | (another dwelling | sec:portable electric,whw903` +### C012 · Σ|Δ| 6.5 · 1 certs · `h191/elec | cavity wall | (another dwelling` +- [ ] `10002272664` · L 79 / E 72.47 / Δ -6.53 + +### C013 · Σ|Δ| 6.5 · 1 certs · `h408/elec | granite or | (another dwelling | sec:portable electric,whw903` - [ ] `100121397382` · L 69 / E 75.49 / Δ +6.49 -### C013 · Σ|Δ| 6.5 · 1 certs · `h691/elec | solid brick | (another dwelling | ext1,sec:room heaters,whw903` +### C014 · Σ|Δ| 6.5 · 1 certs · `h691/elec | solid brick | (another dwelling | ext1,sec:room heaters,whw903` - [ ] `100062100640` · L 54 / E 47.51 / Δ -6.49 -### C014 · Σ|Δ| 6.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 225` +### C015 · Σ|Δ| 6.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 225` - [ ] `100050844968` · L 71 / E 65.02 / Δ -5.98 -### C015 · Σ|Δ| 5.8 · 1 certs · `hpcdb17777/gas+2mains | cavity wall | pitched insulated | ext1,sec:room heaters,whw914` +### C016 · Σ|Δ| 5.8 · 1 certs · `hpcdb17777/gas+2mains | cavity wall | pitched insulated | ext1,sec:room heaters,whw914` - [ ] `line804` · L 52 / E 57.76 / Δ +5.76 -### C016 · Σ|Δ| 5.6 · 2 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` -- [ ] `11071248` · L 78 / E 81.86 / Δ +3.86 -- [ ] `12126160` · L 69 / E 70.71 / Δ +1.71 +### C017 · Σ|Δ| 5.8 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` +- [ ] `80838` · L 41 / E 35.25 / Δ -5.75 -### C017 · Σ|Δ| 4.6 · 1 certs · `hpcdb18560/gas | solid brick | pitched no | RR` +### C018 · Σ|Δ| 4.6 · 1 certs · `hpcdb18560/gas | solid brick | pitched no | RR` - [ ] `100051233481` · L 65 / E 69.64 / Δ +4.64 -### C018 · Σ|Δ| 4.5 · 1 certs · `h691/elec | timber frame | pitched limited | RR,ext2,whw903` +### C019 · Σ|Δ| 4.5 · 1 certs · `h691/elec | timber frame | pitched limited | RR,ext2,whw903` - [ ] `100061646773` · L 68 / E 63.46 / Δ -4.54 -### C019 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` +### C020 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` - [ ] `100071010014` · L 55 / E 50.47 / Δ -4.53 -### C020 · Σ|Δ| 4.5 · 1 certs · `hpcdb17815/gas | cavity wall | flat insulated` +### C021 · Σ|Δ| 4.5 · 1 certs · `hpcdb17815/gas | cavity wall | flat insulated` - [ ] `47084930` · L 74 / E 69.51 / Δ -4.49 -### C021 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` +### C022 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` - [ ] `10093342182` · L 82 / E 77.51 / Δ -4.49 -### C022 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` +### C023 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` - [ ] `5117280` · L 76 / E 71.56 / Δ -4.44 -### C023 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` +### C024 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` - [ ] `217060420` · L 42 / E 37.58 / Δ -4.42 -### C024 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` +### C025 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` - [ ] `72399971` · L 69 / E 64.60 / Δ -4.40 -### C025 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` +### C026 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` - [ ] `10007016314` · L 57 / E 52.64 / Δ -4.36 -### C026 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` +### C027 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` - [ ] `100052159386` · L 56 / E 51.92 / Δ -4.08 -### C027 · Σ|Δ| 4.0 · 1 certs · `h191/elec | cavity wall | (another dwelling` -- [ ] `10002272664` · L 79 / E 74.96 / Δ -4.04 - ### C028 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` - [ ] `100040767294` · L 43 / E 47.04 / Δ +4.04 @@ -112,77 +111,77 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C034 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` - [ ] `200004818752` · L 34 / E 30.73 / Δ -3.27 -### C035 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` +### C035 · Σ|Δ| 3.2 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` +- [ ] `200004522639` · L 37 / E 33.77 / Δ -3.23 + +### C036 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` - [ ] `72351021` · L 64 / E 60.85 / Δ -3.15 -### C036 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` +### C037 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` - [ ] `22077224` · L 37 / E 33.90 / Δ -3.10 -### C037 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` +### C038 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` - [ ] `10011740578` · L 70 / E 67.00 / Δ -3.00 -### C038 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +### C039 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` - [ ] `100110680822` · L 79 / E 76.07 / Δ -2.93 -### C039 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` +### C040 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` - [ ] `452032915` · L 75 / E 72.09 / Δ -2.91 -### C040 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` +### C041 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` - [ ] `100071306639` · L 73 / E 70.14 / Δ -2.86 -### C041 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` +### C042 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` - [ ] `100061346049` · L 55 / E 52.15 / Δ -2.85 -### C042 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` +### C043 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` - [ ] `10013008238` · L 41 / E 38.26 / Δ -2.74 -### C043 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` +### C044 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` - [ ] `10033187652` · L 70 / E 71.21 / Δ +1.21 - [ ] `200002730` · L 65 / E 64.13 / Δ -0.87 - [ ] `10023328117` · L 78 / E 78.64 / Δ +0.64 -### C044 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` +### C045 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` - [ ] `10004873253` · L 65 / E 62.29 / Δ -2.71 -### C045 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` +### C046 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` - [ ] `10090793715` · L 73 / E 75.71 / Δ +2.71 -### C046 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` +### C047 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100120745600` · L 65 / E 67.69 / Δ +2.69 -### C047 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` +### C048 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` - [ ] `100051178830` · L 63 / E 65.66 / Δ +2.66 -### C048 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` +### C049 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` - [ ] `100120018282` · L 64 / E 61.36 / Δ -2.64 -### C049 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +### C050 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` - [ ] `83035979` · L 65 / E 67.60 / Δ +2.60 -### C050 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` +### C051 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` - [ ] `10014073761` · L 75 / E 72.52 / Δ -2.48 -### C051 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` +### C052 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` - [ ] `100050964834` · L 60 / E 62.47 / Δ +2.47 -### C052 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` +### C053 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` - [ ] `100120752995` · L 71 / E 73.42 / Δ +2.42 -### C053 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` +### C054 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` - [ ] `100032230128` · L 55 / E 52.60 / Δ -2.40 -### C054 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` +### C055 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` - [ ] `100000034023` · L 73 / E 70.71 / Δ -2.29 -### C055 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` +### C056 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` - [ ] `100020377671` · L 62 / E 64.23 / Δ +2.23 -### C056 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` +### C057 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` - [ ] `22027335` · L 76 / E 73.77 / Δ -2.23 -### C057 · Σ|Δ| 2.2 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` -- [ ] `80838` · L 41 / E 43.19 / Δ +2.19 - ### C058 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` - [ ] `48056153` · L 65 / E 62.89 / Δ -2.11 @@ -217,15 +216,15 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C068 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` - [ ] `100022668387` · L 68 / E 66.25 / Δ -1.75 -### C069 · Σ|Δ| 1.8 · 1 certs · `hpcdb17803/gas | timber frame | pitched 100` -- [ ] `200004017091` · L 71 / E 72.75 / Δ +1.75 - -### C070 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` +### C069 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` - [ ] `100100892216` · L 69 / E 67.28 / Δ -1.72 -### C071 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` +### C070 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100060878876` · L 49 / E 50.71 / Δ +1.71 +### C071 · Σ|Δ| 1.7 · 1 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` +- [ ] `12126160` · L 69 / E 70.71 / Δ +1.71 + ### C072 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` - [ ] `22032926` · L 61 / E 62.71 / Δ +1.71 @@ -286,401 +285,395 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C091 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` - [ ] `250063088` · L 73 / E 71.60 / Δ -1.40 -### C092 · Σ|Δ| 1.4 · 1 certs · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` -- [ ] `100050048691` · L 58 / E 59.39 / Δ +1.39 - -### C093 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` +### C092 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` - [ ] `100110097281` · L 64 / E 65.37 / Δ +1.37 -### C094 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` +### C093 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` - [ ] `10091630692` · L 58 / E 56.63 / Δ -1.37 -### C095 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` +### C094 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` - [ ] `100031433810` · L 70 / E 68.63 / Δ -1.37 -### C096 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` +### C095 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` - [ ] `100012368622` · L 39 / E 40.32 / Δ +1.32 -### C097 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +### C096 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` - [ ] `90077194` · L 65 / E 63.69 / Δ -1.31 -### C098 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` +### C097 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` - [ ] `100031461986` · L 70 / E 71.29 / Δ +1.29 -### C099 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` +### C098 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` - [ ] `30095054` · L 46 / E 44.74 / Δ -1.26 -### C100 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` +### C099 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` - [ ] `100100055589` · L 58 / E 59.26 / Δ +1.26 -### C101 · Σ|Δ| 1.2 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` +### C100 · Σ|Δ| 1.2 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` - [ ] `74061136` · L 73 / E 71.75 / Δ -1.25 <- electric storage cat7 E7: over-rate = off-peak rate/fraction too generous; needs Elmhurst tariff arbitration -### C102 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` +### C101 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` - [ ] `100091435353` · L 65 / E 66.23 / Δ +1.23 -### C103 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` +### C102 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` - [ ] `10091070164` · L 69 / E 69.60 / Δ +0.60 - [ ] `10090927185` · L 79 / E 79.60 / Δ +0.60 -### C104 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` +### C103 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` - [ ] `100100614412` · L 53 / E 51.81 / Δ -1.19 -### C105 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` +### C104 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` - [ ] `217091901` · L 62 / E 60.82 / Δ -1.18 -### C106 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` +### C105 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` - [x] `line768` · L 57 / E 55.84 / Δ -1.16 -### C107 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` +### C106 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` - [ ] `217061895` · L 61 / E 59.84 / Δ -1.16 -### C108 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C107 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `10002349227` · L 76 / E 77.14 / Δ +1.14 -### C109 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` +### C108 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` - [ ] `200001634005` · L 66 / E 67.11 / Δ +1.11 -### C110 · Σ|Δ| 1.1 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` -- [ ] `200004522639` · L 37 / E 35.89 / Δ -1.11 - -### C111 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +### C109 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [ ] `100071059081` · L 63 / E 64.09 / Δ +1.09 -### C112 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` +### C110 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` - [ ] `100011820199` · L 55 / E 56.06 / Δ +1.06 -### C113 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` +### C111 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` - [ ] `90214753` · L 83 / E 81.95 / Δ -1.05 -### C114 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` +### C112 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` - [ ] `100051051866` · L 70 / E 71.04 / Δ +1.04 -### C115 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` +### C113 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` - [ ] `10013836852` · L 100 / E 98.97 / Δ -1.03 -### C116 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` +### C114 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` - [ ] `line899` · L 73 / E 71.97 / Δ -1.03 -### C117 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` +### C115 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` - [ ] `40037847` · L 81 / E 79.98 / Δ -1.02 -### C118 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` +### C116 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` - [ ] `10070056075` · L 80 / E 78.99 / Δ -1.01 -### C119 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` +### C117 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` - [ ] `200131078` · L 86 / E 85.00 / Δ -1.00 -### C120 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` +### C118 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` - [ ] `10000245212` · L 101 / E 100.00 / Δ -1.00 -### C121 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` +### C119 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` - [ ] `15129162` · L 62 / E 61.00 / Δ -1.00 -### C122 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` +### C120 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` - [ ] `23032873` · L 73 / E 72.00 / Δ -1.00 -### C123 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` +### C121 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` - [ ] `45019020` · L 62 / E 61.01 / Δ -0.99 -### C124 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` +### C122 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` - [ ] `42065028` · L 59 / E 58.02 / Δ -0.98 -### C125 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` +### C123 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` - [ ] `10032928147` · L 77 / E 76.04 / Δ -0.96 -### C126 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` +### C124 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` - [ ] `10010678937` · L 78 / E 77.04 / Δ -0.96 -### C127 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` +### C125 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` - [ ] `100011010151` · L 62 / E 62.96 / Δ +0.96 -### C128 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` +### C126 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` - [ ] `100050477371` · L 65 / E 64.04 / Δ -0.96 -### C129 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` +### C127 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` - [ ] `10002945522` · L 61 / E 61.94 / Δ +0.94 -### C130 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` +### C128 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` - [ ] `10032957680` · L 45 / E 45.94 / Δ +0.94 -### C131 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` +### C129 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` - [ ] `2465057465` · L 81 / E 81.93 / Δ +0.93 -### C132 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` +### C130 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` - [ ] `100090616327` · L 63 / E 63.93 / Δ +0.93 -### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` +### C131 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` - [ ] `100012753833` · L 74 / E 73.07 / Δ -0.93 -### C134 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` +### C132 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` - [ ] `100031269525` · L 53 / E 53.91 / Δ +0.91 -### C135 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` +### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` - [ ] `200003725358` · L 75 / E 74.09 / Δ -0.91 -### C136 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` +### C134 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` - [ ] `100050986162` · L 62 / E 61.10 / Δ -0.90 -### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` +### C135 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` - [ ] `5300000141` · L 78 / E 77.10 / Δ -0.90 -### C138 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` +### C136 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` - [ ] `100050618404` · L 73 / E 73.89 / Δ +0.89 -### C139 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` +### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` - [ ] `100090476016` · L 81 / E 81.89 / Δ +0.89 -### C140 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` +### C138 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` - [ ] `10012119141` · L 45 / E 45.89 / Δ +0.89 -### C141 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` +### C139 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` - [ ] `100040938206` · L 75 / E 75.89 / Δ +0.89 -### C142 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` +### C140 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `38188474` · L 76 / E 76.87 / Δ +0.87 -### C143 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +### C141 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100061194957` · L 69 / E 69.87 / Δ +0.87 -### C144 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` +### C142 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` - [ ] `100021236527` · L 72 / E 71.13 / Δ -0.87 -### C145 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` +### C143 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` - [ ] `100040193752` · L 71 / E 71.86 / Δ +0.86 -### C146 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` +### C144 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` - [ ] `100060701552` · L 74 / E 74.86 / Δ +0.86 -### C147 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` +### C145 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` - [ ] `10070396146` · L 61 / E 60.14 / Δ -0.86 -### C148 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` +### C146 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` - [ ] `100030528930` · L 74 / E 73.16 / Δ -0.84 -### C149 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` +### C147 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` - [ ] `100020982570` · L 72 / E 71.17 / Δ -0.83 -### C150 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` +### C148 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` - [ ] `394024487` · L 75 / E 74.17 / Δ -0.83 -### C151 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` +### C149 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` - [ ] `217070698` · L 78 / E 78.83 / Δ +0.83 -### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` +### C150 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` - [ ] `77022508` · L 69 / E 68.18 / Δ -0.82 -### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` +### C151 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` - [ ] `100040259104` · L 68 / E 68.82 / Δ +0.82 -### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` +### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` - [ ] `100031399026` · L 70 / E 70.81 / Δ +0.81 -### C155 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` +### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` - [ ] `10009645698` · L 67 / E 67.81 / Δ +0.81 -### C156 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` +### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` - [ ] `100080818887` · L 56 / E 55.19 / Δ -0.81 -### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` +### C155 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100012374381` · L 69 / E 69.80 / Δ +0.80 -### C158 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` +### C156 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` - [ ] `100012350270` · L 78 / E 77.20 / Δ -0.80 -### C159 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` +### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` - [ ] `100051109723` · L 60 / E 60.78 / Δ +0.78 -### C160 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` +### C158 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` - [ ] `100061616915` · L 63 / E 62.22 / Δ -0.78 -### C161 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` +### C159 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` - [ ] `line71` · L 74 / E 74.77 / Δ +0.77 -### C162 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` +### C160 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` - [ ] `100011603934` · L 72 / E 71.23 / Δ -0.77 -### C163 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` +### C161 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` - [ ] `24030987` · L 73 / E 73.76 / Δ +0.76 -### C164 · Σ|Δ| 0.8 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` +### C162 · Σ|Δ| 0.8 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` - [ ] `100032043038` · L 74 / E 73.24 / Δ -0.76 -### C165 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` +### C163 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` - [ ] `100010866608` · L 71 / E 70.24 / Δ -0.76 -### C166 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` +### C164 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` - [ ] `100090399615` · L 67 / E 67.75 / Δ +0.75 -### C167 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` +### C165 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` - [ ] `100062174575` · L 46 / E 46.75 / Δ +0.75 -### C168 · Σ|Δ| 0.7 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` +### C166 · Σ|Δ| 0.7 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` - [ ] `200004296092` · L 71 / E 71.74 / Δ +0.74 -### C169 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` +### C167 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `10012341135` · L 79 / E 79.73 / Δ +0.73 -### C170 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +### C168 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` - [ ] `100091005853` · L 70 / E 69.27 / Δ -0.73 -### C171 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` +### C169 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` - [ ] `100021533514` · L 71 / E 71.73 / Δ +0.73 -### C172 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` +### C170 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` - [ ] `5062075` · L 69 / E 69.72 / Δ +0.72 -### C173 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` +### C171 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100040813308` · L 62 / E 62.72 / Δ +0.72 -### C174 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` +### C172 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` - [ ] `38105600` · L 68 / E 67.28 / Δ -0.72 -### C175 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` +### C173 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` - [ ] `line255` · L 72 / E 71.29 / Δ -0.71 -### C176 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` +### C174 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` - [ ] `5300047580` · L 69 / E 68.30 / Δ -0.70 -### C177 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` +### C175 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` - [ ] `100110433403` · L 69 / E 68.32 / Δ -0.68 -### C178 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` +### C176 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` - [ ] `10093416558` · L 79 / E 78.32 / Δ -0.68 -### C179 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` +### C177 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` - [ ] `100050958217` · L 68 / E 68.68 / Δ +0.68 -### C180 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` +### C178 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` - [ ] `100022667797` · L 68 / E 67.32 / Δ -0.68 -### C181 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C179 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100030528925` · L 78 / E 78.65 / Δ +0.65 -### C182 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` +### C180 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` - [ ] `100110300037` · L 74 / E 73.35 / Δ -0.65 -### C183 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` +### C181 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` - [ ] `217092450` · L 52 / E 52.64 / Δ +0.64 -### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` +### C182 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` - [ ] `100061164545` · L 72 / E 71.36 / Δ -0.64 -### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` +### C183 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` - [ ] `100051075936` · L 71 / E 70.36 / Δ -0.64 -### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` +### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` - [ ] `100011565830` · L 72 / E 72.64 / Δ +0.64 -### C187 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` +### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` - [ ] `61010956` · L 75 / E 74.37 / Δ -0.63 -### C188 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` +### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` - [ ] `100110752514` · L 67 / E 67.62 / Δ +0.62 -### C189 · Σ|Δ| 0.6 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` +### C187 · Σ|Δ| 0.6 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` - [ ] `100070295212` · L 75 / E 74.38 / Δ -0.62 -### C190 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` +### C188 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` - [ ] `100012534027` · L 65 / E 64.38 / Δ -0.62 -### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` +### C189 · Σ|Δ| 0.6 · 1 certs · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` - [x] `10009812472` · L 40 / E 39.40 / Δ -0.60 -### C192 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` +### C190 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` - [ ] `34080035` · L 77 / E 76.41 / Δ -0.59 -### C193 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` +### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` - [ ] `21032732` · L 69 / E 69.59 / Δ +0.59 -### C194 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` +### C192 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100060562056` · L 66 / E 65.41 / Δ -0.59 -### C195 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` +### C193 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` - [ ] `100091086558` · L 79 / E 79.58 / Δ +0.58 -### C196 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` +### C194 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` - [ ] `line599` · L 74 / E 73.42 / Δ -0.58 -### C197 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` +### C195 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` - [ ] `100020407741` · L 72 / E 71.42 / Δ -0.58 -### C198 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` +### C196 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` - [ ] `100050839457` · L 70 / E 70.57 / Δ +0.57 -### C199 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` +### C197 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` - [ ] `42105250` · L 59 / E 59.57 / Δ +0.57 -### C200 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` +### C198 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` - [ ] `77200509` · L 69 / E 69.57 / Δ +0.57 -### C201 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` +### C199 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` - [ ] `200040534` · L 65 / E 65.56 / Δ +0.56 -### C202 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` +### C200 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` - [ ] `200049463` · L 69 / E 69.56 / Δ +0.56 -### C203 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` +### C201 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` - [ ] `100062527568` · L 61 / E 61.56 / Δ +0.56 -### C204 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` +### C202 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` - [ ] `100100268900` · L 69 / E 69.56 / Δ +0.56 -### C205 · Σ|Δ| 0.6 · 1 certs · `hpcdb17004/fuel27+2mains | sandstone as | pitched no | ext3,sec:room heaters` +### C203 · Σ|Δ| 0.6 · 1 certs · `hpcdb17004/fuel27+2mains | sandstone as | pitched no | ext3,sec:room heaters` - [x] `200003110548` · L 29 / E 28.45 / Δ -0.55 -### C206 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` +### C204 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` - [ ] `90036914` · L 60 / E 60.55 / Δ +0.55 -### C207 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` +### C205 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` - [ ] `10004742671` · L 70 / E 69.46 / Δ -0.54 -### C208 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` +### C206 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` - [ ] `100010657450` · L 75 / E 75.54 / Δ +0.54 -### C209 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` +### C207 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` - [ ] `100061834344` · L 71 / E 70.46 / Δ -0.54 -### C210 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` +### C208 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` - [ ] `4510097194` · L 70 / E 70.53 / Δ +0.53 -### C211 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` +### C209 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` - [ ] `100010913220` · L 72 / E 72.53 / Δ +0.53 -### C212 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` +### C210 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` - [ ] `43074051` · L 63 / E 62.48 / Δ -0.52 -### C213 · Σ|Δ| 0.5 · 1 certs · `h104/gas | cavity wall | pitched 300` +### C211 · Σ|Δ| 0.5 · 1 certs · `h104/gas | cavity wall | pitched 300` - [ ] `100010723814` · L 69 / E 69.52 / Δ +0.52 -### C214 · Σ|Δ| 0.5 · 1 certs · `hpcdb16137/gas | cavity wall | (another dwelling` +### C212 · Σ|Δ| 0.5 · 1 certs · `hpcdb16137/gas | cavity wall | (another dwelling` - [ ] `100020955792` · L 77 / E 77.52 / Δ +0.52 -### C215 · Σ|Δ| 0.5 · 1 certs · `hpcdb19079/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +### C213 · Σ|Δ| 0.5 · 1 certs · `hpcdb19079/gas | cavity wall | pitched 200 | ext1,sec:room heaters` - [ ] `77172223` · L 65 / E 65.52 / Δ +0.52 -### C216 · Σ|Δ| 0.5 · 1 certs · `hpcdb10242/gas | granite or | pitched insulated | RR,sec:room heaters` +### C214 · Σ|Δ| 0.5 · 1 certs · `hpcdb10242/gas | granite or | pitched insulated | RR,sec:room heaters` - [ ] `100051245439` · L 62 / E 61.48 / Δ -0.52 -### C217 · Σ|Δ| 0.5 · 1 certs · `hpcdb10328/gas | cavity wall | (another dwelling` +### C215 · Σ|Δ| 0.5 · 1 certs · `hpcdb10328/gas | cavity wall | (another dwelling` - [ ] `100012553958` · L 67 / E 66.48 / Δ -0.52 -### C218 · Σ|Δ| 0.5 · 1 certs · `hpcdb10033/gas | cavity wall | pitched 200 | ext2,sec:room heaters` +### C216 · Σ|Δ| 0.5 · 1 certs · `hpcdb10033/gas | cavity wall | pitched 200 | ext2,sec:room heaters` - [ ] `100110108632` · L 63 / E 63.51 / Δ +0.51 -### C219 · Σ|Δ| 0.5 · 1 certs · `h109/gas | cavity wall | pitched 270 | consv2,ext1,sec:room heaters` +### C217 · Σ|Δ| 0.5 · 1 certs · `h109/gas | cavity wall | pitched 270 | consv2,ext1,sec:room heaters` - [ ] `100091102581` · L 65 / E 65.51 / Δ +0.51 -### C220 · Σ|Δ| 0.5 · 1 certs · `hpcdb19008/gas | cavity wall | pitched 150 | ext1,sec:room heaters` +### C218 · Σ|Δ| 0.5 · 1 certs · `hpcdb19008/gas | cavity wall | pitched 150 | ext1,sec:room heaters` - [ ] `10002326688` · L 69 / E 68.50 / Δ -0.50 -### C221 · Σ|Δ| 0.5 · 1 certs · `h129/fuel28 | granite or | pitched 200 | ext2,sec:room heaters` +### C219 · Σ|Δ| 0.5 · 1 certs · `h129/fuel28 | granite or | pitched 200 | ext2,sec:room heaters` - [ ] `10023132869` · L 46 / E 45.50 / Δ -0.50 -### C222 · Σ|Δ| 0.5 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` +### C220 · Σ|Δ| 0.5 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` - [ ] `10091707271` · L 41 / E 41.50 / Δ +0.50 -## Resolved ≤0.5 (770 certs — no action) +## Resolved ≤0.5 (773 certs — no action)
expand @@ -841,6 +834,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `74041417` · L 79 / E 79.39 / Δ +0.39 · `hpcdb17507/gas | cavity wall | pitched 300 | PV` - [x] `100110452552` · L 67 / E 67.39 / Δ +0.39 · `hpcdb15068/gas | cavity wall | pitched 175 | mv2,sec:room heaters` - [x] `100022607800` · L 73 / E 72.61 / Δ -0.39 · `hpcdb18119/gas | solid brick | pitched 270` +- [x] `200004017091` · L 71 / E 71.39 / Δ +0.39 · `hpcdb17803/gas | timber frame | pitched 100` - [x] `100022277442` · L 58 / E 58.39 / Δ +0.39 · `h409/elec | cavity wall | pitched insulated | whw903` - [x] `250029611` · L 73 / E 72.61 / Δ -0.39 · `hpcdb17553/gas | cavity wall | pitched 250 | consv2,ext1` - [x] `100022887979` · L 72 / E 72.39 / Δ +0.39 · `hpcdb18861/gas | solid brick | (another dwelling` @@ -1185,6 +1179,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100010043608` · L 56 / E 56.16 / Δ +0.16 · `h401/elec | cavity wall | pitched 200 | PV,RR,consv2,ext1,sec:room heaters,whw903` - [x] `100022232588` · L 56 / E 56.16 / Δ +0.16 · `h102/gas | solid brick | pitched 25 | ext1` - [x] `100110450961` · L 69 / E 68.84 / Δ -0.16 · `h104/gas | sandstone as | pitched 250 | ext1` +- [x] `11071248` · L 78 / E 77.84 / Δ -0.16 · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` - [x] `10014540481` · L 81 / E 81.15 / Δ +0.15 · `hpcdb16400/gas | timber frame | roof room(s) | RR` - [x] `100061860491` · L 69 / E 68.85 / Δ -0.15 · `hpcdb18824/gas | cavity wall | pitched 250 | consv3` - [x] `100121065133` · L 81 / E 80.85 / Δ -0.15 · `hpcdb17511/gas | cavity wall | (another dwelling` @@ -1248,6 +1243,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `202028377` · L 66 / E 66.13 / Δ +0.13 · `hpcdb17548/gas | solid brick | pitched 75` - [x] `100090533643` · L 85 / E 85.13 / Δ +0.13 · `hpcdb17507/gas | cavity wall | pitched insulated | PV,ext1` - [x] `100090335261` · L 70 / E 70.13 / Δ +0.13 · `hpcdb17974/gas | cavity wall | (another dwelling` +- [x] `100050048691` · L 58 / E 57.87 / Δ -0.13 · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` - [x] `100061898123` · L 70 / E 70.13 / Δ +0.13 · `hpcdb17511/gas | solid brick | pitched 100` - [x] `38149813` · L 74 / E 73.87 / Δ -0.13 · `h104/gas | solid brick | pitched 350 | ext1` - [x] `10014619006` · L 77 / E 77.13 / Δ +0.13 · `hpcdb17045/gas | cavity wall | pitched 350 | mv2` diff --git a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py index ded178ade..d6a3c1cdc 100644 --- a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py +++ b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py @@ -738,6 +738,30 @@ def test_cylinder_present_but_size_not_determined_defaults_to_normal_110l() -> N assert volume_l is not None and abs(volume_l - 110.0) <= 1e-9 +def test_cylinder_size_not_determined_still_incurs_storage_loss() -> None: + # Arrange — the size-0 (not determined) cylinder's Table 28 default of + # 110 L must flow into the STORAGE-LOSS override too, not just the Table + # 13 high-rate fraction. `_cylinder_storage_loss_override` read the + # volume via `_cylinder_volume_l_from_code` (None for size 0) and bailed + # `if volume_l is None: return None`, dropping the loss entirely — while + # the rest of the DHW cascade used `_hot_water_cylinder_volume_l` + # (110 L). A present cylinder with no storage loss under-costs the DHW + # and over-rates the dwelling (7 corpus certs lodge cylinder_size=0 + + # has_cylinder=true). RdSAP 10 §10.5 Table 28: a present-but-unsized + # cylinder is a 110 L cylinder and incurs the Table 2 storage loss. + from domain.sap10_calculator.rdsap.cert_to_inputs import ( + _cylinder_storage_loss_override, # pyright: ignore[reportPrivateUsage] + ) + epc = _cylinder_epc(cylinder_size=0) + + # Act + storage_56m = _cylinder_storage_loss_override(epc, None) + + # Assert — a real 110 L cylinder loss series, not the dropped None. + assert storage_56m is not None + assert sum(storage_56m) > 0.0 + + def test_cylinder_size_inaccessible_code_5_solid_fuel_boiler_uses_160l() -> None: # Arrange — RdSAP 10 §10.5 Table 28: an "Inaccessible" cylinder (code 5) # heated "from a solid fuel boiler" uses 160 litres. diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index d7e22cd64..e63d946bf 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -790,6 +790,21 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-200004296092", sap_score=72, ), + # UPRN 200004017091 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # END-TERRACE HOUSE, mains-gas boiler, hot-water cylinder lodged with + # `cylinder_size=0` (present but "size not determined") + has_cylinder=true. + # The unsized-cylinder storage-loss cert: `_cylinder_storage_loss_override` + # read the volume via `_cylinder_volume_l_from_code` → None for size 0 → + # bailed and DROPPED the cylinder's Table-2 storage loss, under-costing the + # DHW → engine 72.75 (Δ +1.75 vs lodged 71). RdSAP 10 §10.5 Table 28: an + # unsized present cylinder is the 110 L "Normal" default and still incurs + # the loss → engine 71.39 = lodged 71. PINNED to the observed engine 71. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_200004017091", + cert_num="uprn-200004017091", + sap_score=71, + ), ) diff --git a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py index 36ea16c3a..197e6f7e0 100644 --- a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py +++ b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py @@ -218,7 +218,16 @@ _CORPUS = Path( # lodged 36 / engine 20.8 -> 35.9. 55 corpus certs carry a colliding # secondary. Unit-pinned in test_cert_to_inputs (fuel_cost cost path, not # just the display helper the prior enum-9 test guarded). -_MIN_WITHIN_HALF_SAP = 0.770 +# 0.770 -> 0.773 via the unsized-cylinder storage-loss fix: a present +# cylinder lodging gov-API cylinder_size=0 ("size not determined") resolved +# to None volume in `_cylinder_storage_loss_override`, so `if volume_l is +# None: return None` DROPPED its storage loss (under-costing the DHW -> +# over-rate). RdSAP 10 §10.5 Table 28: an unsized present cylinder is the +# 110 L "Normal" default and still incurs the Table-2 loss (the value the +# Table-13 fraction path already used). Gated on the explicit 0 so a +# full-SAP unlodged size (None) keeps its own handling. 7 corpus certs; +# within 77.0% -> 77.3%, PE 3.2 -> 3.05, CO2 0.074 -> 0.073. +_MIN_WITHIN_HALF_SAP = 0.773 # 0.793 -> 0.789 via the §12 Unknown-meter + dual-electric-immersion off-peak # trigger (RdSAP 10 PDF p.62): Apartment 241 (main 691 + 903 dual immersion) # -5.38 -> -1.05. Worksheet-validated on "simulated case 48" (Elmhurst SAP 57, @@ -305,8 +314,8 @@ _MIN_WITHIN_HALF_SAP = 0.770 # brick/stone (the only §5.8 R-value path); within-0.5 held at 77.0%, MAE # 0.658 -> 0.647, PE 3.2 -> 3.1. Unit-pinned in test_rdsap_uvalues. _MAX_SAP_MAE = 0.648 -_MAX_CO2_MAE_TONNES = 0.075 # t CO2 / yr vs co2_emissions_current -_MAX_PE_PER_M2_MAE = 3.2 # kWh / m2 / yr vs energy_consumption_current +_MAX_CO2_MAE_TONNES = 0.074 # t CO2 / yr vs co2_emissions_current +_MAX_PE_PER_M2_MAE = 3.1 # kWh / m2 / yr vs energy_consumption_current def _load_corpus() -> list[dict[str, Any]]: From 8e33a8de53c72acad237e13f70ebcb4aff4cdb05 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 23:27:57 +0000 Subject: [PATCH 10/84] test(accuracy): ratchet 77.3% -> 77.7% via flat-roof insulation-thickness fix (Elmhurst-validated) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A FLAT roof lodges its insulation thickness in the DEDICATED gov-EPC API `flat_roof_insulation_thickness` field (e.g. "75mm"), leaving `roof_insulation_thickness` None (that field is for pitched-loft joists). `heat_transmission_from_cert` read only the latter, so a measured flat-roof thickness was ignored and the roof billed at the uninsulated age-band flat default (age E = 1.5) instead of its Table-16 insulated U. Fixed by preferring `flat_roof_insulation_thickness` when the part is a flat roof — the exact mirror of the existing rafter-thickness branch. An "AB"/"NI" (as-built/unknown) value parses to None and keeps the age-band default, unchanged; only measured thicknesses move. PER-CERT ELMHURST VALIDATION (cert 47084930, top-floor flat, flat roof 75 mm): built on the lodged inputs in accredited Elmhurst RdSAP10-Online (evidence saved: elmhurst_summary.pdf / elmhurst_worksheet.pdf). The worksheet bills "insulated flat roof" at U 0.5 (floor 0.70 + wall 0.25 also matching the engine). The fix takes the engine roof 96.4 -> 32.1 W/K (= 64.26 x 0.5, Elmhurst-exact), PE +47 -> +0.2, SAP 69.51 -> 74.34 = lodged 74. Gauge: within 77.3% -> 77.7%, SAP MAE 0.648 -> 0.641, CO2 0.074 -> 0.072, PE 3.1 -> 2.97. Unit-pinned in test_heat_transmission (flat_roof_insulation_thickness -> U 0.5); RealCertExpectation 47084930 = 74 (Elmhurst-validated). Also adds the build script build_47084930.py. Co-Authored-By: Claude Fable 5 --- .../uprn_47084930/elmhurst_summary.pdf | Bin 0 -> 77720 bytes .../uprn_47084930/elmhurst_worksheet.pdf | Bin 0 -> 43647 bytes .../uprn_47084930/epc.json | 324 ++++++++++++++ .../worksheet/heat_transmission.py | 16 + scripts/corpus_1000/worklist.md | 416 +++++++++--------- scripts/hyde/build_47084930.py | 299 +++++++++++++ .../test_real_cert_sap_accuracy.py | 18 + .../worksheet/test_heat_transmission.py | 40 ++ .../epc_client/test_sap_accuracy_corpus.py | 18 +- 9 files changed, 915 insertions(+), 216 deletions(-) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/elmhurst_summary.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/elmhurst_worksheet.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/epc.json create mode 100644 scripts/hyde/build_47084930.py diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/elmhurst_summary.pdf new file mode 100644 index 0000000000000000000000000000000000000000..80c83175cb665a85eba4de660b00945bd147ac13 GIT binary patch literal 77720 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 z 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 literal 0 HcmV?d00001 diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/epc.json new file mode 100644 index 000000000..f268aac88 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/epc.json @@ -0,0 +1,324 @@ +{ + "uprn": 47084930, + "roofs": [ + { + "description": "Flat, insulated", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "description": "Cavity wall, with internal insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "(other premises below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "NE12 8AQ", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "NEWCASTLE UPON TYNE", + "built_form": "NR", + "created_at": "2026-05-06 10:59:38", + "door_count": 0, + "region_code": 1, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 0, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 17815 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.23, + "window_height": 1.61, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.23, + "window_height": 1.61, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.23, + "window_height": 1.61, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.23, + "window_height": 1.61, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.23, + "window_height": 1.61, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Top-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "83 Station Road", + "address_line_2": "Forest Hall", + "assessment_type": "RdSAP", + "completion_date": "2026-05-06", + "inspection_date": "2026-05-05", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 3, + "top_storey": "Y", + "storey_count": 2, + "flat_location": 1, + "heat_loss_corridor": 1 + }, + "total_floor_area": 64, + "transaction_type": 8, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 3, + "registration_date": "2026-05-06", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 380, + "floor_heat_loss": 3, + "roof_construction": 1, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.32, + "quantity": "metres" + }, + "total_floor_area": { + "value": 64.26, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 18.15, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 18.15, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 3, + "construction_age_band": "E", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 6, + "wall_insulation_thickness": "100mm", + "flat_roof_insulation_thickness": "75mm" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 623, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 2.0, + "energy_rating_average": 60, + "energy_rating_current": 74, + "lighting_cost_current": { + "value": 42, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 553, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 207, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 69, + "currency": "GBP" + }, + "indicative_cost": "\u00a3900 - \u00a31,200", + "improvement_type": "A2", + "improvement_details": { + "improvement_number": 45 + }, + "improvement_category": 5, + "energy_performance_rating": 76, + "environmental_impact_rating": 78 + } + ], + "co2_emissions_potential": 1.8, + "energy_rating_potential": 76, + "lighting_cost_potential": { + "value": 42, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 208, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2384.75, + "space_heating_existing_dwelling": 5681.26 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 170, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 154, + "environmental_impact_current": 76, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 78, + "led_fixed_lighting_bulbs_count": 9, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 31, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/domain/sap10_calculator/worksheet/heat_transmission.py b/domain/sap10_calculator/worksheet/heat_transmission.py index 32ae5bf75..789483e6c 100644 --- a/domain/sap10_calculator/worksheet/heat_transmission.py +++ b/domain/sap10_calculator/worksheet/heat_transmission.py @@ -922,6 +922,22 @@ def heat_transmission_from_cert( raw_rafter_thickness = getattr(part, "rafter_insulation_thickness", None) if raw_rafter_thickness is not None: raw_roof_thickness = raw_rafter_thickness + elif "flat" in (part.roof_construction_type or "").lower(): + # RdSAP 10 §5.11 — a FLAT roof lodges its insulation thickness in + # the dedicated gov-API `flat_roof_insulation_thickness` field + # (e.g. "75mm"), NOT `roof_insulation_thickness` (which stays None + # for flat roofs). Prefer it so a measured flat-roof thickness + # bills at its Table-16 U instead of the uninsulated age-band flat + # default. Mirrors the rafter branch above. Cert 47084930: flat + # roof "75mm" -> U 0.5 (accredited Elmhurst worksheet, "insulated + # flat roof") vs the age-E default 1.5 (roof 96.4 -> 32.1 W/K). An + # "AB"/"NI" (as-built/unknown) value parses to None and keeps the + # age-band default, unchanged. + raw_flat_thickness = getattr( + part, "flat_roof_insulation_thickness", None + ) + if raw_flat_thickness is not None: + raw_roof_thickness = raw_flat_thickness roof_thickness = _parse_thickness_mm(raw_roof_thickness) floor_ins_thickness = _parse_thickness_mm(getattr(part, "floor_insulation_thickness", None)) diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index 7f57b370c..3cb6cbaf8 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -1,10 +1,10 @@ # RdSAP-21.0.1 corpus campaign ledger -**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.3%** · MAE = **0.648** (floors in test_sap_accuracy_corpus.py) +**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.7%** · MAE = **0.641** (floors in test_sap_accuracy_corpus.py) Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail engine bug · ⛔ unbuildable. Line: `uprn · lodged L / eng E / Δ · signature`. Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` (preserves statuses & `<-` notes). -## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 227 certs in 220 clusters +## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 223 certs in 216 clusters ### C001 · Σ|Δ| 23.9 · 1 certs · `hpcdb100053/elec | solid brick | (another dwelling | sec:room heaters` - ⚠ `4510053280` · L 51 / E 74.94 / Δ +23.94 <- lodged software billed out-of-range-PSR (2.031 > 2.0) PCDB 100053 as 100% direct electric; engine follows SAP10.2 N2 extension (305%), Elmhurst-validated on case 56. Pinned engine 75 in test_real_cert_sap_accuracy. @@ -69,611 +69,599 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C020 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` - [ ] `100071010014` · L 55 / E 50.47 / Δ -4.53 -### C021 · Σ|Δ| 4.5 · 1 certs · `hpcdb17815/gas | cavity wall | flat insulated` -- [ ] `47084930` · L 74 / E 69.51 / Δ -4.49 - -### C022 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` +### C021 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` - [ ] `10093342182` · L 82 / E 77.51 / Δ -4.49 -### C023 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` +### C022 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` - [ ] `5117280` · L 76 / E 71.56 / Δ -4.44 -### C024 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` +### C023 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` - [ ] `217060420` · L 42 / E 37.58 / Δ -4.42 -### C025 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` +### C024 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` - [ ] `72399971` · L 69 / E 64.60 / Δ -4.40 -### C026 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` +### C025 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` - [ ] `10007016314` · L 57 / E 52.64 / Δ -4.36 -### C027 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` +### C026 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` - [ ] `100052159386` · L 56 / E 51.92 / Δ -4.08 -### C028 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` +### C027 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` - [ ] `100040767294` · L 43 / E 47.04 / Δ +4.04 -### C029 · Σ|Δ| 3.6 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` +### C028 · Σ|Δ| 3.6 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` - [ ] `10002188054` · L 68 / E 64.42 / Δ -3.58 -### C030 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` +### C029 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` - [ ] `39066537` · L 78 / E 81.49 / Δ +3.49 -### C031 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` +### C030 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` - [ ] `100100137438` · L 69 / E 72.48 / Δ +3.48 -### C032 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C031 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100080122910` · L 60 / E 63.45 / Δ +3.45 -### C033 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` +### C032 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` - [ ] `452010022` · L 42 / E 38.67 / Δ -3.33 -### C034 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` +### C033 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` - [ ] `200004818752` · L 34 / E 30.73 / Δ -3.27 -### C035 · Σ|Δ| 3.2 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` +### C034 · Σ|Δ| 3.2 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` - [ ] `200004522639` · L 37 / E 33.77 / Δ -3.23 -### C036 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` +### C035 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` - [ ] `72351021` · L 64 / E 60.85 / Δ -3.15 -### C037 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` +### C036 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` - [ ] `22077224` · L 37 / E 33.90 / Δ -3.10 -### C038 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` +### C037 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` - [ ] `10011740578` · L 70 / E 67.00 / Δ -3.00 -### C039 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +### C038 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` - [ ] `100110680822` · L 79 / E 76.07 / Δ -2.93 -### C040 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` +### C039 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` - [ ] `452032915` · L 75 / E 72.09 / Δ -2.91 -### C041 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` +### C040 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` - [ ] `100071306639` · L 73 / E 70.14 / Δ -2.86 -### C042 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` +### C041 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` - [ ] `100061346049` · L 55 / E 52.15 / Δ -2.85 -### C043 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` +### C042 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` - [ ] `10013008238` · L 41 / E 38.26 / Δ -2.74 -### C044 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` +### C043 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` - [ ] `10033187652` · L 70 / E 71.21 / Δ +1.21 - [ ] `200002730` · L 65 / E 64.13 / Δ -0.87 - [ ] `10023328117` · L 78 / E 78.64 / Δ +0.64 -### C045 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` +### C044 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` - [ ] `10004873253` · L 65 / E 62.29 / Δ -2.71 -### C046 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` +### C045 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` - [ ] `10090793715` · L 73 / E 75.71 / Δ +2.71 -### C047 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` +### C046 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100120745600` · L 65 / E 67.69 / Δ +2.69 -### C048 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` +### C047 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` - [ ] `100051178830` · L 63 / E 65.66 / Δ +2.66 -### C049 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` +### C048 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` - [ ] `100120018282` · L 64 / E 61.36 / Δ -2.64 -### C050 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +### C049 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` - [ ] `83035979` · L 65 / E 67.60 / Δ +2.60 -### C051 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` +### C050 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` - [ ] `10014073761` · L 75 / E 72.52 / Δ -2.48 -### C052 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` +### C051 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` - [ ] `100050964834` · L 60 / E 62.47 / Δ +2.47 -### C053 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` +### C052 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` - [ ] `100120752995` · L 71 / E 73.42 / Δ +2.42 -### C054 · Σ|Δ| 2.4 · 1 certs · `hpcdb1245/gas | solid brick | pitched insulated | ext1` -- [ ] `100032230128` · L 55 / E 52.60 / Δ -2.40 +### C053 · Σ|Δ| 2.4 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` +- [ ] `100062174575` · L 46 / E 48.40 / Δ +2.40 -### C055 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` +### C054 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` - [ ] `100000034023` · L 73 / E 70.71 / Δ -2.29 -### C056 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` +### C055 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` - [ ] `100020377671` · L 62 / E 64.23 / Δ +2.23 -### C057 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` +### C056 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` - [ ] `22027335` · L 76 / E 73.77 / Δ -2.23 -### C058 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` +### C057 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` - [ ] `48056153` · L 65 / E 62.89 / Δ -2.11 -### C059 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` +### C058 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` - [ ] `100021924710` · L 63 / E 65.00 / Δ +2.00 -### C060 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` +### C059 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` - [ ] `100031270375` · L 69 / E 70.93 / Δ +1.93 -### C061 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` +### C060 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` - [ ] `10001118522` · L 80 / E 78.07 / Δ -1.93 -### C062 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` +### C061 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` - [ ] `10010234711` · L 81 / E 79.08 / Δ -1.92 -### C063 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` +### C062 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` - [ ] `100031768368` · L 61 / E 59.12 / Δ -1.88 -### C064 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` +### C063 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` - [ ] `4510729926` · L 73 / E 71.15 / Δ -1.85 -### C065 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` +### C064 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` - [ ] `100091329112` · L 49 / E 50.82 / Δ +1.82 -### C066 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` +### C065 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` - [ ] `100061275133` · L 76 / E 77.24 / Δ +1.24 - [ ] `207032630` · L 74 / E 73.47 / Δ -0.53 -### C067 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` +### C066 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` - [ ] `10011797347` · L 47 / E 48.77 / Δ +1.77 -### C068 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` +### C067 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` - [ ] `100022668387` · L 68 / E 66.25 / Δ -1.75 -### C069 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` +### C068 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` - [ ] `100100892216` · L 69 / E 67.28 / Δ -1.72 -### C070 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` +### C069 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100060878876` · L 49 / E 50.71 / Δ +1.71 -### C071 · Σ|Δ| 1.7 · 1 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` +### C070 · Σ|Δ| 1.7 · 1 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` - [ ] `12126160` · L 69 / E 70.71 / Δ +1.71 -### C072 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` +### C071 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` - [ ] `22032926` · L 61 / E 62.71 / Δ +1.71 -### C073 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` +### C072 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` - [ ] `100010942905` · L 72 / E 73.70 / Δ +1.70 -### C074 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` +### C073 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` - [ ] `100030307976` · L 71 / E 69.37 / Δ -1.63 -### C075 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` +### C074 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` - [ ] `100061404488` · L 70 / E 68.38 / Δ -1.62 -### C076 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` +### C075 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` - [ ] `21067296` · L 67 / E 68.60 / Δ +1.60 -### C077 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` +### C076 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` - [ ] `5870047440` · L 58 / E 59.58 / Δ +1.58 -### C078 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` +### C077 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` - [ ] `100070450818` · L 65 / E 63.43 / Δ -1.57 -### C079 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` +### C078 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` - [ ] `100050881708` · L 70 / E 71.55 / Δ +1.55 -### C080 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` +### C079 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` - [ ] `10010254955` · L 79 / E 77.46 / Δ -1.54 -### C081 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` +### C080 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` - [ ] `3455011834` · L 69 / E 67.48 / Δ -1.52 -### C082 · Σ|Δ| 1.5 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` +### C081 · Σ|Δ| 1.5 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` - [ ] `100100274789` · L 60 / E 61.51 / Δ +1.51 -### C083 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` +### C082 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` - [ ] `100050852755` · L 65 / E 66.49 / Δ +1.49 -### C084 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` +### C083 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` - [ ] `100021326422` · L 70 / E 68.51 / Δ -1.49 -### C085 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` +### C084 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100050988345` · L 61 / E 59.51 / Δ -1.49 -### C086 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` +### C085 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` - [ ] `100030285758` · L 54 / E 55.48 / Δ +1.48 -### C087 · Σ|Δ| 1.5 · 1 certs · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` -- [ ] `100090536443` · L 86 / E 84.52 / Δ -1.48 - -### C088 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` +### C086 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` - [ ] `line80` · L 72 / E 70.56 / Δ -1.44 -### C089 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` +### C087 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` - [ ] `100080518673` · L 57 / E 58.42 / Δ +1.42 -### C090 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` +### C088 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` - [ ] `235025284` · L 69 / E 67.59 / Δ -1.41 -### C091 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` +### C089 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` - [ ] `250063088` · L 73 / E 71.60 / Δ -1.40 -### C092 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` +### C090 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` - [ ] `100110097281` · L 64 / E 65.37 / Δ +1.37 -### C093 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` +### C091 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` - [ ] `10091630692` · L 58 / E 56.63 / Δ -1.37 -### C094 · Σ|Δ| 1.4 · 1 certs · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` -- [ ] `100031433810` · L 70 / E 68.63 / Δ -1.37 - -### C095 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` +### C092 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` - [ ] `100012368622` · L 39 / E 40.32 / Δ +1.32 -### C096 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +### C093 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` - [ ] `90077194` · L 65 / E 63.69 / Δ -1.31 -### C097 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` +### C094 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` - [ ] `100031461986` · L 70 / E 71.29 / Δ +1.29 -### C098 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` +### C095 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` - [ ] `30095054` · L 46 / E 44.74 / Δ -1.26 -### C099 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` +### C096 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` - [ ] `100100055589` · L 58 / E 59.26 / Δ +1.26 -### C100 · Σ|Δ| 1.2 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` +### C097 · Σ|Δ| 1.2 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` - [ ] `74061136` · L 73 / E 71.75 / Δ -1.25 <- electric storage cat7 E7: over-rate = off-peak rate/fraction too generous; needs Elmhurst tariff arbitration -### C101 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` +### C098 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` - [ ] `100091435353` · L 65 / E 66.23 / Δ +1.23 -### C102 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` +### C099 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` - [ ] `10091070164` · L 69 / E 69.60 / Δ +0.60 - [ ] `10090927185` · L 79 / E 79.60 / Δ +0.60 -### C103 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` +### C100 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` - [ ] `100100614412` · L 53 / E 51.81 / Δ -1.19 -### C104 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` +### C101 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` - [ ] `217091901` · L 62 / E 60.82 / Δ -1.18 -### C105 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` +### C102 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` - [x] `line768` · L 57 / E 55.84 / Δ -1.16 -### C106 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` +### C103 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` - [ ] `217061895` · L 61 / E 59.84 / Δ -1.16 -### C107 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C104 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `10002349227` · L 76 / E 77.14 / Δ +1.14 -### C108 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` +### C105 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` - [ ] `200001634005` · L 66 / E 67.11 / Δ +1.11 -### C109 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +### C106 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` - [ ] `100071059081` · L 63 / E 64.09 / Δ +1.09 -### C110 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` +### C107 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` - [ ] `100011820199` · L 55 / E 56.06 / Δ +1.06 -### C111 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` +### C108 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` - [ ] `90214753` · L 83 / E 81.95 / Δ -1.05 -### C112 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` +### C109 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` - [ ] `100051051866` · L 70 / E 71.04 / Δ +1.04 -### C113 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` +### C110 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` - [ ] `10013836852` · L 100 / E 98.97 / Δ -1.03 -### C114 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` +### C111 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` - [ ] `line899` · L 73 / E 71.97 / Δ -1.03 -### C115 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` +### C112 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` - [ ] `40037847` · L 81 / E 79.98 / Δ -1.02 -### C116 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` +### C113 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` - [ ] `10070056075` · L 80 / E 78.99 / Δ -1.01 -### C117 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` +### C114 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` - [ ] `200131078` · L 86 / E 85.00 / Δ -1.00 -### C118 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` +### C115 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` - [ ] `10000245212` · L 101 / E 100.00 / Δ -1.00 -### C119 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` +### C116 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` - [ ] `15129162` · L 62 / E 61.00 / Δ -1.00 -### C120 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` +### C117 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` - [ ] `23032873` · L 73 / E 72.00 / Δ -1.00 -### C121 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` +### C118 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` - [ ] `45019020` · L 62 / E 61.01 / Δ -0.99 -### C122 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` +### C119 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` - [ ] `42065028` · L 59 / E 58.02 / Δ -0.98 -### C123 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` +### C120 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` - [ ] `10032928147` · L 77 / E 76.04 / Δ -0.96 -### C124 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` +### C121 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` - [ ] `10010678937` · L 78 / E 77.04 / Δ -0.96 -### C125 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` +### C122 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` - [ ] `100011010151` · L 62 / E 62.96 / Δ +0.96 -### C126 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` +### C123 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` - [ ] `100050477371` · L 65 / E 64.04 / Δ -0.96 -### C127 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` +### C124 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` - [ ] `10002945522` · L 61 / E 61.94 / Δ +0.94 -### C128 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` +### C125 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` - [ ] `10032957680` · L 45 / E 45.94 / Δ +0.94 -### C129 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` +### C126 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` - [ ] `2465057465` · L 81 / E 81.93 / Δ +0.93 -### C130 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` +### C127 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` - [ ] `100090616327` · L 63 / E 63.93 / Δ +0.93 -### C131 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` +### C128 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` - [ ] `100012753833` · L 74 / E 73.07 / Δ -0.93 -### C132 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` +### C129 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` - [ ] `100031269525` · L 53 / E 53.91 / Δ +0.91 -### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` +### C130 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` - [ ] `200003725358` · L 75 / E 74.09 / Δ -0.91 -### C134 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` +### C131 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` - [ ] `100050986162` · L 62 / E 61.10 / Δ -0.90 -### C135 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` +### C132 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` - [ ] `5300000141` · L 78 / E 77.10 / Δ -0.90 -### C136 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` +### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` - [ ] `100050618404` · L 73 / E 73.89 / Δ +0.89 -### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` +### C134 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` - [ ] `100090476016` · L 81 / E 81.89 / Δ +0.89 -### C138 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` +### C135 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` - [ ] `10012119141` · L 45 / E 45.89 / Δ +0.89 -### C139 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` +### C136 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` - [ ] `100040938206` · L 75 / E 75.89 / Δ +0.89 -### C140 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` +### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `38188474` · L 76 / E 76.87 / Δ +0.87 -### C141 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +### C138 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100061194957` · L 69 / E 69.87 / Δ +0.87 -### C142 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` +### C139 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` - [ ] `100021236527` · L 72 / E 71.13 / Δ -0.87 -### C143 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` +### C140 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` - [ ] `100040193752` · L 71 / E 71.86 / Δ +0.86 -### C144 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` +### C141 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` - [ ] `100060701552` · L 74 / E 74.86 / Δ +0.86 -### C145 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` +### C142 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` - [ ] `10070396146` · L 61 / E 60.14 / Δ -0.86 -### C146 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` +### C143 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` - [ ] `100030528930` · L 74 / E 73.16 / Δ -0.84 -### C147 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` +### C144 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` - [ ] `100020982570` · L 72 / E 71.17 / Δ -0.83 -### C148 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` +### C145 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` - [ ] `394024487` · L 75 / E 74.17 / Δ -0.83 -### C149 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` +### C146 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` - [ ] `217070698` · L 78 / E 78.83 / Δ +0.83 -### C150 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` +### C147 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` - [ ] `77022508` · L 69 / E 68.18 / Δ -0.82 -### C151 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` +### C148 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` - [ ] `100040259104` · L 68 / E 68.82 / Δ +0.82 -### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` +### C149 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` - [ ] `100031399026` · L 70 / E 70.81 / Δ +0.81 -### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` +### C150 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` - [ ] `10009645698` · L 67 / E 67.81 / Δ +0.81 -### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` +### C151 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` - [ ] `100080818887` · L 56 / E 55.19 / Δ -0.81 -### C155 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` +### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100012374381` · L 69 / E 69.80 / Δ +0.80 -### C156 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` +### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` - [ ] `100012350270` · L 78 / E 77.20 / Δ -0.80 -### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` +### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` - [ ] `100051109723` · L 60 / E 60.78 / Δ +0.78 -### C158 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` +### C155 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` - [ ] `100061616915` · L 63 / E 62.22 / Δ -0.78 -### C159 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` +### C156 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` - [ ] `line71` · L 74 / E 74.77 / Δ +0.77 -### C160 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` +### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` - [ ] `100011603934` · L 72 / E 71.23 / Δ -0.77 -### C161 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` +### C158 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` - [ ] `24030987` · L 73 / E 73.76 / Δ +0.76 -### C162 · Σ|Δ| 0.8 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` +### C159 · Σ|Δ| 0.8 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` - [ ] `100032043038` · L 74 / E 73.24 / Δ -0.76 -### C163 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` +### C160 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` - [ ] `100010866608` · L 71 / E 70.24 / Δ -0.76 -### C164 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` +### C161 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` - [ ] `100090399615` · L 67 / E 67.75 / Δ +0.75 -### C165 · Σ|Δ| 0.7 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` -- [ ] `100062174575` · L 46 / E 46.75 / Δ +0.75 - -### C166 · Σ|Δ| 0.7 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` +### C162 · Σ|Δ| 0.7 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` - [ ] `200004296092` · L 71 / E 71.74 / Δ +0.74 -### C167 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` +### C163 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `10012341135` · L 79 / E 79.73 / Δ +0.73 -### C168 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +### C164 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` - [ ] `100091005853` · L 70 / E 69.27 / Δ -0.73 -### C169 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` +### C165 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` - [ ] `100021533514` · L 71 / E 71.73 / Δ +0.73 -### C170 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` +### C166 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` - [ ] `5062075` · L 69 / E 69.72 / Δ +0.72 -### C171 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` +### C167 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100040813308` · L 62 / E 62.72 / Δ +0.72 -### C172 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` +### C168 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` - [ ] `38105600` · L 68 / E 67.28 / Δ -0.72 -### C173 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` +### C169 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` - [ ] `line255` · L 72 / E 71.29 / Δ -0.71 -### C174 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` +### C170 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` - [ ] `5300047580` · L 69 / E 68.30 / Δ -0.70 -### C175 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` +### C171 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` - [ ] `100110433403` · L 69 / E 68.32 / Δ -0.68 -### C176 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` +### C172 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` - [ ] `10093416558` · L 79 / E 78.32 / Δ -0.68 -### C177 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` +### C173 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` - [ ] `100050958217` · L 68 / E 68.68 / Δ +0.68 -### C178 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` +### C174 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` - [ ] `100022667797` · L 68 / E 67.32 / Δ -0.68 -### C179 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C175 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100030528925` · L 78 / E 78.65 / Δ +0.65 -### C180 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` +### C176 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` - [ ] `100110300037` · L 74 / E 73.35 / Δ -0.65 -### C181 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` +### C177 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` - [ ] `217092450` · L 52 / E 52.64 / Δ +0.64 -### C182 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` +### C178 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` - [ ] `100061164545` · L 72 / E 71.36 / Δ -0.64 -### C183 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` +### C179 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` - [ ] `100051075936` · L 71 / E 70.36 / Δ -0.64 -### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` +### C180 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` - [ ] `100011565830` · L 72 / E 72.64 / Δ +0.64 -### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` +### C181 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` - [ ] `61010956` · L 75 / E 74.37 / Δ -0.63 -### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` +### C182 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` - [ ] `100110752514` · L 67 / E 67.62 / Δ +0.62 -### C187 · Σ|Δ| 0.6 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` +### C183 · Σ|Δ| 0.6 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` - [ ] `100070295212` · L 75 / E 74.38 / Δ -0.62 -### C188 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` +### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` - [ ] `100012534027` · L 65 / E 64.38 / Δ -0.62 -### C189 · Σ|Δ| 0.6 · 1 certs · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` +### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` - [x] `10009812472` · L 40 / E 39.40 / Δ -0.60 -### C190 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` +### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` - [ ] `34080035` · L 77 / E 76.41 / Δ -0.59 -### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` +### C187 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` - [ ] `21032732` · L 69 / E 69.59 / Δ +0.59 -### C192 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` +### C188 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100060562056` · L 66 / E 65.41 / Δ -0.59 -### C193 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` +### C189 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` - [ ] `100091086558` · L 79 / E 79.58 / Δ +0.58 -### C194 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` +### C190 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` - [ ] `line599` · L 74 / E 73.42 / Δ -0.58 -### C195 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` +### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` - [ ] `100020407741` · L 72 / E 71.42 / Δ -0.58 -### C196 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` +### C192 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` - [ ] `100050839457` · L 70 / E 70.57 / Δ +0.57 -### C197 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` +### C193 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` - [ ] `42105250` · L 59 / E 59.57 / Δ +0.57 -### C198 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` +### C194 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` - [ ] `77200509` · L 69 / E 69.57 / Δ +0.57 -### C199 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` +### C195 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` - [ ] `200040534` · L 65 / E 65.56 / Δ +0.56 -### C200 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` +### C196 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` - [ ] `200049463` · L 69 / E 69.56 / Δ +0.56 -### C201 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` +### C197 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` - [ ] `100062527568` · L 61 / E 61.56 / Δ +0.56 -### C202 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` +### C198 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` - [ ] `100100268900` · L 69 / E 69.56 / Δ +0.56 -### C203 · Σ|Δ| 0.6 · 1 certs · `hpcdb17004/fuel27+2mains | sandstone as | pitched no | ext3,sec:room heaters` +### C199 · Σ|Δ| 0.6 · 1 certs · `hpcdb17004/fuel27+2mains | sandstone as | pitched no | ext3,sec:room heaters` - [x] `200003110548` · L 29 / E 28.45 / Δ -0.55 -### C204 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` +### C200 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` - [ ] `90036914` · L 60 / E 60.55 / Δ +0.55 -### C205 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` +### C201 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` - [ ] `10004742671` · L 70 / E 69.46 / Δ -0.54 -### C206 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` +### C202 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` - [ ] `100010657450` · L 75 / E 75.54 / Δ +0.54 -### C207 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` +### C203 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` - [ ] `100061834344` · L 71 / E 70.46 / Δ -0.54 -### C208 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` +### C204 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` - [ ] `4510097194` · L 70 / E 70.53 / Δ +0.53 -### C209 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` +### C205 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` - [ ] `100010913220` · L 72 / E 72.53 / Δ +0.53 -### C210 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` +### C206 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` - [ ] `43074051` · L 63 / E 62.48 / Δ -0.52 -### C211 · Σ|Δ| 0.5 · 1 certs · `h104/gas | cavity wall | pitched 300` +### C207 · Σ|Δ| 0.5 · 1 certs · `h104/gas | cavity wall | pitched 300` - [ ] `100010723814` · L 69 / E 69.52 / Δ +0.52 -### C212 · Σ|Δ| 0.5 · 1 certs · `hpcdb16137/gas | cavity wall | (another dwelling` +### C208 · Σ|Δ| 0.5 · 1 certs · `hpcdb16137/gas | cavity wall | (another dwelling` - [ ] `100020955792` · L 77 / E 77.52 / Δ +0.52 -### C213 · Σ|Δ| 0.5 · 1 certs · `hpcdb19079/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +### C209 · Σ|Δ| 0.5 · 1 certs · `hpcdb19079/gas | cavity wall | pitched 200 | ext1,sec:room heaters` - [ ] `77172223` · L 65 / E 65.52 / Δ +0.52 -### C214 · Σ|Δ| 0.5 · 1 certs · `hpcdb10242/gas | granite or | pitched insulated | RR,sec:room heaters` +### C210 · Σ|Δ| 0.5 · 1 certs · `hpcdb10242/gas | granite or | pitched insulated | RR,sec:room heaters` - [ ] `100051245439` · L 62 / E 61.48 / Δ -0.52 -### C215 · Σ|Δ| 0.5 · 1 certs · `hpcdb10328/gas | cavity wall | (another dwelling` +### C211 · Σ|Δ| 0.5 · 1 certs · `hpcdb10328/gas | cavity wall | (another dwelling` - [ ] `100012553958` · L 67 / E 66.48 / Δ -0.52 -### C216 · Σ|Δ| 0.5 · 1 certs · `hpcdb10033/gas | cavity wall | pitched 200 | ext2,sec:room heaters` +### C212 · Σ|Δ| 0.5 · 1 certs · `hpcdb10033/gas | cavity wall | pitched 200 | ext2,sec:room heaters` - [ ] `100110108632` · L 63 / E 63.51 / Δ +0.51 -### C217 · Σ|Δ| 0.5 · 1 certs · `h109/gas | cavity wall | pitched 270 | consv2,ext1,sec:room heaters` +### C213 · Σ|Δ| 0.5 · 1 certs · `h109/gas | cavity wall | pitched 270 | consv2,ext1,sec:room heaters` - [ ] `100091102581` · L 65 / E 65.51 / Δ +0.51 -### C218 · Σ|Δ| 0.5 · 1 certs · `hpcdb19008/gas | cavity wall | pitched 150 | ext1,sec:room heaters` +### C214 · Σ|Δ| 0.5 · 1 certs · `hpcdb19008/gas | cavity wall | pitched 150 | ext1,sec:room heaters` - [ ] `10002326688` · L 69 / E 68.50 / Δ -0.50 -### C219 · Σ|Δ| 0.5 · 1 certs · `h129/fuel28 | granite or | pitched 200 | ext2,sec:room heaters` +### C215 · Σ|Δ| 0.5 · 1 certs · `h129/fuel28 | granite or | pitched 200 | ext2,sec:room heaters` - [ ] `10023132869` · L 46 / E 45.50 / Δ -0.50 -### C220 · Σ|Δ| 0.5 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` +### C216 · Σ|Δ| 0.5 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` - [ ] `10091707271` · L 41 / E 41.50 / Δ +0.50 -## Resolved ≤0.5 (773 certs — no action) +## Resolved ≤0.5 (777 certs — no action)

expand @@ -926,6 +914,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `100010779964` · L 72 / E 72.34 / Δ +0.34 · `hpcdb17683/gas | sandstone as | pitched 75` - [x] `64106486` · L 72 / E 71.66 / Δ -0.34 · `hpcdb17926/fuel27 | timber frame | pitched 270 | ext1` - [x] `100060109253` · L 62 / E 62.34 / Δ +0.34 · `hpcdb18435/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +- [x] `47084930` · L 74 / E 74.34 / Δ +0.34 · `hpcdb17815/gas | cavity wall | flat insulated` - [x] `200002819281` · L 72 / E 71.66 / Δ -0.34 · `h104/gas | solid brick | pitched insulated | RR,ext1` - [x] `100051237659` · L 65 / E 64.67 / Δ -0.33 · `hpcdb18560/gas | sandstone as | pitched insulated | sec:room heaters` - [x] `12027355` · L 70 / E 70.33 / Δ +0.33 · `hpcdb1838/gas | solid brick | pitched insulated | ext1` @@ -999,6 +988,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `32049938` · L 63 / E 62.71 / Δ -0.29 · `hpcdb17983/gas | solid brick | pitched 350 | sec:room heaters` - [x] `100110433442` · L 70 / E 69.71 / Δ -0.29 · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1` - [x] `100070532674` · L 76 / E 76.29 / Δ +0.29 · `hpcdb17983/gas | cavity wall | pitched insulated` +- [x] `100032230128` · L 55 / E 54.71 / Δ -0.29 · `hpcdb1245/gas | solid brick | pitched insulated | ext1` - [x] `10024298029` · L 72 / E 72.29 / Δ +0.29 · `hpcdb17503/gas | solid brick | pitched 270 | ext1,sec:room heaters` - [x] `5079850` · L 39 / E 39.29 / Δ +0.29 · `h301/coal-anth | system built | (another dwelling | ext1,whw903` - [x] `10001235167` · L 74 / E 73.71 / Δ -0.29 · `hpcdb17645/gas | solid brick | pitched 225` @@ -1054,6 +1044,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `83147775` · L 71 / E 71.25 / Δ +0.25 · `hpcdb16839/gas | cavity wall | pitched insulated` - [x] `72303880` · L 63 / E 62.75 / Δ -0.25 · `hpcdb17507/gas | cavity wall | pitched 150 | sec:room heaters` - [x] `100022711136` · L 72 / E 71.75 / Δ -0.25 · `hpcdb16495/gas | cavity wall | (another dwelling` +- [x] `100090536443` · L 86 / E 86.25 / Δ +0.25 · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` - [x] `83147745` · L 75 / E 75.25 / Δ +0.25 · `hpcdb16839/gas | cavity wall | (another dwelling | sec:room heaters` - [x] `200002598542` · L 61 / E 61.25 / Δ +0.25 · `h402/elec | cavity wall | pitched 175 | ext1,sec:room heaters,whw903` - [x] `100010572385` · L 62 / E 62.25 / Δ +0.25 · `hpcdb18817/gas | cavity wall | pitched 250 | ext2,sec:room heaters` @@ -1328,6 +1319,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `5870046999` · L 73 / E 73.09 / Δ +0.09 · `hpcdb17973/gas | cavity wall | (another dwelling` - [x] `100010384681` · L 75 / E 74.91 / Δ -0.09 · `hpcdb19080/gas | cavity wall | pitched 400+ | PV,ext1,sec:room heaters` - [x] `100022536385` · L 71 / E 70.92 / Δ -0.08 · `hpcdb17505/gas | solid brick | pitched 300` +- [x] `100031433810` · L 70 / E 70.08 / Δ +0.08 · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` - [x] `1710029098` · L 69 / E 69.08 / Δ +0.08 · `hpcdb17958/gas | cavity wall | pitched 270 | sec:room heaters` - [x] `100040884417` · L 70 / E 70.08 / Δ +0.08 · `hpcdb10328/gas | cavity wall | (another dwelling` - [x] `100080706339` · L 65 / E 65.08 / Δ +0.08 · `hpcdb16396/gas | system built | pitched 250` diff --git a/scripts/hyde/build_47084930.py b/scripts/hyde/build_47084930.py new file mode 100644 index 000000000..679a9e56e --- /dev/null +++ b/scripts/hyde/build_47084930.py @@ -0,0 +1,299 @@ +"""Elmhurst build for UPRN 47084930 (RdSAP-21.0.1, TOP-FLOOR FLAT, band E, +CAVITY wall with INTERNAL insulation (100 mm), FLAT ROOF insulated 75 mm, floor +over OTHER PREMISES below, mains-gas COMBI (PCDB 17815), 5 DG windows ~9.9 m², +no doors, TFA 64. Lodged SAP 74; engine 69.51 (Δ −4.49, PE +47 over-count). + +Per-cert worksheet validation. Suspected engine gap: the flat-roof insulation +thickness is lodged in `flat_roof_insulation_thickness` (75 mm) but the U-value +calc reads `roof_insulation_thickness` (None) → bills the roof at the age-E flat +default 1.5 (96 W/K) instead of the 75 mm insulated ~0.5 (~30 W/K). This build +gets the accredited flat-roof + floor U. Run: + DISPLAY=:99 python scripts/hyde/build_47084930.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +WP = "TabContainer_TabPanelWindowsPanel_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_47084930") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def _options(page, suffix): + return page.evaluate( + """(id)=>{const s=document.getElementById(id);if(!s)return []; + return Array.from(s.options).map(o=>o.text);}""", f"{E.FP}{suffix}") + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + _pick(page, "DropDownListPropertyType1", "flat") or \ + E.set_select(page, "DropDownListPropertyType1", "F Flat") + E.set_text(page, "TextBoxStoreys", "1") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1967-1975")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.save_close(page) + + +def flats(page): + E.goto(page, "Flats", "WebFormFlats.aspx") + print("flat positions:", _options(page, "" if False else "DropDownListPositionOfFlat")) + _pick(page, "DropDownListPositionOfFlat", "top") or \ + E.set_select(page, "DropDownListPositionOfFlat", "Top Floor") + E.set_text(page, "TextBoxFloor", "3") + E.set_select(page, "RadioButtonListFlatCoridor", "None") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "64.26") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.32") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "18.15") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "18.15") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + E.set_select(page, f"{WALL}DropDownListType", "CA Cavity") + page.wait_for_timeout(500) + print("insulation opts:", _options(page, f"{WALL}DropDownListInsulation")) + _pick(page, f"{WALL}DropDownListInsulation", "internal") + page.wait_for_timeout(500) + for suf in (f"{WALL}DropDownListInsulationThickness",): + if page.locator(f"#{E.FP}{suf}").count(): + print("wall ins thickness opts:", _options(page, suf)) + _pick(page, suf, "100") + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + print("ROOF TYPE opts:", _options(page, f"{ROOF}DropDownListType")) + _pick(page, f"{ROOF}DropDownListType", "flat") + page.wait_for_timeout(600) + # discover flat-roof insulation fields + for suf in (f"{ROOF}DropDownListInsulationAt", f"{ROOF}DropDownListThickness", + f"{ROOF}DropDownListInsulation"): + if page.locator(f"#{E.FP}{suf}").count(): + print(f" {suf.split('_')[-1]} opts:", _options(page, suf)) + # flat roof insulated 75 mm + if page.locator(f"#{E.FP}{ROOF}DropDownListThickness").count(): + _pick(page, f"{ROOF}DropDownListThickness", "75") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + print("FLOOR LOCATION opts:", _options(page, f"{FLOOR}DropDownListLocation")) + # "(other premises below)" = above a partially-heated space + (_pick(page, f"{FLOOR}DropDownListLocation", "partially heated") + or _pick(page, f"{FLOOR}DropDownListLocation", "other premises") + or _pick(page, f"{FLOOR}DropDownListLocation", "unheated")) + page.wait_for_timeout(400) + tsel = page.locator(f"#{E.FP}{FLOOR}DropDownListType") + if tsel.count(): + _pick(page, f"{FLOOR}DropDownListType", "solid") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + _add_window(page, 9.9, "North", _glazing(page)) + _delete_zero_rows(page) + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "0") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + for needle in ("unknown install date", "before 2002", "pre 2002"): + for opt in _options(page, f"{WP}DropDownListExtGlazing"): + low = opt.lower() + if needle in low and "triple" not in low and "single" not in low and "known data" not in low: + return opt + return "Double post or during 2022" + + +def _add_window(page, area, orientation, glazing): + print("glazing ->", glazing) + E.set_select(page, f"{WP}DropDownListExtGlazing", glazing) + page.wait_for_timeout(400) + ft = page.locator(f"#{E.FP}{WP}DropDownListExtFrameType") + if ft.count(): + ft.select_option("PVC") + gg = page.locator(f"#{E.FP}{WP}DropDownListExtGlazingGap") + if gg.count(): + gg.select_option("12 mm") + wid = f"{E.FP}{WP}TextBoxExtWidth" + page.evaluate( + """(a)=>{const e=document.getElementById(a[0]);if(e){e.value=a[1]; + e.dispatchEvent(new Event('input',{bubbles:true})); + e.dispatchEvent(new Event('change',{bubbles:true})); + e.dispatchEvent(new Event('blur',{bubbles:true}));}}""", [wid, str(area)]) + page.locator(f"#{E.FP}{WP}TextBoxExtHeight").fill("1.00") + page.locator(f"#{E.FP}{WP}DropDownListExtOrientation").select_option(orientation) + page.locator(f"#{E.FP}{WP}DropDownListExtBuildingPartId").select_option("Main") + page.locator(f"#{E.FP}{WP}DropDownListExtLocation").select_option("External wall") + page.wait_for_timeout(300) + before = E.window_row_count(page) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}{WP}ButtonAddWindow") + for _ in range(25): + page.wait_for_timeout(200) + if E.window_row_count(page) > before: + break + + +def _grid_rows(page): + return page.evaluate( + """()=>{const t=document.querySelector("[id*=GridViewExtendedWidows]"); + if(!t)return[];return Array.from(t.querySelectorAll('tr')).slice(1) + .map(r=>Array.from(r.querySelectorAll('td')).map(c=>c.innerText.trim()));}""") + + +def _delete_zero_rows(page): + g = 0 + while g < 6 and E.window_row_count(page) > 1: + g += 1 + rows = _grid_rows(page) + bad = next((i for i, c in enumerate(rows) if len(c) > 1 and c[1] in ("0.00", "0", "0.0")), None) + if bad is None: + break + _delete_row(page, bad) + page.wait_for_timeout(400) + + +def _delete_row(page, idx): + before = E.window_row_count(page) + btn = page.evaluate( + """(i)=>{const b=document.querySelectorAll("[id*='GridViewExtendedWidows_DeleteButton_']");return b[i]?b[i].id:null;}""", idx) + if not btn: + return + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", btn) + page.wait_for_selector(f"#{E.FP}DeleteWindowDialog_LinkButtonYes", state="visible", timeout=5000) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}DeleteWindowDialog_LinkButtonYes") + for _ in range(20): + page.wait_for_timeout(200) + if E.window_row_count(page) < before: + break + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "0") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "6") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "No") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + E.goto(page, "Recommendations", "WebFormRecommendations.aspx") + page.wait_for_timeout(1500) + with page.expect_navigation(wait_until="networkidle", timeout=40000): + page.click("#ContentBody_buttonActionSummary_Link", timeout=15000) + page.wait_for_timeout(2000) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60000) as dl: + page.click(f"#{btn}", timeout=15000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +_ORDER = ["property_description", "flats", "dimensions", "walls", "roofs", + "floors", "openings", "ventilation", "space_heating", "water_heating", + "download"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_47084930.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index e63d946bf..9f3bce1b2 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -805,6 +805,24 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-200004017091", sap_score=71, ), + # UPRN 47084930 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # TOP-FLOOR FLAT, band E, cavity wall + 100 mm internal insulation, FLAT + # ROOF insulated 75 mm, floor over other premises, mains-gas combi. The + # flat-roof insulation-thickness cert: the 75 mm is lodged in + # `flat_roof_insulation_thickness`, but heat_transmission read + # `roof_insulation_thickness` (None) → billed the flat roof at the + # uninsulated age-E default 1.5 (roof 96.4 W/K) → PE +47, engine 69.51 + # (Δ −4.49 vs lodged 74). Preferring the flat field → U 0.5 (roof 32.1 + # W/K), engine 74.34 = lodged 74. VALIDATED against the accredited + # Elmhurst worksheet (built on the lodged inputs, evidence saved: + # elmhurst_summary.pdf / elmhurst_worksheet.pdf): "insulated flat roof" + # U 0.5, floor 0.70 and wall 0.25 both matching the engine. PINNED 74. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_47084930", + cert_num="uprn-47084930", + sap_score=74, + ), ) diff --git a/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py b/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py index d0bb7bacc..2df247a2d 100644 --- a/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py +++ b/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py @@ -370,6 +370,46 @@ def test_rafter_insulation_thickness_field_drives_table16_column_2() -> None: assert abs(result.roof_w_per_k - 25.0) <= 1e-4 +def test_flat_roof_insulation_thickness_field_drives_insulated_u() -> None: + # Arrange — a FLAT roof lodges its insulation thickness in the DEDICATED + # gov-EPC API `flat_roof_insulation_thickness` field (e.g. "75mm"), + # leaving `roof_insulation_thickness` None (that field is for pitched-loft + # joists). heat_transmission must prefer the flat field when the part is a + # flat roof so the measured thickness bills at its RdSAP 10 §5.11 Table-16 + # U (75 mm → 0.5) instead of the uninsulated age-band flat default (age E + # → 1.5). Cert 47084930 (top-floor flat, flat roof "75mm"): roof 96.4 -> + # 32.1 W/K, engine 69.51 -> 74.34 = lodged 74, matching the accredited + # Elmhurst worksheet ("insulated flat roof", U 0.5). Mirrors the rafter + # field. Geometry: 100 m² plan → roof 100 m². 0.5 × 100 = 50 W/K. + main = make_building_part( + construction_age_band="E", + wall_construction=4, + wall_insulation_type=4, + party_wall_construction=1, + roof_construction=1, # flat + floor_dimensions=[ + make_floor_dimension( + total_floor_area_m2=100.0, room_height_m=2.5, + party_wall_length_m=0.0, heat_loss_perimeter_m=40.0, floor=0, + ), + ], + ) + main.roof_construction_type = "Flat" + main.roof_insulation_thickness = None # gov leaves this None for flat roofs + main.flat_roof_insulation_thickness = "75mm" # the thickness lives here + epc = make_minimal_sap10_epc( + total_floor_area_m2=100.0, + country_code="ENG", + sap_building_parts=[main], + ) + + # Act + result = heat_transmission_from_cert(epc) + + # Assert — 75 mm insulated flat roof at U 0.5, not the age-E default 1.5. + assert abs(result.roof_w_per_k - 50.0) <= 1e-4 + + def test_lodged_roof_u_value_overrides_construction_default() -> None: # Arrange — RdSAP 10 §5.1: where an element's U-value is known from the # assessment (documentary evidence / the lodged RdSAP output) it is used diff --git a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py index 197e6f7e0..345f426e5 100644 --- a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py +++ b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py @@ -227,7 +227,17 @@ _CORPUS = Path( # Table-13 fraction path already used). Gated on the explicit 0 so a # full-SAP unlodged size (None) keeps its own handling. 7 corpus certs; # within 77.0% -> 77.3%, PE 3.2 -> 3.05, CO2 0.074 -> 0.073. -_MIN_WITHIN_HALF_SAP = 0.773 +# 0.773 -> 0.777 via the flat-roof insulation-thickness fix: a FLAT roof +# lodges its thickness in the dedicated `flat_roof_insulation_thickness` +# field (e.g. "75mm"), but heat_transmission read `roof_insulation_thickness` +# (None for flat roofs) -> billed the roof at the uninsulated age-band flat +# default (age E 1.5) instead of the insulated Table-16 U. Prefer the flat +# field when the part is flat (mirrors the rafter-thickness branch). Cert +# 47084930 (top-floor flat, flat roof 75mm): roof 96.4 -> 32.1 W/K, engine +# 69.51 -> 74.34 = lodged 74, VALIDATED against the accredited Elmhurst +# worksheet ("insulated flat roof" U 0.5). within 77.3% -> 77.7%, PE 3.1 -> +# 2.97, CO2 0.074 -> 0.072. +_MIN_WITHIN_HALF_SAP = 0.777 # 0.793 -> 0.789 via the §12 Unknown-meter + dual-electric-immersion off-peak # trigger (RdSAP 10 PDF p.62): Apartment 241 (main 691 + 903 dual immersion) # -5.38 -> -1.05. Worksheet-validated on "simulated case 48" (Elmhurst SAP 57, @@ -313,9 +323,9 @@ _MIN_WITHIN_HALF_SAP = 0.773 # (U~1.4) -> ~0.29, PE +59.6 -> ~0, SAP 64.35 -> 71.74 (lodged 71). Scoped to # brick/stone (the only §5.8 R-value path); within-0.5 held at 77.0%, MAE # 0.658 -> 0.647, PE 3.2 -> 3.1. Unit-pinned in test_rdsap_uvalues. -_MAX_SAP_MAE = 0.648 -_MAX_CO2_MAE_TONNES = 0.074 # t CO2 / yr vs co2_emissions_current -_MAX_PE_PER_M2_MAE = 3.1 # kWh / m2 / yr vs energy_consumption_current +_MAX_SAP_MAE = 0.641 +_MAX_CO2_MAE_TONNES = 0.072 # t CO2 / yr vs co2_emissions_current +_MAX_PE_PER_M2_MAE = 3.0 # kWh / m2 / yr vs energy_consumption_current def _load_corpus() -> list[dict[str, Any]]: From 7987c94876fc2bc2bcb53e57485d66d4036a3ece Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 2 Jul 2026 23:54:35 +0000 Subject: [PATCH 11/84] chore(hyde): harden Elmhurst automation for per-cert builds (window cleanup + reset) Support for the per-cert Elmhurst worksheet loop: - goto()/save_close(): fall back networkidle -> domcontentloaded on timeout so an incomplete-validation state (half-set RR, 0-area window) no longer hangs navigation. - add_combined_window(): select glazing first (AutoPostBack), then JS input+change+blur the width/height with settle waits so the Area cell computes before Add (a plain .fill() raced the postback -> 0.00 row). - set_single_window(): leave the grid holding exactly one row, deleting rows carried over from a prior build of the SHARED assessment (the window grid is the only accumulating page). - reset_transient_state(): return the shared assessment to neutral after a run (clear RR age band, secondary = No, meter = Single). KNOWN RESIDUAL: the window grid still intermittently persists a 0.00 area through Save & Close (Elmhurst's "each Add wipes the previous row" + last-row-undeletable behaviour), and the secondary-heating dialog's modal background can intercept the cascade click. Reliable autonomous grinding of per-cert builds needs these two hardened further; the loop currently completes clean single-main gas certs (see the 47084930 flat-roof slice) but stalls on secondary-heating + stale-window combinations. build_ 100021924710.py is the WIP template for that harder shape. No engine change. Co-Authored-By: Claude Fable 5 --- scripts/hyde/build_100021924710.py | 231 +++++++++++++++++++++++++++++ scripts/hyde/elmhurst_lib.py | 92 ++++++++++-- 2 files changed, 313 insertions(+), 10 deletions(-) create mode 100644 scripts/hyde/build_100021924710.py diff --git a/scripts/hyde/build_100021924710.py b/scripts/hyde/build_100021924710.py new file mode 100644 index 000000000..ec06d8427 --- /dev/null +++ b/scripts/hyde/build_100021924710.py @@ -0,0 +1,231 @@ +"""Elmhurst build for UPRN 100021924710 (RdSAP-21.0.1, MID-TERRACE HOUSE, band B, +SOLID BRICK 250 mm uninsulated, pitched insulated (assumed) loft, floor to +UNHEATED space, mains-gas COMBI (PCDB 19008) + gas room-heater SECONDARY, DUAL +meter, 11 DG windows ~18.32 m², TFA 116. Lodged SAP 63; engine 65.0 (Δ +2.0). + +Per-cert Elmhurst validation. Uses set_single_window (deletes the shared +assessment's carried-over window rows) + reset_transient_state at the end so the +assessment is left neutral. Run: + DISPLAY=:99 python scripts/hyde/build_100021924710.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +PWALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelPartyWallMain_WebUserControlPartyWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_100021924710") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + E.set_select(page, "DropDownListPropertyType1", "H House") + _pick(page, "DropDownListPropertyType2", "mid-terrace") or \ + _pick(page, "DropDownListPropertyType2", "mid terrace") + E.set_text(page, "TextBoxStoreys", "2") + E.set_text(page, "TextBoxHabitableRooms", "5") + E.set_text(page, "TextBoxHeatedHabitableRooms", "5") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1900-1929")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.set_select(page, "DropDownListRoomInRoofMain", "") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "59.20") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.74") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "16.0") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "21.1") + E.set_text(page, f"{DIM}TextBoxFloorArea1stFloor", "57.10") + E.set_text(page, f"{DIM}TextBoxRoomHeight1stFloor", "2.74") + E.set_text(page, f"{DIM}TextBoxWallPerimeter1stFloor", "15.7") + E.set_text(page, f"{DIM}TextBoxPartyWallLength1stFloor", "21.7") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + _pick(page, f"{WALL}DropDownListType", "solid brick") + page.wait_for_timeout(500) + print("insulation ->", _pick(page, f"{WALL}DropDownListInsulation", "as built")) + print("party ->", _pick(page, f"{PWALL}DropDownListPartyWallType", "determine") + or _pick(page, f"{PWALL}DropDownListPartyWallType", "masonry")) + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + _pick(page, f"{ROOF}DropDownListType", "access to loft") or \ + _pick(page, f"{ROOF}DropDownListType", "loft") + _pick(page, f"{ROOF}DropDownListInsulationAt", "joists") + _pick(page, f"{ROOF}DropDownListThickness", "unknown") or \ + _pick(page, f"{ROOF}DropDownListThickness", "assumed") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + _pick(page, f"{FLOOR}DropDownListLocation", "unheated") + page.wait_for_timeout(400) + _pick(page, f"{FLOOR}DropDownListType", "solid") + ins = page.locator(f"#{E.FP}{FLOOR}DropDownListInsulation") + if ins.count(): + E.set_select(page, f"{FLOOR}DropDownListInsulation", "A As built") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + page.wait_for_timeout(500) + E.set_single_window(page, 18.32, "North", + _glazing(page) if False else "Double post or during 2022") + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "1") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + return "Double with unknown install date" + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "1") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "8") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + # dual meter (cert meter_type 1) + E.click_tab(page, "TabContainer_TabPanelMeters") + try: + E.set_select(page, "TabContainer_TabPanelMeters_RadioButtonListElectricityType", "Dual") + except Exception: + pass + E.save_close(page) + + +def secondary(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(600) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "Yes") + page.wait_for_timeout(900) + E.set_heating_dialog(page, "ButtonSecondaryHeatingCode", + "^Gas", "Mains gas", "Room Heater") + tb = page.locator(f"#{E.FP}TextBoxSecondaryHeatingCode") + print("secondary code:", tb.input_value() if tb.count() else "?") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + E.goto(page, "Recommendations", "WebFormRecommendations.aspx") + page.wait_for_timeout(1500) + with page.expect_navigation(wait_until="networkidle", timeout=40000): + page.click("#ContentBody_buttonActionSummary_Link", timeout=15000) + page.wait_for_timeout(2000) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60000) as dl: + page.click(f"#{btn}", timeout=15000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +def cleanup(page): + """Leave the shared assessment neutral for the next build.""" + E.reset_transient_state(page) + print("reset transient state (RR/secondary/meter)") + + +_ORDER = ["property_description", "dimensions", "walls", "roofs", "floors", + "openings", "ventilation", "space_heating", "secondary", + "water_heating", "download", "cleanup"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_100021924710.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/hyde/elmhurst_lib.py b/scripts/hyde/elmhurst_lib.py index 71d1ba792..0e8ca6d1c 100644 --- a/scripts/hyde/elmhurst_lib.py +++ b/scripts/hyde/elmhurst_lib.py @@ -235,24 +235,96 @@ def add_combined_window( ) -> None: """Add ONE window row of `total_area_m2` (width=area, height=1.0). Sets the required per-row fields (orientation/location/building-part) so the - Recommendations validation passes. Caller then deletes the prior rows.""" + Recommendations validation passes. Caller then deletes the prior rows. + + Glazing MUST be selected first (it AutoPostBacks and re-renders the form); + width/height are set via JS input+change+blur events with settle waits so + the Area cell (18.32 = w×h) computes before Add — a plain Playwright + `.fill()` raced the postback and Elmhurst added a 0.00-area row.""" set_select(page, f"{_WP}DropDownListExtGlazing", glazing) - page.locator(f"#{FP}{_WP}TextBoxExtWidth").fill(str(total_area_m2)) - h = page.locator(f"#{FP}{_WP}TextBoxExtHeight") - h.fill("1.00") - commit(page, lambda: h.press("Tab")) - page.locator(f"#{FP}{_WP}DropDownListExtOrientation").select_option(orientation) - page.locator(f"#{FP}{_WP}DropDownListExtBuildingPartId").select_option("Main") - page.locator(f"#{FP}{_WP}DropDownListExtLocation").select_option("External wall") - page.wait_for_timeout(200) + page.wait_for_timeout(SETTLE_MS) + + def _jset(suffix: str, value: str) -> None: + page.evaluate( + """(a)=>{const e=document.getElementById(a[0]);if(e){e.value=a[1]; + e.dispatchEvent(new Event('input',{bubbles:true})); + e.dispatchEvent(new Event('change',{bubbles:true})); + e.dispatchEvent(new Event('blur',{bubbles:true}));}}""", + [f"{FP}{suffix}", value], + ) + page.wait_for_timeout(300) + + _jset(f"{_WP}TextBoxExtWidth", str(total_area_m2)) + _jset(f"{_WP}TextBoxExtHeight", "1.00") + for suffix, opt in ( + (f"{_WP}DropDownListExtOrientation", orientation), + (f"{_WP}DropDownListExtBuildingPartId", "Main"), + (f"{_WP}DropDownListExtLocation", "External wall"), + ): + loc = page.locator(f"#{FP}{suffix}") + if loc.count(): + loc.select_option(opt) + page.wait_for_timeout(300) before = window_row_count(page) _jsclick(page, f"{FP}{_WP}ButtonAddWindow") for _ in range(20): - page.wait_for_timeout(200) + page.wait_for_timeout(250) if window_row_count(page) > before: break +def set_single_window( + page: Page, total_area_m2: float, orientation: str = "North", + glazing: str = "Double post or during 2022", +) -> None: + """Leave the window grid holding EXACTLY one row of `total_area_m2`, + deleting any rows carried over from a prior build of the shared + assessment. Elmhurst refuses to delete the last row, so we add the fresh + row FIRST, then delete every other row (they sort ahead of the new one). + This is the accurate-per-run cleanup: the window grid is the only page + that ACCUMULATES rather than overwrites across builds.""" + add_combined_window(page, total_area_m2, orientation, glazing) + guard = 0 + while window_row_count(page) > 1 and guard < 25: + guard += 1 + before = window_row_count(page) + delete_first_window(page) + if window_row_count(page) >= before: + break # couldn't delete (last-row guard / stuck) — stop + + +def reset_transient_state(page: Page) -> None: + """Return the shared assessment to a NEUTRAL state after a run so the next + build (or Khalim's) is not polluted by this cert's carried-over settings. + Clears the room-in-roof age band, forces secondary-heating present = No, + and the electricity meter back to Single. The window grid is left to the + next build's `set_single_window` (Elmhurst can't empty it to zero rows). + Call once at the end of a build session.""" + goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + rr = page.locator("#ContentBody_ContentPlaceHolder1_DropDownListRoomInRoofMain") + if rr.count() and rr.input_value(): + rr.select_option("") + page.wait_for_timeout(SETTLE_MS) + save_close(page) + goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(SETTLE_MS) + sec = page.locator(f"#{FP}DropDownListSecondaryHeatingPresent") + if sec.count(): + try: + set_select(page, "DropDownListSecondaryHeatingPresent", "No") + except Exception: + pass + meters = "TabContainer_TabPanelMeters" + click_tab(page, meters) + et = page.locator(f"#{FP}{meters}_RadioButtonListElectricityType") + if et.count(): + try: + set_select(page, f"{meters}_RadioButtonListElectricityType", "Single") + except Exception: + pass + save_close(page) + + def delete_first_window(page: Page) -> None: """Delete the first window row via the Yes/No modal. Will refuse to drop the LAST row (Elmhurst blocks it) — so add the replacement BEFORE deleting.""" From b4dbaef7f298843fa3384861d9572f91d53b05e3 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 03:44:49 +0000 Subject: [PATCH 12/84] chore(hyde): window-grid entry findings (fill+Tab persistence, frame/gap required) Continued hardening for the per-cert Elmhurst loop. Confirmed findings: - The window Width/Height must be set via Playwright .fill() + Tab (fires the ASP.NET AutoPostBack so the server commits the area); a JS-set of .value bypasses the postback and Elmhurst persists a 0.00-area row. - Frame Type (PVC) + Glazing Gap (12 mm) are REQUIRED per row or the Recommendations gate blocks the worksheet ("Frame Type/Glazing Gap must be entered"). add_combined_window now sets both. KNOWN BLOCKER (documented for the next attempt): the window grid is not yet reliably automatable when stale rows exist on the shared assessment. New rows insert at index 0; the delete flow reliably removes only index 0 (the newest), so accumulated 0.00 junk rows BELOW cannot be targeted, and grid reads are timing-inconsistent across postbacks. A robust handler needs to either (a) drive the per-row Delete by matching the row's server-side id rather than DOM index, or (b) start each build from a freshly-created assessment (not the shared one) so the grid is empty. Until then the per-cert loop runs only on the FIRST build after a manual window reset. build_100050881708.py is the WIP template. No engine change. Co-Authored-By: Claude Fable 5 --- scripts/hyde/build_100050881708.py | 223 +++++++++++++++++++++++++++++ scripts/hyde/elmhurst_lib.py | 35 +++-- 2 files changed, 243 insertions(+), 15 deletions(-) create mode 100644 scripts/hyde/build_100050881708.py diff --git a/scripts/hyde/build_100050881708.py b/scripts/hyde/build_100050881708.py new file mode 100644 index 000000000..e61ddbd8d --- /dev/null +++ b/scripts/hyde/build_100050881708.py @@ -0,0 +1,223 @@ +"""Elmhurst build for UPRN 100050881708 (RdSAP-21.0.1, MID-TERRACE HOUSE, band B, +SOLID BRICK 250 mm uninsulated, pitched insulated (assumed) loft, floor to +UNHEATED space, mains-gas COMBI (PCDB 19008) + gas room-heater SECONDARY, DUAL +meter, 11 DG windows ~18.32 m², TFA 116. Lodged SAP 63; engine 65.0 (Δ +2.0). + +Per-cert Elmhurst validation. Uses set_single_window (deletes the shared +assessment's carried-over window rows) + reset_transient_state at the end so the +assessment is left neutral. Run: + DISPLAY=:99 python scripts/hyde/build_100050881708.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +PWALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelPartyWallMain_WebUserControlPartyWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_100050881708") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + E.set_select(page, "DropDownListPropertyType1", "H House") + _pick(page, "DropDownListPropertyType2", "semi") + E.set_text(page, "TextBoxStoreys", "2") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1900-1929")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.set_select(page, "DropDownListRoomInRoofMain", "") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "31.62") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "16.4") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "6.2") + E.set_text(page, f"{DIM}TextBoxFloorArea1stFloor", "31.62") + E.set_text(page, f"{DIM}TextBoxRoomHeight1stFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeter1stFloor", "16.4") + E.set_text(page, f"{DIM}TextBoxPartyWallLength1stFloor", "6.2") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + _pick(page, f"{WALL}DropDownListType", "cavity") + page.wait_for_timeout(500) + print("insulation ->", _pick(page, f"{WALL}DropDownListInsulation", "filled")) + print("party ->", _pick(page, f"{PWALL}DropDownListPartyWallType", "determine") + or _pick(page, f"{PWALL}DropDownListPartyWallType", "masonry")) + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + _pick(page, f"{ROOF}DropDownListType", "access to loft") or \ + _pick(page, f"{ROOF}DropDownListType", "loft") + _pick(page, f"{ROOF}DropDownListInsulationAt", "joists") + _pick(page, f"{ROOF}DropDownListThickness", "225") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + _pick(page, f"{FLOOR}DropDownListLocation", "unheated") + page.wait_for_timeout(400) + _pick(page, f"{FLOOR}DropDownListType", "solid") + ins = page.locator(f"#{E.FP}{FLOOR}DropDownListInsulation") + if ins.count(): + E.set_select(page, f"{FLOOR}DropDownListInsulation", "A As built") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + page.wait_for_timeout(500) + E.set_single_window(page, 9.56, "North", + _glazing(page) if False else "Double post or during 2022") + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "2") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + return "Double with unknown install date" + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "2") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "8") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "No") + E.save_close(page) + + +def secondary(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(600) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "Yes") + page.wait_for_timeout(900) + E.set_heating_dialog(page, "ButtonSecondaryHeatingCode", + "^Gas", "Mains gas", "Room Heater") + tb = page.locator(f"#{E.FP}TextBoxSecondaryHeatingCode") + print("secondary code:", tb.input_value() if tb.count() else "?") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + E.goto(page, "Recommendations", "WebFormRecommendations.aspx") + page.wait_for_timeout(1500) + with page.expect_navigation(wait_until="networkidle", timeout=40000): + page.click("#ContentBody_buttonActionSummary_Link", timeout=15000) + page.wait_for_timeout(2000) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60000) as dl: + page.click(f"#{btn}", timeout=15000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +def cleanup(page): + """Leave the shared assessment neutral for the next build.""" + E.reset_transient_state(page) + print("reset transient state (RR/secondary/meter)") + + +_ORDER = ["property_description", "dimensions", "walls", "roofs", "floors", + "openings", "ventilation", "space_heating", "water_heating", "download", "cleanup"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_100050881708.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/hyde/elmhurst_lib.py b/scripts/hyde/elmhurst_lib.py index 0e8ca6d1c..25f9b0eb2 100644 --- a/scripts/hyde/elmhurst_lib.py +++ b/scripts/hyde/elmhurst_lib.py @@ -238,32 +238,37 @@ def add_combined_window( Recommendations validation passes. Caller then deletes the prior rows. Glazing MUST be selected first (it AutoPostBacks and re-renders the form); - width/height are set via JS input+change+blur events with settle waits so - the Area cell (18.32 = w×h) computes before Add — a plain Playwright - `.fill()` raced the postback and Elmhurst added a 0.00-area row.""" + width/height are then set via a Playwright `.fill()` + Tab so the ASP.NET + AutoPostBack fires and the server-side Area (w×h) commits — a JS-set of the + value bypasses the postback and Elmhurst persists a 0.00-area row. + Frame Type + Glazing Gap are REQUIRED by the Recommendations validation + gate (else "Frame Type/Glazing Gap must be entered" blocks the worksheet).""" set_select(page, f"{_WP}DropDownListExtGlazing", glazing) page.wait_for_timeout(SETTLE_MS) - def _jset(suffix: str, value: str) -> None: - page.evaluate( - """(a)=>{const e=document.getElementById(a[0]);if(e){e.value=a[1]; - e.dispatchEvent(new Event('input',{bubbles:true})); - e.dispatchEvent(new Event('change',{bubbles:true})); - e.dispatchEvent(new Event('blur',{bubbles:true}));}}""", - [f"{FP}{suffix}", value], - ) - page.wait_for_timeout(300) + def _fill_tab(suffix: str, value: str) -> None: + loc = page.locator(f"#{FP}{suffix}") + loc.fill(value) + loc.press("Tab") + page.wait_for_timeout(1200) # AutoPostBack settle - _jset(f"{_WP}TextBoxExtWidth", str(total_area_m2)) - _jset(f"{_WP}TextBoxExtHeight", "1.00") + _fill_tab(f"{_WP}TextBoxExtWidth", str(total_area_m2)) + _fill_tab(f"{_WP}TextBoxExtHeight", "1.00") + # Frame Type (PVC) + Glazing Gap (12 mm) are validation-required per row. for suffix, opt in ( + (f"{_WP}DropDownListExtFrameType", "PVC"), + (f"{_WP}DropDownListExtGlazingGap", "12 mm"), (f"{_WP}DropDownListExtOrientation", orientation), (f"{_WP}DropDownListExtBuildingPartId", "Main"), (f"{_WP}DropDownListExtLocation", "External wall"), ): loc = page.locator(f"#{FP}{suffix}") if loc.count(): - loc.select_option(opt) + try: + loc.select_option(opt) + except Exception: + pass + page.wait_for_timeout(250) page.wait_for_timeout(300) before = window_row_count(page) _jsclick(page, f"{FP}{_WP}ButtonAddWindow") From 6f2b73e613cdb9b7d471037f724880f67e54cfd2 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 03:55:48 +0000 Subject: [PATCH 13/84] chore(hyde): fix window-grid automation (keep good row, delete stale below) + pin 100050881708 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SOLVED the window-grid blocker (per Junte's "keep one and edit, don't delete all"): set_single_window now ADDS the fresh window (it inserts at DOM index 0), then deletes the STALE rows BELOW it by index (high->low, never index 0) via the per-row Delete image button + JS-clicked Yes modal. The freshly-added row survives as the single window; no 0.00 junk strands to block the Recommendations gate. Verified end-to-end: cert 100050881708 built, worksheet downloaded, walls (0.70) + roof (0.19) match the engine EXACTLY. Combined with the earlier fill+Tab (area postback) + frame/gap (validation) fixes, the per-cert loop now runs autonomously on clean single-main certs. Pin: 100050881708 (semi, cavity filled, pitched 225mm, suspended ground floor, combi) engine 72 = lodged 70 +2; walls/roof accredited-Elmhurst- matched. NB the build entered the suspended ground floor as an upper "above unheated space" floor, so Elmhurst's worksheet SAP (61) is not a clean comparison — the engine uses the correct §3.12 suspended-ground U (0.74); the pin rests on the walls+roof match + lodged. No engine change. Co-Authored-By: Claude Fable 5 --- .../uprn_100050881708/elmhurst_summary.pdf | Bin 0 -> 64297 bytes .../uprn_100050881708/elmhurst_worksheet.pdf | Bin 0 -> 44141 bytes .../uprn_100050881708/epc.json | 426 ++++++++++++++++++ scripts/hyde/elmhurst_lib.py | 48 +- .../test_real_cert_sap_accuracy.py | 19 + 5 files changed, 483 insertions(+), 10 deletions(-) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/elmhurst_summary.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/elmhurst_worksheet.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/epc.json diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/elmhurst_summary.pdf new file mode 100644 index 0000000000000000000000000000000000000000..28a0ee26dc25cdc8ff2ac6aa2d07ca0c12c53101 GIT binary patch literal 64297 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 Sdp3c%;Ijvdj!sfZ>i+;p#8AEf literal 0 HcmV?d00001 diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/epc.json new file mode 100644 index 000000000..100e4eb06 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/epc.json @@ -0,0 +1,426 @@ +{ + "uprn": 100050881708, + "roofs": [ + { + "description": "Pitched, 225 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Cavity wall, filled cavity", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "To unheated space, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Below average lighting efficiency", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "postcode": "S65 3RW", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "ROTHERHAM", + "built_form": 2, + "created_at": "2026-05-27 15:09:39", + "door_count": 2, + "region_code": 3, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 0, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 17741 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.7, + "window_height": 1.4, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.2, + "window_height": 1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": 0.6, + "window_height": 1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 0.6, + "window_height": 0.7, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 0.6, + "window_height": 1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.2, + "window_height": 1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.2, + "window_height": 1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.1, + "window_height": 0.8, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 2, + "window_width": 0.6, + "window_height": 0.7, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 2, + "window_width": 0.6, + "window_height": 1.1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Semi-detached house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "9 Woodgrove Road", + "assessment_type": "RdSAP", + "completion_date": "2026-05-27", + "inspection_date": "2026-05-27", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 63, + "transaction_type": 14, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2026-05-27", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "extract_fans_count": 2, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "floor_heat_loss": 2, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.4, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 31.62, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 6.2, + "quantity": "metres" + }, + "floor_construction": 2, + "heat_loss_perimeter": { + "value": 16.4, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.41, + "quantity": "metres" + }, + "total_floor_area": { + "value": 31.62, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 6.2, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 16.4, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 2, + "construction_age_band": "B", + "party_wall_construction": 1, + "wall_thickness_measured": "N", + "roof_insulation_location": 2, + "roof_insulation_thickness": "225mm", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 777, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 2.3, + "energy_rating_average": 60, + "energy_rating_current": 70, + "lighting_cost_current": { + "value": 79, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 671, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 172, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 110, + "currency": "GBP" + }, + "indicative_cost": "\u00a35,000 - \u00a310,000", + "improvement_type": "W1", + "improvement_details": { + "improvement_number": 57 + }, + "improvement_category": 5, + "energy_performance_rating": 73, + "environmental_impact_rating": 75 + }, + { + "sequence": 2, + "typical_saving": { + "value": 30, + "currency": "GBP" + }, + "indicative_cost": "\u00a3120 - \u00a3140", + "improvement_type": "E", + "improvement_details": { + "improvement_number": 35 + }, + "improvement_category": 5, + "energy_performance_rating": 74, + "environmental_impact_rating": 75 + }, + { + "sequence": 3, + "typical_saving": { + "value": 184, + "currency": "GBP" + }, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 79, + "environmental_impact_rating": 77 + } + ], + "co2_emissions_potential": 1.9, + "energy_rating_potential": 79, + "lighting_cost_potential": { + "value": 45, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 172, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2070.91, + "space_heating_existing_dwelling": 7543.77 + }, + "draughtproofed_door_count": 2, + "energy_consumption_current": 205, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 161, + "environmental_impact_current": 71, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 77, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 37, + "low_energy_fixed_lighting_bulbs_count": 4, + "incandescent_fixed_lighting_bulbs_count": 4 +} \ No newline at end of file diff --git a/scripts/hyde/elmhurst_lib.py b/scripts/hyde/elmhurst_lib.py index 25f9b0eb2..fb99966fb 100644 --- a/scripts/hyde/elmhurst_lib.py +++ b/scripts/hyde/elmhurst_lib.py @@ -278,24 +278,52 @@ def add_combined_window( break +def _delete_window_at_index(page: Page, i: int) -> bool: + """Delete the window grid row at DOM index `i` via its per-row Delete + image button + the Yes modal (JS-clicked to bypass the modal background + that intercepts real clicks). Returns True if a delete fired.""" + bid = ( + "ContentBody_ContentPlaceHolder1_TabContainer_TabPanelWindowsPanel_" + f"GridViewExtendedWidows_DeleteButton_{i}" + ) + if not page.evaluate("(id)=>!!document.getElementById(id)", bid): + return False + page.evaluate("(id)=>{const e=document.getElementById(id);if(e)e.click();}", bid) + page.wait_for_timeout(2000) + yid = "ContentBody_ContentPlaceHolder1_DeleteWindowDialog_LinkButtonYes" + if not page.evaluate( + "(id)=>{const e=document.getElementById(id);return e?e.offsetParent!==null:false;}", + yid, + ): + return False + page.evaluate("(id)=>{const e=document.getElementById(id);if(e)e.click();}", yid) + page.wait_for_timeout(2500) + return True + + def set_single_window( page: Page, total_area_m2: float, orientation: str = "North", glazing: str = "Double post or during 2022", ) -> None: - """Leave the window grid holding EXACTLY one row of `total_area_m2`, - deleting any rows carried over from a prior build of the shared - assessment. Elmhurst refuses to delete the last row, so we add the fresh - row FIRST, then delete every other row (they sort ahead of the new one). - This is the accurate-per-run cleanup: the window grid is the only page - that ACCUMULATES rather than overwrites across builds.""" + """Leave the window grid holding EXACTLY one correct row of + `total_area_m2`, cleaning any rows carried over from a prior build of the + SHARED assessment. + + The grid can't be emptied (Elmhurst refuses to delete the last row) and it + has no inline edit, so per [[window-grid]] the reliable pattern is: ADD the + fresh window (it inserts at DOM index 0), then delete the STALE rows BELOW + it (indices high->low, never index 0) so the freshly-added row survives as + the single remaining window. Deleting index 0 (delete_first_window) would + drop the good row and strand a 0.00-area junk row that then blocks the + Recommendations gate.""" add_combined_window(page, total_area_m2, orientation, glazing) + page.wait_for_timeout(500) guard = 0 while window_row_count(page) > 1 and guard < 25: guard += 1 - before = window_row_count(page) - delete_first_window(page) - if window_row_count(page) >= before: - break # couldn't delete (last-row guard / stuck) — stop + i = window_row_count(page) - 1 # bottom-most (oldest) stale row + if not _delete_window_at_index(page, i): + break def reset_transient_state(page: Page) -> None: diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index 9f3bce1b2..d7b72cb49 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -823,6 +823,25 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-47084930", sap_score=74, ), + # UPRN 100050881708 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # SEMI-DETACHED HOUSE, band B, cavity FILLED wall, pitched 225 mm loft, + # SUSPENDED ground floor "to unheated space", mains-gas combi, no cylinder. + # Lodged 70 / engine 72 (71.55). Built in accredited Elmhurst RdSAP10 + # (evidence saved: elmhurst_summary.pdf / elmhurst_worksheet.pdf): the WALL + # (cavity, U 0.70, 69.56 m²) and ROOF (insulated slope 225 mm, U 0.19) + # match the engine EXACTLY (walls 48.8 W/K, roof 6.0 W/K). The engine is + # faithful on the checkable fabric; the +1.55 vs lodged is a small + # methodology gap. (Elmhurst''s worksheet SAP 61 is NOT comparable — the + # build entered the suspended ground floor as an upper "above unheated + # space" floor, which Elmhurst bills via Table-20 exposed 1.20; the cert''s + # §3.12 suspended-ground-floor U is 0.74, which the engine uses.) PINNED to + # the observed engine 72. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_100050881708", + cert_num="uprn-100050881708", + sap_score=72, + ), ) From 17ced10e94baeceb1394e9d2521447336b13f08f Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 04:16:47 +0000 Subject: [PATCH 14/84] test(accuracy): validate + pin 217091901 (single-glazing confirmed vs Elmhurst) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Top-floor flat, solid brick uninsulated, uninsulated flat roof, gas combi, SINGLE glazing (glazed_type 5). Built in accredited Elmhurst RdSAP10 and every heat-loss element matches the engine EXACTLY: walls 53.18, flat roof 145.57, floor 0, party 0, and — with the faithful single glazing — windows 34.7114 W/K (8.62 m2 x eff U 4.0268). Confirms the mapper's glazed_type 5 -> single (raw U 4.8) is spec-correct per epc_codes.csv, not the double it superficially resembles. Engine 61 vs lodged 62; the -1.18 is a cost-side residual, not a fabric bug. Pinned to the observed engine 61. Co-Authored-By: Claude Opus 4.8 --- .../uprn_217091901/elmhurst_summary.pdf | Bin 0 -> 79974 bytes .../uprn_217091901/elmhurst_worksheet.pdf | Bin 0 -> 43333 bytes .../uprn_217091901/epc.json | 384 ++++++++++++++++++ scripts/hyde/build_217091901.py | 287 +++++++++++++ .../test_real_cert_sap_accuracy.py | 21 + 5 files changed, 692 insertions(+) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_summary.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_worksheet.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/epc.json create mode 100644 scripts/hyde/build_217091901.py diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_summary.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bf5e1e38263ee164b96224bf04b600cede8742eb GIT binary patch literal 79974 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 literal 0 HcmV?d00001 diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_worksheet.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c995532927f9a81fbcb3ab7ad56a19c8bfe61171 GIT binary patch literal 43333 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 NxS^M6X(f~-{{zw*HXi^0 literal 0 HcmV?d00001 diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/epc.json new file mode 100644 index 000000000..5ac1c41ad --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/epc.json @@ -0,0 +1,384 @@ +{ + "uprn": 217091901, + "roofs": [ + { + "description": "Flat, no insulation", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "walls": [ + { + "description": "Solid brick, as built, no insulation (assumed)", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "floors": [ + { + "description": "(another dwelling below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Single glazed", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + }, + "lighting": { + "description": "Good lighting efficiency", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "W11 1EP", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "LONDON", + "built_form": "NR", + "created_at": "2026-05-16 15:45:17", + "door_count": 0, + "region_code": 17, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 0, + "main_heating_number": 1, + "main_heating_control": 2107, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 18658 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 5, + "window_width": 1.2, + "window_height": 1.8, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 5, + "window_width": 1.2, + "window_height": 1.8, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 9, + "window_type": 2, + "glazing_type": 5, + "window_width": 0.5, + "window_height": 0.5, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 9, + "window_type": 2, + "glazing_type": 5, + "window_width": 0.7, + "window_height": 0.5, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 1.2, + "window_height": 1.8, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 1.1, + "window_height": 1.4, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Top-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "Second Floor Flat", + "address_line_2": "216 Westbourne Park Road", + "assessment_type": "RdSAP", + "completion_date": "2026-05-16", + "inspection_date": "2026-05-16", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 3, + "top_storey": "Y", + "storey_count": 3, + "flat_location": 2, + "heat_loss_corridor": 0 + }, + "total_floor_area": 63, + "transaction_type": 8, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 3, + "registration_date": "2026-05-16", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 280, + "floor_heat_loss": 6, + "roof_construction": 1, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.85, + "quantity": "metres" + }, + "total_floor_area": { + "value": 63.29, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 22.8, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 14, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "A", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 6, + "wall_insulation_thickness": "NI", + "flat_roof_insulation_thickness": "AB" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 967, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 2.8, + "energy_rating_average": 60, + "energy_rating_current": 62, + "lighting_cost_current": { + "value": 43, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, TRVs and bypass", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "blocked_chimneys_count": 1, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 330, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 167, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 411, + "currency": "GBP" + }, + "indicative_cost": "\u00a3900 - \u00a31,200", + "improvement_type": "A2", + "improvement_details": { + "improvement_number": 45 + }, + "improvement_category": 5, + "energy_performance_rating": 74, + "environmental_impact_rating": 76 + }, + { + "sequence": 2, + "typical_saving": { + "value": 129, + "currency": "GBP" + }, + "indicative_cost": "\u00a37,500 - \u00a311,000", + "improvement_type": "Q", + "improvement_details": { + "improvement_number": 7 + }, + "improvement_category": 5, + "energy_performance_rating": 78, + "environmental_impact_rating": 81 + }, + { + "sequence": 3, + "typical_saving": { + "value": 18, + "currency": "GBP" + }, + "indicative_cost": "\u00a3150 - \u00a3250", + "improvement_type": "D", + "improvement_details": { + "improvement_number": 10 + }, + "improvement_category": 5, + "energy_performance_rating": 79, + "environmental_impact_rating": 82 + }, + { + "sequence": 4, + "typical_saving": { + "value": 78, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,500 - \u00a36,000", + "improvement_type": "O", + "improvement_details": { + "improvement_number": 8 + }, + "improvement_category": 5, + "energy_performance_rating": 81, + "environmental_impact_rating": 85 + } + ], + "co2_emissions_potential": 1.0, + "energy_rating_potential": 81, + "lighting_cost_potential": { + "value": 45, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 167, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2022.69, + "space_heating_existing_dwelling": 9246.82 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 245, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 0, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 90, + "environmental_impact_current": 59, + "cfl_fixed_lighting_bulbs_count": 2, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 85, + "led_fixed_lighting_bulbs_count": 9, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 45, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/scripts/hyde/build_217091901.py b/scripts/hyde/build_217091901.py new file mode 100644 index 000000000..f487d973c --- /dev/null +++ b/scripts/hyde/build_217091901.py @@ -0,0 +1,287 @@ +"""Elmhurst build for UPRN 217091901 (RdSAP-21.0.1, TOP-FLOOR FLAT, band A, +SOLID BRICK 280 mm UNINSULATED, FLAT ROOF no insulation (As Built), floor over +ANOTHER DWELLING below (zero loss), mains-gas COMBI (PCDB 18658), 6 DG windows +~8.62 m², no doors, TFA 63. Lodged SAP 62; engine 60.82 (Δ −1.18, PE +8.7). + +Per-cert worksheet validation. The roof dominates loss (145.6 W/K at flat-default +U 2.30); this build confirms the accredited uninsulated flat-roof + solid-brick +wall U against the engine. Run: + DISPLAY=:99 python scripts/hyde/build_217091901.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +WP = "TabContainer_TabPanelWindowsPanel_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_217091901") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def _options(page, suffix): + return page.evaluate( + """(id)=>{const s=document.getElementById(id);if(!s)return []; + return Array.from(s.options).map(o=>o.text);}""", f"{E.FP}{suffix}") + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + _pick(page, "DropDownListPropertyType1", "flat") or \ + E.set_select(page, "DropDownListPropertyType1", "F Flat") + E.set_text(page, "TextBoxStoreys", "1") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "before 1900")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.save_close(page) + + +def flats(page): + E.goto(page, "Flats", "WebFormFlats.aspx") + print("flat positions:", _options(page, "" if False else "DropDownListPositionOfFlat")) + _pick(page, "DropDownListPositionOfFlat", "top") or \ + E.set_select(page, "DropDownListPositionOfFlat", "Top Floor") + E.set_text(page, "TextBoxFloor", "3") + E.set_select(page, "RadioButtonListFlatCoridor", "None") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "63.29") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.85") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "14.0") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "22.8") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + _pick(page, f"{WALL}DropDownListType", "solid brick") + page.wait_for_timeout(500) + print("insulation opts:", _options(page, f"{WALL}DropDownListInsulation")) + _pick(page, f"{WALL}DropDownListInsulation", "as built") or \ + _pick(page, f"{WALL}DropDownListInsulation", "none") + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + print("ROOF TYPE opts:", _options(page, f"{ROOF}DropDownListType")) + _pick(page, f"{ROOF}DropDownListType", "flat") + page.wait_for_timeout(600) + _pick(page, f"{ROOF}DropDownListInsulationAt", "flat roof insulation") + page.wait_for_timeout(600) + # discover the thickness/additional field that appears for flat-roof insulation + for suf in (f"{ROOF}DropDownListThickness", f"{ROOF}DropDownListInsulation", + f"{ROOF}DropDownListAdditionalInsulation"): + if page.locator(f"#{E.FP}{suf}").count(): + print(f" {suf.split('_')[-1]} opts:", _options(page, suf)) + _pick(page, suf, "as built") or _pick(page, suf, "unknown") or \ + _pick(page, suf, "none") or _pick(page, suf, "nil") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + print("FLOOR LOCATION opts:", _options(page, f"{FLOOR}DropDownListLocation")) + # "(other premises below)" = above a partially-heated space + _pick(page, f"{FLOOR}DropDownListLocation", "another dwelling below") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + E.set_single_window(page, 8.62, "North", _glazing(page)) + _delete_zero_rows(page) + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "0") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + # Cert glazed_type=5 → SINGLE glazing (epc_codes.csv, RdSAP-Schema-21). + for opt in _options(page, f"{WP}DropDownListExtGlazing"): + if "single" in opt.lower(): + return opt + return "Single glazed" + + +def _add_window(page, area, orientation, glazing): + print("glazing ->", glazing) + E.set_select(page, f"{WP}DropDownListExtGlazing", glazing) + page.wait_for_timeout(400) + ft = page.locator(f"#{E.FP}{WP}DropDownListExtFrameType") + if ft.count(): + ft.select_option("PVC") + gg = page.locator(f"#{E.FP}{WP}DropDownListExtGlazingGap") + if gg.count(): + gg.select_option("12 mm") + wid = f"{E.FP}{WP}TextBoxExtWidth" + page.evaluate( + """(a)=>{const e=document.getElementById(a[0]);if(e){e.value=a[1]; + e.dispatchEvent(new Event('input',{bubbles:true})); + e.dispatchEvent(new Event('change',{bubbles:true})); + e.dispatchEvent(new Event('blur',{bubbles:true}));}}""", [wid, str(area)]) + page.locator(f"#{E.FP}{WP}TextBoxExtHeight").fill("1.00") + page.locator(f"#{E.FP}{WP}DropDownListExtOrientation").select_option(orientation) + page.locator(f"#{E.FP}{WP}DropDownListExtBuildingPartId").select_option("Main") + page.locator(f"#{E.FP}{WP}DropDownListExtLocation").select_option("External wall") + page.wait_for_timeout(300) + before = E.window_row_count(page) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}{WP}ButtonAddWindow") + for _ in range(25): + page.wait_for_timeout(200) + if E.window_row_count(page) > before: + break + + +def _grid_rows(page): + return page.evaluate( + """()=>{const t=document.querySelector("[id*=GridViewExtendedWidows]"); + if(!t)return[];return Array.from(t.querySelectorAll('tr')).slice(1) + .map(r=>Array.from(r.querySelectorAll('td')).map(c=>c.innerText.trim()));}""") + + +def _delete_zero_rows(page): + g = 0 + while g < 6 and E.window_row_count(page) > 1: + g += 1 + rows = _grid_rows(page) + bad = next((i for i, c in enumerate(rows) if len(c) > 1 and c[1] in ("0.00", "0", "0.0")), None) + if bad is None: + break + _delete_row(page, bad) + page.wait_for_timeout(400) + + +def _delete_row(page, idx): + before = E.window_row_count(page) + btn = page.evaluate( + """(i)=>{const b=document.querySelectorAll("[id*='GridViewExtendedWidows_DeleteButton_']");return b[i]?b[i].id:null;}""", idx) + if not btn: + return + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", btn) + page.wait_for_selector(f"#{E.FP}DeleteWindowDialog_LinkButtonYes", state="visible", timeout=5000) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}DeleteWindowDialog_LinkButtonYes") + for _ in range(20): + page.wait_for_timeout(200) + if E.window_row_count(page) < before: + break + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "0") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "6") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "No") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + E.goto(page, "Recommendations", "WebFormRecommendations.aspx") + page.wait_for_timeout(1500) + with page.expect_navigation(wait_until="networkidle", timeout=40000): + page.click("#ContentBody_buttonActionSummary_Link", timeout=15000) + page.wait_for_timeout(2000) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60000) as dl: + page.click(f"#{btn}", timeout=15000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +_ORDER = ["property_description", "flats", "dimensions", "walls", "roofs", + "floors", "openings", "ventilation", "space_heating", "water_heating", + "download"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_217091901.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index d7b72cb49..a1caa14aa 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -842,6 +842,27 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-100050881708", sap_score=72, ), + # UPRN 217091901 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # TOP-FLOOR FLAT, band A (before 1900), SOLID BRICK 280 mm uninsulated, + # FLAT ROOF no insulation (As Built), floor over ANOTHER DWELLING below + # (zero loss), mains-gas COMBI, SINGLE glazing (glazed_type 5), TFA 63. + # Lodged 62 / engine 61 (60.82). Built in accredited Elmhurst RdSAP10 + # (evidence saved: elmhurst_summary.pdf / elmhurst_worksheet.pdf): EVERY + # heat-loss element matches the engine EXACTLY — walls (solid U 1.70, + # 53.18 W/K), flat roof (uninsulated U 2.30, 145.57 W/K), floor (0), + # party (0), and — with the faithful SINGLE glazing entered — WINDOWS + # (8.62 m² × effective U 4.0268 = 34.7114 W/K, identical to the engine). + # This confirms the mapper''s glazed_type 5 → single (raw U 4.8) is + # spec-correct (epc_codes.csv: glazed_type 5 = single glazing), NOT the + # double it superficially resembles. The −1.18 vs lodged is a cost-side + # methodology residual (PE +8.7 kWh/m², CO2/PE-driven), not a fabric bug. + # PINNED to the observed engine 61. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_217091901", + cert_num="uprn-217091901", + sap_score=61, + ), ) From 1032a4f128dbcd2e10d2e31804e0c92650b20c40 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 04:28:25 +0000 Subject: [PATCH 15/84] test(accuracy): validate + pin 100061275133 (slice-5 external-insulation U confirmed) 2-storey semi, solid brick 400mm with EXTERNAL insulation, 300mm loft, suspended uninsulated ground floor, gas combi, double glazing (glazed_type 13). Built in accredited Elmhurst RdSAP10: roof (U 0.14, 5.459 W/K) and windows (15.32 x eff U 1.3258 = 20.311 W/K) match the engine EXACTLY; the externally-insulated wall is engine U 0.29 vs Elmhurst 0.30, validating the slice-5 external-insulation default (100mm added over solid brick); suspended ground floor engine 0.68 vs Elmhurst 0.70. Elmhurst's overall SAP 67 is not comparable (reused-assessment Standard-Combi keep-hot loss, a build artifact). Engine 77 vs lodged 76 (within 1.24). Pinned to the observed 77. Co-Authored-By: Claude Opus 4.8 --- .../uprn_100061275133/elmhurst_summary.pdf | Bin 0 -> 79070 bytes .../uprn_100061275133/elmhurst_worksheet.pdf | Bin 0 -> 44121 bytes .../uprn_100061275133/epc.json | 410 ++++++++++++++++++ scripts/hyde/build_100061275133.py | 224 ++++++++++ .../test_real_cert_sap_accuracy.py | 22 + 5 files changed, 656 insertions(+) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_worksheet.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/epc.json create mode 100644 scripts/hyde/build_100061275133.py diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7e17907d954d755eb7f43d62abfdeb2cbf634bf8 GIT binary patch literal 79070 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 CW9e`J literal 0 HcmV?d00001 diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_worksheet.pdf new file mode 100644 index 0000000000000000000000000000000000000000..da423eee1188bd92e5477ff5cb0a4f9eca9c86aa GIT binary patch literal 44121 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 +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +PWALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelPartyWallMain_WebUserControlPartyWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_100061275133") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + E.set_select(page, "DropDownListPropertyType1", "H House") + _pick(page, "DropDownListPropertyType2", "semi") + E.set_text(page, "TextBoxStoreys", "2") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1900-1929")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.set_select(page, "DropDownListRoomInRoofMain", "") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "38.99") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "17.92") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "5.09") + E.set_text(page, f"{DIM}TextBoxFloorArea1stFloor", "38.99") + E.set_text(page, f"{DIM}TextBoxRoomHeight1stFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeter1stFloor", "17.92") + E.set_text(page, f"{DIM}TextBoxPartyWallLength1stFloor", "5.09") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + _pick(page, f"{WALL}DropDownListType", "solid brick") + page.wait_for_timeout(500) + print("insulation ->", _pick(page, f"{WALL}DropDownListInsulation", "external")) + print("party ->", _pick(page, f"{PWALL}DropDownListPartyWallType", "determine") + or _pick(page, f"{PWALL}DropDownListPartyWallType", "masonry")) + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + _pick(page, f"{ROOF}DropDownListType", "access to loft") or \ + _pick(page, f"{ROOF}DropDownListType", "loft") + _pick(page, f"{ROOF}DropDownListInsulationAt", "joists") + _pick(page, f"{ROOF}DropDownListThickness", "300") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + _pick(page, f"{FLOOR}DropDownListLocation", "ground floor") + page.wait_for_timeout(400) + _pick(page, f"{FLOOR}DropDownListType", "suspended") + ins = page.locator(f"#{E.FP}{FLOOR}DropDownListInsulation") + if ins.count(): + E.set_select(page, f"{FLOOR}DropDownListInsulation", "A As built") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + page.wait_for_timeout(500) + E.set_single_window(page, 15.32, "North", _glazing(page)) + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "2") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + # glazed_type 13 -> double glazed, 2022 or later (U 1.4) + return "Double post or during 2022" + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "1") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "6") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "No") + E.save_close(page) + + +def _unused_secondary(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(600) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "Yes") + page.wait_for_timeout(900) + E.set_heating_dialog(page, "ButtonSecondaryHeatingCode", + "^Gas", "Mains gas", "Room Heater") + tb = page.locator(f"#{E.FP}TextBoxSecondaryHeatingCode") + print("secondary code:", tb.input_value() if tb.count() else "?") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + E.goto(page, "Recommendations", "WebFormRecommendations.aspx") + page.wait_for_timeout(1500) + with page.expect_navigation(wait_until="networkidle", timeout=40000): + page.click("#ContentBody_buttonActionSummary_Link", timeout=15000) + page.wait_for_timeout(2000) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60000) as dl: + page.click(f"#{btn}", timeout=15000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +def cleanup(page): + """Leave the shared assessment neutral for the next build.""" + E.reset_transient_state(page) + print("reset transient state (RR/secondary/meter)") + + +_ORDER = ["property_description", "dimensions", "walls", "roofs", "floors", + "openings", "ventilation", "space_heating", + "water_heating", "download", "cleanup"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_100061275133.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index a1caa14aa..21af95ba8 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -863,6 +863,28 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-217091901", sap_score=61, ), + # UPRN 100061275133 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # 2-storey SEMI-DETACHED HOUSE, band B, SOLID BRICK 400 mm with EXTERNAL + # insulation, pitched 300 mm loft, SUSPENDED uninsulated ground floor, + # mains-gas COMBI, double glazing (glazed_type 13, 2022+), TFA 78. + # Lodged 76 / engine 77 (77.24). Built in accredited Elmhurst RdSAP10 + # (evidence saved: elmhurst_summary.pdf / elmhurst_worksheet.pdf): the + # checkable FABRIC matches the engine closely — ROOF (300 mm loft, U 0.14) + # and WINDOWS (15.32 m² × eff U 1.3258 = 20.3106 W/K) match EXACTLY; the + # externally-insulated WALL is U 0.29 (engine) vs 0.30 (Elmhurst) — which + # VALIDATES the slice-5 external-insulation default (100 mm added over solid + # brick, `_WALL_ADDED_INSULATION_UNKNOWN_THICKNESS_MM`); the suspended + # ground floor is U 0.68 (engine) vs 0.70 (Elmhurst). (Elmhurst''s overall + # worksheet SAP 67 is NOT comparable — the reused-assessment combi entered + # as a "Standard Combi" carries a ~50 kWh/month Table-3a keep-hot loss the + # lodged assessment did not, a build-side heating artifact, not an engine + # gap.) Engine 77 sits within 1.24 of lodged; PINNED to the observed 77. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_100061275133", + cert_num="uprn-100061275133", + sap_score=77, + ), ) From bf53d29690c8eb2fe5ca6e8384c252b75e542732 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 04:30:22 +0000 Subject: [PATCH 16/84] test(accuracy): pin 100051051866 + 10070056075 (clean single-main loop complete) Final two clean single-main gas certs. Both small cost-side residuals (+1.04 / -1.01 SAP) on cavity-insulated fabric already Elmhurst-validated on sibling certs, with properly-insulated cylinders (insulation type 1, 50/80mm - not the type-0/NULL zero-storage-loss bug). No fabric anomaly; the register data fully explains the engine output. Pinned to observed engine 71 / 79. Co-Authored-By: Claude Opus 4.8 --- .../uprn_100051051866/epc.json | 351 +++++++++++++ .../uprn_10070056075/epc.json | 491 ++++++++++++++++++ .../test_real_cert_sap_accuracy.py | 31 ++ 3 files changed, 873 insertions(+) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100051051866/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10070056075/epc.json diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100051051866/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100051051866/epc.json new file mode 100644 index 000000000..4e226b29f --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100051051866/epc.json @@ -0,0 +1,351 @@ +{ + "uprn": 100051051866, + "roofs": [ + { + "description": "Pitched, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Cavity wall, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Suspended, limited insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "addendum": { + "addendum_numbers": [ + 15 + ] + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "S20 7NQ", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "SHEFFIELD", + "psv_count": 0, + "built_form": 1, + "created_at": "2026-05-18 17:37:45", + "door_count": 1, + "region_code": 11, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 2, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 4 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "Y", + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 1, + "main_heating_number": 1, + "main_heating_control": 2104, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 102, + "central_heating_pump_age": 0, + "main_heating_data_source": 2, + "main_heating_index_number": 18773 + } + ], + "immersion_heating_type": "NA", + "cylinder_insulation_type": 1, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 50 + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.6, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.2, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.6, + "quantity": "m" + }, + "window_height": { + "value": 1.6, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.6, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 0.5, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Detached bungalow", + "language_code": 1, + "pressure_test": 4, + "property_type": 1, + "address_line_1": "3 Pentland Gardens", + "address_line_2": "Waterthorpe", + "assessment_type": "RdSAP", + "completion_date": "2026-05-18", + "inspection_date": "2026-05-18", + "extensions_count": 0, + "measurement_type": 1, + "open_flues_count": 0, + "total_floor_area": 60, + "transaction_type": 1, + "conservatory_type": 2, + "heated_room_count": 4, + "other_flues_count": 0, + "registration_date": "2026-05-18", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 3, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 0, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 300, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.4, + "floor_insulation": 1, + "total_floor_area": 60, + "party_wall_length": 0, + "floor_construction": 2, + "heat_loss_perimeter": 32 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "I", + "party_wall_construction": "NA", + "wall_thickness_measured": "Y", + "roof_insulation_location": 4, + "roof_insulation_thickness": "NI" + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 4, + "heating_cost_current": { + "value": 701, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 2.3, + "energy_rating_average": 60, + "energy_rating_current": 70, + "lighting_cost_current": { + "value": 40, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer and room thermostat", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "blocked_chimneys_count": 0, + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 701, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 235, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "schema_version_current": "LIG-21.0", + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 238, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 82, + "environmental_impact_rating": 73 + } + ], + "co2_emissions_potential": 2.1, + "energy_rating_potential": 82, + "lighting_cost_potential": { + "value": 40, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0", + "hot_water_cost_potential": { + "value": 235, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2544.67, + "space_heating_existing_dwelling": 6292.1 + }, + "draughtproofed_door_count": 1, + "energy_consumption_current": 209, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "10.2.2.0", + "energy_consumption_potential": 185, + "environmental_impact_current": 70, + "cfl_fixed_lighting_bulbs_count": 0, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 73, + "led_fixed_lighting_bulbs_count": 8, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 38, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10070056075/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10070056075/epc.json new file mode 100644 index 000000000..cc408d73d --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10070056075/epc.json @@ -0,0 +1,491 @@ +{ + "uprn": 10070056075, + "roofs": [ + { + "description": "Pitched, insulated", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Cavity wall, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Suspended, insulated (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "addendum": { + "addendum_numbers": [ + 15 + ] + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "BD10 9UG", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BRADFORD", + "psv_count": 0, + "built_form": 1, + "created_at": "2026-05-15 10:22:34", + "door_count": 1, + "region_code": 11, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 4, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 4 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "Y", + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 1, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 19012 + } + ], + "immersion_heating_type": "NA", + "cylinder_insulation_type": 1, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 80 + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Detached house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "36 Longlands", + "address_line_2": "Idle", + "assessment_type": "RdSAP", + "completion_date": "2026-05-15", + "inspection_date": "2026-05-08", + "extensions_count": 0, + "measurement_type": 1, + "open_flues_count": 0, + "total_floor_area": 139, + "transaction_type": 5, + "conservatory_type": 1, + "heated_room_count": 8, + "other_flues_count": 0, + "registration_date": "2026-05-15", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 1, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 0, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 400, + "floor_heat_loss": 7, + "roof_construction": 8, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.3, + "floor_insulation": 1, + "total_floor_area": 69.6, + "party_wall_length": 0, + "floor_construction": 2, + "heat_loss_perimeter": 37.7 + }, + { + "floor": 1, + "room_height": 2.3, + "total_floor_area": 69.6, + "party_wall_length": 0, + "heat_loss_perimeter": 37.7 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "K", + "party_wall_construction": "NA", + "wall_thickness_measured": "N", + "roof_insulation_location": 7, + "wall_insulation_thickness": "NI", + "sloping_ceiling_insulation_thickness": "AB" + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 8, + "heating_cost_current": { + "value": 938, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 3.0, + "energy_rating_average": 60, + "energy_rating_current": 80, + "lighting_cost_current": { + "value": 89, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "blocked_chimneys_count": 0, + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 938, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 236, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "schema_version_current": "LIG-21.0", + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 308, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 87, + "environmental_impact_rating": 81 + } + ], + "co2_emissions_potential": 2.8, + "energy_rating_potential": 87, + "lighting_cost_potential": { + "value": 89, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0", + "hot_water_cost_potential": { + "value": 236, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2744.25, + "space_heating_existing_dwelling": 9473.16 + }, + "draughtproofed_door_count": 1, + "energy_consumption_current": 117, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "10.2.2.0", + "energy_consumption_potential": 106, + "environmental_impact_current": 79, + "cfl_fixed_lighting_bulbs_count": 0, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 81, + "led_fixed_lighting_bulbs_count": 18, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 21, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index 21af95ba8..7d810b0ee 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -885,6 +885,37 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-100061275133", sap_score=77, ), + # UPRN 100051051866 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # DETACHED BUNGALOW, band I, CAVITY wall as-built insulated, pitched + # insulated loft, SUSPENDED limited-insulation floor, mains-gas regular + # boiler + cylinder (size 2, insulation type 1, 50 mm — a properly + # insulated cylinder, so NOT the type-0/NULL zero-storage-loss bug), TFA 60. + # Lodged 70 / engine 71 (71.04). Reduced-field cavity fabric already + # Elmhurst-validated on sibling certs; the +1.04 is a cost-side residual + # (PE −13.6 kWh/m² under-count) with no fabric anomaly — walls 29.9, roof + # 15.6, floor 29.4, windows 15.6 W/K all register-explained. PINNED to the + # observed engine 71; the register data fully accounts for the engine output. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_100051051866", + cert_num="uprn-100051051866", + sap_score=71, + ), + # UPRN 10070056075 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # DETACHED HOUSE, band K, CAVITY wall as-built insulated, pitched insulated + # loft, SUSPENDED insulated floor, mains-gas regular boiler + cylinder + # (size 4, insulation type 1, 80 mm — properly insulated), dual meter, + # TFA 139. Lodged 80 / engine 79 (78.99). Cavity fabric already + # Elmhurst-validated on sibling certs; the −1.01 is a cost-side residual + # (PE +5.4 kWh/m² over-count) with no fabric anomaly — walls 50.0, roof + # 20.1, floor 16.7, windows 26.7 W/K all register-explained. PINNED to the + # observed engine 79; the register data fully accounts for the engine output. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_10070056075", + cert_num="uprn-10070056075", + sap_score=79, + ), ) From 6c47951d60cea9163639f07edbbc5da36e3fcb66 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 04:55:42 +0000 Subject: [PATCH 17/84] =?UTF-8?q?test(accuracy):=20pin=20code-195=20electr?= =?UTF-8?q?ic=20storage-boiler=20certs=20as=20spec-faithful=20(=C2=A712=20?= =?UTF-8?q?Rule=202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Electric-tariff cluster investigation. The 112-cert electric-main cohort is mixed-sign within every category/meter - no systematic tariff bias. Root cause of the biggest non-xfail divergences (10012334488 +13.2, 10091578598 +7.81): SAP code 195 = 'Electric water storage boiler' (Table 4a p.170), which SAP 10.2 §12 Rule 2 correctly bills mostly at the 7-hour off-peak rate. Both are pure cost gaps (PE/CO2 match lodged -> demand right); the lodged software over-billed the storage boilers at peak rate. The engine is SPEC-FAITHFUL - matching lodged would tune against §12/Table-4a. Pinned to the spec-faithful engine values. Adds scripts/corpus_1000/elec_cohort.py (electric-main cohort analyzer). Co-Authored-By: Claude Opus 4.8 --- .../uprn_10012334488/epc.json | 337 ++++++++++++++++++ .../uprn_10091578598/epc.json | 316 ++++++++++++++++ scripts/corpus_1000/elec_cohort.py | 61 ++++ scripts/corpus_1000/worklist.md | 4 +- .../test_real_cert_sap_accuracy.py | 34 ++ 5 files changed, 750 insertions(+), 2 deletions(-) create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10012334488/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10091578598/epc.json create mode 100644 scripts/corpus_1000/elec_cohort.py diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10012334488/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10012334488/epc.json new file mode 100644 index 000000000..59f78d7aa --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10012334488/epc.json @@ -0,0 +1,337 @@ +{ + "uprn": 10012334488, + "roofs": [ + { + "description": "(another dwelling above)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "walls": [ + { + "description": "System built, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "(another dwelling below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "SL4 3BP", + "hot_water": { + "description": "From main system, no cylinder thermostat", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 4 + }, + "post_town": "WINDSOR", + "built_form": "NR", + "created_at": "2026-05-14 18:33:57", + "door_count": 1, + "region_code": 17, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 0, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 29, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 29, + "heat_emitter_type": 2, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2110, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 195, + "central_heating_pump_age": 0, + "main_heating_data_source": 2 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and underfloor heating, electric", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 5 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Mid-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "Flat 12", + "address_line_2": "Alexandra Court 25a", + "address_line_3": "St. Leonards Road", + "assessment_type": "RdSAP", + "completion_date": "2026-05-14", + "inspection_date": "2026-05-14", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 2, + "top_storey": "N", + "storey_count": 4, + "flat_location": 3, + "heat_loss_corridor": 1 + }, + "total_floor_area": 62, + "transaction_type": 14, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 2, + "registration_date": "2026-05-14", + "sap_energy_source": { + "mains_gas": "N", + "meter_type": 1, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 1, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "extract_fans_count": 2, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 260, + "floor_heat_loss": 6, + "roof_construction": 3, + "wall_construction": 8, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.48, + "quantity": "metres" + }, + "total_floor_area": { + "value": 62, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 23.99, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 11.89, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "L", + "party_wall_construction": 1, + "wall_thickness_measured": "Y", + "roof_insulation_location": "ND", + "roof_insulation_thickness": "ND", + "wall_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 2, + "heating_cost_current": { + "value": 136, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 0.5, + "energy_rating_average": 60, + "energy_rating_current": 72, + "lighting_cost_current": { + "value": 51, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Time and temperature zone control", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 136, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 893, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 91, + "currency": "GBP" + }, + "indicative_cost": "\u00a3600 - \u00a31,500", + "improvement_type": "Y", + "improvement_details": { + "improvement_number": 49 + }, + "improvement_category": 5, + "energy_performance_rating": 74, + "environmental_impact_rating": 93 + } + ], + "co2_emissions_potential": 0.5, + "energy_rating_potential": 74, + "lighting_cost_potential": { + "value": 51, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 802, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2802.07, + "space_heating_existing_dwelling": 628.72 + }, + "draughtproofed_door_count": 1, + "energy_consumption_current": 92, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 85, + "environmental_impact_current": 93, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 93, + "led_fixed_lighting_bulbs_count": 23, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 9, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10091578598/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10091578598/epc.json new file mode 100644 index 000000000..04774b623 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10091578598/epc.json @@ -0,0 +1,316 @@ +{ + "uprn": 10091578598, + "roofs": [ + { + "description": "(another dwelling above)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "walls": [ + { + "description": "Cavity wall, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "(another dwelling below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 2, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Good lighting efficiency", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "RM1 3FB", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 5 + }, + "post_town": "ROMFORD", + "built_form": "NR", + "created_at": "2026-05-16 17:47:19", + "door_count": 1, + "region_code": 2, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 4, + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 29, + "cylinder_thermostat": "Y", + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 29, + "heat_emitter_type": 1, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 195, + "central_heating_pump_age": 0, + "main_heating_data_source": 2 + } + ], + "immersion_heating_type": "NA", + "cylinder_insulation_type": 1, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 50 + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 2, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.15, + "window_height": 1.65, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 2, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.15, + "window_height": 1.65, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 2, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.15, + "window_height": 1.65, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 2, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.15, + "window_height": 1.65, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and radiators, electric", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 5 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Mid-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "41 Verve Apartments", + "address_line_2": "5 Mercury Gardens", + "assessment_type": "RdSAP", + "completion_date": "2026-05-16", + "inspection_date": "2026-05-16", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 2, + "top_storey": "N", + "storey_count": 6, + "flat_location": 3, + "heat_loss_corridor": 2, + "unheated_corridor_length": 6 + }, + "total_floor_area": 60, + "transaction_type": 8, + "conservatory_type": 1, + "heated_room_count": 2, + "registration_date": "2026-05-16", + "sap_energy_source": { + "mains_gas": "N", + "meter_type": 4, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 300, + "floor_heat_loss": 6, + "roof_construction": 3, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.5, + "quantity": "metres" + }, + "total_floor_area": { + "value": 60, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 20, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 12, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "I", + "sap_alternative_wall_1": { + "wall_area": 15, + "sheltered_wall": "Y", + "wall_dry_lined": "N", + "wall_thickness": 300, + "wall_construction": 4, + "wall_insulation_type": 4, + "wall_thickness_measured": "Y", + "wall_insulation_thickness": "NI" + }, + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": "ND", + "roof_insulation_thickness": "ND", + "wall_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 2, + "heating_cost_current": { + "value": 202, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 0.6, + "energy_rating_average": 60, + "energy_rating_current": 71, + "lighting_cost_current": { + "value": 55, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 370, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 847, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 80, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 76, + "currency": "GBP" + }, + "indicative_cost": "\u00a3150 - \u00a3250", + "improvement_type": "D", + "improvement_details": { + "improvement_number": 10 + }, + "improvement_category": 5, + "energy_performance_rating": 79, + "environmental_impact_rating": 92 + } + ], + "co2_emissions_potential": 0.6, + "energy_rating_potential": 79, + "lighting_cost_potential": { + "value": 48, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 611, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2659.46, + "space_heating_existing_dwelling": 1061.64 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 102, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 102, + "environmental_impact_current": 92, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 92, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 10, + "low_energy_fixed_lighting_bulbs_count": 20, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/scripts/corpus_1000/elec_cohort.py b/scripts/corpus_1000/elec_cohort.py new file mode 100644 index 000000000..ad5fb44b1 --- /dev/null +++ b/scripts/corpus_1000/elec_cohort.py @@ -0,0 +1,61 @@ +"""Electric-main cohort analysis: for every corpus cert whose main heating is +electric, dump heating SAP code / tariff (meter_type) / lodged vs engine SAP / +cost-vs-demand signature. Used to steer a spec-grounded Table-12a tariff fix +without regressing in-band certs.""" +from __future__ import annotations +import json +from pathlib import Path +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +from domain.sap10_calculator.calculator import calculate_sap_from_inputs +from domain.sap10_calculator.rdsap.cert_to_inputs import ( + SAP_10_2_SPEC_PRICES, cert_to_demand_inputs, cert_to_inputs, _is_electric_main, + _first_main_heating, +) + +CORPUS = Path("backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl") + +def hcode(doc): + sh = doc.get("sap_heating") or {} + ds = sh.get("main_heating_details") or [{}] + return ds[0].get("main_heating_category"), ds[0].get("main_fuel_type") + +rows = [] +for line in CORPUS.read_text().splitlines(): + doc = json.loads(line) + try: + epc = EpcPropertyDataMapper.from_api_response(doc) + except Exception: + continue + main = _first_main_heating(epc) + if not _is_electric_main(main): + continue + try: + r = calculate_sap_from_inputs(cert_to_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + d = calculate_sap_from_inputs(cert_to_demand_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + except Exception as e: + continue + L = doc.get("energy_rating_current"); pe_l = doc.get("energy_consumption_current") + if L is None: continue + dsap = r.sap_score_continuous - L + dpe = (d.pe_per_m2 - pe_l) if (pe_l is not None and hasattr(d,'pe_per_m2')) else None + cat, fuel = hcode(doc) + mt = (doc.get("sap_energy_source") or {}).get("meter_type") + sh = doc.get("sap_heating") or {} + code = (sh.get("main_heating_details") or [{}])[0].get("main_heating_code") \ + or (sh.get("main_heating_details") or [{}])[0].get("main_heating_index_number") + rows.append((doc.get("uprn"), code, cat, mt, sh.get("water_heating_code"), + L, round(r.sap_score_continuous,1), round(dsap,2))) + +rows.sort(key=lambda x:-abs(x[7])) +print(f"electric-main certs: {len(rows)}") +print(f"{'uprn':14s} {'hcode':>6} {'cat':>4} {'mtr':>4} {'whc':>5} {'L':>3} {'E':>6} {'dSAP':>6}") +for r in rows: + print(f"{str(r[0]):14s} {str(r[1]):>6} {str(r[2]):>4} {str(r[3]):>4} {str(r[4]):>5} {r[5]:3d} {r[6]:6.1f} {r[7]:+6.2f}") +# summary by (hcode, meter) +from collections import defaultdict +agg = defaultdict(lambda:[0,0.0,0,0]) +for r in rows: + k=(r[1], r[3]); a=agg[k]; a[0]+=1; a[1]+=r[7]; a[2]+=(abs(r[7])>0.5); a[3]+=(abs(r[7])<=0.5) +print("\n=== by (hcode, meter): n, meanΔ, #div>0.5, #inband ===") +for k,a in sorted(agg.items(), key=lambda x:-abs(x[1][1])): + print(f" code {str(k[0]):>6} meter {str(k[1]):>4}: n={a[0]:3d} meanΔ={a[1]/a[0]:+6.2f} div={a[2]:3d} inband={a[3]:3d}") diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index 3cb6cbaf8..a7dcf8f62 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -13,7 +13,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [ ] `103001004` · L 50 / E 69.69 / Δ +19.69 <- needs Elmhurst arbitration: lodged hw £1054 vs ours £113 (single-immersion on-peak fraction + cylinder declared-loss 1.8 kWh/day vs Table-2-sized loss); register data can't decompose. Other 14 declared-loss certs match lodged; only sibling outlier is 100121325434 (C008). ### C003 · Σ|Δ| 13.2 · 1 certs · `h195/elec | system built | (another dwelling` -- [ ] `10012334488` · L 72 / E 85.20 / Δ +13.20 +- ⚠ `10012334488` · L 72 / E 85.20 / Δ +13.20 <- SPEC-FAITHFUL: SAP code 195 = electric water-storage boiler (Table 4a p.170); §12 Rule 2 bills space+water at 7-hr off-peak (5.5p). Pure cost gap (PE/CO2 match). Lodged over-billed a storage system at peak rate. Pinned engine 85 in test_real_cert_sap_accuracy. ### C004 · Σ|Δ| 13.1 · 1 certs · `hpcdb10326/gas | solid brick | pitched 75 | ext1,sec:room heaters` - [ ] `12109191` · L 58 / E 71.10 / Δ +13.10 @@ -34,7 +34,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [ ] `100022294004` · L 75 / E 83.13 / Δ +8.13 ### C009 · Σ|Δ| 7.8 · 1 certs · `h195/elec | cavity wall | (another dwelling` -- [ ] `10091578598` · L 71 / E 78.81 / Δ +7.81 <- electric-main off-peak tariff cohort: cost-only signature, storage/electric E7 high-rate-fraction split needs Elmhurst per-config arbitration (fixing blind regresses in-band storage certs) +- ⚠ `10091578598` · L 71 / E 78.81 / Δ +7.81 <- SPEC-FAITHFUL: code 195 electric water-storage boiler → §12 Rule 2 7-hr off-peak. Pure cost gap (PE/CO2 match). Same as 10012334488; lodged over-billed storage at peak. Pinned engine 79. ### C010 · Σ|Δ| 7.1 · 1 certs · `h408/elec | cavity wall | (another dwelling | whw941` - [ ] `200000322700` · L 58 / E 65.05 / Δ +7.05 <- electric storage cat7 E7 over-rate; see 74061136 diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index 7d810b0ee..e57859941 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -916,6 +916,40 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-10070056075", sap_score=79, ), + # UPRN 10012334488 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # mid-floor FLAT, mains-electric with SAP heating code 195 ("Electric water + # storage boiler", Table 4a PDF p.170) serving underfloor heating, on an + # off-peak (7-hour) meter, TFA 62. Lodged 72 / engine 85 (85.20). This is a + # PURE COST gap, NOT a fabric bug: PE (−1.4 kWh/m²) and CO2 (+0.01 t) both + # match lodged, so demand is right. Code 195 is a STORAGE boiler → SAP 10.2 + # §12 Rule 2 routes it to the 7-hour tariff and bills space+water heat mostly + # at the off-peak low rate (5.5 p/kWh) — the spec-faithful treatment. The + # lodged software billed it far higher (implying peak-rate billing of a + # storage system), the same lodged-outlier pattern as the §12/PSR xfail + # cohort. PINNED to the spec-faithful engine 85 — the engine follows SAP + # §12/Table-4a; matching lodged 72 would require billing a storage boiler at + # peak rate, against spec. (Not Elmhurst-verified: my RdSAP10 builds carry a + # combi/heating artifact that makes them unreliable on the E7 storage side.) + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_10012334488", + cert_num="uprn-10012334488", + sap_score=85, + ), + # UPRN 10091578598 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # FLAT, mains-electric SAP code 195 ("Electric water storage boiler"), + # off-peak meter, TFA 60. Lodged 71 / engine 79 (78.81). Same signature as + # 10012334488: PURE COST gap (PE +1.6, CO2 −0.04 both match lodged → demand + # right); code 195 is a §12-Rule-2 storage system billed at the 7-hour + # off-peak rate per spec. Lodged over-billed the storage boiler at a higher + # rate. PINNED to the spec-faithful engine 79 — matching lodged would tune + # against SAP §12/Table-4a. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_10091578598", + cert_num="uprn-10091578598", + sap_score=79, + ), ) From 4fba35acbd41143912c79d378592cc92ea8f914a Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 05:09:10 +0000 Subject: [PATCH 18/84] chore(corpus): demand-driven analyzer + confirm no generic fabric bug remains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added scripts/corpus_1000/demand_cohort.py (isolates fabric/demand-driven divergences from cost noise). Investigation conclusion: the demand-side tail is one-offs, not a cluster. 12109191 (+13.1) is a LODGED decimal error (365.67 m² floor, 10x its ground floor). 217060420 (-4.4) is spec-faithful (36.6 m2 lodged glazing at spec U). The only >=3 structural clusters among diverging certs are electric flats (already diagnosed spec-faithful). No generic fabric bug remains; gauge 77.7% is near its structural ceiling. Marked 12109191 unbuildable in ledger. Co-Authored-By: Claude Opus 4.8 --- scripts/corpus_1000/demand_cohort.py | 58 ++++++++++++++++++++++++++++ scripts/corpus_1000/worklist.md | 2 +- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 scripts/corpus_1000/demand_cohort.py diff --git a/scripts/corpus_1000/demand_cohort.py b/scripts/corpus_1000/demand_cohort.py new file mode 100644 index 000000000..cffa01e9e --- /dev/null +++ b/scripts/corpus_1000/demand_cohort.py @@ -0,0 +1,58 @@ +"""Demand-driven divergence analyzer. Flags corpus certs where the SAP miss is +driven by FABRIC/DEMAND (PE & CO2 move with SAP), not cost — the fixable class. +Tags nbp (building parts) and room-in-roof so multi-part / RR bugs surface.""" +from __future__ import annotations +import json +from pathlib import Path +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +from domain.sap10_calculator.calculator import calculate_sap_from_inputs +from domain.sap10_calculator.rdsap.cert_to_inputs import ( + SAP_10_2_SPEC_PRICES, cert_to_demand_inputs, cert_to_inputs) + +CORPUS = Path("backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl") + +def has_rr(doc): + for bp in doc.get("sap_building_parts") or []: + r = bp.get("room_in_roof") or bp.get("rooms_in_roof") + if r: return True + for r in doc.get("roofs") or []: + if "room in roof" in (r.get("description") or "").lower(): return True + return False + +rows = [] +for line in CORPUS.read_text().splitlines(): + doc = json.loads(line) + L = doc.get("energy_rating_current"); peL = doc.get("energy_consumption_current") + co2L = doc.get("co2_emissions_current") + if L is None: continue + try: + epc = EpcPropertyDataMapper.from_api_response(doc) + r = calculate_sap_from_inputs(cert_to_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + d = calculate_sap_from_inputs(cert_to_demand_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + except Exception: + continue + dsap = r.sap_score_continuous - L + if abs(dsap) < 0.5: continue + peE = getattr(d, "primary_energy_kwh_per_m2", None) + dpe = (peE - peL) if (peE is not None and peL is not None) else None + co2E = d.co2_kg_per_yr/1000 if d.co2_kg_per_yr is not None else None + dco2 = (co2E - co2L) if (co2E is not None and co2L is not None) else None + nbp = len(doc.get("sap_building_parts") or []) + rr = has_rr(doc) + # demand-driven: PE moves same direction as SAP-miss inverse (PE up -> SAP down) + # i.e. dpe and dsap have OPPOSITE signs, and |dpe| is material + demand = (dpe is not None and abs(dpe) >= 4 and (dpe > 0) == (dsap < 0)) + rows.append((doc.get("uprn"), L, round(r.sap_score_continuous,1), round(dsap,2), + round(dpe,1) if dpe is not None else None, + round(dco2,3) if dco2 is not None else None, nbp, rr, demand)) + +demand_rows = [r for r in rows if r[8]] +demand_rows.sort(key=lambda x:-abs(x[3])) +print(f"diverging certs: {len(rows)} | demand-driven: {len(demand_rows)}") +mp = [r for r in demand_rows if r[6] > 1] +rr = [r for r in demand_rows if r[7]] +print(f" demand+multipart(nbp>1): {len(mp)} | demand+RR: {len(rr)}") +print(f"\n=== top demand-driven divergences ===") +print(f"{'uprn':13s} {'L':>3} {'E':>5} {'dSAP':>6} {'dPE':>6} {'dCO2':>6} {'nbp':>3} {'RR':>3}") +for r in demand_rows[:32]: + print(f"{str(r[0]):13s} {r[1]:3d} {r[2]:5.1f} {r[3]:+6.2f} {str(r[4]):>6} {str(r[5]):>6} {r[6]:3d} {'Y' if r[7] else '':>3}") diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index a7dcf8f62..758365356 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -16,7 +16,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - ⚠ `10012334488` · L 72 / E 85.20 / Δ +13.20 <- SPEC-FAITHFUL: SAP code 195 = electric water-storage boiler (Table 4a p.170); §12 Rule 2 bills space+water at 7-hr off-peak (5.5p). Pure cost gap (PE/CO2 match). Lodged over-billed a storage system at peak rate. Pinned engine 85 in test_real_cert_sap_accuracy. ### C004 · Σ|Δ| 13.1 · 1 certs · `hpcdb10326/gas | solid brick | pitched 75 | ext1,sec:room heaters` -- [ ] `12109191` · L 58 / E 71.10 / Δ +13.10 +- ⛔ `12109191` · L 58 / E 71.10 / Δ +13.10 <- LODGED DATA ERROR: BP0 floor-1 area 365.67 m² (10× its 36.77 ground floor; TFA 407 for a 4-habitable mid-terrace) — a decimal misplacement. Engine faithfully computes the near-wall-less huge floor → low HTC/m² → over-rate. Garbage-in, not an engine bug. ### C005 · Σ|Δ| 10.3 · 4 certs · `h691/elec | cavity wall | (another dwelling | whw909` - ⚠ `line279` · L 81 / E 78.44 / Δ -2.56 <- same as 10093237426 From 58125503f0acd5663a194b738f5b7f28c33c6461 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 05:19:20 +0000 Subject: [PATCH 19/84] =?UTF-8?q?chore(corpus):=20why=5Fdiverge.py=20?= =?UTF-8?q?=E2=80=94=20categorize=20all=20223=20diverging=20certs=20by=20r?= =?UTF-8?q?eason?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- scripts/corpus_1000/why_diverge.py | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 scripts/corpus_1000/why_diverge.py diff --git a/scripts/corpus_1000/why_diverge.py b/scripts/corpus_1000/why_diverge.py new file mode 100644 index 000000000..cf2aef86b --- /dev/null +++ b/scripts/corpus_1000/why_diverge.py @@ -0,0 +1,76 @@ +"""Categorize every corpus cert outside +-0.5 SAP by the REASON it diverges, +combining the computed cost-vs-demand signature, the electric heating code / +meter, and the ledger's RR/multipart tokens.""" +from __future__ import annotations +import json, re +from pathlib import Path +from collections import defaultdict +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +from domain.sap10_calculator.calculator import calculate_sap_from_inputs +from domain.sap10_calculator.rdsap.cert_to_inputs import ( + SAP_10_2_SPEC_PRICES, cert_to_demand_inputs, cert_to_inputs, _is_electric_main, + _first_main_heating) + +CORPUS = Path("backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl") +# ledger signatures (for RR / multipart tokens) +sig_of={}; cur="" +for l in Path("scripts/corpus_1000/worklist.md").read_text().splitlines(): + if l.startswith('### C'): + m=re.search(r'`([^`]*)`',l); cur=m.group(1) if m else "" + m=re.match(r'^- .*?`([^`]+)`',l) + if m: sig_of[m.group(1)]=cur + +def bucket(doc, dsap, dpe, dco2, code, mt, sig): + rr = 'RR' in (sig or '') + elec = code in range(191,600) if code else False + demand = dpe is not None and abs(dpe) >= 4 and (dpe>0)==(dsap<0) + cost = dpe is not None and abs(dpe) < 4 + # 1. electric storage-boiler / CPSU on off-peak (spec §12 Rule 2/1) + if code in (192,193,194,195,196) and dsap>0: + return "elec storage/CPSU boiler → §12 off-peak (spec-faithful; lodged over-billed)" + # 2. electric direct + storage heaters, tariff/cost + if elec and cost: + return "electric tariff/cost (meter-column & high-rate fraction; spec-faithful vs lodged)" + if elec and demand: + return "electric + fabric/demand mismatch" + if elec: + return "electric other" + # 3. RR + if rr: + return "room-in-roof surface geometry (spec-mandated, worksheet-validated; high variance)" + # 4. non-elec demand/fabric + if demand: + return "non-electric fabric/demand (per-cert: glazing area, lodged geometry, mixed walls)" + if cost: + return "non-electric cost (secondary fuel / cylinder / tariff)" + return "unclassified" + +cnt=defaultdict(list) +band=defaultdict(int) +for line in CORPUS.read_text().splitlines(): + doc=json.loads(line); L=doc.get('energy_rating_current') + if L is None: continue + try: + epc=EpcPropertyDataMapper.from_api_response(doc) + r=calculate_sap_from_inputs(cert_to_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + d=calculate_sap_from_inputs(cert_to_demand_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + except Exception: continue + dsap=r.sap_score_continuous-L + if abs(dsap)<0.5: continue + peL=doc.get('energy_consumption_current'); co2L=doc.get('co2_emissions_current') + dpe=(d.primary_energy_kwh_per_m2-peL) if peL is not None else None + dco2=(d.co2_kg_per_yr/1000-co2L) if co2L is not None else None + sh=doc.get('sap_heating') or {}; det=(sh.get('main_heating_details') or [{}])[0] + code=det.get('sap_main_heating_code'); mt=(doc.get('sap_energy_source') or {}).get('meter_type') + b=bucket(doc,dsap,dpe,dco2,code,mt,sig_of.get(str(doc.get('uprn')),'')) + cnt[b].append((doc.get('uprn'),L,round(r.sap_score_continuous,1),round(dsap,1))) + ad=abs(dsap); band['0.5-1' if ad<1 else '1-2' if ad<2 else '2-4' if ad<4 else '4+']+=1 + +total=sum(len(v) for v in cnt.values()) +print(f"TOTAL diverging (|Δ|≥0.5): {total}\n") +print("by |Δ| band:", dict(band), "\n") +print("=== by REASON (count, mean|Δ|, examples) ===") +for b,rows in sorted(cnt.items(), key=lambda x:-len(x[1])): + mabs=sum(abs(x[3]) for x in rows)/len(rows) + ex=", ".join(f"{x[0]}({x[3]:+.1f})" for x in sorted(rows,key=lambda x:-abs(x[3]))[:3]) + print(f"\n[{len(rows):3d}] mean|Δ|={mabs:.1f} {b}\n e.g. {ex}") From a593921a8346c780f33ddf161cc973a6eb5a5951 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 05:54:47 +0000 Subject: [PATCH 20/84] fix(rdsap): thin present wall-insulation no longer maps to uninsulated bucket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Field-level bias scan (scripts/corpus_1000/field_bias.py) flagged solid-brick + internal-insulation certs (wall_con+ins=(3,3)) systematically under-rating (median -0.40, n=18). Root cause: _insulation_bucket routed insulation that is KNOWN PRESENT but with a thin lodged thickness (5-24mm, below the smallest tabulated 50mm column) to bucket 0 (uninsulated, U 1.7) - WORSE than the present-but-unknown case, which the RdSAP Table 6 footnote correctly routes to the 50mm row. A known 10mm shouldn't read as higher-U than not knowing at all. Now present insulation never falls to bucket 0; thin/unknown thickness both round up to the 50mm row. Only genuinely absent insulation maps to 0. Corpus cert 5117280 (10mm internal, no wall thickness -> bucket path): Δ -4.44 -> +1.08. Corpus MAE 0.641 -> 0.637, PE MAE 3.0 -> 2.9. Gauge 77.7% holds; 44 RealCert pins + 342 fabric tests green. TDD: 2 new unit tests. Co-Authored-By: Claude Opus 4.8 --- domain/sap10_ml/rdsap_uvalues.py | 8 +++- domain/sap10_ml/tests/test_rdsap_uvalues.py | 38 +++++++++++++++++ scripts/corpus_1000/field_bias.py | 46 +++++++++++++++++++++ scripts/corpus_1000/worklist.md | 2 +- 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 scripts/corpus_1000/field_bias.py diff --git a/domain/sap10_ml/rdsap_uvalues.py b/domain/sap10_ml/rdsap_uvalues.py index 0d2246394..be1ab2f62 100644 --- a/domain/sap10_ml/rdsap_uvalues.py +++ b/domain/sap10_ml/rdsap_uvalues.py @@ -353,7 +353,13 @@ def _insulation_bucket(thickness_mm: Optional[int], insulation_present: bool) -> to the 50 mm bucket when `insulation_present=True`; when not present, the as-built (bucket 0) row applies regardless. """ - if insulation_present and (thickness_mm is None or thickness_mm == 0): + # Insulation known to be present must never fall to the uninsulated + # (bucket 0) row. RdSAP 10 Table 6 footnote routes present-but-unknown + # thickness to the 50 mm row; a KNOWN thin lodgement (5-24 mm, below the + # smallest tabulated 50 mm column) must not read as WORSE (higher U) than + # the unknown case — so it too rounds up to the 50 mm row rather than to + # bucket 0. Only genuinely absent insulation (present=False) maps to 0. + if insulation_present and (thickness_mm is None or thickness_mm < 25): return 50 if thickness_mm is None: return 0 diff --git a/domain/sap10_ml/tests/test_rdsap_uvalues.py b/domain/sap10_ml/tests/test_rdsap_uvalues.py index f7067759c..95993be78 100644 --- a/domain/sap10_ml/tests/test_rdsap_uvalues.py +++ b/domain/sap10_ml/tests/test_rdsap_uvalues.py @@ -31,6 +31,7 @@ from domain.sap10_ml.rdsap_uvalues import ( WALL_STONE_SANDSTONE, WALL_SYSTEM_BUILT, WALL_TIMBER_FRAME, + _insulation_bucket, thermal_bridging_y, u_door, u_exposed_floor, @@ -114,6 +115,43 @@ def test_u_wall_solid_brick_with_ni_thickness_uses_50mm_row_per_table6_footnote( assert result == pytest.approx(0.55, abs=0.001) +def test_u_wall_solid_brick_present_insulation_thin_known_thickness_not_uninsulated() -> None: + # Arrange — a solid-brick wall lodging internal insulation (type 3) + # with a KNOWN thin thickness (10 mm) but no documentary wall + # thickness (so the §5.8 formula branch, which needs wall_thickness, + # cannot fire) falls to the Table-6 bucket. A known 10 mm value sits + # below the smallest tabulated 50 mm column, but insulation IS present + # — it must NOT read as WORSE (higher U) than the present-but-unknown + # case, which the footnote routes to the 50 mm row. Pre-fix, + # `_insulation_bucket(10, present=True)` returned 0 (uninsulated, + # U=1.7), under-crediting the wall (corpus cert 5117280: Δ −4.44). + + # Act + result = u_wall( + country=Country.ENG, + age_band="B", + construction=WALL_SOLID_BRICK, + insulation_thickness_mm=10, + insulation_present=True, + wall_insulation_type=3, + ) + + # Assert — present insulation → 50 mm row (U=0.55), never uninsulated 1.7. + assert result == pytest.approx(0.55, abs=0.001) + + +def test_insulation_bucket_present_thin_thickness_rounds_up_to_50_not_zero() -> None: + # Direct guard on the bucket: present insulation never maps to bucket 0. + assert _insulation_bucket(10, True) == 50 + assert _insulation_bucket(24, True) == 50 + assert _insulation_bucket(None, True) == 50 + assert _insulation_bucket(50, True) == 50 + assert _insulation_bucket(100, True) == 100 + # Genuinely absent insulation still routes thin/zero to bucket 0. + assert _insulation_bucket(10, False) == 0 + assert _insulation_bucket(None, False) == 0 + + def test_u_wall_cavity_as_built_insulated_assumed_routes_to_as_built_row() -> None: # Arrange — a cavity lodged "Cavity wall, as built, insulated (assumed)" # with wall_insulation_type=4 is in its AS-BUILT state, NOT a retrofit diff --git a/scripts/corpus_1000/field_bias.py b/scripts/corpus_1000/field_bias.py new file mode 100644 index 000000000..8331780f7 --- /dev/null +++ b/scripts/corpus_1000/field_bias.py @@ -0,0 +1,46 @@ +"""Field-level systematic-bias scan: mean Δ(SAP) grouped by each mapped +attribute. A subgroup with large |meanΔ| AND enough n is a systematic mapping +error for that attribute (would cancel in the overall ~0 bias).""" +from __future__ import annotations +import json, statistics +from collections import defaultdict +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +from domain.sap10_calculator.calculator import calculate_sap_from_inputs +from domain.sap10_calculator.rdsap.cert_to_inputs import SAP_10_2_SPEC_PRICES, cert_to_inputs +CORPUS="backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl" +G=defaultdict(lambda: defaultdict(list)) +def gv(x): return x.get('value') if isinstance(x,dict) else x +for line in open(CORPUS): + d=json.loads(line); L=d.get('energy_rating_current') + if L is None: continue + try: + epc=EpcPropertyDataMapper.from_api_response(d) + r=calculate_sap_from_inputs(cert_to_inputs(epc,prices=SAP_10_2_SPEC_PRICES)) + except Exception: continue + dsap=r.sap_score_continuous-L + bp=(d.get('sap_building_parts') or [{}])[0] + sh=d.get('sap_heating') or {}; md=(sh.get('main_heating_details') or [{}])[0] + G['wall_con'][bp.get('wall_construction')].append(dsap) + G['wall_ins'][bp.get('wall_insulation_type')].append(dsap) + G['wall_con+ins'][(bp.get('wall_construction'),bp.get('wall_insulation_type'))].append(dsap) + G['roof_con'][bp.get('roof_construction')].append(dsap) + G['floor_hl'][bp.get('floor_heat_loss')].append(dsap) + G['age'][bp.get('construction_age_band')].append(dsap) + G['main_cat'][md.get('main_heating_category')].append(dsap) + G['whc'][sh.get('water_heating_code')].append(dsap) + G['meter'][(d.get('sap_energy_source') or {}).get('meter_type')].append(dsap) + G['country'][d.get('country_code')].append(dsap) + G['dwelling'][d.get('dwelling_type')].append(dsap) + G['nbp'][len(d.get('sap_building_parts') or [])].append(dsap) + G['glz'][tuple(sorted(set(w.get('glazing_type') for w in (d.get('sap_windows') or []))))[:1]].append(dsap) +print("=== subgroups with |meanΔ| >= 0.5 and n >= 8 (systematic-bias candidates) ===") +hits=[] +for field, groups in G.items(): + for key, vals in groups.items(): + if len(vals) >= 8: + m=statistics.mean(vals) + if abs(m) >= 0.5: + hits.append((abs(m), field, key, len(vals), m, statistics.median(vals))) +for am,field,key,n,m,med in sorted(hits, reverse=True): + print(f" {field:12s} = {str(key):20s} n={n:4d} meanΔ={m:+.2f} medianΔ={med:+.2f}") +if not hits: print(" (none — no systematic subgroup bias)") diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index 758365356..4941bcc1f 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -73,7 +73,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [ ] `10093342182` · L 82 / E 77.51 / Δ -4.49 ### C022 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` -- [ ] `5117280` · L 76 / E 71.56 / Δ -4.44 +- [ ] `5117280` · L 76 / E 71.56 / Δ -4.44 <- 🔧 thin-internal-insulation bucket-0 fix: present insulation + known <25mm thickness was mapped to uninsulated (U 1.7); now routes to 50mm row like unknown-thickness. Δ-4.44 -> +1.08. ### C023 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` - [ ] `217060420` · L 42 / E 37.58 / Δ -4.42 From 61934af97b12c33c7b2b533740ea790373b7ca66 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 06:13:09 +0000 Subject: [PATCH 21/84] chore(hyde): fix 100061275133 Elmhurst build faithfulness (lighting 5 LED, wall thickness 400) Input reconciliation (Elmhurst summary vs EpcPropertyData vs raw cert) exposed two Playwright-entry errors: lighting entered as 6 incandescent (cert has 5 LED, 100% low-energy) and wall thickness left at Elmhurst's 260mm default (cert lodges 400mm). Fixing both moved Elmhurst 67->69. Confirmed the MAPPER is faithful (every fabric/heating/lighting field matches the raw cert) and the engine uses the correct PCDB 18908 efficiency (88.7%). The remaining Elmhurst gap to lodged 76 is the un-enterable PCDB boiler (automation falls back to generic BGW 84% + keep-hot); the engine (77) is faithful. Not a mapping error. Co-Authored-By: Claude Opus 4.8 --- .../uprn_100061275133/elmhurst_summary.pdf | Bin 79070 -> 79069 bytes .../uprn_100061275133/elmhurst_worksheet.pdf | Bin 44121 -> 44098 bytes scripts/hyde/build_100061275133.py | 10 ++++++++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf index 7e17907d954d755eb7f43d62abfdeb2cbf634bf8..fe9d91f0f7aed371068601896182c64ece79c715 100644 GIT binary patch delta 4035 zcmZXTbyO3M;>8(^8cIq?4Ww(}fYE{o0&_@7hk{H&1P9VX2aEv{Qo`u&mXPj{l$0JN zAYBsD@ArG}k9W@d-oNg-=X~z{>&|Zg2^&D)D!^?_I$tETx+?+91HTl3$L+%m$?eNW zgnTndtZCHN+qk40;TT1<@--SIH!mbu;Ud~3{^qlal zfhuD~Y}ZJvn(ZzzK_CVPHE_x5bIC~SZ4wr+hbA4nyx+v!r+aMP-mR5zQpB}Fy&isW zF35*e5Ojk(6|G`-Ybw8tI4ItJR6D2-x`&BiK^3*~24%z7aX=9`7CA z0Gs3jYbx2J_h(gedJnV5)$7{cktQgKL~IiJ{lHS(bHzE>5$i`^%X8$*ZV8%2k9=3K z;fkxMODe#WQ;hC$LOR#tDLnCbm6ZG=7WX!HO?d(9m5&;9`z{H0NO>duebC0KrB%>{ z`P0J1z35IQP(kTHC4w1(k0mSfL3w@nLRAi|eXt8rY5hUEyOKiwO?tfvm_kmwZ$N6l zEUGoeGw^xw1}ePL%$2e17AfU$;U6#(9^}um`T-N8Y;RE7gM%1GGhMjtD6*>w#_H_c zzR3u0a(Fub0rzSgC%GN1nS`~7*-vDmv(MoO5C1m0a>>69*StA_@2%TD zm>3Yc<%`084XXVe8cKi(oZ0Ft@y+nXoaOsQg!h4@zZ$ULElXvej`C$ga=I1dW$PBW zbK#xwu+qw9t;sp&Lf2p2p1WzIi(d?O8)!A?lYBBm{ShgqbnzhutY#CfIO%PDOwXCB z4ksmI5J(2kyzxVs%TUxk$?i>mLLtnf>o<2tzzY-f8Q|r1J?eVa9DRanJjgeG#2zJ+rUq!%06423v6JGRwAnpt6 zU)l~FH>>T*u#9wei#{)R4ta)}Q88AJCTN=Fhu+}RWr`Zb~`6*x1T3quFxFa;S9tHPGHdJ`rv+z)} zHj)z?`10yS%v#-s29!pAI~Wxl;d^l0aix)EC{9~{i&8ELwT2GsYbCz1Fk`thBEkEs zeHXWC%7JpNv>DmE-uwW>+CYFvbAgJCVVW?QcLs^&hHdjY=0ke>*9qM+`LPgRNO1hOscIsVgZrl zV>x9kwY#_se&VpEH5Ul)zH&GoQ;aNV>=p@Rf?M?-@qB3edw*e`Y7ma6n z|4w%WAjOU9i9%lsaZm=u7rk_io#@s7F>-3mXct`kc@rZQ^Ye7_oo+I(e4PUhTAk0) zxTLpFe0TgoLQlkc7QDzCJs$%U+D z@%_0|Z(ZxXh5wGNN_pa=>EMu>fl2J<2>OQa4gSp2(Ih`iwclyFl zGcXg4JT~S16Te<#8C-oY^m8lnmC({O)_KkxEh+iAh+^}dM>4JCTP}{4v}qSsoj@7m z)$;v!zFgCes4vCMYXMsSu`;paAtWuxf8SXxI6FdUn3M>uH%(BZjUiTlm^%B z>hC*fbR6-$)m9aBmBRQ*WN#^KmaRAGPjh>O+g;^Lx)vxB+S^DARC=L>49D$-U)wZoTzn~@xgQQX|nvzT z@WfZic8^ZJz{I#Z6>$a(pDoTRArHAn?m_1M-bQ!go-fb`U3xeh=A6exJxj%j($J|W(4NoX~OvvXk`p;H98taJRXGV}cIPdl;{Lu@-X3orl3!6XJ`rhzByrVW0p_3-UD+nNlvMLPn~eO zJ5^2+!D(gJHAIbnX;P496+#c`j2wdbchYu*^A%)QmuSz0-|4dmE&alG-NTV=)N48j z#>m*|XGOd*eYT!mAUJw5RAKDwbwL(B`{Wqg{JxEbUSdY2Iv|F@#Xx!a(zzn!8dGzR z{%;KrFJO-nAXCEt0gM4KoTx-08|4alwu`JM!Xkcx-kCj$TLcHVymwuG^&JbqQ$D+b zz~p7(C0%O3n>?wKT>O&RJIuTjuaKZ3sJlRsTwNHn6?oXYsP{_gqiMAFBQXat1d_BQ zwr+;j&2yTewb;_-Co~10k|%L#CU=w8fKb-|yfQ}HDMiQmvn z1{M54WBxsDnlF#beuRK+G^R5&PjI*35~>ALGKf6*h*+gzhMzeF*H=-sAo8poC<3p{Z0M>Gu_2spK_QqRJ^vQjad@qyxJxk|5u%y1;rZ z6ZZswpY+J%(NSy)grv^J3@4#{ZWFQ>W>TJ`pD)mT3dc0t2>(`a@F(rRE=J>a=h98C)e8CafdGr@CkD|KmR2j+Jc4(x(hGW89tLsE++@ zr0hJ{SbNUTfs&euIEW`hfrH)Kd3$(iL9n9}*Y{~T<89;ek3+%ZDcw`zx6j9K@>Dl( zTK$cYJh6I#>X;BS_cC_Unqr%^rMa=&9gLrpG0)3PpDw*0l=3`~6P3Oc?lWs^Y{M(6 zN2K##%LmPNkB@^2o;0S{ekaP0)&kW~iTmw)&oloK|71WCQ3Hhn2mlO>OXB~<<-`U0 zw~>L$Nyz+DVNe~~O Iy3XT&0Y>|ug#Z8m delta 4039 zcmZXNXEfW5!-j@7A85G0_a1FeWJ?3n9zThTUEF-Sa zNyYWCM1!bkZSV4I8dwP9O?>p6ialPzim|V0WeP zKJb0w_3OB7zg!#T;V`6eg{pmHH2M7TyG^MAd*napzjwNoluWlae#z(6H!uBS<_t|Yjv|0dp$Iv`UQ}EmIYPT5$pXl*u>=;Qtt8?Goqw29O;98GPT5o1 zx|a7o9dka(yYUpC^3uY18jg;LeVUu$)r2LZFen0m2i?Z)l<~}@38Hcs{Cz$zT3^30 zbkcgmOB4`U_DX{X#g-zwoYV9v7`PR|5yQ0ymhLV*eYk)P`v5My00Bf(7NY^@&ZuZx z)n)>A#a32x8?rrL+m5tAIw~xBO7k$NZ zF(^Rgrpz&8!z=XVI)m892(6T}w@>fY<)tAD>ALh<692;m!505E9R~biQjl?`#C;h%Wl!fgTI8X=fLk zcwrYP|Gex|X%yCY@59WM)exxMy|eg4F9bMg7tD>RO55m0%Z?8HZE0kQdzCWOe;9rz zGP^7xeAKQYw%1d($Thjaw!+m`fWXJS@?Oh)0AiVFD(-?x;dhJ$6WQBLvfcFhIBW@J zAC6uk97gBknWCBn1Edi#S_*=1F?$DQ*v})SnPdHmF-)6PtsaweSDyK$xqZDBd4Se% zCONkw=fUvu-zrup{*~)EMR8&6L#WkPPWB&jkzB9e$| zo#n@TQ*}2KKoV=Lcu_p@)e@Sl4bigCyZQ^Mvh;=#Q_%oVU;NhNWIGb5j^k4~FtUj) z`{P5gFSt#@2l-2B9qX{$A04bHUjU4f_pB|P&Jt&*pM0FlqdJk4$)<~5x|Ap0>Iu22 z(SE~-3$Rph;pql~#$pxt)CzkI90K4bk&xfxdu`L4QoV_*Cxgk%_nRj!CeXH8$Q%Z8 z_sn|xby?weTBCvaj~-)UwpaOLQ8JtP;Gi)@9i9Cgp>^s>?geL|}$Ntb~3I<&- z1-))6n(bC6a}KSa$=v9R(FEuX2SVf75tDt39IQ_Y#^d{h?^ZpW{LakDRhQ${@iB>! zzBgX?#56Q4Y3FZ((G{#9xEXtv&>vaA6dl2|qJ_tSX5@W{HcGf)hWWQ^hWmKt6rBYsQ9ve(krpIcH@`9Z<4TYEU~^c~)^Kw@+tgOjCmE z<>lj3=ip<244KiF^!NPrsVn1Q-UEWgE7zYR1gHJrN#Wd4Mgc4rlRZ0DeoTefrzni# zBri;obzQ{dHS&Rz-{17!2xXmz5pIzcI(4%qLB?D^a~d!kO#Ja5AB%em66Hb`9XgkY zaE^c8?Dp|FM)GiSZEd4Ilsn7Z#P8*rykL1#HyelsE`w`JbY0Quia7q8BuG2u{XY%Q z<)1_2S*TG_*9LY8x2&H=w(7#d`~ywMeM7mm`cIS2rhNBIVV9=Fk7$Gb%4ZgdNCJaX zkhbHu5BN_UMTa$aJch)*Jrt~4`^k$s-sAl;n|A;M^qtb6O##BtOW{n8lf6pCkvm=? z>>?zcg9}8}^oR*$f)A9uU8g0I-&2}%Ia;qwJZyCgS;jx>A#;U32`eOdwqLN`cJYd%)3gr zgtj46N*?lpEp!n^eMK3Fwl_S|aS0V!DsDZ5PUgTnuXa?bn5q#h84gTYZ-h8; zTS?h!tFc&cGDM;J+Efyr%RX8;DBO6JX>$;3FS*12o_&3j?i@mnhp~2TV?#ITs?rM>Q+iOSzDp9+t=?w|r*5p`*Pv5w(zwE;jVKYD6 z#Du5SY+U%R<~$CoyJL5YZ>cfoJ^gaRzqt0v;lqh*z1KVXzAa&)B>HcYY;bfZ6SovJ zWX{dvYcXMRGIVT%7;HEQrovAK27ITd3Y)9fFD43}@eZO1-_hFJ1457paTF%;N7?gl zis*xise(iXT$y;Ck=@TI%Y{Mek;|ijPG&>l{E3%HyW?efQGr$;70$adSe+JkQ|E1V ziukDXMEE|Rv#C;~FQk-*>C?$;^AME+gjw@3<3%J%M>{v!)zMlx@`$?yAPSN~^@JOY zfEH4NGJ`T&qbej1mLo}@puV)xeKaaXR`}M^v)Aj;on!F-@*h zL*I!gkd5RGm=P8@3zGvt!(7VE^f@7ZJTtGX((HSx#{5xgcxTIuW<$rOBnm_ASLQ&o z(qE%g^Uc42d-VeBZ8d8bB_f&8MX88l=UYZOH{Ux~ZX{PkT;hv4)@Dw%M%#0_vTuf~ zd3mna8PL#qoZSZO-{Nd>veTms8;Z+Ma(8V!NalfDB`P&9*F8Y#UDsf4X)Jc_vz**B z@}0_r%~->FQ`?>-YO%NrcqszkU!da4rhvmBsa03|NtfIZ5#wgv418U=F6MHYURn7k zIP~|`9zfC=eK&5BCY(h@W7!aHH+j2I9nunNz(SV);e;nFkxDVhL_l9Up*p%g9PS&+ zBXRvc4H1UI@$)+03HU?Pn_R}5KcgS-$kF{_0~L~@HKk?PrOr9WSYZ`AcSIp~R3}aB zT%e=-Aju|5AOX2Re1 z4Cmt69wb$y?Y8ZE%I6pB?H!Cxjtix-zdezC^?k|boZ zsa45nA65WwkbfxThR6`L!q&PWl*rz8OIgEz(vatUp7}Y1Mg?8q&hX?8x3>ECz7yrU zYs8fuF4s{Zd4zG5)Woa|!ilU${n2;VJ`C#zoQr8H(XYECEM=UYYJb9s&~ki@3lpAa z8;=dJmdN1+IOoPfTOa3J{LVN>KMgl=4L;YXm&9d)Q%#=(zWI)Fl|lHk%RPOx7a^QZ zv3XxlG$v z**;e_vZ?*-cN58PWJBFlsTCnC(Y{DNNNHg7E-u*EiZ52Uwr^LV`ghtVj+pI&q)6~oQ!&~SqZVGN!X!P%hXxsQ1 z%ftnAuTQ6H{Wp1=ZJ=W0+qoF}YK=cvH-4k;kavzHUD01H%T|r_W+7Xo?Hhc4_au(z zWR@gLN}g$$uMzetfR$3U^qb9n?qlap+cN-=q8UiHNfZuR1_9D+BL5vW3>)NsiWFQ% zRP_IE;?g1#|Jr0E|HVp*OaF_NlobCLD*aE`X0=g{rbTqo6n7tHT>*p4r=Wv6T|A5IdPqqK4tb#2Cr(LRRC zz%><08I<7~3C`?Fc zsEh?~N>*24$wtNwRJuEcHmd>`E(JAO9l*SF^}N`qgpaf08LSk8UKp~_6n|`sx7j#- z${~Ip-6*yvErg^%zNiG6HTRfD)$uCL>cf!X6jX5t%n)w3TNkd{i1zImmw`E5v6xEO zsHU=>%x#`dz+~>gNYZSp#}Xbm8KXur(WOgrGEW!zp&m%ssv{FoCFB}!2!!Qe0uIDW z63V&uc%5h;8_c7+>GF`eAb%%WQNgoeTDnkN4r$YP+38Ri@u!U^GE~Qr?DUsmGxU?K{JvH{gD0tgQn(=+g>OjSzJGuRE_US$_LoR% zngEe%IyJxwUgeipz}z8;U~GeUKAVB7PF{dI+NGVO^-D`411DuPQcb%Sp)bx(iSOI( z&J0x&XTD)zFeilN=}1JBMNQxK#z95|@{3)+8O(D5s;~Psdh9^e^O$OBJSdcnle$cC z)sV!>bT-?RImXs)Nq?^4)f;EO1)_5bLB^x|N)f#ZcXzMS2!mr0O@xa6mZ}7yNt4is zCq0we(CPNzfx47NP{w%=h;iv)4;)odktZA0Ba(@tnngVau`p1jzW!$?33{Gk;K%q@kLQVeMqpMKOWr$YFimWek$3IfU)I@xZYIAY~sm$}V;YQ;+cwYpk5UbaH&K2y-F6Haq zAP~FeuIcDOUI=su;I&+=yNSM^=h2R~V~k*so538g#Sq4=B}-^5*f#W;rwQ9uHL}wb zO)XF-Oi;;XyxzLv8MrVgrnJ}u>S3E>hwvi@VH7n?zkd$goju5~TqqJlBV*zXr+Q4u zW8*?TdILR}jEGoMov36l4T@b``vFKO9pl79 z-Y$x7u8WO(2U1^t;7CwtNt2i-4G~)`RylHkPTHRnRK*lXOCzY86u29QAp_x{j8^MH z{Z$IENq=U#=j6ub4ytzF!@yQ8I$en#0^HiWcc7n$D56?1^S3Ekn=pnhWI{zGd%%rc zygfp>h>)BnQhUIAT-ZUChpSyE8VS?OcaYZLK=W>A3S2oi6iTsmvlG(%!C@FD!xA$4 z!nVN}S5x^iA#f&v_a1t34iTu)%$I75^93eO!GAOr0VV))2jOvJ@P5NO>SWVazPA6> zj$Q|0rpgVTME5LeT+}ur`3lchuylB|^}NFDwrpD;VXa}FXuRyuryq!mjjSgxP`yq2 zBorJbc*1DgE4rOyE%w^wjtz(JPHucMfjk0FM?OU_n_>w(C3xY%LylcpqKhAn zF<;6@8&o~nC1sC!+*t;3NJZ`ChOV^nDWGCj-0?g~2-s z4dl{IQgF|q^Q5TySt*6UO9kRh-B{#YEa;r(565P}y@1%x5@Sgw%V2*_s-AHoD+5-%Jyov)*dlYcK4 zN8``eSLAv~&aTczpMEDJc;V_(5SWSa>cHE&sA?GA9e7(ZB@x~dcv~{X3El$mGI2_- z@kSp+m)`0obBou=T#4p53CsL3$3y(7$is{U66x8PwiXocn75yPv!(vehE+ z6ehvz0qb^Vzd!%{czC}Mne#5iV7XF9-wHL=PMP``EPS3wlJoCaZ>#fR8S4UZF-?z=CUS;Q1)3n*W zHRV|doM($8akhAZcRtb&l4&0A%i;ca@pe$mI6FQ6Ef5NbC#S!E^WyZIfBZQn9+-4t zhUsP5cKv-rnqyktz+??!TF!qk39guu%8buPOv_|Ul6fa1rqia+s{u{k7I}91@&rBs z-R6rYPl;ns=_B}OMSqIL6UG=2HH~T3oMXYmfbXL%j&vd<7cA4(L`cs+6jfE$7uox! z+N_Iv8Oh$j6tPDUdla!p5qs3g9);|o`GWEJ5OBUsG9=Ep@e$IuU!Z@b4azH6k3!?1 zB+LF?)O}gyec9AmoA*UpAFxEE*7|V)bDVkQ^j6NlZdCHt zwY2dY&$v`^{6BBjXMnvq&zh^E&X$+ux-PD}FEUu3{SEZvU^p_6Kr$#cPnB9Dm=*RA zj`M0$d>Ie}4tW4as@;Ec+AzsMVeR0Urs8-&llOhTyew8(-(<_G>3}*f+k4cxh(jE} zk!tH47*?=%H*o9^zH6!y#=a@4?5ruP;y!Krh~vT@N7G-T+9*I7-#3H_ z2e=)3IEqvp(tv;9Z{Rqqn&lq=;LC~nr{?246^97SfWy0sqpW{{?d!7d!7gUS$G**% z;40?z!vPX=`4AHhm#nXZV!~;=i{mQqy7GOIy$2j$PVXL&bC;~IxMj{dyDuMA(RJBH z-bKaq;9wAkK7b=xUvbWq<@PJv@sqLzVa)3b;Mkq~5DURpFe;A!hx)v%Kn9|FxY`ua zNDLDGY}8#C9+H26d^gzHr(~v{l9qo;O7bb`n5QJ7_~#=2arA(@3(Cfi(~S> zrw7o#<{obP#L2PVF{3R_&UTe`ebb`SD(eiiZ?+oakHt~l?ZrnA)g*i_B;ycFs6aSQ zR;veFvg14Khbhtn;p^+v{xE)LrcEGdO{r5e$(E!+MD34Z-*U z7SyH#hj9f4@k7(BqU#9p`LnD*^MY`o^G)3qc~yXD5C8%9#yjw2)fMC8|HE9tr-m7k z$xs9f!cTut>Ly#Y`R3xX&#LC^?0O4=n|mAP?J)Q-BPtb!0a^%x@up~(Fv$F(KxzL_ z)~n_NX|5GaOE&?86;oba!K^(@Q);v(A~h{ybpV;t1mj&C_(KbM6t-`(|KKY9+b~wp zydc@X%>~`-2qZNbVzp#8xCrD8nDK4{K}KJ6{R4j>xLf- z&Vtft0Y$P2l!1A#{H~wXl`F92-DOdMC_k70+|p13iewWg71Pc}9B*md;D;>xdrj)j z+u}%a@;yWb@__=vodF9-gZ?es`iwyuK0Kd>ML5Q7_{7@ESHEw-@Wtq`te4ehRg5$B zzaxK!QHqF)mQaKfacs0RWjX1TpPTn1`Mg+WiJ2_RHK;%naQvupGqB~8NEmW)h~y)wS=f?# zORAAn%pWA(_E~=5HOw2swFqUF|U997RP+C2qvB3BWd_V%IWR|RNz7<64v(k z>@K-|jURXoI-B+DNIGO{h--piT8jweWcB-C0Mql;#=}%89S$u>gbDU;7_SHYK9DBJ z38oMe%wPu6OQH8k7lI$}qS)-c7Mz?uAuRDBHAFVfGb>%h@#6fv0OuA${Ct@XM5=$0 zRC1iUm^9xfMF=D5l;3|XI3;cXN%aMcld#TscvSlb#u@+})4qyjuZkS~-L4xV+{^Jg zyUH=<0NtC`s|lbF+~Yz@yKFD2VvSj@S=8)Q!n2gujP;PAKx8sFaP-0jbGtL z>iE%ho+pQ%#|UHt-0U`0j%HpYf|<9OC80|`yA(5B{^|Z zrzQ*p(X(+1jH&&2B_S*q+}@7DrJ|6IDJR7Y#!k6ITwtHk#!7&(fj2bUPnUnNfQ6C= z-`s)Wlg%S=CRj7a@!}&WC`<@_$g8URB$B|l{zZm++>Foo@4)K%9UO873qI;(NWc-2 zaR_jCj6aB@Z6HYbSh_@Dm@5~ydFhH2w(UsfvBnK#@sfiA;ToKY7&m1Y2jVnkGs z`t87rT`!JKo`LqcE!8Nj-<>&;&uM@p)sZ(`Fb9qoB6*pgwdHba2cJcS_+9pPvxY9C zdcSj~lr#<%T42cW6bC1#{I1tb2$3)|lNcCXe->7Z-9ZAYc7=N&i=$sVK(Z>%%NlGf zIUt}34DR>zQA~@ES8@LvMfEK0 zk_bUT94qClM(u_QdB{PlQJvU{m|zGVnDWZv-Be#e8!Z1K$9Y~ewFR@xtL5Opt(&^P zGOVt#f4_LLhOdI_qA0au@W#hGRFP>A1kg0+_E3O&2s$Pb00VPDtD7WNof>);l%kb4UxN_b z3QZ(f#Q@Phup%}2s-S|N=DmH~2X2u=TqNoz0nU_B2kY(r z5^^OZ_uI)7uQ)^{C88fLm;&{`s3Z@@pX}Z zw~0$ndGKchm4H1S*iJFabsW@5*KO9|P&CWs<|?n3lcxFNO)`zOy&%`AVTG~|B*;Y^ zubLi$BAmZXho&MHYLp-0y1Q&X6m6H-Bj(q+IiRu8+-uTN#(<+n(g3c3H9TgtjYQWV z${zSrM)>FiXwQtL+`V>8>oDH6o>J+57=$Q2_8=5#Pw3ZJJ^C3&dSXm!oi&Y%b9&D5_C!`DD^P2@=G#)i@YI7;PAhd4qtv74?)WQ#K7^6aw@1wSNd zLNy9MkqXuUiX4)Yd>bEs=*7*vtW{n@WN|rTQUQHdW#1Ov@hZQ5c&jM{hzd6tKIzoV zi<01mXn(LM@~_}*DPh2K7M3jh-VCJm0b!?6Ln+TLM?sRDu_lrrbtWdgg@h&J>8`M- zs6r$`6_ctH+=F&9F*e|6D<$0x%vn#bLA(>37$z-{))P{}s*D?defVLGz86eoYDE%w zlMLRAFkX-qUV^WKyE&4>EUUQBEASKOkMUkS;Aa0R1dZQvBYsv3SjjLqgDtPgbNof*hrY&5JA3nHW# zJ|X>JlLBU3!vHJ|2CPIdX%PnbkXY@Dsxi30BtfSd7kvxdUD3f~8M;jk=p^WDuPl|5 zy?gb4Zy%R9T9q1qNpOp_3=znie`l)_T&-%k2(^s8~qLTd3WOY}J4cC0SYd-KX4XI;q@#mlAw+kS za5EMKFh)vvq)82TF}xP!EqUhru&Iez3d%R(Cphf{e}Lq3%E;N&;8?bBjTOadus4%nB!Mix$>iNYjSEG4jZr<6col*Oa?d?k{Gl!kdh}Fk4QW$Cy>}@g#vw4XuN~bRm@?TwPUVe_k((?oNyZhX6S#)aSF(8!U`HP|~4* zX+p;$3x$wf%zP@~A9wLUhzwZW5i_6C;WoHNH7>EFMaKOl_&>}5-Nh{iNzcNH1LYrk z081f4>{oiUY4kM?&(bLyn_AuC(1BEng8Sx=yDmsDOOcP}^ZDo`9_Tw%=wt-AyefP> zP!jl&K5^5xr#a98NLYPH64Q~*agdq z_xV*b98O#u)x|{~&mhHeO7hkw%S4~~e>d?BgOds&vwt`~K67+(Wnpa!ScTPGOLH5? z5x(nJ?8Q}dl{A|7BUL%bjuks)DN2d94`B{VU_rtG7c?HS`S0^}&+Y;sKzZPZ6uhcZ zHJ7uq(>*=iUq6;#oj;S+`2zpZzs1$d*Q#>DRp*muMpjWd;iEUz`S`5bxn3kMlJWlY zkr!t{U4MM}<@wLgzBzyP)yLV8N$8N6ji2gOv#73{dNpmYs;he1E-}@4eK~6?S3I8< zG3WzgQ8EZ;qhrzu<*jB?3U6Yh5lM=uv?VfH5rUzyRfxg{X_&Man>3R_MDKV&RKi>7 znT!}<6HgX}bSdyFywE8r5{oWmBS4haJ7(j2zJID`)wG3hS`aLk!bv375D&=0d8|1m zTBvhL7^8_3XO(c$5hqT96U73s!HJ}uBGMY+bRt<;?S*lY@9G4>CLU|O@Y+j$ERlW^ z>7c5?vk09HLMChvWMN8W5smOpSz_bG6I^ABf&yr3c~M?e@8`36am>~P=$Z*9#*??g z8h^=)`u9KT_CHnO^=i@7!w*>$liB*W{ef3|cV55VooO^`mdo8Ce=nD+!=cm0?koK7 zT{n8`hiq|t$I|=TW;C5lN7cAqJ$$RXCiQ4FU+mBSQ{nn?EMb_AU;q9KUv5~!f;yHi z_iv5%86O{*uWbF+2`ym>PD-my6z~eXsDHQf#p=39elS@^OSyB4JcY44!=woJM$s*~ ze=F?Xa$dv~0+~TuY6guKCb<(6u7-1nkr%aP19x~N$wd*2B?q9$vwBauso~>7ROEzA zN+Kk7y;cXzn0$8^?u!Ix6#RyY@hEK3#!Ri*5O;bW}PB-~i+V}BIA zO1X`{9r*An;#Yy(oAW!(|EGf@G6GFtV`%XhCW7LzF~FHBUS=dA8AFQ?aFEUi z-%S<*g9Q%|q_Q5lh_OzxXHFL0)=A={SV@!-3NJY=B>?~m#55KaMD?br+YOvqH8;1- zqF${R4H)gg-?FKf^R|>}U^wIDX@4>8lfgzBUex&(kK^@%80;Cv{pozXggmO%byLlz zALwpP4t27a-*hH9J+IEM2|#{*@nwJg?fRdVYgfEt{riq%MA`63Qfh$Q1&b^yKSiaA|Mq!SBAhU4Lxu-VKkf z+YLDz#;ylY^1iw4$$ySkJ^6P2p(p>=khd&bKVpSIMhNR))$83oNFphQ*_DCSvZ*Hx zA{QnJ1~8x|GEy8sq=E5KZlBaibI1V);gZz%A5+4>Np-J?!K5+w41r)RVen3i8)^iy0<_en3D7+K*LkAcNPNSD1mc ze0+WBNwRP*(lQ%wzB}Jx1Fj8DOm!sAc<9I&*acPO7NzHH&`?#G*MA0*VQMC07yN<@ zNy&~hA*gN!MB1jCH%X^E(nz>|@DYmn(83d*AcJ~c=^Z}Ee}>SLT|7^uO+6o4x_*FG z-u0x<`*Dv9ei&t$0m1uRI6CO)K@ za?ruJ(ZLV~y>f%T#(xm{v7tZ4QrKjB#dALIGmW)&&_S;TGH&!WDF$7sR1(?<8+`0F zb9+k_VZ%-bJzkR2GC+YQb$2PhqI!MxI+$)hWZG=5F$1ad31c0Mt|L{-*&NJkU8f#E zttLhAkz^?!1WtWoKEB^^;P8;-DIe#WeE+KYYqkBtmsmBBB7g37JEBvfGnPuTah_rv zuj4^m5g^2Du}EB+K`fEc*j}_Y#{SUDAp1k;T(^4w`JLY*tB_1Tz}O_a8NA7^istR~ zm|h$rov~D!KJ(HF?OeJKzUuMM>*eaEX;;-}xFkcbA_iOn{}kkq_vJ-59rfi=7e_kksCx7x8PkQ z?3GHxaZ0XR$&lrTWiwfC(h6j0Wp=)VGXV>U46s|#2Y)(vIhV=jmGZK1&a^adI8j0i zwjNs?Tw;;}?3}m>|13M2|VDTu4S?4$+(?dPtau`sB;V#~$a}b+KQLv-LOD;2gi<4f> z=F4RTuYb@Kre>W5{EhqJs5bly?I|(kKpKj=G_Wl|5+Nh1GYJ{-Xr-WO0M5Km5du-c z=JE*8vSM{}hAJhRvr0I@ic2)gVE+?mps)gp@hEAeH6<8KHpitH+96sD*;MUXz5o7n zT{eLZ6iuo-mdw*SaR>m8`Tm7k$azLIRB@y`vyoQcM zqIEdJ;7WVAFc+!nm||&q!D#}qPVGx#+y1|(R-6k2eyHvm7|4q=2uI{!KWC=z1 zt{o#b9@=R+`U|`Z*ONTDE!n(WoWfg>JynmnE~6y8Q@T*abq<)u` z8^Gvp-4|!e$1&f#tfZcm(j0^}LHJ-Za-K}4qiNHQ?uePZ_#MO0Z2^^d@VhS_k$<6R zdk3p!DR{OkmLg!QDZ-KmSb6Al?DF-z`r?zbK|N>#Bc*9%OIaRw zxYy;+5aA<27t-clmk0fP*-X+=Ti(7TP6YWBZYXs-0QVdaNVCz?i!(lP_svG}E3}B( z9nzWJEF4K51MNRP8FXKjCfrT*0)P7N_C+;WH?zY+DxMk(R=E*mSD8$pauO9El(GT- zKv769EtN?XH*`crRYC4&i3tnz;YbmA7^mboU5kk*&^H|ZOJS&Sl|)p$)xiia?Ew+} zt~QlAIOFMbg?&*SrxuSCK5A9Y2Nf>mQQA~4Bxi+*=46Fbn#eb#@*y{Y9Dfwj;695d zRKoc~4IVJtBEW1{xn~;(j}y3D5iwll^VAT`Su$)M&c@MJ8)h4)HuCv|O$>%RxnZ^` zDU?_+rMXc!5`kFH?=`TOJx#ol*V$`-Kh_Hxt;tFpkf(OkBEoh_YXc5ha@tVAD3daZ zm@BM+x6}B@KmE&eNMSs2A&MUr)04TWJ%9n)H+yV#F4eiL2!G^iOHDSt!T5`V^ zXTCIJZj__!z2C=YzYgMQ4m8+4>J{APz?5QUBa;9;u$>Xb>Up+s&$4Hi1iZAL~~%nNyuWJaMzKT56AI#?|Fr_3lUdTFECqt7Rx&b*{TUKI9PeO!9KPNCzg_2P2cHlI?C)(KdqL5}wHkrPPpo}SyjzLvL5o^ z+p>MTE8FRW=jfiB7B}X@kpg4-jgUvDC*;z)6hb9ob^5sCep>U1;70-_4(9XnY%kby0o+?qd$RI^~dQ!BdQdBX}r);0wb}9}|+<$PYPfwz*SfYViYxcbQXSbY+ z+PHFW2lF#NJrR$KS<%$##Js#}TPnwLiGEr2h552+9JNM;106dYYQ5Ml30A6liYs^o z0NzJ?RAyEoC^cS|G4d3>0(|{}l%PV)ot$}?ks&4cR7`NAh6ohqACtmUR0XnLonp?Z zkO68u%zsT9yIDlu3AScWd>JhfFez?NEYGJXZRo2x{XjnDGhKfm{XzXgh8m0SITp&C z-45xHN!>30QaB%d85Xp?N+yx_`%JB>D{_rJ9-)eN|@;DeA0GcU_!~ z>e*;LW8{M!8_>@8kJR146$$I*Q3(DV^r{sT-Dft>^=+tE?!H(#DU z!Y#`k{s&_q;^-bye_Bq86FM%@S9p78aua>LsNPWUQ5^_Ao`{v6lm7wLY{Y_-MliE~ zHa9*#b98cLVQmUnh1FbJbKABOe($fqqf;j^?w8K=!FBC6ZIk%KZZn-a53~f?Y$VY` zQjYz5&L2GsfRt#8PLRZwbP6|QXQ%&ucX;~UPoM6MSj@Byy&cY7 zd2x%X?Anb{QKAb6H?kToHr)s&(9qcqIqoC7l=*-qOHP0$pGZE zs9{3KZkk`a62Q0!Yyy*$O{X4UwE+;68ZIzVR0kj?83>@4CIES{ftJRU;aEw3Dm+t^ zWEdSS+!T$9s;)qV7F9mKK&RRH)FH~yRhf?x^+;=tnGj;Tz-odG*MX@=mXR=w{p&D( z>yP=-PUBw*EI4^={y)6C+`DyIx%R=;9(>fl`QPwt8voK@!g%2S+U~k9mCw^E#U?=6QYF;CgJ^v^1_l^Hd;0Vn(bSnvu$liupJzZ=pvDU4IXbmRYnL ze&>7W14b*IIZY|n%=Shfg+BXpLW#k~%ZZ;8mI{T#mk0|`-oYf4ODJc5J4Jm7*Aq~- zFJbwf#u=g5fDc&vU_iVmz!t0#uVk0U8Rk~Xj_>v^E}vI*Hi!RRv8a%nx={@V1yz^D zM^~QhR9}Uy5t<&?0&`0HcRSu&=qwcr=%O_yU^!mQuBzu~lFciW&BrSUADp{-aaq*R zHNmzkY4i&u&8T!N6h@eTXc@5BR4CM93E^gMTBiBMWg}Ea;mQ6nDq9Ef5@h9nIv+1!&|6d6IJ&gX zjmA=_EkkT5rrfHIjt5B^yU8@GLEF!E+Hm;n*$c~Lfh5dg)Onk9g;jZaR%4}t{_LiJ=g!d#>#vq}O@=@QDh_vhQu4$=S! zm^dQzc3B_6u(CQZMH$%JgRDFUxftigO+I$W&GM=OL8(4zeIZaBO&7tB&+<`Oyg2yv zIPK@T^3k~2t}zMm4L6UTv^O@gxoAeZwU&1tY-b^nf5;1ew0dm*hm!UW7d|iTCGE}4 z$aemZIY_I6Lo z?h_kD)!lm(vL3=oa3U%dh_nzW3uB)yWgieOh?^icgogtZkqia$d_g;N;vM40JD@h) z7&m@Jgwp_jBsC9_#!sZMY5Dp$wBc;s3zy)mchhIa zAZxnAA-iCV1t6)RmIQfZjMzJN>p9r*;YHd_GzL?InIJ(&bm|J7R1%ahESh@Dy9#Em zKuKo(Ip0k46Jldxm27{(^kP9`UiET2vJj*p$gqZgCi2f4-peO3OoL5_)0k^U+dPvJ^zO~u-%ox$JUm55Z{DKAo4g7_ zJpSmW(+t&)L(gZ)1a{`_PA^yQn^ z=*z~o_+n2BQ-~NpbUmw2x3=ynZ0 zxHbw|{+2NXQ7MF4Tg8;H5_6E#kho*?=Gv9MAYmz!emxx$NmqJd9i=6X0>U@T3EM89 zhGEG#+rSq3e(AF1#R(+g?iNC6AHMaU{HvIME@m!`f2}a3D)9fxXRpgCdiZv>GaFvd zgAa!8!|l`%L@0|jv7Kr7r7RZU1Siv?c)*yDg9yg(h@MB5Z{i0GBA^&HHTUDXuH{&2 zwS4}C&uh<wsy-obQ~mwvtaVIg%fje3}rjF?6pOq2jyjLY`4-b6z0?CWdZTWtQL?D=h+3 z45Po?yw0at*e38rh>3kr3>ov50b>Gx8%6jATu4%z@sNOC7K^k6Q9%tBl5e7l>`PlB z{|plmiCaddgbm_*ZF3@ON_*&jcUOu4B^*HDNj#OWN$1TH# z$sUe%=Br|wkHg9?Ixq66d*~&s`{rYuio+-jIxatlBd$>U#oY&ou*3mj#~Kcoj03(y zX%ENwv>1H=0Gm_w`{rYkibHd(i0I+S=P>NEysp77B6m~!^eV1YKUSk%{h&)6$(3+i zX-uu|;ke4GD!+E<8gOjR?hfdGxlXoMiePQYfPPF}RiTTl3Wn*?!FU{E07tUDk^*zX zf0KFOzb8N-Do6tqm9{(D(e4Sgg-idLB}unVO|#VEL*DowFoJ&jvRPAk_w{ta^lKh?}g>dG{y5?eu+Q04_1m)XLvk4=m7^V<~& zA|H&+&%+?ijHE7QabhuKQ(-#|9lLS_OlB9(Yx~E1J}y2+%Qc37X{nX~L1OZ&t4BM| z#(C>aXzH>ECmd52OSjOw!1!Y;c~G_&=pQeo-#5I1E$*QSW?RAj|0L%jAdd)BTWs@gko?r`h$4^A63uK04OO(DFXI1$ae0g>0 zrgb<1`6SI-K$_}*0zoOTur`*8M!tut>K?A0?JyE!4~jrPyn^_n9ybls@6jq|v`mub z`9v%f6B}#D)@3Uj|GTK_m>tF%OxMoTw<88FX+RZ4C>B|Vvn5M3MhV?Kmxe|Otc)Bi zP5doenye#t-jc6Y1t2~^14PEJw)ox-PN;t)mfJu{+f>3!BSIPCL|V0n0Tz{-^Kx^uU9i}A%2J@2&mUQ z3MyJAtu+IGq*Q91RGQHCF6C_xz@;1@SI>68<~#G_keVVh9`=%A?b&4FtNS6v&qgf} ze+IcBskQ5*Hi`|9FuY5S#BwMo;R9sn*$(MD^JV_2IGDmr@a-xIVbsD1s=yS-=vSBd zfVZle6!)^dMpv0nI>7iQcFVC~cFV95jR|8>kfv^b<`=t?+b^Xbh1lLemII0Ma#7~B ztGoN_f4=CIvF(F@`Ln(FedyEQ69Eu^Qu=GR+j~`kpSXOtH)FqdKYX{hy8Q54?^C#u z#y_S><;$4$k zeN)wcJ|v)=b@-(Ic$R6em=D8=8vN!R6sZ-x)cC6Z?t0ywqK6<~U(wonfVP3ac6Qal z0!q48kUW6Gq&i8eg+CG9fpK^PM#`@WeaxoQ>Rup_*T}AvfUoR~K18N>j-Qh|2kV*l z12zGMO@^TiZVJ}=FvdXHb9aZ%u^}-N$7y&C_DFM`b$^%JXpgY z(aB;4T?X6!#jB;!+{9uF5)O0%!Io>hMqo<&r$UDCq^=85Vf}$<`gzxp*d6mnnY;3T zdYqN@?PqlEvyI8Smb~{qg~8V=42()@szAB&ho+;vUb=Dy!a2*j!Hz$n{OTBHmmWE9s7Ndvz5&wF6C-Vp z6p+IBV+Ee{Aqx#rh)}+?-1f=Nvn#UgEV7gag!+Tjp~fsEh;^CGs|nbYQQ;<&v^VI5 zR}&4CsZj;`ZUqmdPxPhglLQN8Wsj8pMRqij5E~F-0tvs!rR4%xl~T$dpN^9F$MIeM zna}fNL$>rs`e31Tql2D$Vm@VdO(LYvy52Q)QS}{m{>!V(K za`E4iyAFT@hSBGI;HXj~9!z_=VSRvubWyalKfI+2kF5UfnK!X_u?I5o46bIUe!B z^n8%f`OKu3DHm<<4l_`WNrMeubk8g4buvV{Bz@4_!A0p@?ps4LzU!;3>qpQQd!>x) zgHzpyy-7tdO|4|2lF7#RO6ICr-&RT_IO(i9CJ~dROTl!1q;iR8ZW8+Iz$Ap3T_K?c z&X&Gjx|~^h#>t#=-x`$mU0)Nr!7xHhei%39?rSy$&l0(+m55JL(f)dmL>B8?{<*Cb zi`O#fa7-*tW4+3PI;^cOq{Ti^jybVG=G>8xMe0Z^b37z>I_$i*9c%`9rhp$#3qK+t$GZ{%teglGCB@=B6iKw|71HkI~?Z|Gs$Jli#%? z{9ieLBW?D+c=&@As2c-Xlv6q)0}V}zK6oafb>1ffCb4Cc?m{4cTeMuPo;DV{GP>@= z&Su_~u68MP#6L{U(JV=kV1IK2VmRfSu>w+ zn(1fNrHjS7nToG}#p}(i%zB0&h!yfVLEAbeuqfG4L))$AAr^# zj)eI5b}_qunryispqzaHfGz;bMfb233a^Vr_|?{rdF}En=vqGTx>hc3wU?sGK9(Fa z;{0VV+8j00(PqlKn10zdqgxK}Z!5oN$f+IK#>SI_W^ZQ5WCo5@FFQ$X5`0ziSY!`npXQ{7^w}L0``mp)+0t6hxVWc+D2|%YRWM<^~ zUr%srjR6HKIZ-l@8iSL6Y}T|I*UQCB{PL{QRwyTp2fRN`TTvS%_>5_}bcBsh{1p3r z2koW2-(CuTu*cRk>4L2x*n+Je$BIV4rJ0rQr|k$Bd(@?^F3(oAgCtLhq@(gUf&J}j zO{b5D&rJOIbuH`F#aoD+$KvW9R%^9xfEVZOVzUzM5h1^4VVizsKb9LKjZw_a3xWVQ z3|Wi9?gD^wL0_-;_=x3Y(#P^oiNek;Y^Wx!<+(@#LL&buJK{G@RObl?7suSGl3}Z>Fn-*xC7Y zGthAEKI!Af20pkxvtxYXBNL;g^(EfYLFy0-X<$;iRwaQsxUbfL6D9qP&sbZWjn2|o z&h}Ae$C>U7f>Py{NlGcD!1lW~uJ!;thys}nNNPHNY38GL^(avS3Xm+d{SCrYT1Ehb zLt$EoO*@yE1k;fdpB55SF?$wvg4j6mX`+|GIx^tKlYsbm3IAgaN-Lc(n9>)U4rZT6 zfRE6b$2EW$F_f<<^o^c{nJR_pG6sc$mEeBy^J6z9JQ7RNf4n4JN|fC*$IkaORL15n zM?#W+wP_Lu#O;k`Hh$d9?pEjGx|w%*61#<8k0Boe>pnQxBq)-D*SBnr zf!$p!sd@lT>}rOK5s_N(+#zWhoMLkfRSdSkP#7tNcutg4CPSyg5KC>=$Wio|N;yLT z|C2r7RyT-qa5egfED+AhkTOk_;3|S%;>6QwD;-e^b`psAsMW#7X2TB4ISU=lBnt)q;wBg+ng6Th7$bk-p%X zvuNPbFV9k~kFn8WQ0KS)cHo1K3w&0jO(BH72rlyRdZM`{geEqy*G~WoQ6-uX-T(%6 zG~+}Sb((XB!K5+X%5C$>of6d)^} zRFvX}wwZ6?%(|W3wZO%jB~@hg;BVD7tHr#QX~@?mdtyuj>EzfIJM8c{-Ykj1o>8<< z7Gth`Uf;H2I(bX24LMX!s1}o)&&9-sYjF*N>n@^6wUF8pEDWW8=HjRIWI9=u zD5mpubhO)LfI;mra4zN(eLmaEG3MIrB9t8v-5f3S_#-6VENoZwp69=AHhc58mX1^U zvPhG;0PO)8UGNV{vLY&Xq)w$I2xQVx9g;hJ2eJ%S$$*hC!^}W4y}RARIhd+)x+hCg zEIwWl|+}s*-KY}%X`WU(GyZagjt7AY@Mqe`n8*JO%tywpKqVhQRo;n%?bgm~; z8py~lfk{`Yvp}X&Z%1Ts-gG2FsN9oXp%(S+YQbm(pZ)NOvfBJ%LzRcAHgRf|mD-d# ziXUEH?6CpBA454H0ht}wT-{@EW?i&4>ZoJewr$(C?WAKTPi)(^ZL?$BPC91CIeGWl zr|SF8zg4yVu2r*Y-uJi$oKuR{-K4JfiS4+#GO!1i2XIDX1YQO}g-e#n2ey)j`DgxI zE#S})pCh&RaUXTPW%-0o4j!yk`g6R7(c8xqdQ?_n6frJ-{X%3RbIU@zhJN`%bfY{r zp2xS16ak#yS|!v2C9lzOEp5`R1wG2fv8%i$f^8f`JLKQh6zYTEh7m-_(#=4%bKY0v zJgoOzXm8zh>=+mzuk^9TNXCiHNMf{m8MKy6u7yg#R+>7C!0qHZ@h_yTS}pk*(Qgq` zw-AI&LQ0Fi=!sDyF}1b=Pq8pKyRaTRStSiQ4D`_HI@Pur)lxgkuoN2=KXPkn>tZL? zhKv4vqHz_!+|##Zjsu&9_W=vl{c(z(?a1_ODyS@*CP#8WzZRmRfH{r-iVEZ>bMP8N z5Zs7t!mqoa#&%9i$avqnV5v>N9Dk>Gc%n-Ehi2xU0EbSUMoIga*K)Z$th}>CF)zs8 z%sT)_72CG=o2zvd@ zugK+JVL>mpJw_AoS?#A>mRu#dW!W_E{SB@7F_iraRWXS;1|Y^wT@f)JfYJti2d#%`Q}OG*H+e;wc?U zmEDAA_6y2lhfUw=49UiR=(;L)U+ zXmNDO=VOny=q`2c@14nL)ayW(zCbnC(V!+gR19!9vWy4fOYdH?JkVa>$ zWZ?A@EJnBA>4*>N$zt*$y!1DCi%TfI9UlEj#F?3$QCDjKeI#DOaIG=>st;WZ#=AQ} z^GJfal#C%eZcQ_DdB^ea)QdYpARO9=krj=8udT(AThBM9b;&XtcCe(XW5pv^)!x(q zx949OU2bIB1Jl9bU1?X%umsFM$WrqvXQqs}(kv#nY4W1ugYz~9zv_=h>a;)wY21l< zI+om}2mYJ-cJwNvo0NxOH5fH4j>-3*D*p8LcJePVj*CduP$!%kfdsB#bW|04RXb!5 zNX)GdY6_OUGy9E_wNDm-NO=|*iWV!#y@z<2m_PqkSCi(8O9aG0^e49dO$oOFq3Z3q z1Ky%PNLRZwimV--?_DCUl(N%jXUEYg3Hd9&Kxtf}t{^FH7NdPzXGZe)xiC~|gV=AC zvczLU=^OAWuHH<*UWn!z{6F)<>bfmOImY0R9f;%045q(9-H_xzle83@0IdIKuX zOpN?qb79rm6|kM?;rS(5|A759An>#tr7}+2cKLCifKDqpsppWHgAmKVZTgw5ce-9o zS*Pjesr48I=)T--+?l7OnHZrs+`JIYim9%ng?kx$#3cAQj=`HT)7%2d@7`uJ**!AY#s+XsuE7zV+w-=?mqO46`4f=%X&#l zhsEvSuz9mCP}m{t$%sN${Oj*oYUD$lAZgAIL3?m>ZPKqlq{J~es8BRLLO+8N<{DY{ z(^{@M2eR`W?e**MW2&4OXKN6fF5$3O(PC3XrNhw+MkDY+PK?ZtTF5s|j=?P^S}cM9 z5KzpKQU*o$mrB4Du`QHpd#rjU?5O2eGx2f%0%4QGNPUkd1#KLpQj%g$pvKy7ci*9_ zG487jg{f+Pz(!}ZkZ;eJq3kGR(YwWnoDk3jlQD4(yf@R>tzWFxQpnFJC6b8U zJbUt@o2r6I)$V#&1qvqzg~DGNCnNj~h^o3U&9?ZJ%K1{U)Qr5f8P1M=N&JGILJDEc z@6KXKRD%%1yZEu1R2vnbVNI16C z+lkebOWPy${?w_v7jJ3#!RPtzqp5PIOm?0PvMIjeDp!_Ht90)}_YsFVCsrtXuX567 z@V?8GkNS=9LIdDqIr;oqX&W^OSQ@?b7E@D(D4mZNI^xD~>hl)9R%s}Q{16NS%~T+~ z80`vqd=xt^4ihOfN;nHSoGo!TI6={^8_Kt^=kKDB5J@d!)YZZv*zf_dIvfaY*IeID zswkOQ5{Hb7-ikjD%2L1~%v?05IuiO9%$sizInk1{ z6?ZHV?IwYH$}Z8}=B1l~SE`OeA6*JYJNl@0MdbO@wP01nxg_LJZ!iH9NOvIq!sAH0 z5EwQHgi=V>wo;z6;L$4e>P~koiqkdVp!oX)aS@l4#ci)J1*`>f=Q3HYLEHiBTDp{1 z@ik;CY&p}rZ(o7Y#;r*b5Ta{-{6f%tl6<;Bvrans=E+qt;5BoKsl(f?8m;>VBvdk| z4uzkS1FW^K)`2VUj5@v_u!bI=4K0dY&qxH!CBe`-h~SV*vC1_`U-|pBDFo2o34xVf2)NMI zb#io_1M@qI?8Z2$8=$8?^taLy0@L^97|;8ezh<&8{1fZ;4Lj9L+QH90q01Wys-@Y4 zg*qP5V~H5}H4sUYBELC^gc)&!juIB+)x-ueIDW!>dQ0b2mY^L~wn$p4X8C*2 zC^!B=v@5$HeqhBmTyQ6kr9&DAD}@}k1?QhI#OD2HULt^nze;zOV4`ptAmk`-ie1NHk6JVFJ^nA_B^YNt4>H2rFE}DOKCb zh;{;7>~+3ywsn~YFenv6F{MKYS@T%=cQ?t|3| zGBoL*F#~n6_V^{r`J7`l;IUwew9EchrybG!LR|Q;(69#mkp+Hmh|=HORdw(p<>+D{ zXB~c80P9pCo&jIf))aaxbMTzMLSeguz}S1Lk`rbX1<|dcL$n+6NaS|BalKsmq-c!8 z8d|=<0oVEEeyBm&$3@1x;LAe2FBFzDZN`jt#|WqPb(HTzRtr@lspt*fw^+4Y>PvVT z{$gQgo|CVGd}$dG8K2BateCT3#o8t253`m^fLiqcZ<`zMk4?#=RhlCy8&W5ADe?qu zs#-ao6o4i&RePchyQZ`Uhj?D=Iqtek!0&KD0Ul{$wj9w&Nc=yx>*bp__}h4>$apm} zV-uUdsFLj{i;F<#bt_Nm7l#!8&`peFL+A%-AR|Jv8C4V>>bGzxBskRIR)5){@}O&y z0)XQRN~cvMo}#FsYfGM4zg}?6c)UfA2Z`#0fKf>8BC+sNma6jaz{C5Z_^zwA2Jleg z+e4J3OER$vP8tmZ96(p>N9_4PdHmvQ%4>cN(vO>1UN?AJ50`fjhoEtbF&IWTW7uLR zF9~+=FO5K6okp+jz|1SxGp8WnB?X5#0LCUAC<|N2&(sQA-iYizMx73)eB<(Do3(Ei zM(ap0R(^9KxMCKDXh5%AHn612BgMennPL>8xwmqyEejQj&8|=#w=;WPMB@fpO2zl+ z9MTS0;~Pg?iT~+EJX4sX=f|DjDAe7s>Sm{2n2DwE7OCh^VsZ@is*>NEz@90WeM$nN7)D_vvBe6skiA-7=Bv%F46qKUzA-$#4Qe)+zqM^dO%UfN^*U6Xf%S291&yY#_N$)I_fQZXro4)bPA{WyPntpSC?u_on-Xd)nUUsBdw z^2%Yf_3P6QE*@7JTPxm#3tE?qjS6{qRZw95wlB8#U}PR!;B5Ep@!VMn(>$_hL?aSI zAJe=?ZDjsquk7k?u{Oq4q2+8TuvV(8nvD{<9AKIpCCYHW zhmO4ny4f&`Y4}}b=D4sT!~5*HDfhrMJG>ugwvnmh*qp`kab8W$k%u=JE|PJ<38=Ki z^%#4h;gnCkxnn6Tt{6Fo9@iEixgYmA|PZ+ zL0~#?Fr$Y*O<#J0j(upn`0K8A2hZ6XJ<%yNqgUJO6w6YV-Ahj}S$Pq;*ccUgzB7Ob z-vc4>^G2Pe#$(uV*W^=@r+O6;FxtrVYivfUpn21E=OxBMx03TK?Pm&67@Xa86ZOFk zEk=}KKMrDhc?tsfHS`GK;#rAVCGJN6N=`m1DmK97!E|so z8zn-ZIO5KnvP~;?fccLHZ)?1>#Wr~;hwnxrq=PbLAS4uv-RcrfuxP%39Zj3}X{T$uel>;anEcU>(x?sp2(I^sGF^_Uql(Nu>T-HD4aq$WSGP_p{CU7 zV25PrORYgeoMA#fyR8p^Gw#-_H%FxePa@7UpG_CFj%q?|DF6PRefV5mx8>WHy!5K= z=s&uY3-x=SkR?`8ubo@Dxpt9e-cC*ppaatu{}DhQ0wmNJp^#JkX>pAD8W&jLTDj_^ zS2q{tJG}~-HnCRc;{KXUPp@3&SNhoI#`WaF7DI}%oOUG9ZH|Dwe{@GmYq_X>3)G(y z0_v9f(O+$oksKgQ9fCi0QzzsR+muI}SbRf8=QQ7c0#L;?7*LC0M~^wi-33dijJs{N zk*+DQSS?huP=jG|&!vUy6K-oaPgN@7@jJ5rCbpGef(=NG`;;Y)W4F{{C;@X2Szp;a z9)V=84}y{)KR{Bjou%I2YOW8BCyz;T=>3%C$JkMAH?m84*llC;q!yWY1j%{eR`%Y&znbq;5I0?;I9NWz4ANKA8Hh0$JMWV}} zEyPvqIbl)4u!mjmBv)f<)Rxt3*h30hLL>qw5z{KNPA8)>{p0w-|DD)K{JZKF(UNG2U2*2vz%m zj>3byTC3HQFDLAGYa(DOKBFli0`Ak3Un@3nYpa~vKaR({oH}wmB*N+$`d~2xF5fQ@ zGJxuZYodYtXpvgu07TyUI^$cDZ3-IqVdn(9{M&k8cb_SJ2jb*FwFRz3LOdytcCcct zdlqeasirq#B%nR6lunVOTX>oO|z)R$vMmM1VZjw<7)ZMZcR|Y(LI~)K_nzG_>2X4TEF&t|>U+8j*~rbP_F?`4s#)Rm{yiQUfDD~r9=9_OY@Q8eOqfF9 zBkEWa!klU{wwD2Y+IEa2$gU^0C1mbv@HhPBU7Dk;;ke~8ebk&jE)h=H!<2Lz##pCV zyVGH??(xgm_e92AlFU%^T^j>U%Ebx}#lFHFlQoz0THtiM~`#uHYBJ}P&^j6~ch?0^uNycR#=o+kJzVO;`+QYHK@Zy4) zWc|8ZfazyM!=pepq-j7w^@W-A+-3jN#Bue%O?A5_E**Wv@2{5&v|i{iv67|80vv(` ze)XNS5c5%wJNM~Q%xfZ3;#h#;pIWS#{3MCl8Oro@#BFgBEeCCsh`AgR)rew?g};`0 zE#|opemSV@Pe38;>Cfjjx9!z2`}F}b71fug07{ey|DjTnL`;196|+UUd{uM17ERNq z0#II^@R6r=)Qy3vd;Y{!t78w+JNtO*L=gD|c?81Re~G#h1-OgM%xB0}84nc@oP0AL ze#dNd8TU+hgsf!2Y+|?69Iuspyi_A3(L?UbnQrQZF!67MBt%C~zFXe*5hB9o!tqm* zfEEk#FMOvGywvu3#}5Ymp58&IsU`$asnBAI8k|Ol+?^{adpiYgnq~Zj$8km>aVY}; zT$J@kaI5LLOKnm$U2tL;(%79)2Ko}lrpN9sahNDM*a#sk(qNleB?%!8<8z7IK>g$U zHML(@m%A4of`7wQ*wH9|I%!JiHv}IF0HQ?ejvakCp@&T3=X8EL7i*~fYO7iGeR1)* z9ouXw!%*v((eq-&+=_w#$I;&6#)EKObKOM4jdWw*%uSoNU1BxpmeNEok*akzfvy3& ztc~K-Z^jW7Wd&@;%8Jo0l?&{3^4RQZT+r7^K&kxh*eGgf@Y5q8!WOM0k^^bt(zN50eXh6fLx`3LrA=6CLp{sBP(1QH1B6T+rarO}m!Qo1@Hg3~P8AC?{2{PLq zL-&9bf6gU4Q71*FM_!Q<1sS6X&IM!eQJ{8`tV>9OAg{aP&hjySVQe64OI9RO91vbo zVX)C(38$SQm#v&TZQQA@x<2pjZU_9xLZTr!GKx+p^qNSplRF=JIdsPmR^%#d^KGk1 zN|vYqSyz|{vcp9^BPk`ZS$yKUq)L?V>UL)0#9@PsYvuUEMH^`5Yf%9!A}c;3w0h2M zfM(K`5w$Z-VzR3&7={tAjJgN7L0GFJsf1#|0e_vtOD^*rNxJuqDsC23|GqJ+2ynVe ztR$J$4RfL*DSJDotfWT1vK;ZaSo0mQ3`zok+Znu)ax@kMI$DLQ=A86s=mP3t9XCJ3RN;c zs=D9l!+XjB(Ei)DXS?|u z*pc|x_3UjnEc7uF2c4SYx)vX=4TSLt(rvGey;9_{R@0)4-5RR1Jg350vl{I?jrFH5 zw5B3muNrYP@>V~ zD4s~8Y$TnMK+EY47tX8PiEfFlf^}~ECTzwa*xgxVz(rx0?Y>FRW3;yTQ?n)F9zIJf zof9`p1k{f&X~{fU`Xt_$trcDqSWWYb*piBw?V=S)i3RJBp-^smmPQP9$tq+4YmVg) zn#!cQg3&0;HjPb8!brK#zr`+v{Dr9Q6Xq&L#dZUq)m_5PeAzkjlkiDMX=EcGucE%Y zJv9$3)$Bh)$Yh1&6UV;MAFykmJl3v>fX3mniczA&RDV5?Td#I)|!QWdb6v6hCj4sRPB!2Y-bQP>?R&T1^eOZ;(GA7rdeFglD+#(dR4jxs%3AoG9 zS=e>ykGc0tQ}z$~Ef*x;+rrxO+n0h8lD}O_r(rgA*;d3moyyMDXU@!>mHl0WQ)Z#jH(c9skb8g8BRSuV(c&s(l7_wXUmj+!O4i-|1^k>FWxjfFR0Y8k|wM zp2f39@_-y}pg5SfH#}N?kl%De{Olv5!q8#3YU`zs#fw3l=qq!hx-QPNAg*Z(_M?fg zqaG2F1!{n_K-&Z#@?aGGKfPi3Dk~BE1B-q@!Fgrf+0$?d`y@hae{S>d4--`eT%)02 zY4q8Bk<>D|xrH>)B#y@$0o1b9n`|9XLSWNx+BFbCY9110Bqlk^EmR5{WW&aS8%4!K zf#EhBo=ZzarSM77&9D&{6!1;TQBa%;L|rs<|w`)!GNC~m+{?W;Jj1E-Zt|si6+E3?T;~LAf29r-J=bY@TF3$qa*CU@OX5 zC0KR2wKHhJEL*IzN()nA=1y@+_+6aX3-9tsBOVm83hPBtX>wW+q}+*Lx>VWRcd=)# zi9+BHFm&bC0qpZt6j6dGDsKh10}q{Fs^?oXrDbsqZVD2+zqY<5uBNVr<;N88d4EG% zo^N5pB~5f9JtM=5XaP2gX^nx2jrlvP3XFoHPo!-|WVxftjE<8dEVfwJ`SF%3S5mdG zI7nE3&G09R$A`wivTi6nhXhKcbs<21(t-jse^JCPn1NHrjyDn?C)}ToNOA8x*CT4l zlx-fQ`-Nz{>m;m~O00T`)241BtP*tlDek>KO!7^eFE4|f-ZXkfn%UNDX`DLAbh*UR zRbX$Dcsc7&|NS)>=GoEls=jN_t@gzZ_x%kYbdjCZX5R$h_`hq%I=^u^(EVoX_GExD z>MeH|U@k>AZq5m|Z{mj%Oed+9hhw>c15La_hi-0f zx5jp}`w%aE0>0075B^@Zn5OEu@%t70f?06F$TmMMLV31YeQ&~1J9`bx;YeFd1$0b? zi44_*br#I$zV`BeACFW$VC?$%eEt_#YJcxx)lP^};de_%dGQ!j*H*oR<;+Qk=MW9# zteBs&4}A7?SxWNa-gk+t+#&W@U{LJn`sjrWNsPrbjg9CM{K8-_7W-t)V~25DmNlQm ziyrRi?_tmUW7zHCN z7mmw#cG2|&VLl&Nr*gGRePBCs8eqx=Yp9>5QjfhGqC=9aDsc{5$m6_wF`K87DEBe< z0u{q^JojJW$YPZnKJ%8A5LEsZV8R+4VUYUJHTx*@ZLma5ntze`dra1=Nq7u`;M+;^ z8N$#MJPQy8;yDqOfM{ttZe;Ss)UglqM#{JG!Uh)~y(_82Oqn&jz`K+82RuwhJH^~i zk|L?mbl^60X%|yQCOS!|+8kHB^Bhz>tdeCstU$`5m6I_>5!HE@Vrc$U3~waJu(}bV zv$dDt!;j1gJX{xiVb6$!TG}1T?YO~kjD=$~6s#OyNo~t(05f*<_CxxWmKiG{utfQ& zP&8_7+N4;QZo_N3-t6jRt2HzRTQ=Agev)j3x8oKv`EDGxPB7KlTvX9&2y1PcU6ou0 z5hdOPEc>IWgIJ`AsuZ&c8HMhxB1&!A)D>MwpG7qqUc}Q&Y;?n>xQ7{gvK-=CJaMNI z>VgM>moj<=Kv8_%9^670NdkDRwwqJZ3BRcPCr@8u+J7+`^B)pUEb+;-`52OUR%rbk zWU0o^B^K|(Q({WA71xRy9^#=`^~|fiRs7X^t6!eat!(j|&nA9)oJHBy6tOWI$8tiy z&IKB^c(FH|si29x*psJ4n!ycGWlyn%b5F;{?9=xYP=)o`s9$Tpu^#CgAVa!Zh3p@! z4+kZv@4{oe9g908zBH;f6PUU{kYWQrG+DxEr4-PVXP;%X$#WF-y!vE1PmWcQE$1lV zc&#K9Y*IlCd%3&h>lS_~GPmzHHJ?MW<{$GpKhhSd|6Du+L7LIN13vhOzCf)sMP#ex zNo%?Ii4RE;$=sbP`b0?k5>y>U2Lcj?t-)(lJSsml`FE4j5Jz@^11A}iBCsX$$#XVUSC z(OWtCmJU+7`IC^K*t;bzfpZAFIEG3yKzF!vM4SF^B;(n1vRh-A_cFV`6gdm5oA~ey zfHtqBX^}Lkd?C9jDNag?+4Xh%h_mjXH``>p zK481N_aayW)9(<0>Hdm;zFzRZ{(bRfAbn))o9B76vx~QH0l)T8-J#QENf#vpSSdB^ zUoKbc>2BLajUgM~e%c1Fc{GR8KAMI6%q?(Cs<3Ckm0cjgZOev6z3y$^?5Oo-AbYFh zWAN+=YvL>v>ZfH7`AntuoE>WqHjW5ku|;(?9lt%hWnzZpan}k`I>qWw%ohI=dtRcK zPcD}e)I@3*?SHXQwBHkTzv$%zXz|Ca?1Ui0ByZpbqjB2a#wSkl;wywExv_VXFnZqc zcol4dP~Yvj8}Je38%AoW6|UH@Cj>&Y=R*i8DIk~~5>YB$ykNJ_DMj%q;`88jwac$- zBbO2z#)P)YLqNwxaNpt-z}M4SpxjNUAdsIu!Vg_}wr7hsD&SU7j_?Vv z7lw1>Tni}4G>8&}N;!GWbPPj_q>hn~D;8GEQYu5BrWlEq*UC2~Hfd#-z)gZ>X)AYr zE*6A|zXMs9u{nzdex3dUxK;VS<|~a`<4)Y}4GS%(&XQuaH*~-qVP>di{o(jYq@7Uy z=#xL4G`R^IRb2OlF}chI|B=#>o>|ik_wSigF3YYiV5iNfT1chY)u5@;65J+Z#z5}b z*DiVEU1E1v+>Bsq$xyOZ4#JY>+~Gh?a*M9;(Z0*S94bR-4dmtoz#DBY*5uP(D$CY@ zNn8Du$=~8~xX)*SD&q-Gb`SQ3QDAt|ljOu)D0M?VCs8#xLDEO*p04p(`klDJmfz|5 z=*gT-eql!}B{wFRn_nfDZlh^RdjYyqz)O4oIJSc;3Ed^96sBkf>k`X_FzFC$eVD_+nC&iP56-q+Zg_u;U}vW9Cd5Ohu_=`KJ^#yKSOay>MhsCuZwBu6VAk z0M>~w(+u^e%8EyqE?-x}{jxGg$y=1iIL-ZXdsasF?f$tnCx*PQi6eZ6LEil8Ke;IN zv(w)EM=tsl$3#Ji00lt-O3lnCbhG8+ zAoF=ly8tYT9 zeL62MKlv(p31O2W`Q2gQyVi2qePUF)H(FwCColK)`Nm+i6ZqR|C_@4NxQQzNqYvxY zn1sr-giLJx2PZ+Eh%d1}`^+P6%h;F-KxbOzZ%$*!u&3@{6`J7f4jK|7Y&?P_i55*t z5_^}ydnfjyLR;!Z1}&m7ck74uxM4-e$#RzBDI%pF)+s{x5jx0J~MfTjm?MyCk+e2=x z+O|(EbHTH-s3aVrf=h4n3-hN-%!g|g)zM`ashIa4oR{dat=M6Ovwx3HqVAq|=okNW zPal7XcyDaBmx&{9flIYyYs>5|1IB#=x#^(lqLPeQ@M_D(uLg3TYG)7>mUa`Yk(WOF zBqL=qCG%FyC_5-@*XK@^EO2(CYBu(tZ25BxJ1te+Jf z=DWpt!mqGTd0yK@(Y3G%Q^ES;wZR?9yjaD7R@5L8gMgs7G=vnnMgDOIrnMUtTPe;U z7jSvSB`gdDR#HF4ma;=o2P8jI?K*x&1@eRr@OzTbX{(CI&S7s-7U*jLd zclm5hzoUcvl~vGNwN{E;=h03{$N87n@Ch-)+~#9NA+xXh-ZwA;1;_?w(xz`SfcgK* zt^W_;Y3%<6o+ui0+N3Tca!hBIJoCvW%t<2f6QwT!0CXU+1ysBtcf4j41}f+c1kFo0 zn6J|pjKEl!m$6TcY`YsJ(gxA7Bm+*NQ0eOEgENnA$83#p)E+KFN~%epWHL2wae>Ca z0Nj}Sbz7#{N*Y!D6g6&|`9=0XC{~w7B31#!`xOXgF-(|hM0`cjg%s5e z4PDxcvg@Ilvr9OsTX4O*I+5!m?<5MjWYI+xZ5=Y@^fj)TbDi=gqz3)}BaU={K`EtJ z(O*(o@hA6<-IRL8lT7ssP5JGKd}J1*Y96`+YoS{8q>9|*S&I%D6hpZH^9v>o4T`X1 z(#rE$sa9@o`jhLR>3u7hOly#65FrDD%p2U4*KG&+mOsuE{=|$&wwe|{1l`Gz&1HV{ zOws|ZuXV_>$e8wPA}coJKl4;}5}jwI~V1NyHFMeRjSpdX~_B?f3= zGOF7l^zVS3Ccr^fqs8mfmK5kmp(<>tXV}Tax&^_uNo@vl6|A-mC>D~H@YL!-LKCee(A;)Qkoa@emF{+G*`e}LLa%Z z80RGSfV$EFWK94aF)-p3niUYL48$9xY*-(WP#=0J?@xNm>bKPMx}(` zJ+BXp*QYH&LnDt~F%it^L5U8sd=*O2E5?&Q_b$o#K>=4N>s@5f5w(s5E?B50@ z<81PMIUU2}>^{w2i+ng^ePEf&e91%UWP2qL6(WyDA2K!rpG~6w1PIgTbL(U>9_k5k zovCF;Mwz8GA+bXA7psxuW~iwK42vK4qMNl!!rE}0r0MU~m!9pl15@I6@~bQfbvquD zJv*`&{2c(Ebe1u2ia&fu9{FBr4vGaLKo|6BDn^Jkprd&TG$KX>^-$B&>;PFB!E)%F zltMSKX-6(izHk9Tm3l=-Rn?@hx`Qg`QS&O)G!er1-JNUAeRMEdv`ZT`HP!gU(U~!_ zKhhuVOPC9jgLg|m@03oObVc-@5@^91)7_cGp8_y5@bPH>^F4*+yY)CR8i9BFkCNM$ z1pJAG@t&^l1(z@xA@Xb$uQ@mpl@K3i zz62!J$T319@ua$Kdw}SeXUam7olOpm^~HT{ZS#qHLlDego2h%f+R2_rc+YjUP~hY( z4vu9Q9tl}omz0eRdfx1Hi`mf4G}NZ7%ye<&?OfsB5cmi}cw7Fvg)2WOIxJeX{P+1a zkF>=v%tP>lLB+k_xbuHuT=}hizKj9*(g5!_2m<&%JHAmne(S#f?7xQy9Q&qOPcrA9 zG7-h=)tsi&10hAFo6KbcZlsCY|Gkn&!}kX9aOJcH{(YuOLKEg?m+rQ3ki~~k( zIpN?4V7J3I8~h>|VP!^n7H=gI82TyYOFh5BbBV*|8+R-U%L0xkZ-GH=aD6J?{MKUY zab;>UPuq04Pgv2D)YFxh2b$B+?6Zy?|Ce)u{U6TBVG1j4@|3SsiI&`q2)4fZ=?pY; zc>MWp2mS-hB`dpo1D2!}faN#*i4`VrK28(Og!q7#Fps^NBAn~Z-q(f-1vLs9T^aP~ z*5T3nj`owZS2Kn@3=O3X4Q<~BzcxbS*lhcZlv)S77-+E|$VmnY>3Ei6 zisvnQrpSrJf^5A=+EM&qPqkQ#wG9h_0zps_)-2aW3lBa>X=50GY~#|$joV!-#}Af( z7~H|_5e5F%vTo)jT<{A=Y8hdX} z^$dmwEB0p`+4Ul!)_|!NRS0p!p#e_#dF`N8Vz?Vn&Me@bL>%yfSPONs zAEBju@-Ud9JR`IF^Ggr9q8kpc)H={JsnPbYK>z}@llK^7_2#8><9hyEq-K-M{cx}+ zcpBxILB5EZDh{*|bB61ZpLN3(7m`PO4uj&eM z%A>=dut?hA5>arI|0n^7vy@iVRj(Wr^Q?Y#Mw zmbeD>c&u1DC5}Jp%wO(G>O|bIB}3;ciU`IE2T9QaXukq*$cqgj5$b37Rr9$^8?5&?Pi9 z1trb4o$2amiswa&uea>-mhCL`oL+3WtKrdc4w$VN7e|8+Grw2B8Tk#SNka%q%q0nh zx+_?Js(Wgn#S6Cnq_VV94y@M5ya4!CX}7$q_*xbY_y!_o6l569m|k5oX2&pP!eIq* z8NyN{Eh`&vNwG_yacusSy-6wMrF!7T2iq{0oQ_4R2F~_h-$cox)ze?VhkivfEF(;B zEOOaHI;pPV-o4%87!fesg0G{llc?r_by(`w4g1tfd2)*xGHzmR0?-`L1pqw3WY7So zq~zCl_3h6m1)ZLSR=j$Kyi^PTg72F5>8hQ80` zcT{^(5JGH}QCkVJo~MF8AfrvXvY!EA@3`w{nuQMQHGw6~EfgFa8amiri4iIYl|ctG zc)EON?NDHR|DjIT!Aj0EfB>$sxaw>)O)(^$Ncoz6S2pv{V;eIB{r>CuR5akp6OgKz zk`ZnHZx0%16dUr2`Ri~eh|z1Za;h|pw*=X;;}}6&D?GHL)=nYTO_|%!+Mcx_U2iie z*--Q6)&(7ZqeCM_jRbzMqCZ5c9gf^@ho27$dY^z(WZEj$wn@}Dfa`gMK#B1Nbd0BV z$Q!JGJUwuU&}-`6#Ed+!XbE1lSXE9SqT@UjI z9v+?fT+!;4`%Egh8A>EwxIh>zn2l4nvLU3~dU}r#BR=*zNLJNS>WP#oshrzL6_^bElGRDV@P_(C3J>sA0`3V`yQMELV0H<2R;ug5DU5_Qd37v& zgS#ac+EcppRXL|T)Y3@v_PIiUuD@s-Y;^n1CazS6V>u9uY*Fc|>&JC><#%O3I6OI8 z{!yK}(e?Yh2DaO~MaZy9HarD`jvKxau+XFUtv zInMa$vJ-5gY!hC}z@&0-#V%rh3l%z(6aU3gVeIi_+|mZsNzGI6%)0&QWWkJB`=~0p zj&EZ4x8dk|Zeeu`CX6v7*-u$>dBpGN{L-REex2e8_&W9u`sMy}>`LRf7p^ybpLPxH zaQdqZz9c3G{xl`RffstJD#-O*@9*hZL`>gp!;bW0MIXD?(s^dL`Z?Dn16h04vef60 zAz7&J;gGKhn%3OXY>^A?cQZ|V)!nur)hZ|ng0NXmKx#E|J&kD za*e41W=kT9MF*s(sVb?V2ER+H;iHZ<9wlC>4vQif;fHpKI34n(^O@f5o?d{PyQOt0 z_e(ae6j7_8U>natboSY^KAuMXHg#?oHh8q~e7Fp;&UTm{dEyXf|DQcP(<3iaktcRt z*QwKXtF;slS*2O-lUeWP>z@`ZT5e7Dz4~lv7Jc140AIJ=mdQy91^TbgX?Kj>kJm$k z|914ez$gHM%AAz6hx0v^W;Lp&t8qA@<}IC9XC(ejuX;7tZ)k?E{gvJiJqme>ef8+j zsbd8XrFlLUFqUlabm4cJI z_*0AukQb9Hjv4eEVOS%qmisJ^+emRQY50Vl@Xz6`dr(hB;K6G$+|V8u4RYOYB8Z<- z>*}pZmV^}6v5Auur7-$Q#gf_YCtOi~5?xY1wsl!ym6ap+oO-H;$7VFDQokjc&Woc4LB)OOTAIAys136WpMzv|i@{*%h<=0g!!faQ{Vy^`> zPet4jmk0}^H^hqH2)2gu&Xu5b#JCmypR&$6D(dH7YwwH{x-y& z8l-2<>!?Z7A)T)3fj^R_G!r`lbMFVCU2ZKb^de5>SbUEKCXk+{l)|Buk`~T0QLU+x z7WpAY<-JwWg#&5#;GHw>Ka!>S4awgSGq?sX-rv-UL|4tA%4Zy`YUQoB+UTI49@80G zdp&9LMyZwJbh<%oTfbSSS#w`lWU8&RQnRNBbOTrfZ5m=!L`ie7_{rLM5{HTL;e~rt zk}hSE#=)BHwmNKM&cs9Akrg}Gn!NqKU4sE%jL|m%vzndz7OjtEMUEFGyW{q7L#bY( zK7xL_8g+Uyg3s8TU(GcQj&`8iPW6bFyW^f;O+2D@n0AqcOi}i{G zrD9Joi9QWWH!Bx-919fwRd<@9hZ((}StTbW6jx$Yrwrq<^*~_rT!$o^q-gCMS(Dle z2vH0iE_9*rqy=bS$W^1BdKbMc7zOpErqy6%T0EyT~ z^;T_o-^JA<{Xf?>L^EU1yy;-zX433o@?p*&D)msQ}5aQH&}7V7Mh?oON%- zG0FYj{=N}{#n~OY7%7~L6MU{1vY=fUgp(~?cr4!GF^g4>!SKcT4$n@?Wx1)~8 zWyo-d^B>1B5?KN~~Z8Zz!eOU~CI5!|08oE7W z9QVa?&_GMSP;{DQkFS*DU}6$DkN9?E8`NZ+L&(|~9j9a#KP|w@-|_L2Bhd2?l4RD+?JD&0?ZMbW4dI;f5?@CAB6Q5?6Y62}(hwV!)d^;^C!HZtUaf@*f#n4OlCp2v z)?{}jU8{d=G#VUH`hHmD1y>YHuxt}?B2Pqap&n%PDZkP(QvsN+)OEYh+n!=f(Ejlc z?DN5NtRx)lBjQ}^n_lWS`}g!pv3>_A6WZ(-e`JJ(cjF4(HwHc{F#O$U>>Lm0Sbuwoi!#n-aShPLBLvxSis5P0)FT?%7=;qEx z2O9R#fS`}pMEZT&5lwGFW!Smzd;psee_0%fjr`EW#?|&N9Q4`Zt3>)E7piQ{>yZl; zc=4xQ#(T!YanH*sA*@}K*ReCZnsPjDe4h996RS{z!T9G{O@VewZ9_`zCiq((9YyWh z(zd$21<5*G!D7G7i!eAmZcL4H6X@RSlS0w%jq%(P2B{!C?i5<~vO;pH+f#HqTBl`5 z!X7&*Llb>dYAU6g9E=52vy+xdTc2t1l~2R9)cYCh)l!O56l;b|pGlTg84%fpW z@Vh2&Ad|F3&)Sp>LlGHn_S&cM?xTxmcqH6s?KIslf8U8j`-It84VYMANwE|eK*d_# z-klp2$iKE$Y1K+7)Mvpkr;}Kd8~CB|#~%nZHf8^cf7pG!dFcUaGtGv~pR|8h8KVr6 ziU@dCdAo0$`c4LQPQprInjSwNJ4awzK?cb`SZ(x)wKKTgS!{2^ys36xZJgCe%|jDs zb9WYenpI>h|LYh^PkY+Qfd6660Gg6;gE(W{+L9A+ zuqAd1-z2Nd9tia5nu^r@)D~d*#*5UrW-?s?26qa!uukC|RQ?p4mc{R4h90nK(q$uO zNbGupp1)xHV)A>TP|VWU+45twtrf}MGczJsR1loL0>|JyBcA1D(RiXt$Zc252bGbR6UC-v8qHd>!K3c`y&D!x3-=|Vm@ap&xf zR?`O!z0nHBt|p%G!EcW?q^(4qzMSO9fT$uto|I z80U+r5;ik=Ig*gZrp8M;q>tZNo?-toLMBnfqaZ!;duMl`t$`EGPM0hWPH*rs%k(s& zyDhK2B0#u$!|&U(z(~1~MpM4;Q+{5(QtxC~3*RF8(bQo;Rm)#3F75QcbI}cIN#3wu z9d4md1KJrJT}aBJ&*-36tX;ARiIm}M7`VuWO=Wto80UUw?Z)&A$sBSvA2{15ql24y zv(TpnG}MXsg)Ga&6<@-i+O^bgczy;_JB*#@hdKluqi-lDD%%##pP029>na%#-5Z#< znT$E7Ux&=JklCPZ<~h=NogxR%>{Xs!f3^;&qpsnUGh6c>_dJKjDVh?LnrV;oiDg5m znr!jbf}B1+PdZAP?lXD3A?;wN+1)-p8uqLkF;*i1I8_d6%OO5A5P|Of1_sODV=un)&Mx zWx|*wae8f=UKt0)loLy`$3-8koG?rX>X)2?Y~7N?WdAJFv}yH-5f&6p!WG|Wb}=L@ z`S?Je!{!8o_ervBaKQpg=ChSqub%?)i7uy^@-C!aj2`aOO_d;oad?<2zL!Dg`vYPy zXPC5jfeAiu6Yz$w_<@7d%+Q|xjou8QVPpop^%W|>(UYxYViO~l5i<6f^x&_hjL|Vyrn~wWWKr@r5#= zWy6^(0qCR_ByL5{Sq@>cpG6$cm)#e8EN3K`UKm1c~GW)HBzYrEL-GVk73|1O>EuE9k z&kt>-g($F=-!P}uL5u#d-M&;v!A}RQl!vU48N6>L(?RpBy^oNa=St*IZ+l7)~%K<5eZa`~@ zV#UwztDC>?7S2=1t1I+iCRX}-ylkner9TNP`})IQ&jrisVt$%rEu|e+k=|2p6w77b zvkY+E^Y7fPG{5vOa&|3h-@)gz7a}Zi_&$e%*_Xy~b+T<;9eKG{bP!SqHAOBe1o=(pt zIny14q6?1IegWoL$AeKPY8zT}t9k-KnqX4%t*_w~8>=GYJO{loYej`jbD@qJgBD^O z3qH`!_Nt?~&^OUDTMZl$>>0`jP~5YyXGGvZHUTQf(GOLV+UlxV9M-||D7Q&;uSw4r zZXtKJr|~z0)PbUXeY?buY4+T>t>)gGkt+f}8;qfaZ_n#r!Lyp44j6dk?prS+F>W0+ za9h9nH|$*={W2;xTAHg0ATP?XeM{(BV&A-eMO$&MlcwdT0U7+x@m^Kw3AAcMnPiCxIiZIHm6a&p$rvaKq}7~N#pk7+zx8vwKU_yb z^E17Sx#ilv=;jR5%c?BGoQ+MxwLNn}H5c!n@PIH5>V7Pr+<#&m;U?f|^ulA~U9qw; z=xFOed}gQr>jSi8=MS0`B&X003W47CQrU8%r8}IAW3%)Mo!`fA%DX`QG?B`fUF~o( zg5l67+*3HJ9J$UMpGE$#RupE?@1sCG)kpdyVs0}T*L`$kiK@__S}Tt^>9gs6vt z{(rjBxY?4&(hy1DFT-`6)wHdax99c}-Y(_dkky#F+kC3DaQQx9DUQn0AHr1nKPG=tbdtRO1 z1{m3HvAj*5Gxu(L$-W33pA+VEIEvL5XN!i{kcd!MqN^yy zdTWXWcZE5B^BPG9R}cxLMPzr& z4eaeF37tZr!(=n4dW}U!j-Ffx>&lb00tYED#slYijicNC(}G&9`_O;RDGNia(t=+^n%Prkc$+ z5m3U4%nOK=Yy?4NIl?w)&{5l7ebx9(55+v)^$IR!6`usr1-1p0BYtKB$zp} z*>?>^z^RJdH_}{BM62aghUa4*t&eR#8kkV!;VFW@!}ZL$WTP#*)$*$aWDRGLo9zRD zHLs$ZEf;D_YA8g2z*!s`;30fhuX02YkF>H2C#XIAGU3oz01Awv%E*KQ4y^jIWNw8^O-co4`dGe|Z1N6(mIl55Zs=l6OoykOktPL^mHOCvfG2R@j45vUrs6{#ad zOI{H_pEG{Am&_HOSZK|oH~%VK9H~x!nF93(&hF6l;peq-QyPCzM$LNQ)dl^!7<5^@ zNAfJ4!v~C33@5mM^i9F1BykaI=Gzy+6`PuOJu8@ zaF6fTHxT-XM!{%Re@-aJHg=IEXDnJwn%r-kmL02G1WeB<_gtuauFA=iTSBS+^>$)+ zMZsZx7fx_EE(38OCDWo01uio`mC0!DYjn?g%j>Qr%k-yY4>kmT6WE!~1dV|_l4rZ8 zq@`BAW-5hVOz*sR?U`gSCY_+mIwBN%V<8?RpU^&!LBv;BGLTymoFn^RE`rW`NQ`X8Q4moDo}2;PjQ0C4ddy ztGkSEf4)?n`~0}DOd>FXP>4P(sQ%DoAvK@{FxF}}Y}&tPQUxfFbGkEOA7Llcd-MUU zVPv>tq#<|9Dj~!(78%eW3(n)DxGy?D)+;LnWGG1CFwsjp9%N-DH{BCLueaNY*gZ|7 zUZv_K4cO!D3$`;K^DDsNPd@jbAEV7jl1#KL!Ht?vpHykF3^hF8CKW?lF)cTRp=dEP z$|2qE`s%@tRH_W8LBKkI$yu)*iOxyx;24wY7LeSB0VoUc8ya$Yctr&2Ec9v;;1&Qe1+D z&(7wxH^**x@&ZM#?uhJDe${Lg{EdCsGBm10viL84r9Cu`<;g4`wg?+DsX0`40pZF< z314>1s#befa6&7cktpGygOyHC_~afaN}L+l0gn}|Jo0R<6lef9Yo6qoJaNW`$keMo zbqpLtRh&GA98n0>Fvdu6r*+Mdh^t)TU_@646qZ!GBJ0Pg%dyUi4`( zK=Rh)JH+tfvLI+ij8)iWTvyB}!LH=H19g+X?K-CAjjNk6a_E>yJ;=w~89oxS`OTeOS7zn|eOh!a zynN9NdTB4ro!AjfCHI$xIeA00=5zw4-Kc@N-xwt3n$itmZEuLv822l{T71LROo918 zBzl%D^vrISxJL19?69r#>_noAT)B_wyf~4ttv(;yD1b>p`J5?ubLnqo5G8o_;FZuz zAI5V=NsI{sZKtN_S}L~_f`m|y-lVTGg;VeKp(b+|G$Q?#r?SeDKjmNs@PQrlz~=RY zeX6dTkiSh9#(*YFmxgn!t^FQA`HK79+K5gf#jJ<)6RP0w-JErFM{>cALEt~xsVQ^r zb-=;-j*mN17F&D*^PqGG-p}T#ms$%3_uf~%sx!nZk+F+>K1R?1&kkY`>`e&*N;P@| z4Ty}sV;D6yx2>mRB?D~Rznft*iX;D%c&b5I=jJ%PDJ6kaWleTPvRx(YP=iOO@zua} z9~BT66z7<6Vd=S$_!;nWC+fKVDu79s+D_b}4-vcN$(2f^Q|J)2RZC>EA4PM}gaW+i zo|t%GRQzD8C&QiiQ}`*?#(=`|o|_(&Kr-|KyDD=v*TcBJGZx!Hs##}5UozF}5aZ=5 zk=yFl{qc{D*xM1og>m{ujw_{?h*4Aw4i+K>#~O zE`AvKewZz z@qq5bU%-#d#`jZ)8ut~ARA`!vWT7s6Y19rm_Far`b~wI6io9^gyCiKzqwJZMv@S%h zPkPsn$o892rb1K+;#DU8`@mE&X!M>vzXIT={xqW3i{K@gOM_Mw8`7^c95V+VV>rjS zUm~QyMr3{?f3Dr5CZ3F(`*{paP0c883dtP>t7}=Mjsd12I%EJ${X>}h zdGKRr`71ihdaT0SV$cgwhvlfzIM_j1Eu{d2 zN#MU5lPeR!|8xX|g@homnsRY_QP97J1cgKdMEXQhXxS@ z!?Y^Ip%B4;4~Ytk{o5WSBn0}mJ?K&T_YOc{A;JIDKp?Syc?b&#ga3CuqW{~zuz-jt T1V&XUhA%88M8L+Tpr!a;GpA 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
expand @@ -920,6 +919,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en - [x] `12027355` · L 70 / E 70.33 / Δ +0.33 · `hpcdb1838/gas | solid brick | pitched insulated | ext1` - [x] `100120926050` · L 71 / E 70.67 / Δ -0.33 · `hpcdb18514/gas | cavity wall | pitched 175 | ext2` - [x] `100012548450` · L 74 / E 74.33 / Δ +0.33 · `hpcdb10338/gas | cavity wall | (another dwelling` +- [x] `100061275133` · L 76 / E 76.33 / Δ +0.33 · `hpcdb18908/gas | solid brick | pitched 300` - [x] `10012184174` · L 75 / E 74.67 / Δ -0.33 · `hpcdb19006/gas | solid brick | pitched insulated` - [x] `100031680815` · L 61 / E 60.67 / Δ -0.33 · `h402/elec | cavity wall | pitched 150 | sec:room heaters,whw903` - [x] `100070057052` · L 66 / E 65.67 / Δ -0.33 · `hpcdb10200/gas | cavity wall | pitched 250 | ext1` From f69d345493fae305c03febbeec3cfa3de8c85b62 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 09:41:09 +0000 Subject: [PATCH 37/84] =?UTF-8?q?docs(corpus):=20correct=20100061275133=20?= =?UTF-8?q?pin=20comment=20=E2=80=94=20real=20driver=20is=20Table=2011?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prior comment blamed a stale build-side combi artifact (already fixed this session) and my earlier conversational claim that Elmhurst's overall SAP used regional weather was wrong too — verified the worksheet's (5) dwelling volume and wind table match our UK-average rating cascade exactly. The actual, now-quantified driver: Elmhurst's worksheet (201)/(202)/(215) show it unconditionally applies SAP 10.2 Table 11's 10% secondary/portable- electric-heater fraction based on main heating category alone, with no secondary lodged on the cert. Our `_secondary_fraction` deliberately gates this on an actual lodged/forced secondary (see the adjacent S-B30 note: applying it unconditionally regressed the full 1000-cert corpus MAE by +0.16). Forcing Table 11 on for just this cert moves 76.33 -> 73.62 (~62% of the 76.33-vs-72 gap) — confirms this, not a mapping error, drives the residual. Documented so the next reader doesn't re-litigate it. Co-Authored-By: Claude Fable 5 --- .../test_real_cert_sap_accuracy.py | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index e1877c598..d19acf630 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -875,10 +875,11 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( # U 0.29 (engine) vs 0.30 (Elmhurst) — which VALIDATES the slice-5 # external-insulation default (100 mm added over solid brick, # `_WALL_ADDED_INSULATION_UNKNOWN_THICKNESS_MM`); the suspended ground - # floor is U 0.68 (engine) vs 0.70 (Elmhurst). (Elmhurst''s overall - # worksheet SAP is NOT comparable — the reused-assessment combi entered - # as a "Standard Combi" carries a Table-3a keep-hot loss the lodged - # assessment did not, a build-side heating artifact, not an engine gap.) + # floor is U 0.68 (engine) vs 0.68 (Elmhurst) — EXACT after rebuilding + # with 0 extract fans + PCDB 18908 (was 0.70 pre-rebuild). Ventilation + # (21) shelter-adjusted ACH is EXACT too (0.6938 = 0.6938), and dwelling + # volume (5) 196.8995 m³ matches (confirming the mapper's +0.25 m + # upper-floor height convention mirrors Elmhurst's own internal one). # §5 (12) fix: the Main bp lodges no `floor_construction_type` (gov-API # leaves it None), but `epc.floors[0].description` = "Suspended, no # insulation (assumed)" — `_has_suspended_timber_floor_per_spec` was @@ -886,7 +887,20 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( # genuinely suspended-timber floor. Now falls back to the joined # description (mirroring `_main_floor_u_value`'s existing fallback), # applying (12)=0.2 unsealed; engine converges EXACTLY on lodged (76). - # PINNED to the observed exact match. + # Elmhurst's OWN overall worksheet SAP (72) still differs from ours + # (76.33) even on these now-identical inputs — traced to SAP 10.2 + # Table 11: Elmhurst's (201)/(202)/(215) show it assumes 10% of space + # heat comes from a portable-electric secondary (658 kWh/yr @ the + # electric rate) purely from the main system's category (gas boiler), + # with NO secondary lodged (`secondary_heating.description == "None"`). + # `_secondary_fraction` only applies Table 11 when a secondary is + # actually lodged or forced by §A.2.2 — deliberately, per the S-B30 + # note a few lines below: applying Table 11 unconditionally regressed + # the full 1000-cert corpus MAE by +0.16 (lodged software doesn't + # apply Elmhurst's blanket convention). Verified: forcing Table 11 on + # for just this cert moves 76.33 -> 73.62, ~62% of the 76.33-vs-72 gap + # — confirms this is the dominant driver, not a mapping/entry error. + # PINNED to the observed exact match (vs lodged, the correct target). RealCertExpectation( schema="RdSAP-Schema-21.0.1", sample="uprn_100061275133", From d15ea8b7d49f241d4ebb1e25d8ef6f8a0bf45639 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 09:52:22 +0000 Subject: [PATCH 38/84] docs(corpus): find the second driver of 100061275133's residual gap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Walked the worksheet section-by-section (dimensions, ventilation, fabric, internal/solar gains, MIT, space-heating requirement, fuel cost) against the calculator's matching intermediates. Internal gains and heat loss matched closely, but solar gains (worksheet line 83) was 2.2x off in January (56.9 W vs our 123.4 W) — traced to the Elmhurst BUILD entering all 12 real windows (3 orientations: NW 7.05 m2, NE 1.21 m2, SE 7.06 m2) as a single synthetic 15.32 m2 "North" group, understating solar gain. Verified by reproducing both build artifacts in the calculator: real windows + real Table-11 gating = 76.33 (our answer, matches lodged 76 exactly); collapsing to a synthetic single-North window + forcing Table 11 on = 72.62, reproducing Elmhurst's 72 almost exactly. Confirms neither residual is a mapping or calculator bug — one is a deliberate, regression-tested spec choice (Table 11) and the other is an artifact of how this specific Elmhurst reconciliation build was entered. Co-Authored-By: Claude Fable 5 --- .../test_real_cert_sap_accuracy.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index d19acf630..24dde9482 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -898,9 +898,21 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( # note a few lines below: applying Table 11 unconditionally regressed # the full 1000-cert corpus MAE by +0.16 (lodged software doesn't # apply Elmhurst's blanket convention). Verified: forcing Table 11 on - # for just this cert moves 76.33 -> 73.62, ~62% of the 76.33-vs-72 gap - # — confirms this is the dominant driver, not a mapping/entry error. - # PINNED to the observed exact match (vs lodged, the correct target). + # for just this cert moves 76.33 -> 73.62, ~62% of the 76.33-vs-72 gap. + # The remaining ~1.6 pts is a second, separate cause: (6) Solar gains — + # the BUILD entered all 12 windows as one 15.32 m2 "North" group + # (E.set_single_window), but the cert's real sap_windows lodge 3 + # orientations (NW 7.05 m2, NE 1.21 m2, SE 7.06 m2 incl. the largest + # single window) — collapsing to due-north understates solar gain + # (Elmhurst Jan (83)=56.9 W vs our real-orientation 123.4 W). Verified: + # forcing our engine to ALSO use a single synthetic North window (i.e. + # replicating the build's simplification, not a cert or engine fact) + # plus the forced Table 11 above reproduces 72.62 -- matches Elmhurst's + # 72 almost exactly. Conclusion: the calculator is faithful (it already + # matches lodged exactly using the cert's REAL window orientations); + # both residuals are Elmhurst-worksheet-reconciliation artifacts (a + # deliberate spec choice + a build-entry simplification), not mapping + # or calculator bugs. PINNED to the observed exact match vs lodged. RealCertExpectation( schema="RdSAP-Schema-21.0.1", sample="uprn_100061275133", From b37be6327c1b7906438273a7aeb7592a321c988e Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 10:13:19 +0000 Subject: [PATCH 39/84] =?UTF-8?q?ASHP=20sizing=20selects=20the=20smallest?= =?UTF-8?q?=20pump=20meeting=20the=20dwelling's=20design=20heat=20loss=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../generators/heating_recommendation.py | 25 +++++++++++++++++++ .../modelling/test_heating_recommendation.py | 17 ++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/domain/modelling/generators/heating_recommendation.py b/domain/modelling/generators/heating_recommendation.py index 70c33142c..dab016843 100644 --- a/domain/modelling/generators/heating_recommendation.py +++ b/domain/modelling/generators/heating_recommendation.py @@ -137,6 +137,31 @@ _ASHP_OVERLAY = HeatingOverlay( ) +# ASHP sizing ladder (ADR-0049): the Vaillant aroTHERM plus "& AI VIH RW" family, +# one representative PCDB Table 362 record per nominal size, ascending by rated +# max output (kW). The pump is sized to the dwelling's design heat loss so SAP +# 10.2 Appendix N reads the heat-pump efficiency near its PSR peak (~1.0), rather +# than a single fixed unit that is grossly undersized on high-heat-loss dwellings +# — where the PSR collapses and the ASHP scores at/below the resistance baseline. +# 110257 (the 5 kW rung) is the previously-fixed anchor, validated against the +# relodged after-cert. +_ASHP_SIZING_LADDER: tuple[tuple[float, int], ...] = ( + (3.76, 110249), # aroTHERM plus 3.5 kW + (4.37, 110257), # aroTHERM plus 5 kW + (6.40, 110265), # aroTHERM plus 7 kW + (7.93, 110273), # aroTHERM plus 10 kW + (11.48, 110281), # aroTHERM plus 12 kW +) + + +def select_ashp_pcdb_id(design_heat_loss_kw: float) -> int: + """The PCDB heat-pump record to install for a dwelling with + `design_heat_loss_kw`: the smallest ladder rung whose rated output meets the + load (PSR >= 1.0), capped at the largest rung when the load exceeds the + domestic aroTHERM plus range (ADR-0049).""" + raise NotImplementedError + + # --- Gas boiler upgrade (Heating/HW expansion): replace an existing wet boiler # with a modern gas condensing boiler. Validated against Elmhurst before/after # re-lodgements (cert 001431): the upgrade always targets mains gas — gas->gas diff --git a/tests/domain/modelling/test_heating_recommendation.py b/tests/domain/modelling/test_heating_recommendation.py index 366c51869..deca9ffad 100644 --- a/tests/domain/modelling/test_heating_recommendation.py +++ b/tests/domain/modelling/test_heating_recommendation.py @@ -7,7 +7,10 @@ later slices. Detection + pricing only; impact is produced by scoring (ADR-0016) from datatypes.epc.domain.epc_property_data import EpcPropertyData from domain.geospatial.planning_restrictions import PlanningRestrictions -from domain.modelling.generators.heating_recommendation import recommend_heating +from domain.modelling.generators.heating_recommendation import ( + recommend_heating, + select_ashp_pcdb_id, +) from domain.modelling.measure_type import MeasureType from domain.modelling.product import Product from domain.modelling.recommendation import Recommendation @@ -764,3 +767,15 @@ def test_boiler_upgrade_leaves_adequate_controls_unchanged() -> None: ).overlay.heating assert overlay is not None assert overlay.main_heating_control is None + + +def test_ashp_sizing_selects_the_smallest_pump_meeting_the_design_heat_loss() -> None: + # A 6 kW design heat loss needs a pump whose rated output covers it: the 7 kW + # aroTHERM plus (PCDB 110265, ~6.40 kW), the smallest ladder rung meeting the + # load — not the fixed 5 kW unit (4.37 kW) that would sit below the load and + # collapse SAP's Appendix-N PSR efficiency. + # Act + pcdb_id = select_ashp_pcdb_id(design_heat_loss_kw=6.0) + + # Assert — the 7 kW aroTHERM plus rung. + assert pcdb_id == 110265 From b18fc3878bb5ba49bbe4d9c9e9c691847d7f625c Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 10:13:46 +0000 Subject: [PATCH 40/84] =?UTF-8?q?ASHP=20sizing=20selects=20the=20smallest?= =?UTF-8?q?=20pump=20meeting=20the=20dwelling's=20design=20heat=20loss=20?= =?UTF-8?q?=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sizing ladder (Vaillant aroTHERM plus 3.5-12 kW PCDB records) picks the smallest rung whose rated output meets the design heat loss, so SAP 10.2 Appendix N reads the heat-pump efficiency near its PSR peak instead of collapsing on an undersized fixed unit. Co-Authored-By: Claude Opus 4.8 --- domain/modelling/generators/heating_recommendation.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/domain/modelling/generators/heating_recommendation.py b/domain/modelling/generators/heating_recommendation.py index dab016843..f4f7375dc 100644 --- a/domain/modelling/generators/heating_recommendation.py +++ b/domain/modelling/generators/heating_recommendation.py @@ -159,7 +159,10 @@ def select_ashp_pcdb_id(design_heat_loss_kw: float) -> int: `design_heat_loss_kw`: the smallest ladder rung whose rated output meets the load (PSR >= 1.0), capped at the largest rung when the load exceeds the domestic aroTHERM plus range (ADR-0049).""" - raise NotImplementedError + for max_output_kw, pcdb_id in _ASHP_SIZING_LADDER: + if max_output_kw >= design_heat_loss_kw: + return pcdb_id + return _ASHP_SIZING_LADDER[-1][1] # --- Gas boiler upgrade (Heating/HW expansion): replace an existing wet boiler From 7707df3294b54ffc46ac865579ae9581cd704e98 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 10:14:10 +0000 Subject: [PATCH 41/84] =?UTF-8?q?ASHP=20sizing=20caps=20at=20the=20largest?= =?UTF-8?q?=20pump=20for=20a=20high-heat-loss=20dwelling=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../domain/modelling/test_heating_recommendation.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/domain/modelling/test_heating_recommendation.py b/tests/domain/modelling/test_heating_recommendation.py index deca9ffad..51d41f035 100644 --- a/tests/domain/modelling/test_heating_recommendation.py +++ b/tests/domain/modelling/test_heating_recommendation.py @@ -779,3 +779,15 @@ def test_ashp_sizing_selects_the_smallest_pump_meeting_the_design_heat_loss() -> # Assert — the 7 kW aroTHERM plus rung. assert pcdb_id == 110265 + + +def test_ashp_sizing_caps_at_the_largest_pump_for_a_high_heat_loss_dwelling() -> None: + # A very leaky dwelling (17.5 kW design heat loss, e.g. UPRN 10002468116) + # exceeds the domestic aroTHERM plus range, so sizing caps at the largest + # rung — the 12 kW aroTHERM plus (PCDB 110281, ~11.48 kW) — an honest, still + # far better than the fixed 5 kW pump whose PSR collapsed to ~0.25. + # Act + pcdb_id = select_ashp_pcdb_id(design_heat_loss_kw=17.5) + + # Assert — capped at the 12 kW rung, not left undersized at 5 kW. + assert pcdb_id == 110281 From cd4ed81185c809339db0a322c44c719ebb6e4c8d Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 10:16:43 +0000 Subject: [PATCH 42/84] =?UTF-8?q?The=20calculator=20exposes=20the=20dwelli?= =?UTF-8?q?ng=20design=20heat=20loss=20for=20heat-pump=20sizing=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- domain/sap10_calculator/calculator.py | 6 ++++++ .../domain/sap10_calculator/test_calculator.py | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/domain/sap10_calculator/calculator.py b/domain/sap10_calculator/calculator.py index c30234a7c..f3a10165b 100644 --- a/domain/sap10_calculator/calculator.py +++ b/domain/sap10_calculator/calculator.py @@ -403,6 +403,11 @@ class SapResult: space_heating_kwh_per_yr: float space_cooling_kwh_per_yr: float fabric_energy_efficiency_kwh_per_m2_yr: float + # The dwelling's SAP design heat loss (kW) — the annual-average heat loss + # coefficient at the design temperature difference (24.2 K). Output-only: + # it is the quantity Appendix N's PSR divides a heat pump's rated output by, + # so the ASHP recommendation sizes the pump to the dwelling from it. + design_heat_loss_kw: float main_heating_fuel_kwh_per_yr: float main_2_heating_fuel_kwh_per_yr: float secondary_heating_fuel_kwh_per_yr: float @@ -872,6 +877,7 @@ def calculate_sap_from_inputs(inputs: CalculatorInputs) -> SapResult: space_heating_kwh_per_yr=space_heating_kwh, space_cooling_kwh_per_yr=space_cooling_kwh, fabric_energy_efficiency_kwh_per_m2_yr=inputs.fabric_energy_efficiency_kwh_per_m2_yr, + design_heat_loss_kw=0.0, # stub — computed in GREEN main_heating_fuel_kwh_per_yr=main_fuel_kwh, main_2_heating_fuel_kwh_per_yr=inputs.energy_requirements.main_2_fuel_kwh_per_yr, secondary_heating_fuel_kwh_per_yr=secondary_fuel_kwh, diff --git a/tests/domain/sap10_calculator/test_calculator.py b/tests/domain/sap10_calculator/test_calculator.py index 7ab7d3c0c..12157d172 100644 --- a/tests/domain/sap10_calculator/test_calculator.py +++ b/tests/domain/sap10_calculator/test_calculator.py @@ -815,3 +815,20 @@ def test_split_tariff_charges_space_heating_at_off_peak_rate() -> None: + (r_e7.pumps_fans_kwh_per_yr + r_e7.lighting_kwh_per_yr) * 0.1319 ) assert r_e7.total_fuel_cost_gbp == pytest.approx(expected_cost, rel=1e-6) + + +def test_calculate_exposes_the_design_heat_loss_for_heat_pump_sizing() -> None: + # The ASHP recommendation sizes the pump to the dwelling's SAP design heat + # loss — the annual-average HLC at the design temperature difference (24.2 K), + # the quantity Appendix N's PSR divides the pump's rated output by. The + # calculator surfaces it as a typed output, derived from the HLC it already + # computes. + # Arrange + inputs = _baseline_inputs() + + # Act + result = calculate_sap_from_inputs(inputs) + + # Assert — HLC (W/K) x 24.2 K / 1000 = design heat loss (kW). + hlc = result.intermediate["heat_transfer_coefficient_w_per_k"] + assert result.design_heat_loss_kw == pytest.approx(hlc * 24.2 / 1000) From 039df7ae8767b88c8d8b167838b1116026895d8c Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 10:17:42 +0000 Subject: [PATCH 43/84] =?UTF-8?q?The=20calculator=20exposes=20the=20dwelli?= =?UTF-8?q?ng=20design=20heat=20loss=20for=20heat-pump=20sizing=20?= =?UTF-8?q?=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit design_heat_loss_kw = annual-average HLC x 24.2 K (SAP design temperature difference) / 1000, the quantity Appendix N's PSR divides a heat pump's rated output by — surfaced so the ASHP recommendation can size the pump. Co-Authored-By: Claude Opus 4.8 --- domain/sap10_calculator/calculator.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/domain/sap10_calculator/calculator.py b/domain/sap10_calculator/calculator.py index f3a10165b..34f0f1ce7 100644 --- a/domain/sap10_calculator/calculator.py +++ b/domain/sap10_calculator/calculator.py @@ -65,6 +65,11 @@ from domain.sap10_calculator.worksheet.rating import ( _AIR_HEAT_CAPACITY_WH_PER_M3_K: Final[float] = 0.33 _TIME_CONSTANT_DIVISOR_KJ_TO_WH: Final[float] = 3.6 +# SAP design temperature difference (21 C internal - -3.2 C external): the delta +# the design heat loss and Appendix N's PSR are evaluated at (matches +# `_SAP_DESIGN_HEAT_LOSS_DELTA_T_K` in rdsap.cert_to_inputs). +_DESIGN_HEAT_LOSS_DELTA_T_K: Final[float] = 24.2 +_WATTS_PER_KW: Final[float] = 1000.0 # §9a default — used as `CalculatorInputs.energy_requirements` default for # synthetic constructions that bypass cert_to_inputs. All-zero fuel; the @@ -877,7 +882,9 @@ def calculate_sap_from_inputs(inputs: CalculatorInputs) -> SapResult: space_heating_kwh_per_yr=space_heating_kwh, space_cooling_kwh_per_yr=space_cooling_kwh, fabric_energy_efficiency_kwh_per_m2_yr=inputs.fabric_energy_efficiency_kwh_per_m2_yr, - design_heat_loss_kw=0.0, # stub — computed in GREEN + design_heat_loss_kw=(sum(monthly_hlc) / 12.0) + * _DESIGN_HEAT_LOSS_DELTA_T_K + / _WATTS_PER_KW, main_heating_fuel_kwh_per_yr=main_fuel_kwh, main_2_heating_fuel_kwh_per_yr=inputs.energy_requirements.main_2_fuel_kwh_per_yr, secondary_heating_fuel_kwh_per_yr=secondary_fuel_kwh, From 645789456e10dcde4ee24891f889370342af1d6e Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 10:19:05 +0000 Subject: [PATCH 44/84] =?UTF-8?q?docs(corpus):=20find=20the=20third=20driv?= =?UTF-8?q?er=20=E2=80=94=20mixer-shower=20default,=2091%=20of=20gap=20now?= =?UTF-8?q?=20traced?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Walked the water-heating worksheet section: assumed occupancy (42) matched exactly (2.4234 both sides), but (43) average daily hot water use was 117.41 L/day (Elmhurst) vs 110.73 L/day (ours) — same occupancy, different shower/bath demand. Root cause: the cert's shower_outlets field is genuinely unlodged, which the mapper correctly maps to 0 mixer showers per its documented, already-validated "no entry = no shower" convention. Elmhurst's build shows a "Non-electric shower" fixture anyway — its UI silently defaults one when the build script doesn't explicitly configure "0 showers" to match the cert. Verified: a single 7 L/min vented mixer reproduces Elmhurst's (42a) monthly series exactly (4 d.p., all 12 months) and closes hot water to 2616.04 vs Elmhurst's 2616.03. Corpus-wide check across 170 certs sharing this "bath present, no shower data" pattern shows no systematic bias (mean dSAP +0.12, median -0.04) — confirms the mapper convention is correct on average; this is a build-entry artifact on this one cert, not a mapper bug (no code change warranted). Combining all three found causes (window orientation, Table 11, shower default): SAP 72.4567 vs Elmhurst's precise 72.0681 — residual 0.39, ~91% of the original 4.26-point gap now precisely explained. Co-Authored-By: Claude Fable 5 --- .../test_real_cert_sap_accuracy.py | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index 24dde9482..0bc3a95a7 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -907,12 +907,34 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( # (Elmhurst Jan (83)=56.9 W vs our real-orientation 123.4 W). Verified: # forcing our engine to ALSO use a single synthetic North window (i.e. # replicating the build's simplification, not a cert or engine fact) - # plus the forced Table 11 above reproduces 72.62 -- matches Elmhurst's - # 72 almost exactly. Conclusion: the calculator is faithful (it already - # matches lodged exactly using the cert's REAL window orientations); - # both residuals are Elmhurst-worksheet-reconciliation artifacts (a - # deliberate spec choice + a build-entry simplification), not mapping - # or calculator bugs. PINNED to the observed exact match vs lodged. + # plus the forced Table 11 above reproduces 72.62 (precise Elmhurst + # value is 72.0681, not the rounded "72" -- true residual after Table + # 11 + windows was ~0.55, not ~1.6). Third cause found by walking the + # rest of the worksheet monthly: (43) Average daily hot water use is + # 117.4056 L/day (Elmhurst) vs our 110.7281 L/day -- SAME occupancy + # (42)=2.4234 both sides, so the gap is in shower/bath demand, not + # occupancy. Root cause: cert's `mixer_shower_count` is unlodged (raw + # `shower_outlets=None`), which `_mixer_shower_flow_rates_from_cert` + # maps to 0 showers (see its docstring: gov-API "no shower_outlets + # entry" convention, validated on cert 2225) -- but Elmhurst's build + # shows a "Non-electric shower" fixture (1 vented mixer @ Table J4), + # since its UI silently defaults one when the build script never + # explicitly configured "0 showers" to match the cert. Verified: a + # single 7 L/min vented mixer reproduces Elmhurst's (42a) monthly + # series EXACTLY (4 d.p., all 12 months) and closes hot water to + # 2616.04 vs Elmhurst's 2616.03 (Δ0.005). Corpus-wide check (170 + # certs sharing "bath present, no shower data lodged") shows NO + # systematic bias (mean dSAP +0.12, median -0.04, 46.5% over-rated) -- + # confirms the mapper's 0-showers convention is correct on average; + # this is a THIRD build-entry artifact, not a mapper bug. Combining + # all three (windows + Table 11 + 1 shower): SAP 72.4567 vs Elmhurst's + # precise 72.0681 -- residual 0.39, ~91% of the original 4.26-point + # gap (76.33 vs 72.07) now precisely explained. Conclusion: the + # calculator is faithful (matches lodged 76 exactly using the cert's + # REAL windows and REAL shower data); all three residuals are Elmhurst + # -reconciliation-build artifacts or deliberate spec choices, not + # mapping or calculator bugs. PINNED to the observed exact match vs + # lodged. RealCertExpectation( schema="RdSAP-Schema-21.0.1", sample="uprn_100061275133", From df38dda7b034a673872e2dc5f40593f470477cee Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 10:26:35 +0000 Subject: [PATCH 45/84] =?UTF-8?q?The=20ASHP=20bundle=20sizes=20the=20heat?= =?UTF-8?q?=20pump=20to=20the=20dwelling's=20design=20heat=20loss=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../generators/heating_recommendation.py | 14 ++++++++++--- .../modelling/test_heating_recommendation.py | 21 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/domain/modelling/generators/heating_recommendation.py b/domain/modelling/generators/heating_recommendation.py index f4f7375dc..4fc0b0736 100644 --- a/domain/modelling/generators/heating_recommendation.py +++ b/domain/modelling/generators/heating_recommendation.py @@ -335,17 +335,23 @@ def recommend_heating( products: ProductRepository, restrictions: PlanningRestrictions = PlanningRestrictions(), considered_measures: Optional[frozenset[MeasureType]] = None, + *, + design_heat_loss_kw: Optional[float] = None, ) -> Optional[Recommendation]: """Return a "Heating & Hot Water" Recommendation of competing whole-system bundles for the dwelling, else None when no bundle is eligible. ASHP is - additionally gated by the Property's planning protections (ADR-0024).""" + additionally gated by the Property's planning protections (ADR-0024). + + ``design_heat_loss_kw`` (the calculator's SAP design heat loss) sizes the + ASHP to the dwelling so SAP's Appendix-N PSR efficiency reads near its peak + (ADR-0049); when omitted, sizing falls back to the floor-area proxy.""" options: list[MeasureOption] = [] hhr_option = _hhr_storage_option(epc, products) if hhr_option is not None: options.append(hhr_option) - ashp_option = _ashp_option(epc, products, restrictions) + ashp_option = _ashp_option(epc, products, restrictions, design_heat_loss_kw) if ashp_option is not None: options.append(ashp_option) @@ -730,9 +736,11 @@ def _ashp_option( epc: EpcPropertyData, products: ProductRepository, restrictions: PlanningRestrictions, + design_heat_loss_kw: Optional[float] = None, ) -> Optional[MeasureOption]: """The air-source heat-pump bundle, offered for any non-flat house/bungalow - that is not listed/heritage and not already a heat pump.""" + that is not listed/heritage and not already a heat pump. The pump is sized to + ``design_heat_loss_kw`` (ADR-0049), falling back to the floor-area proxy.""" if not _ashp_eligible(epc, restrictions): return None # Cost is composed per-dwelling from the rate sheet (ADR-0025), not the diff --git a/tests/domain/modelling/test_heating_recommendation.py b/tests/domain/modelling/test_heating_recommendation.py index 51d41f035..e01a55c17 100644 --- a/tests/domain/modelling/test_heating_recommendation.py +++ b/tests/domain/modelling/test_heating_recommendation.py @@ -791,3 +791,24 @@ def test_ashp_sizing_caps_at_the_largest_pump_for_a_high_heat_loss_dwelling() -> # Assert — capped at the 12 kW rung, not left undersized at 5 kW. assert pcdb_id == 110281 + + +def test_ashp_bundle_sizes_the_pump_to_the_design_heat_loss() -> None: + # A high-heat-loss house (17.5 kW) must get a pump sized to it — the capped + # 12 kW aroTHERM plus (PCDB 110281) — so SAP's Appendix-N PSR efficiency reads + # near its peak, not the fixed 5 kW unit (110257) whose PSR collapses. + # Arrange + baseline: EpcPropertyData = _gas_boiler_house() + + # Act + recommendation: Recommendation | None = recommend_heating( + baseline, _StubProducts(), design_heat_loss_kw=17.5 + ) + + # Assert — the ASHP overlay carries the sized 12 kW record, not the fixed 5 kW. + assert recommendation is not None + ashp = next( + o for o in recommendation.options if o.measure_type == "air_source_heat_pump" + ) + assert ashp.overlay.heating is not None + assert ashp.overlay.heating.main_heating_index_number == 110281 From 2dd637a6571da5ae0523c08f6da1d1b395fa3221 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 10:28:08 +0000 Subject: [PATCH 46/84] =?UTF-8?q?The=20ASHP=20bundle=20sizes=20the=20heat?= =?UTF-8?q?=20pump=20to=20the=20dwelling's=20design=20heat=20loss=20?= =?UTF-8?q?=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _ashp_option now selects the aroTHERM plus PCDB record matching the threaded design heat loss (floor-area proxy fallback), so the overlay's efficiency anchor is sized to the dwelling instead of a fixed 5 kW unit. Co-Authored-By: Claude Opus 4.8 --- .../modelling/generators/heating_recommendation.py | 13 ++++++++++++- .../domain/modelling/test_heating_recommendation.py | 6 ++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/domain/modelling/generators/heating_recommendation.py b/domain/modelling/generators/heating_recommendation.py index 4fc0b0736..cdadf50bf 100644 --- a/domain/modelling/generators/heating_recommendation.py +++ b/domain/modelling/generators/heating_recommendation.py @@ -12,6 +12,7 @@ boiler bundles land in later slices. Detection + pricing only — impact is produced by scoring (ADR-0016). """ +from dataclasses import replace from typing import Optional from datatypes.epc.domain.epc_property_data import EpcPropertyData, MainHeatingDetail @@ -743,6 +744,16 @@ def _ashp_option( ``design_heat_loss_kw`` (ADR-0049), falling back to the floor-area proxy.""" if not _ashp_eligible(epc, restrictions): return None + # Size the pump to the dwelling: the calculator's design heat loss when the + # caller threaded it, else the floor-area proxy (ADR-0049). + heat_loss_kw: float = ( + design_heat_loss_kw + if design_heat_loss_kw is not None + else epc.total_floor_area_m2 * _KW_PER_M2 + ) + sized_overlay: HeatingOverlay = replace( + _ASHP_OVERLAY, main_heating_index_number=select_ashp_pcdb_id(heat_loss_kw) + ) # Cost is composed per-dwelling from the rate sheet (ADR-0025), not the # single catalogue scalar; the catalogue row is read only for its id, so an # absent ASHP row must not suppress the bundle — it just carries no id. @@ -754,7 +765,7 @@ def _ashp_option( "Replace the heating with an air-source heat pump, time-and-" "temperature-zone controls and a heat-pump hot-water cylinder" ), - overlay=EpcSimulation(heating=_ASHP_OVERLAY), + overlay=EpcSimulation(heating=sized_overlay), cost=cost, material_id=product.id if product is not None else None, ) diff --git a/tests/domain/modelling/test_heating_recommendation.py b/tests/domain/modelling/test_heating_recommendation.py index e01a55c17..2477150ef 100644 --- a/tests/domain/modelling/test_heating_recommendation.py +++ b/tests/domain/modelling/test_heating_recommendation.py @@ -203,8 +203,10 @@ def test_gas_boiler_house_yields_an_ashp_bundle() -> None: # bungalow regardless of current system or efficiency (ADR-0024). baseline: EpcPropertyData = _gas_boiler_house() - # Act - recommendation: Recommendation | None = recommend_heating(baseline, _StubProducts()) + # Act — a ~4 kW design heat loss sizes to the 5 kW aroTHERM plus (110257). + recommendation: Recommendation | None = recommend_heating( + baseline, _StubProducts(), design_heat_loss_kw=4.0 + ) # Assert — the ASHP bundle carries the absolute heat-pump end-state. assert recommendation is not None From 6f70e65bc446d5f6c657d51db1cb1a0cbf06cea0 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 10:29:14 +0000 Subject: [PATCH 47/84] =?UTF-8?q?ASHP=20cost=20sizes=20to=20the=20threaded?= =?UTF-8?q?=20design=20heat=20loss=20over=20the=20floor-area=20proxy=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../generators/heating_recommendation.py | 10 +++++++--- tests/domain/modelling/test_ashp_cost_inputs.py | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/domain/modelling/generators/heating_recommendation.py b/domain/modelling/generators/heating_recommendation.py index cdadf50bf..7efbc05a4 100644 --- a/domain/modelling/generators/heating_recommendation.py +++ b/domain/modelling/generators/heating_recommendation.py @@ -283,10 +283,14 @@ _OIL_FUEL_CODES = frozenset({28, 4, 71, 73, 75, 76}) _LPG_FUEL_CODES = frozenset({27, 2, 3, 5, 9}) -def ashp_cost_inputs(epc: EpcPropertyData) -> AshpCostInputs: +def ashp_cost_inputs( + epc: EpcPropertyData, design_heat_loss_kw: Optional[float] = None +) -> AshpCostInputs: """Read an `EpcPropertyData` into the typed inputs `Products.ashp_bundle_cost` - needs: the existing system, property-size band, design heat loss (floor-area - proxy), radiator count, and whether a wet system can be reused (ADR-0025).""" + needs: the existing system, property-size band, design heat loss, radiator + count, and whether a wet system can be reused (ADR-0025). ``design_heat_loss_kw`` + (the calculator's value, ADR-0049) sizes the cost band; when omitted it falls + back to the floor-area proxy so cost and pump size share one figure.""" system: AshpExistingSystem = _existing_system(epc) floor_area: float = epc.total_floor_area_m2 return AshpCostInputs( diff --git a/tests/domain/modelling/test_ashp_cost_inputs.py b/tests/domain/modelling/test_ashp_cost_inputs.py index c75cf52fc..ce528f1bb 100644 --- a/tests/domain/modelling/test_ashp_cost_inputs.py +++ b/tests/domain/modelling/test_ashp_cost_inputs.py @@ -82,3 +82,19 @@ def test_oil_and_lpg_dwellings_are_reusable_wet_systems() -> None: assert ashp_cost_inputs(_with_fuel(28)).existing_system is AshpExistingSystem.OIL assert ashp_cost_inputs(_with_fuel(27)).existing_system is AshpExistingSystem.LPG assert ashp_cost_inputs(_with_fuel(28)).has_reusable_wet_system is True + + +def test_threaded_design_heat_loss_drives_the_cost_band_over_the_proxy() -> None: + # When the caller threads the calculator's real design heat loss (ADR-0049), + # the ASHP cost sizes to it — not the floor-area proxy — so a leaky dwelling's + # bigger pump is priced on the right band. + # Arrange + epc = parse_recommendation_summary( + "ashp_from_system_boiler_with_cylinder_001431_before.pdf" + ) + + # Act + inputs: AshpCostInputs = ashp_cost_inputs(epc, design_heat_loss_kw=17.5) + + # Assert — the threaded value, not the 4.5 kW proxy. + assert inputs.design_heat_loss_kw == 17.5 From b25e7bb7f9008726840a90305fb29c42405780d1 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 10:29:50 +0000 Subject: [PATCH 48/84] =?UTF-8?q?ASHP=20cost=20sizes=20to=20the=20threaded?= =?UTF-8?q?=20design=20heat=20loss=20over=20the=20floor-area=20proxy=20?= =?UTF-8?q?=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _ashp_option threads its sized design heat loss into ashp_cost_inputs so the cost band and the pump's efficiency record share one figure — a leaky dwelling's larger pump is priced on the matching band. Co-Authored-By: Claude Opus 4.8 --- domain/modelling/generators/heating_recommendation.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/domain/modelling/generators/heating_recommendation.py b/domain/modelling/generators/heating_recommendation.py index 7efbc05a4..44173de98 100644 --- a/domain/modelling/generators/heating_recommendation.py +++ b/domain/modelling/generators/heating_recommendation.py @@ -293,10 +293,15 @@ def ashp_cost_inputs( back to the floor-area proxy so cost and pump size share one figure.""" system: AshpExistingSystem = _existing_system(epc) floor_area: float = epc.total_floor_area_m2 + heat_loss_kw: float = ( + design_heat_loss_kw + if design_heat_loss_kw is not None + else floor_area * _KW_PER_M2 + ) return AshpCostInputs( existing_system=system, is_small_property=floor_area <= _SMALL_PROPERTY_MAX_M2, - design_heat_loss_kw=floor_area * _KW_PER_M2, + design_heat_loss_kw=heat_loss_kw, radiator_count=_radiator_count(epc), has_reusable_wet_system=system in (AshpExistingSystem.GAS, AshpExistingSystem.OIL, AshpExistingSystem.LPG), @@ -762,7 +767,9 @@ def _ashp_option( # single catalogue scalar; the catalogue row is read only for its id, so an # absent ASHP row must not suppress the bundle — it just carries no id. product: Optional[Product] = products.get_optional(_ASHP_MEASURE_TYPE) - cost: Cost = Products().ashp_bundle_cost(ashp_cost_inputs(epc)) + cost: Cost = Products().ashp_bundle_cost( + ashp_cost_inputs(epc, design_heat_loss_kw=heat_loss_kw) + ) return MeasureOption( measure_type=_ASHP_MEASURE_TYPE, description=( From cb91954bb458e24ee8683fc3c2d1cabeadc578eb Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 10:31:57 +0000 Subject: [PATCH 49/84] =?UTF-8?q?The=20orchestrator=20threads=20the=20dwel?= =?UTF-8?q?ling=20design=20heat=20loss=20into=20ASHP=20sizing=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- orchestration/modelling_orchestrator.py | 1 + ...st_modelling_heat_pump_sizing_threading.py | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 tests/orchestration/test_modelling_heat_pump_sizing_threading.py diff --git a/orchestration/modelling_orchestrator.py b/orchestration/modelling_orchestrator.py index e3180a4d2..ae43ca85c 100644 --- a/orchestration/modelling_orchestrator.py +++ b/orchestration/modelling_orchestrator.py @@ -264,6 +264,7 @@ def _candidate_recommendations( planning_restrictions: PlanningRestrictions, solar_potential: Optional[SolarPotential], considered_measures: Optional[frozenset[MeasureType]], + design_heat_loss_kw: Optional[float] = None, ) -> list[Recommendation]: """Run the applicable Recommendation Generators; keep the ones that apply. Solid-wall insulation, glazing, heating and solar are additionally gated by diff --git a/tests/orchestration/test_modelling_heat_pump_sizing_threading.py b/tests/orchestration/test_modelling_heat_pump_sizing_threading.py new file mode 100644 index 000000000..0b46bb8a6 --- /dev/null +++ b/tests/orchestration/test_modelling_heat_pump_sizing_threading.py @@ -0,0 +1,60 @@ +"""The ModellingOrchestrator threads the dwelling's SAP design heat loss into +the heating Recommendation Generator so the ASHP is sized to the dwelling +(ADR-0049), mirroring how planning_restrictions and the solar potential are +threaded. Tests the candidate-wiring seam directly; the end-to-end run-through- +repos path is covered by the DB integration tests. +""" + +from datatypes.epc.domain.epc_property_data import EpcPropertyData +from domain.geospatial.planning_restrictions import PlanningRestrictions +from domain.modelling.measure_type import MeasureType +from domain.modelling.product import Product +from domain.modelling.recommendation import Recommendation +from orchestration.modelling_orchestrator import ( + _candidate_recommendations, # pyright: ignore[reportPrivateUsage] +) +from repositories.product.product_repository import ProductRepository +from tests.domain.modelling._elmhurst_recommendation import ( + parse_recommendation_summary, +) + + +class _StubProducts(ProductRepository): + def get(self, measure_type: str) -> Product: + return Product( + measure_type=measure_type, + unit_cost_per_m2=0.0, + contingency_rate=0.15, + id=909, + ) + + +def _ashp_eligible_house() -> EpcPropertyData: + epc = parse_recommendation_summary( + "ashp_from_system_boiler_with_cylinder_001431_before.pdf" + ) + epc.property_type = "House" + return epc + + +def test_candidate_recommendations_sizes_the_ashp_to_the_threaded_design_heat_loss() -> ( + None +): + # Arrange — an ASHP-eligible house and a high (17.5 kW) design heat loss. + epc = _ashp_eligible_house() + + # Act + recommendations: list[Recommendation] = _candidate_recommendations( + epc, _StubProducts(), PlanningRestrictions(), None, None, design_heat_loss_kw=17.5 + ) + + # Assert — the ASHP is sized to the load (capped 12 kW aroTHERM plus 110281), + # not the fixed 5 kW / floor-area-proxy unit. + heating = next(r for r in recommendations if r.surface == "Heating & Hot Water") + ashp = next( + o + for o in heating.options + if o.measure_type == MeasureType.AIR_SOURCE_HEAT_PUMP + ) + assert ashp.overlay.heating is not None + assert ashp.overlay.heating.main_heating_index_number == 110281 From bf240e33155bd80bd9fddcc506f6576e8fc04795 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:02:13 +0000 Subject: [PATCH 50/84] =?UTF-8?q?ASHP=20sizing=20targets=20the=20Appendix-?= =?UTF-8?q?N=20efficiency=20peak=20(realistic=20installed=20pump)=20?= =?UTF-8?q?=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sizing selects the aroTHERM plus rung nearest PSR ~0.8 (0.8 x design heat loss) — the Appendix-N efficiency peak, reproducing the pump a real installer fits — rather than the MCS PSR>=1.0 capacity target, which oversizes. Validated against the relodged Elmhurst ASHP cert (delta 0 held at the 5 kW Vaillant); the two self-snapshot pins re-pin to their correctly-sized larger pumps, and the orchestrator/harness thread the calculator's design heat loss so production sizes to the dwelling. Manual SapResult test stubs carry the new design_heat_loss_kw field. Co-Authored-By: Claude Opus 4.8 --- .../generators/heating_recommendation.py | 22 ++++++++---- harness/console.py | 3 ++ orchestration/modelling_orchestrator.py | 21 +++++++++-- tests/domain/billing/test_energy_breakdown.py | 1 + .../modelling/test_elmhurst_cascade_pins.py | 36 ++++++++++++++----- .../modelling/test_heating_recommendation.py | 19 +++++----- .../test_calculator_rebaseliner.py | 1 + .../test_property_baseline_orchestrator.py | 1 + 8 files changed, 77 insertions(+), 27 deletions(-) diff --git a/domain/modelling/generators/heating_recommendation.py b/domain/modelling/generators/heating_recommendation.py index 44173de98..ebb7d1f5e 100644 --- a/domain/modelling/generators/heating_recommendation.py +++ b/domain/modelling/generators/heating_recommendation.py @@ -153,17 +153,25 @@ _ASHP_SIZING_LADDER: tuple[tuple[float, int], ...] = ( (7.93, 110273), # aroTHERM plus 10 kW (11.48, 110281), # aroTHERM plus 12 kW ) +# SAP 10.2 Appendix-N heat-pump efficiency peaks around PSR 0.8 (output / design +# heat loss); sizing to it reproduces real installer choices (accredited-cert +# validated) rather than the MCS capacity target (PSR 1.0), which oversizes. +_EFFICIENCY_PEAK_PSR: float = 0.8 def select_ashp_pcdb_id(design_heat_loss_kw: float) -> int: """The PCDB heat-pump record to install for a dwelling with - `design_heat_loss_kw`: the smallest ladder rung whose rated output meets the - load (PSR >= 1.0), capped at the largest rung when the load exceeds the - domestic aroTHERM plus range (ADR-0049).""" - for max_output_kw, pcdb_id in _ASHP_SIZING_LADDER: - if max_output_kw >= design_heat_loss_kw: - return pcdb_id - return _ASHP_SIZING_LADDER[-1][1] + `design_heat_loss_kw` (ADR-0049): the ladder rung whose rated output sits + nearest the SAP 10.2 Appendix-N efficiency peak — PSR ~= 0.8, i.e. a rated + output of ``0.8 x design_heat_loss`` — which reproduces the pump a real + installer fits (validated against the relodged Elmhurst ASHP cert) and keeps + the heat pump clear of the low-PSR efficiency collapse. A load beyond the + domestic aroTHERM plus range naturally selects the largest rung.""" + target_output_kw: float = _EFFICIENCY_PEAK_PSR * design_heat_loss_kw + return min( + _ASHP_SIZING_LADDER, + key=lambda rung: abs(rung[0] - target_output_kw), + )[1] # --- Gas boiler upgrade (Heating/HW expansion): replace an existing wet boiler diff --git a/harness/console.py b/harness/console.py index b60528832..a9aa222b5 100644 --- a/harness/console.py +++ b/harness/console.py @@ -273,10 +273,13 @@ def candidate_recommendations( if solar_insights is not None and "solarPotential" in solar_insights else None ) + # The SAP design heat loss sizes the ASHP to the dwelling (ADR-0049). + design_heat_loss_kw: float = Sap10Calculator().calculate(epc).design_heat_loss_kw return _candidate_recommendations( epc, products or ProductJsonRepository(catalogue_path), planning_restrictions, solar_potential, considered_measures, + design_heat_loss_kw, ) diff --git a/orchestration/modelling_orchestrator.py b/orchestration/modelling_orchestrator.py index ae43ca85c..7a30d7e82 100644 --- a/orchestration/modelling_orchestrator.py +++ b/orchestration/modelling_orchestrator.py @@ -332,7 +332,13 @@ def _candidate_recommendations( MeasureType.SYSTEM_TUNE_UP, MeasureType.SYSTEM_TUNE_UP_ZONED, ), - lambda: recommend_heating(effective_epc, products, planning_restrictions, considered_measures), + lambda: recommend_heating( + effective_epc, + products, + planning_restrictions, + considered_measures, + design_heat_loss_kw=design_heat_loss_kw, + ), ), ( admitted(MeasureType.SECONDARY_HEATING_REMOVAL), @@ -385,9 +391,20 @@ def _scored_candidate_groups( ) -> list[list[ScoredOption]]: """One group per Recommendation: each Option scored independently against the baseline (role-1 warm-start signal, ADR-0016).""" + # The SAP design heat loss sizes the ASHP to the dwelling (ADR-0049); read it + # off a baseline score, which the group scoring computes anyway. + baseline_result = scorer.score(effective_epc, []).sap_result + design_heat_loss_kw: Optional[float] = ( + baseline_result.design_heat_loss_kw if baseline_result is not None else None + ) groups: list[list[ScoredOption]] = [] for recommendation in _candidate_recommendations( - effective_epc, products, planning_restrictions, solar_potential, considered_measures + effective_epc, + products, + planning_restrictions, + solar_potential, + considered_measures, + design_heat_loss_kw, ): options = list(recommendation.options) impacts: list[MeasureImpact] = independent_option_impacts( diff --git a/tests/domain/billing/test_energy_breakdown.py b/tests/domain/billing/test_energy_breakdown.py index f754bc662..630c314b1 100644 --- a/tests/domain/billing/test_energy_breakdown.py +++ b/tests/domain/billing/test_energy_breakdown.py @@ -40,6 +40,7 @@ def _sap_result( space_heating_kwh_per_yr=0.0, space_cooling_kwh_per_yr=0.0, fabric_energy_efficiency_kwh_per_m2_yr=0.0, + design_heat_loss_kw=0.0, main_heating_fuel_kwh_per_yr=main_heating_fuel_kwh_per_yr, main_2_heating_fuel_kwh_per_yr=main_2_heating_fuel_kwh_per_yr, secondary_heating_fuel_kwh_per_yr=secondary_heating_fuel_kwh_per_yr, diff --git a/tests/domain/modelling/test_elmhurst_cascade_pins.py b/tests/domain/modelling/test_elmhurst_cascade_pins.py index c99f7b6f0..a52cf9787 100644 --- a/tests/domain/modelling/test_elmhurst_cascade_pins.py +++ b/tests/domain/modelling/test_elmhurst_cascade_pins.py @@ -664,7 +664,11 @@ def test_ashp_overlay_scores_the_vaillant_end_state_from_a_gas_boiler() -> None: before: EpcPropertyData = parse_recommendation_summary( "ashp_from_gas_boiler_001431_before.pdf" ) - recommendation: Recommendation | None = recommend_heating(before, _AnyProduct()) + recommendation: Recommendation | None = recommend_heating( + before, + _AnyProduct(), + design_heat_loss_kw=Sap10Calculator().calculate(before).design_heat_loss_kw, + ) assert recommendation is not None option = next( o for o in recommendation.options if o.measure_type == "air_source_heat_pump" @@ -678,12 +682,15 @@ def test_ashp_overlay_scores_the_vaillant_end_state_from_a_gas_boiler() -> None: # CO2/PE are the postcode DEMAND cascade now that `Sap10Calculator. # calculate` computes EPC emissions/PE on local weather (SAP 10.2 # Appendix U p.124); SAP is unchanged (UK-average rating cascade). + # Re-pinned after ADR-0049 sizes the pump to this dwelling's 9.69 kW design + # heat loss (the 10 kW aroTHERM plus, 110273) instead of the fixed 5 kW unit, + # which was undersized here — the correctly-sized pump raises the end-state SAP. _assert_overlay_scores( before, option.overlay, - sap=51.99820176096402, - co2=1065.7593506066496, - pe=10995.781557709413, + sap=69.6498827017577, + co2=698.896585317197, + pe=7271.044741124457, ) @@ -697,7 +704,11 @@ def test_ashp_overlay_scores_the_vaillant_end_state_from_a_gas_boiler_instant_hw before: EpcPropertyData = parse_recommendation_summary( "ashp_from_gas_boiler_instant_hw_001431_before.pdf" ) - recommendation: Recommendation | None = recommend_heating(before, _AnyProduct()) + recommendation: Recommendation | None = recommend_heating( + before, + _AnyProduct(), + design_heat_loss_kw=Sap10Calculator().calculate(before).design_heat_loss_kw, + ) assert recommendation is not None option = next( o for o in recommendation.options if o.measure_type == "air_source_heat_pump" @@ -709,12 +720,15 @@ def test_ashp_overlay_scores_the_vaillant_end_state_from_a_gas_boiler_instant_hw # see `test_gas_boiler_instant_hw_before_baselines`. # CO2/PE are the postcode DEMAND cascade now (see the boiler-1 pin above); # SAP is unchanged (UK-average rating cascade). + # Re-pinned after ADR-0049 sizes the pump to this dwelling's 12.87 kW design + # heat loss (the capped 12 kW aroTHERM plus, 110281) instead of the fixed 5 kW + # unit, which was badly undersized here — the sized pump raises the SAP. _assert_overlay_scores( before, option.overlay, - sap=39.00740809309464, - co2=1845.8588018295509, - pe=18944.42568846759, + sap=72.22779402266684, + co2=870.0854694592007, + pe=9025.363011043328, ) @@ -734,7 +748,11 @@ def test_ashp_overlay_reproduces_the_relodged_after_from_a_system_boiler_with_cy after: EpcPropertyData = parse_recommendation_summary( "ashp_from_system_boiler_with_cylinder_001431_after.pdf" ) - recommendation: Recommendation | None = recommend_heating(before, _AnyProduct()) + recommendation: Recommendation | None = recommend_heating( + before, + _AnyProduct(), + design_heat_loss_kw=Sap10Calculator().calculate(before).design_heat_loss_kw, + ) assert recommendation is not None option = next( o for o in recommendation.options if o.measure_type == "air_source_heat_pump" diff --git a/tests/domain/modelling/test_heating_recommendation.py b/tests/domain/modelling/test_heating_recommendation.py index 2477150ef..470ff51aa 100644 --- a/tests/domain/modelling/test_heating_recommendation.py +++ b/tests/domain/modelling/test_heating_recommendation.py @@ -203,9 +203,10 @@ def test_gas_boiler_house_yields_an_ashp_bundle() -> None: # bungalow regardless of current system or efficiency (ADR-0024). baseline: EpcPropertyData = _gas_boiler_house() - # Act — a ~4 kW design heat loss sizes to the 5 kW aroTHERM plus (110257). + # Act — a 5.5 kW design heat loss sizes to the 5 kW aroTHERM plus (110257): + # PSR-0.8 target ~4.4 kW, nearest the 4.37 kW rung. recommendation: Recommendation | None = recommend_heating( - baseline, _StubProducts(), design_heat_loss_kw=4.0 + baseline, _StubProducts(), design_heat_loss_kw=5.5 ) # Assert — the ASHP bundle carries the absolute heat-pump end-state. @@ -771,16 +772,16 @@ def test_boiler_upgrade_leaves_adequate_controls_unchanged() -> None: assert overlay.main_heating_control is None -def test_ashp_sizing_selects_the_smallest_pump_meeting_the_design_heat_loss() -> None: - # A 6 kW design heat loss needs a pump whose rated output covers it: the 7 kW - # aroTHERM plus (PCDB 110265, ~6.40 kW), the smallest ladder rung meeting the - # load — not the fixed 5 kW unit (4.37 kW) that would sit below the load and - # collapse SAP's Appendix-N PSR efficiency. +def test_ashp_sizing_targets_the_appendix_n_efficiency_peak() -> None: + # A 6 kW design heat loss sizes to the SAP Appendix-N efficiency peak + # (PSR ~= 0.8, so ~4.8 kW rated output): the 5 kW aroTHERM plus (PCDB 110257, + # ~4.37 kW) — what a real installer fits — not the oversized 7 kW unit, and + # well clear of the low-PSR efficiency collapse. # Act pcdb_id = select_ashp_pcdb_id(design_heat_loss_kw=6.0) - # Assert — the 7 kW aroTHERM plus rung. - assert pcdb_id == 110265 + # Assert — the 5 kW aroTHERM plus rung. + assert pcdb_id == 110257 def test_ashp_sizing_caps_at_the_largest_pump_for_a_high_heat_loss_dwelling() -> None: diff --git a/tests/domain/property_baseline/test_calculator_rebaseliner.py b/tests/domain/property_baseline/test_calculator_rebaseliner.py index f6002bd48..49a2364dc 100644 --- a/tests/domain/property_baseline/test_calculator_rebaseliner.py +++ b/tests/domain/property_baseline/test_calculator_rebaseliner.py @@ -40,6 +40,7 @@ def _sap_result( space_heating_kwh_per_yr=0.0, space_cooling_kwh_per_yr=0.0, fabric_energy_efficiency_kwh_per_m2_yr=0.0, + design_heat_loss_kw=0.0, main_heating_fuel_kwh_per_yr=0.0, main_2_heating_fuel_kwh_per_yr=0.0, secondary_heating_fuel_kwh_per_yr=0.0, diff --git a/tests/orchestration/test_property_baseline_orchestrator.py b/tests/orchestration/test_property_baseline_orchestrator.py index 912dc9085..b4125059d 100644 --- a/tests/orchestration/test_property_baseline_orchestrator.py +++ b/tests/orchestration/test_property_baseline_orchestrator.py @@ -128,6 +128,7 @@ def _sap_result_with_lighting() -> SapResult: space_heating_kwh_per_yr=0.0, space_cooling_kwh_per_yr=0.0, fabric_energy_efficiency_kwh_per_m2_yr=0.0, + design_heat_loss_kw=0.0, main_heating_fuel_kwh_per_yr=0.0, main_2_heating_fuel_kwh_per_yr=0.0, secondary_heating_fuel_kwh_per_yr=0.0, From 30616dc4271851fed1e23d7c4ab6b35337b37f65 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:02:13 +0000 Subject: [PATCH 51/84] Record ADR-0049: ASHP sized to the dwelling's design heat loss at the efficiency peak Co-Authored-By: Claude Opus 4.8 --- ...-sized-to-the-dwelling-design-heat-loss.md | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 docs/adr/0049-ashp-sized-to-the-dwelling-design-heat-loss.md diff --git a/docs/adr/0049-ashp-sized-to-the-dwelling-design-heat-loss.md b/docs/adr/0049-ashp-sized-to-the-dwelling-design-heat-loss.md new file mode 100644 index 000000000..ce53044a7 --- /dev/null +++ b/docs/adr/0049-ashp-sized-to-the-dwelling-design-heat-loss.md @@ -0,0 +1,98 @@ +# The ASHP recommendation sizes the heat pump to the dwelling's design heat loss + +## Status + +accepted + +## Context + +The ASHP measure (ADR-0024) installed **one fixed heat pump** — a 4.37 kW Vaillant +aroTHERM plus (PCDB Table 362 record 110257) — on every eligible dwelling, as a +"representative, contractor-installable" end-state. SAP 10.2 Appendix N reads a +heat pump's efficiency at the dwelling's **PSR** (Power-to-Space-heating-Ratio = +rated output / design heat loss): efficiency peaks around PSR 0.8 and, per +footnote 44, **collapses toward 100% below the record's smallest PSR**. + +A portfolio-796 audit found the fixed pump scoring the ASHP **below the baseline** +on high-heat-loss dwellings. Property 712794 (uprn 10002468116): a leaky dwelling +with a **17.5 kW design heat loss**, so a 4.37 kW pump lands at **PSR 0.25** — the +efficiency collapse zone. The calculator correctly applied ~195% SPF; combined +with pricing electricity at the standard tariff against an off-peak storage +baseline, the ASHP scored **SAP 10.33 vs the baseline 11.96 (−1.63)** and the +Optimiser never selected it. Every electric-heated dwelling too leaky for a 4.37 kW +pump was capped below the goal band by this — a modelling defect, not a calculator +one (SAP's PSR curve is correct: a grossly undersized heat pump *is* inefficient). + +The fix needs the dwelling's design heat loss, which the calculator computes +internally (annual-average HLC × the SAP design temperature difference, 24.2 K) +but did not surface. + +Sizing raised a second question the accredited data answered. MCS capacity sizing +targets **PSR ≈ 1.0** (output ≥ design heat loss). But the **relodged Elmhurst ASHP +cert** — a real dwelling our calculator gives a 6.40 kW design heat loss — was +fitted with the **5 kW** Vaillant (110257, 4.37 kW output), i.e. **PSR 0.68**, and +scores SAP 72.08. A PSR-1.0 rule picks the 7 kW pump for that dwelling → SAP 73.86, +**oversizing by a rung and inflating SAP by ~1.8**, and no longer reproduces the +accredited cert. SAP efficiency at PSR 0.68 and 1.0 is near-identical (~400%), so +the real installer's smaller, cheaper choice is the realistic one. + +## Decision + +Size the heat pump to the dwelling and expose what sizing needs: + +1. **`SapResult.design_heat_loss_kw`** — the calculator surfaces the design heat + loss (annual-average HLC × 24.2 K / 1000), the quantity Appendix N's PSR + divides the pump output by. + +2. **A curated aroTHERM plus ladder** — one representative PCDB record per nominal + size across the domestic range (`_ASHP_SIZING_LADDER`): 3.5 kW (110249), 5 kW + (110257, the prior anchor), 7 kW (110265), 10 kW (110273), 12 kW (110281). All + the same "& AI VIH RW" variant, so the ladder is a consistent product line. + +3. **Size to the Appendix-N efficiency peak, not MCS capacity.** + `select_ashp_pcdb_id` picks the rung whose rated output is nearest **0.8 × + design heat loss** (PSR ≈ 0.8, the efficiency peak). This reproduces the pump a + real installer fits — validated against the relodged Elmhurst cert at delta 0 — + and keeps the pump clear of the low-PSR collapse. A load beyond the 12 kW range + naturally selects the largest rung (an honest, capped undersize; those + dwellings need fabric-first). + +4. **Cost and efficiency share one figure.** `ashp_cost_inputs` takes the same + design heat loss (over the floor-area proxy), so the rate-sheet install band + (ADR-0025) and the pump's efficiency record are sized from one number. The + orchestrator reads `design_heat_loss_kw` off a baseline score and threads it + into the heating generator; the harness computes it via a calculator pass. + +## Consequences + +- Property 712794's ASHP goes from **−1.63 SAP (never selected)** to **+44.2 SAP + (selected)**; its plan lifts **G (12.0) → B (89.1)**. Electric-heated dwellings + previously capped below goal C by the undersized pump can now reach it — the + largest HIGH-severity mover on the portfolio-796 `plan-stops-short-of-goal` and + `plan-stuck-in-low-band` groups. +- The accredited relodged Elmhurst ASHP cert still reproduces at **delta 0** (the + 6.40 kW dwelling sizes to the 5 kW Vaillant it was actually fitted with). Two + self-snapshot cascade pins re-pin to their correctly-sized larger pumps (both + dwellings were undersized by the fixed unit, so their end-state SAP rises). +- Adding `design_heat_loss_kw` to `SapResult` is a required field; manual + constructions (test stubs) carry it. +- Extends [ADR-0024](0024-ashp-bundle-absolute-end-state.md) (the ASHP end-state) + and [ADR-0025](0025-ashp-cost-composed-from-the-rate-sheet.md) (size-banded + cost); the cost bands already scaled — they now receive the real heat loss. + +### Alternatives rejected + +- **MCS capacity sizing (PSR ≈ 1.0, output ≥ design heat loss).** Rejected: it + oversizes relative to real installs, inflating SAP ~1.8 per dwelling and + breaking the accredited-cert reproduction. SAP efficiency is equivalent at + PSR 0.68–1.0, so the realistic (installer) size is preferred. +- **Keep the fixed 4.37 kW pump.** Rejected: the collapse on high-heat-loss + dwellings is the defect under repair. +- **Fabric-first sequencing (score the ASHP only after insulation).** A real + concern — the Optimiser scores each measure independently against the + un-insulated baseline (ADR-0016) — but a separate change to measure scoring/ + sequencing, not pump sizing. Sizing the pump fixes the standalone score + regardless; noted for follow-up. +- **Nearest record from all ~10,000 Table 362 heat pumps.** Rejected: an opaque, + unauditable selection; a curated single-product ladder keeps ADR-0024's + "representative, contractor-installable" intent. From dcd2a7442fab6dddf9169a9cdaba4e04e026c60b Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 11:12:59 +0000 Subject: [PATCH 52/84] =?UTF-8?q?Renamer=20discovers=20=5FSero=20Batch=20r?= =?UTF-8?q?oots=20under=20Property=20Folders=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../sharepoint_renamer_orchestrator.py | 4 +++ tests/scripts/test_rename_sharepoint_files.py | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/orchestration/sharepoint_renamer_orchestrator.py b/orchestration/sharepoint_renamer_orchestrator.py index 42b0e803c..15917f0a2 100644 --- a/orchestration/sharepoint_renamer_orchestrator.py +++ b/orchestration/sharepoint_renamer_orchestrator.py @@ -11,6 +11,7 @@ BASE_PATH = ( "Sero Project Documents/Property Folders" ) ASSESSMENT_SUBFOLDER = "A. Assessment" +BATCH_FOLDER_PREFIX = "_Sero Batch" logger = setup_logger() @@ -65,6 +66,9 @@ class SharepointRenamerOrchestrator: self._csv_path = csv_path self._dry_run = dry_run + def _discover_roots(self) -> list[str]: + raise NotImplementedError + def run(self) -> None: with open(self._csv_path, newline="", encoding="utf-8-sig") as f: reader = csv.DictReader(f) diff --git a/tests/scripts/test_rename_sharepoint_files.py b/tests/scripts/test_rename_sharepoint_files.py index 5affea7e2..35c4edc3e 100644 --- a/tests/scripts/test_rename_sharepoint_files.py +++ b/tests/scripts/test_rename_sharepoint_files.py @@ -4,6 +4,7 @@ from unittest.mock import MagicMock import pytest from orchestration.sharepoint_renamer_orchestrator import ( + BASE_PATH, SharepointRenamerOrchestrator, build_canonical_filename, ) @@ -47,6 +48,35 @@ def test_no_prefix_still_canonical() -> None: assert result == "100_1 High St AB1 2CD_Survey.pdf" +# --------------------------------------------------------------------------- +# _discover_roots — batch subfolders become extra roots +# --------------------------------------------------------------------------- + + +def test_discover_roots_includes_sero_batch_folders() -> None: + # Arrange + sp = MagicMock() + sp.get_folders_in_path.return_value = { + "value": [ + _make_folder("1 High St, AB1 2CD"), + _make_folder("_Sero Batch 3"), + _make_folder("_Sero Batch 2"), + _make_file("stray.pdf"), + ] + } + + # Act + roots = _make_orchestrator(sp)._discover_roots() + + # Assert + assert roots == [ + BASE_PATH, + f"{BASE_PATH}/_Sero Batch 2", + f"{BASE_PATH}/_Sero Batch 3", + ] + sp.get_folders_in_path.assert_called_once_with(BASE_PATH) + + # --------------------------------------------------------------------------- # _process_folder — files only at root level # --------------------------------------------------------------------------- From a442dcfbaad40cd83aaa941de3b5f1893514f6f9 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 11:13:39 +0000 Subject: [PATCH 53/84] =?UTF-8?q?Renamer=20discovers=20=5FSero=20Batch=20r?= =?UTF-8?q?oots=20under=20Property=20Folders=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- orchestration/sharepoint_renamer_orchestrator.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/orchestration/sharepoint_renamer_orchestrator.py b/orchestration/sharepoint_renamer_orchestrator.py index 15917f0a2..3159a607b 100644 --- a/orchestration/sharepoint_renamer_orchestrator.py +++ b/orchestration/sharepoint_renamer_orchestrator.py @@ -67,7 +67,14 @@ class SharepointRenamerOrchestrator: self._dry_run = dry_run def _discover_roots(self) -> list[str]: - raise NotImplementedError + contents = self._sp_client.get_folders_in_path(BASE_PATH) + batch_roots = sorted( + f"{BASE_PATH}/{item['name']}" + for item in contents.get("value", []) + if "folder" in item + and item["name"].lower().startswith(BATCH_FOLDER_PREFIX.lower()) + ) + return [BASE_PATH, *batch_roots] def run(self) -> None: with open(self._csv_path, newline="", encoding="utf-8-sig") as f: From ab8b8decb3882fc5b1f0c05e93ba7fd5646d8535 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 11:15:50 +0000 Subject: [PATCH 54/84] =?UTF-8?q?Renamer=20finds=20properties=20filed=20un?= =?UTF-8?q?der=20=5FSero=20Batch=20roots=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- tests/scripts/test_rename_sharepoint_files.py | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/scripts/test_rename_sharepoint_files.py b/tests/scripts/test_rename_sharepoint_files.py index 35c4edc3e..92a33f7ad 100644 --- a/tests/scripts/test_rename_sharepoint_files.py +++ b/tests/scripts/test_rename_sharepoint_files.py @@ -1,15 +1,32 @@ +from pathlib import Path from typing import Any from unittest.mock import MagicMock import pytest +from backend.pashub_fetcher.sharepoint_subfolders import SharepointSubfolders from orchestration.sharepoint_renamer_orchestrator import ( + ASSESSMENT_SUBFOLDER, BASE_PATH, SharepointRenamerOrchestrator, build_canonical_filename, ) +def _assessment_path(root: str, address: str, postcode: str) -> str: + return ( + f"{root}/{address}, {postcode}" + f"/{SharepointSubfolders.ASSESSMENT.value}/{ASSESSMENT_SUBFOLDER}" + ) + + +def _write_csv(tmp_path: Path, rows: list[tuple[str, str, str]]) -> str: + lines = ["UPRN,Address,Postcode"] + [",".join(row) for row in rows] + csv_file = tmp_path / "addresses.csv" + csv_file.write_text("\n".join(lines) + "\n", encoding="utf-8") + return str(csv_file) + + def _make_file(name: str, item_id: str = "id-1") -> dict[str, Any]: return {"name": name, "id": item_id, "file": {}} @@ -77,6 +94,36 @@ def test_discover_roots_includes_sero_batch_folders() -> None: sp.get_folders_in_path.assert_called_once_with(BASE_PATH) +# --------------------------------------------------------------------------- +# run — properties under a batch root are still found and renamed +# --------------------------------------------------------------------------- + + +def test_run_renames_files_for_property_under_batch_root(tmp_path: Path) -> None: + # Arrange + csv_path = _write_csv(tmp_path, [("100", "1 High St", "AB1 2CD")]) + batch_assessment = _assessment_path( + f"{BASE_PATH}/_Sero Batch 2", "1 High St", "AB1 2CD" + ) + + sp = MagicMock() + + def fake_get(path: str) -> dict[str, Any]: + if path == BASE_PATH: + return {"value": [_make_folder("_Sero Batch 2")]} + if path == batch_assessment: + return {"value": [_make_file("Survey.pdf", "id-1")]} + raise ValueError("not found") + + sp.get_folders_in_path.side_effect = fake_get + + # Act + SharepointRenamerOrchestrator(sp, csv_path).run() + + # Assert + sp.rename_file.assert_called_once_with("id-1", "100_1 High St AB1 2CD_Survey.pdf") + + # --------------------------------------------------------------------------- # _process_folder — files only at root level # --------------------------------------------------------------------------- From 1196a8f75d66bb120436fbcd9375df3b67f308dc Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 11:16:46 +0000 Subject: [PATCH 55/84] =?UTF-8?q?Renamer=20finds=20properties=20filed=20un?= =?UTF-8?q?der=20=5FSero=20Batch=20roots=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../sharepoint_renamer_orchestrator.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/orchestration/sharepoint_renamer_orchestrator.py b/orchestration/sharepoint_renamer_orchestrator.py index 3159a607b..b5206f0ee 100644 --- a/orchestration/sharepoint_renamer_orchestrator.py +++ b/orchestration/sharepoint_renamer_orchestrator.py @@ -77,6 +77,7 @@ class SharepointRenamerOrchestrator: return [BASE_PATH, *batch_roots] def run(self) -> None: + roots = self._discover_roots() with open(self._csv_path, newline="", encoding="utf-8-sig") as f: reader = csv.DictReader(f) required = {"UPRN", "Address", "Postcode"} @@ -89,20 +90,22 @@ class SharepointRenamerOrchestrator: uprn = row["UPRN"].strip() address = row["Address"].strip() postcode = row["Postcode"].strip() - folder_path = ( - f"{BASE_PATH}/{address}, {postcode}" - f"/{SharepointSubfolders.ASSESSMENT.value}/{ASSESSMENT_SUBFOLDER}" - ) - self._process_folder(folder_path, uprn, address, postcode) + for root in roots: + folder_path = ( + f"{root}/{address}, {postcode}" + f"/{SharepointSubfolders.ASSESSMENT.value}/{ASSESSMENT_SUBFOLDER}" + ) + if self._process_folder(folder_path, uprn, address, postcode): + break def _process_folder( self, folder_path: str, uprn: str, address: str, postcode: str - ) -> None: + ) -> bool: try: contents = self._sp_client.get_folders_in_path(folder_path) except ValueError: logger.warning(f"Missing folder for UPRN {uprn}: {folder_path}") - return + return False for item in contents.get("value", []): if "folder" in item: @@ -134,3 +137,4 @@ class SharepointRenamerOrchestrator: logger.error( f'Failed to rename "{original_name}" → "{new_name}" (UPRN: {uprn}): {e}' ) + return True From ce749061aae0098bc9ab52253c18e7eaeeb7c040 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 11:18:10 +0000 Subject: [PATCH 56/84] =?UTF-8?q?Renamer=20warns=20once=20per=20property?= =?UTF-8?q?=20only=20after=20all=20roots=20miss=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- tests/scripts/test_rename_sharepoint_files.py | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/tests/scripts/test_rename_sharepoint_files.py b/tests/scripts/test_rename_sharepoint_files.py index 92a33f7ad..b9d56562b 100644 --- a/tests/scripts/test_rename_sharepoint_files.py +++ b/tests/scripts/test_rename_sharepoint_files.py @@ -198,14 +198,46 @@ def test_ignores_package_items() -> None: # --------------------------------------------------------------------------- -def test_missing_folder_logs_warning_and_returns(caplog: pytest.LogCaptureFixture) -> None: +def test_missing_folder_returns_false_without_warning( + caplog: pytest.LogCaptureFixture, +) -> None: + # Arrange sp = MagicMock() sp.get_folders_in_path.side_effect = ValueError("not found") - _make_orchestrator(sp)._process_folder("missing/path", "400", "4 Elm St", "AA2 2BB") + # Act + found = _make_orchestrator(sp)._process_folder( + "missing/path", "400", "4 Elm St", "AA2 2BB" + ) + # Assert + assert found is False sp.rename_file.assert_not_called() - assert any("Missing folder" in r.message and "400" in r.message for r in caplog.records) + assert not any("Missing folder" in r.message for r in caplog.records) + + +def test_run_warns_once_when_property_missing_from_all_roots( + tmp_path: Path, caplog: pytest.LogCaptureFixture +) -> None: + # Arrange + csv_path = _write_csv(tmp_path, [("400", "4 Elm St", "AA2 2BB")]) + sp = MagicMock() + + def fake_get(path: str) -> dict[str, Any]: + if path == BASE_PATH: + return {"value": [_make_folder("_Sero Batch 2")]} + raise ValueError("not found") + + sp.get_folders_in_path.side_effect = fake_get + + # Act + SharepointRenamerOrchestrator(sp, csv_path).run() + + # Assert + sp.rename_file.assert_not_called() + warnings = [r for r in caplog.records if "Missing folder" in r.message] + assert len(warnings) == 1 + assert "400" in warnings[0].message # --------------------------------------------------------------------------- From 213cd929982404e4c1b13b6d3c1a66081c50dcf6 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 11:18:42 +0000 Subject: [PATCH 57/84] =?UTF-8?q?Renamer=20warns=20once=20per=20property?= =?UTF-8?q?=20only=20after=20all=20roots=20miss=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- orchestration/sharepoint_renamer_orchestrator.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/orchestration/sharepoint_renamer_orchestrator.py b/orchestration/sharepoint_renamer_orchestrator.py index b5206f0ee..84a4b62d7 100644 --- a/orchestration/sharepoint_renamer_orchestrator.py +++ b/orchestration/sharepoint_renamer_orchestrator.py @@ -97,6 +97,11 @@ class SharepointRenamerOrchestrator: ) if self._process_folder(folder_path, uprn, address, postcode): break + else: + logger.warning( + f"Missing folder for UPRN {uprn} in any root: " + f"{address}, {postcode}" + ) def _process_folder( self, folder_path: str, uprn: str, address: str, postcode: str @@ -104,7 +109,6 @@ class SharepointRenamerOrchestrator: try: contents = self._sp_client.get_folders_in_path(folder_path) except ValueError: - logger.warning(f"Missing folder for UPRN {uprn}: {folder_path}") return False for item in contents.get("value", []): From 46ed8bfe86fac2bbfba99eca9a68fd0accc15f65 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 11:19:34 +0000 Subject: [PATCH 58/84] =?UTF-8?q?Renamer=20warns=20once=20per=20property?= =?UTF-8?q?=20only=20after=20all=20roots=20miss=20=F0=9F=9F=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../sharepoint_renamer_orchestrator.py | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/orchestration/sharepoint_renamer_orchestrator.py b/orchestration/sharepoint_renamer_orchestrator.py index 84a4b62d7..15a2bd081 100644 --- a/orchestration/sharepoint_renamer_orchestrator.py +++ b/orchestration/sharepoint_renamer_orchestrator.py @@ -87,21 +87,26 @@ class SharepointRenamerOrchestrator: ) for row in reader: - uprn = row["UPRN"].strip() - address = row["Address"].strip() - postcode = row["Postcode"].strip() - for root in roots: - folder_path = ( - f"{root}/{address}, {postcode}" - f"/{SharepointSubfolders.ASSESSMENT.value}/{ASSESSMENT_SUBFOLDER}" - ) - if self._process_folder(folder_path, uprn, address, postcode): - break - else: - logger.warning( - f"Missing folder for UPRN {uprn} in any root: " - f"{address}, {postcode}" - ) + self._process_row( + roots, + uprn=row["UPRN"].strip(), + address=row["Address"].strip(), + postcode=row["Postcode"].strip(), + ) + + def _process_row( + self, roots: list[str], uprn: str, address: str, postcode: str + ) -> None: + for root in roots: + folder_path = ( + f"{root}/{address}, {postcode}" + f"/{SharepointSubfolders.ASSESSMENT.value}/{ASSESSMENT_SUBFOLDER}" + ) + if self._process_folder(folder_path, uprn, address, postcode): + return + logger.warning( + f"Missing folder for UPRN {uprn} in any root: {address}, {postcode}" + ) def _process_folder( self, folder_path: str, uprn: str, address: str, postcode: str From e110dd0746bc41b724dc8b89ef10da53c4658318 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:35:05 +0000 Subject: [PATCH 59/84] =?UTF-8?q?Record=20ADR-0050=20(underfloor=20overrid?= =?UTF-8?q?e=20companions)=20and=20ADR-0051=20(wall=20U-value=20gate)=20?= =?UTF-8?q?=F0=9F=9F=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WS2 of PRD #1435, diagnosed on property 711795: an electric-underfloor override inherits the replaced community-heating category (no pathway, baseline mis-rated 51 vs 67), and wall generators offer £4k insulation that cannot change an age-band-L wall's derived U (0.280 → 0.280). Glossary: Wall U-Value Gate. Co-Authored-By: Claude Opus 4.8 --- CONTEXT.md | 6 +- ...gory-8-and-conservative-group-7-control.md | 84 +++++++++++++++++++ ...when-it-lowers-the-derived-wall-u-value.md | 71 ++++++++++++++++ 3 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 docs/adr/0050-electric-underfloor-override-drags-category-8-and-conservative-group-7-control.md create mode 100644 docs/adr/0051-wall-insulation-offered-only-when-it-lowers-the-derived-wall-u-value.md diff --git a/CONTEXT.md b/CONTEXT.md index 182959e66..81b2716c3 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -317,7 +317,11 @@ The two competing **Measure Options** for insulating a *solid* (non-cavity) main _Avoid_: solid wall insulation (that names the pair, not one Option), cladding, drylining **Wall Insulation Eligibility**: -The rule fixing which wall Option(s) the main-wall **Recommendation** offers, by wall construction then planning status. By construction: **cavity** → cavity fill only (never solid insulation); **solid brick** / **system-built** → IWI + EWI; **timber-frame** → IWI only (EWI is not constructable); **cob** / **granite or whinstone** / **sandstone or limestone** → none (breathable fabric — standard insulation risks trapping moisture). Then, as planning gates: a **conservation area** or **flat** removes EWI (external-appearance / whole-block constraints), and a **listed** or **heritage** building removes **both** EWI and IWI (protected fabric). +The rule fixing which wall Option(s) the main-wall **Recommendation** offers, by wall construction then planning status. By construction: **cavity** → cavity fill only (never solid insulation); **solid brick** / **system-built** → IWI + EWI; **timber-frame** → IWI only (EWI is not constructable); **cob** / **granite or whinstone** / **sandstone or limestone** → none (breathable fabric — standard insulation risks trapping moisture). Then, as planning gates: a **conservation area** or **flat** removes EWI (external-appearance / whole-block constraints), and a **listed** or **heritage** building removes **both** EWI and IWI (protected fabric). Finally the **Wall U-Value Gate** applies. + +**Wall U-Value Gate**: +The eligibility rule that a wall insulation Option is offered **only when it would lower the wall's derived U-value** (by more than a 0.01 W/m²K float-noise guard) — comparing `u_wall` on the effective wall's current state vs its post-measure state (ADR-0051). Kills the **no-op fabric offer**: on a modern construction age band (e.g. band L, 2012–2022) RdSAP's cascade assigns the as-built wall its at-regs U-value and added insulation resolves to the *same* value, so the measure costs thousands for +0.00 SAP. The gate is physical possibility only — how *much* improvement is worth the cost stays with the Optimiser (ADR-0016/0024). +_Avoid_: no-op filter (it gates generation, not scored output), U-value threshold (there is no absolute target-U; the comparison is before-vs-after) _Avoid_: restricted measures (legacy collapsed conservation/listed/heritage into one boolean — they now gate different Options, so keep them distinct) **Roof Insulation Eligibility**: diff --git a/docs/adr/0050-electric-underfloor-override-drags-category-8-and-conservative-group-7-control.md b/docs/adr/0050-electric-underfloor-override-drags-category-8-and-conservative-group-7-control.md new file mode 100644 index 000000000..1ed2b536c --- /dev/null +++ b/docs/adr/0050-electric-underfloor-override-drags-category-8-and-conservative-group-7-control.md @@ -0,0 +1,84 @@ +# An electric-underfloor override drags category 8 and the conservative Group 7 control + +## Status + +accepted + +## Context + +[ADR-0048](0048-heating-override-forces-category-and-control-defers-fuel-and-meter.md) +established that a system-replacing heating override must emit a **complete, +coherent companion set** — category and control are archetype-forced, never +inherited — and explicitly deferred the category expansion for the still-`None` +archetypes ("electric boiler/CPSU→2, underfloor→8 … flows into the +category-keyed Table 12a resolver and needs a corpus check") to its own change. + +The portfolio-796 audit (PRD #1435, WS2) found the underfloor half of that gap +end-to-end on property **711795** (uprn 10090343115): a lodged **community +heating** cert (SAP 301, category 6, control 2311) overridden to *"Electric +underfloor, in screed above insulation"* (SAP 424, +[ADR-0046](0046-electric-underfloor-scored-by-its-own-codes-meter-deferred-when-tariff-ambiguous.md)). +`_category_for(424)` and `_control_for(424)` both returned `None`, so the +effective cert kept the replaced heat network's **category 6** and community +control. Two independent mis-ratings followed: + +1. **No heating pathway.** `is_heat_network_main` keys on category 6, so the + heating Recommendation Generator excluded both HHRSH and ASHP by the + heat-network topology rule — `recommend_heating` returned `None` and the + flat's whole candidate menu was a no-op wall measure plus lighting. The + dwelling was unliftable from band E (the `plan-stuck-in-low-band` audit + group counts ~7 electric-underfloor dwellings). +2. **Baseline mis-rated.** The calculator scored the electric underfloor as + community heating: baseline SAP **51 (E)** vs **67 (D)** with coherent + companions. With the pathway restored, HHRSH scores **80 (C)** for ~£1k — + the dwelling reaches the scenario goal. + +## Decision + +The three electric-underfloor archetypes (SAP Table 4a **421 / 422 / 424**, +ADR-0046) join the forced-companion branches of `main_heating_system_overlay`: + +1. **Category 8** ("Electric underfloor heating") in `_category_for` — + deterministic from SAP Table 4a, per ADR-0048's category rule. +2. **Control 2701** (SAP Table 4e **Group 7**, "no time or thermostatic control + of room temperature", **+0.3 °C**) in `_control_for` — the conservative + default within the group the category fixes: the largest mean-internal- + temperature adjustment in Group 7, so an unobserved control is never + over-credited. Mirrors the storage manual-charge 2401 + ([ADR-0035](0035-coherent-heating-system-synthesis.md)) and room-heater 2601 + (ADR-0048) precedents. + +Fuel (electricity 29) and meter (Dual for 421/422; **deferred to the cert** for +tariff-ambiguous 424) are already correct per ADR-0046 and are unchanged. + +**Scope**: underfloor only. Electric boiler / CPSU (Group 1) remain +log-and-continue gaps tracked by #1444 — their category (2) feeds the wet-boiler +fallback classification in the generators and needs its own check. + +## Consequences + +- An underfloor override on any lodged system now yields a coherent cert: the + Table 12a resolver and the heat-network gates read the dwelling as electric + underfloor, the baseline re-rates correctly, and the HHRSH bundle is offered + where eligible (a flat's only heating pathway — ASHP stays house/bungalow-only + per ADR-0024). +- The "incomplete companion set" error log no longer fires for 421/422/424. +- **Known deferred gap (pre-existing, unchanged by this ADR):** the Table 12a + space-heating resolver's underfloor rows are wired in the fraction table but + `_table_12a_system_for_main` never returns `UNDERFLOOR_HEATING` ("Underfloor + heating (421-422) — TODO"), so an off-peak-metered underfloor dwelling falls + to the all-low-rate fallback. That affects genuinely-lodged underfloor certs + identically and needs spec sight (SAP 10.2 Table 12a Grid 1, PDF p.191) to + split slab (storage-like) from screed (direct-acting-like); tracked as a + follow-up, not ridden on this override fix. + +### Alternatives rejected + +- **A zero-adjustment Group 7 control (2703/2704).** Rejected: credits a room + thermostat the landlord never reported; the conservative default is the + ADR-0035/0048 pattern. +- **Completing electric boiler / CPSU (category 2) in the same change.** + Rejected: no evidence property in this workstream, and category 2 flows into + the generators' wet-boiler fallback (`_WET_BOILER_CATEGORIES`), which would + make an electric-boiler override newly eligible for tune-up options — a + behaviour change needing its own corpus check (#1444). diff --git a/docs/adr/0051-wall-insulation-offered-only-when-it-lowers-the-derived-wall-u-value.md b/docs/adr/0051-wall-insulation-offered-only-when-it-lowers-the-derived-wall-u-value.md new file mode 100644 index 000000000..90db6f335 --- /dev/null +++ b/docs/adr/0051-wall-insulation-offered-only-when-it-lowers-the-derived-wall-u-value.md @@ -0,0 +1,71 @@ +# Wall insulation is offered only when it lowers the derived wall U-value + +## Status + +accepted + +## Context + +The wall Recommendation Generators trigger on the wall's **insulation state** +alone: `recommend_cavity_wall` offers cavity fill for any cavity wall whose +`wall_insulation_type` is as-built (4), and `recommend_solid_wall` offers +EWI/IWI for any as-built suitable construction +([ADR-0019](0019-solid-wall-insulation-options.md)). Neither asks whether +adding insulation can actually **change the modelled wall**. + +For modern construction age bands it cannot: RdSAP's Table 6-10 cascade +(`u_wall` in `domain/sap10_ml/rdsap_uvalues.py`) assigns an as-built wall its +age band's at-regs U-value, and the post-measure state resolves to the **same +value**. Portfolio-796 evidence (PRD #1435, WS2): property **711795**, timber +frame at age band **L** (2012–2022) — `u_wall` returns **0.280 W/m²K both +as-built and with 100 mm IWI**, so the persisted plan offered +`internal_wall_insulation` at **£4,027 for +0.00 SAP**. Any modern-age-band +dwelling gets the same no-op fabric offer; on an unliftable dwelling it is the +*entire* remedial menu, which reads as "we recommend spending £4k for nothing". + +Scoring already prices the option at +0.00, but the Optimiser keeps +zero-uplift candidates in the persisted menu (they are legitimate for some +measure types, e.g. secondary-heating removal saves bills without SAP), so the +fix belongs at **generation eligibility**, not a blanket score filter. + +## Decision + +Both wall generators consult the **derived wall U-value** before offering: the +measure is offered only when the post-measure state's `u_wall` is **lower than +the current state's by more than 0.01 W/m²K** (a float-noise guard, not a +materiality threshold — economics stay with the Optimiser, ADR-0016/0024). + +- **Current state**: `u_wall` with the effective main wall's construction, age + band, lodged insulation type/thickness — a thin parameter mapping in the + `envelope.py` style, deliberately omitting the calculator's rich extras + (surveyor description, dry-lining, documentary-thickness routes). Omissions + bias the gate toward **offering** (both sides are computed identically, so a + no-op still compares equal), never toward suppressing a real measure. +- **Post-measure state**: the same call with the Option's overlay applied — + filled cavity (`wall_insulation_type=2`) for cavity fill; 100 mm + internal/external insulation for IWI/EWI. + +## Consequences + +- Age-band-L (and any at-regs age band) walls stop polluting candidate menus + with £4k no-ops; genuinely treatable walls (e.g. age-band-D solid brick, + U 2.1 → ~0.3) are offered exactly as before. +- The generators gain a read on `domain/sap10_ml/rdsap_uvalues.u_wall` — same + precedent as the heating generator reading the calculator's PCDB/Table 4b. +- **Deferred:** (a) a cert that lodges an explicit `wall_u_value` overrides the + cascade in the calculator, making fabric measures score +0.00 regardless of + this gate — the measure overlay should adjust the lodged U; (b) roof/floor + generators have the same anti-pattern in principle (roof age-band eligibility + is partly covered by ADR-0047); both tracked as follow-ups. + +### Alternatives rejected + +- **Filter zero-SAP candidates after scoring.** Rejected: zero-uplift options + are legitimate for some measure types (bill-driven), and the pollution would + survive in any consumer that reads Generator output before scoring. +- **Hard-code "age band ≥ K ⇒ no wall offer".** Rejected: duplicates the U + tables coarsely; the tables already encode exactly which + construction × age-band × insulation combinations move. +- **Full-fidelity U parity with the calculator (description, dry-lining, + lodged U).** Rejected for now: heavier coupling for no observed benefit — + the omissions only ever bias toward offering, which is the status quo. From 51fa4977934270f67f3821a5947b0361f56aea46 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:35:55 +0000 Subject: [PATCH 60/84] =?UTF-8?q?Electric=20underfloor=20override=20stamps?= =?UTF-8?q?=20the=20Table=204a=20underfloor=20category=20(8)=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../epc/test_main_heating_system_overlay.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/domain/epc/test_main_heating_system_overlay.py b/tests/domain/epc/test_main_heating_system_overlay.py index 40998c7d7..d9f89b4b6 100644 --- a/tests/domain/epc/test_main_heating_system_overlay.py +++ b/tests/domain/epc/test_main_heating_system_overlay.py @@ -233,6 +233,32 @@ def test_off_peak_underfloor_asserts_a_dual_meter(main_heating_value: str) -> No assert simulation.heating.meter_type == "Dual" +@pytest.mark.parametrize( + "main_heating_value", + [ + "Electric underfloor, in concrete slab (off-peak)", + "Electric underfloor, integrated storage and direct-acting", + "Electric underfloor, in screed above insulation", + ], +) +def test_electric_underfloor_overlays_the_underfloor_category( + main_heating_value: str, +) -> None: + # A system-replacing override must stamp the underfloor heating category + # (SAP Table 4a Category 8). Leaving it unset lets the replaced system's + # category survive onto the effective cert — property 711795's community + # heating (category 6) survived an underfloor override, so the heating + # generator read the dwelling as a heat network and offered no heating + # upgrade at all, and the baseline mis-rated 51 vs 67 (ADR-0050). + # Act + simulation = main_heating_overlay_for(main_heating_value, 0) + + # Assert — SAP Table 4a Category 8 (Electric underfloor heating). + assert simulation is not None + assert simulation.heating is not None + assert simulation.heating.main_heating_category == 8 + + def test_screed_underfloor_defers_the_meter_to_the_cert() -> None: # "In screed above insulation (standard or off peak)" is tariff-ambiguous (81% # of the corpus lodge off-peak), so the archetype cannot know the meter — it From 57e899e8d913491a4bf8a3c49dcaf78047278c9f Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:36:30 +0000 Subject: [PATCH 61/84] =?UTF-8?q?Electric=20underfloor=20override=20stamps?= =?UTF-8?q?=20the=20Table=204a=20underfloor=20category=20(8)=20?= =?UTF-8?q?=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../epc/property_overlays/main_heating_system_overlay.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/domain/epc/property_overlays/main_heating_system_overlay.py b/domain/epc/property_overlays/main_heating_system_overlay.py index d0c498320..1110b1f68 100644 --- a/domain/epc/property_overlays/main_heating_system_overlay.py +++ b/domain/epc/property_overlays/main_heating_system_overlay.py @@ -134,6 +134,13 @@ _ELECTRIC_BOILER_CODES = frozenset({191, 192}) # unambiguously electric (ADR-0046). _ELECTRIC_UNDERFLOOR_CODES = frozenset({421, 422, 424}) +# SAP Table 4a "electric underfloor heating" category. Stamped so an underfloor +# override never leaves the replaced system's category behind — property 711795 +# (PRD #1435 WS2) kept a replaced heat network's category 6, which the heating +# generator's `is_heat_network_main` gate read as community heating: no heating +# upgrade was offered at all and the baseline mis-rated 51 vs 67 (ADR-0050). +_UNDERFLOOR_CATEGORY = 8 + # Heat pumps (SAP Table 4a 211-224 wet, 521-527 warm-air) are category 4 and # unambiguously electric (natural fuel 29). Modellable on the default code's SPF # without a PCDB index (ADR-0041). @@ -287,6 +294,8 @@ def _category_for(code: int) -> Optional[int]: return _ROOM_HEATER_CATEGORY if code in _STORAGE_HEATER_CODES: return _STORAGE_HEATER_CATEGORY + if code in _ELECTRIC_UNDERFLOOR_CODES: + return _UNDERFLOOR_CATEGORY if code in _HEAT_PUMP_CODES: return _HEAT_PUMP_CATEGORY if code in _HEAT_NETWORK_CODES: From 566374bf34dfda2e4a22f71e78f6e65c4092ad1e Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:36:51 +0000 Subject: [PATCH 62/84] =?UTF-8?q?Electric=20underfloor=20override=20drags?= =?UTF-8?q?=20the=20conservative=20Group=207=20control=20(2701)=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../epc/test_main_heating_system_overlay.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/domain/epc/test_main_heating_system_overlay.py b/tests/domain/epc/test_main_heating_system_overlay.py index d9f89b4b6..3ae8b07b7 100644 --- a/tests/domain/epc/test_main_heating_system_overlay.py +++ b/tests/domain/epc/test_main_heating_system_overlay.py @@ -259,6 +259,32 @@ def test_electric_underfloor_overlays_the_underfloor_category( assert simulation.heating.main_heating_category == 8 +@pytest.mark.parametrize( + "main_heating_value", + [ + "Electric underfloor, in concrete slab (off-peak)", + "Electric underfloor, integrated storage and direct-acting", + "Electric underfloor, in screed above insulation", + ], +) +def test_electric_underfloor_drags_the_conservative_group_7_control( + main_heating_value: str, +) -> None: + # The landlord names the system, not its control, so the overlay assumes the + # conservative Table 4e Group 7 default: 2701 ("no time or thermostatic + # control", +0.3 C — the largest adjustment in the group, so an unobserved + # control is never over-credited). Mirrors storage-manual 2401 / room-heater + # 2601; also overwrites a stale control inherited from the replaced system + # (711795 kept a community control 2311) — ADR-0050. + # Act + simulation = main_heating_overlay_for(main_heating_value, 0) + + # Assert — SAP Table 4e Group 7 conservative underfloor control. + assert simulation is not None + assert simulation.heating is not None + assert simulation.heating.main_heating_control == 2701 + + def test_screed_underfloor_defers_the_meter_to_the_cert() -> None: # "In screed above insulation (standard or off peak)" is tariff-ambiguous (81% # of the corpus lodge off-peak), so the archetype cannot know the meter — it From 07362b357a984810ce4395cc3339347e87faa8a8 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:37:19 +0000 Subject: [PATCH 63/84] =?UTF-8?q?Electric=20underfloor=20override=20drags?= =?UTF-8?q?=20the=20conservative=20Group=207=20control=20(2701)=20?= =?UTF-8?q?=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../epc/property_overlays/main_heating_system_overlay.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/domain/epc/property_overlays/main_heating_system_overlay.py b/domain/epc/property_overlays/main_heating_system_overlay.py index 1110b1f68..f99a24f5c 100644 --- a/domain/epc/property_overlays/main_heating_system_overlay.py +++ b/domain/epc/property_overlays/main_heating_system_overlay.py @@ -140,6 +140,12 @@ _ELECTRIC_UNDERFLOOR_CODES = frozenset({421, 422, 424}) # generator's `is_heat_network_main` gate read as community heating: no heating # upgrade was offered at all and the baseline mis-rated 51 vs 67 (ADR-0050). _UNDERFLOOR_CATEGORY = 8 +# SAP Table 4e Group 7 underfloor control: 2701 ("no time or thermostatic +# control of room temperature", +0.3 C) is the conservative default when the +# landlord named only the system — the largest mean-internal-temperature +# adjustment in the group, so an unobserved control is never over-credited +# (the underfloor mirror of storage-manual 2401 and room-heater 2601, ADR-0050). +_UNDERFLOOR_CONTROL = 2701 # Heat pumps (SAP Table 4a 211-224 wet, 521-527 warm-air) are category 4 and # unambiguously electric (natural fuel 29). Modellable on the default code's SPF @@ -278,6 +284,8 @@ def _control_for(code: int) -> Optional[int]: return _FULL_BOILER_CONTROL if code in _CATEGORY_10_ROOM_HEATER_CODES or code in _ELECTRIC_ROOM_HEATER_CODES: return _ROOM_HEATER_CONTROL + if code in _ELECTRIC_UNDERFLOOR_CODES: + return _UNDERFLOOR_CONTROL return None From 573588d4e790aadc273a6005db408eab814ae51c Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:37:57 +0000 Subject: [PATCH 64/84] =?UTF-8?q?Underfloor=20overrides=20no=20longer=20lo?= =?UTF-8?q?g=20an=20incomplete=20companion=20set=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regression guard: category 8 + control 2701 keep the ADR-0048 coherence invariant satisfied for SAP codes 421/422/424. Co-Authored-By: Claude Opus 4.8 --- .../epc/test_main_heating_system_overlay.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/domain/epc/test_main_heating_system_overlay.py b/tests/domain/epc/test_main_heating_system_overlay.py index 3ae8b07b7..5c1b680d2 100644 --- a/tests/domain/epc/test_main_heating_system_overlay.py +++ b/tests/domain/epc/test_main_heating_system_overlay.py @@ -285,6 +285,28 @@ def test_electric_underfloor_drags_the_conservative_group_7_control( assert simulation.heating.main_heating_control == 2701 +@pytest.mark.parametrize( + "main_heating_value", + [ + "Electric underfloor, in concrete slab (off-peak)", + "Electric underfloor, integrated storage and direct-acting", + "Electric underfloor, in screed above insulation", + ], +) +def test_complete_underfloor_overlay_does_not_log_a_companion_gap( + main_heating_value: str, caplog: pytest.LogCaptureFixture +) -> None: + # Electric underfloor now resolves a full companion set (category 8 + + # control 2701, ADR-0050), so the overlay must NOT log an + # incomplete-companion gap — guarding that the set stays complete. + # Act + with caplog.at_level(logging.ERROR): + main_heating_overlay_for(main_heating_value, 0) + + # Assert + assert "incomplete companion set" not in caplog.text + + def test_screed_underfloor_defers_the_meter_to_the_cert() -> None: # "In screed above insulation (standard or off peak)" is tariff-ambiguous (81% # of the corpus lodge off-peak), so the archetype cannot know the meter — it From 574e58a5c8a0109aea5070439dc1c698fc8837a2 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:39:32 +0000 Subject: [PATCH 65/84] =?UTF-8?q?Solid-wall=20insulation=20is=20withheld?= =?UTF-8?q?=20when=20it=20cannot=20lower=20the=20derived=20wall=20U=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../modelling/test_wall_recommendation.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/domain/modelling/test_wall_recommendation.py b/tests/domain/modelling/test_wall_recommendation.py index b47d9eb16..8fe2620d4 100644 --- a/tests/domain/modelling/test_wall_recommendation.py +++ b/tests/domain/modelling/test_wall_recommendation.py @@ -90,6 +90,28 @@ def test_non_cavity_main_wall_yields_no_recommendation() -> None: assert recommendation is None +def test_at_regs_age_band_wall_yields_no_solid_wall_recommendation() -> None: + # Arrange — a timber-frame wall lodged as-built at construction age band L + # (2012-2022). RdSAP's cascade assigns it the at-regs U-value (0.28), and + # 100 mm IWI resolves to the SAME value — the measure cannot change the + # modelled wall, so offering it sells £4k of insulation for +0.00 SAP + # (property 711795, PRD #1435 WS2). The Wall U-Value Gate withholds it + # (ADR-0051). + baseline: EpcPropertyData = build_epc() + main: SapBuildingPart = _part(baseline, BuildingPartIdentifier.MAIN) + main.wall_construction = 5 # timber frame — IWI-only construction + main.wall_insulation_type = 4 # as-built / uninsulated — the legacy trigger + main.construction_age_band = "L" + + # Act + recommendation: Recommendation | None = recommend_solid_wall( + baseline, _StubProducts() + ) + + # Assert + assert recommendation is None + + def test_park_home_wall_yields_no_solid_wall_recommendation() -> None: # Arrange — a park home (wall_construction code 8) with an uninsulated # as-built wall. Code 8 is NOT system-built (ADR-0019); a park home's From 7c8b161653530a2d67d0899b993b5766c6acc44e Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:40:41 +0000 Subject: [PATCH 66/84] =?UTF-8?q?Solid-wall=20insulation=20is=20withheld?= =?UTF-8?q?=20when=20it=20cannot=20lower=20the=20derived=20wall=20U=20?= =?UTF-8?q?=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../generators/solid_wall_recommendation.py | 10 +++ .../modelling/generators/wall_u_value_gate.py | 80 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 domain/modelling/generators/wall_u_value_gate.py diff --git a/domain/modelling/generators/solid_wall_recommendation.py b/domain/modelling/generators/solid_wall_recommendation.py index dff55b669..32cee3437 100644 --- a/domain/modelling/generators/solid_wall_recommendation.py +++ b/domain/modelling/generators/solid_wall_recommendation.py @@ -26,6 +26,7 @@ from domain.building_geometry import gross_heat_loss_wall_area from domain.geospatial.planning_restrictions import PlanningRestrictions from domain.modelling.measure_type import MeasureType from domain.modelling.recommendation import Cost, MeasureOption, Recommendation +from domain.modelling.generators.wall_u_value_gate import wall_insulation_lowers_u from domain.modelling.simulation import BuildingPartOverlay, EpcSimulation from repositories.product.product_repository import ProductRepository @@ -158,6 +159,15 @@ def recommend_solid_wall( measure_type for measure_type in measure_types if _allowed(measure_type, restrictions, is_flat) + # Wall U-Value Gate (ADR-0051): withhold an Option that cannot lower + # the wall's derived U — e.g. an at-regs modern age band, where the + # as-built and insulated cascades resolve to the same value. + and wall_insulation_lowers_u( + main, + epc.country_code, + insulation_type=_INSULATION_TYPE[measure_type], + insulation_thickness_mm=_SOLID_WALL_INSULATION_MM, + ) ) if not allowed: return None diff --git a/domain/modelling/generators/wall_u_value_gate.py b/domain/modelling/generators/wall_u_value_gate.py new file mode 100644 index 000000000..fbbe3248c --- /dev/null +++ b/domain/modelling/generators/wall_u_value_gate.py @@ -0,0 +1,80 @@ +"""The Wall U-Value Gate (ADR-0051). + +A wall insulation Option is offered only when it would actually lower the main +wall's derived U-value: on a modern construction age band RdSAP's Table 6-10 +cascade assigns an as-built wall its at-regs U-value, and the post-measure +state resolves to the *same* value — the measure costs thousands for +0.00 SAP +(property 711795, PRD #1435 WS2: timber frame at age band L, 0.280 → 0.280). + +The comparison uses a deliberately thin `u_wall` parameter mapping (the +`envelope.py` style — construction, age band, insulation type/thickness, +documentary wall thickness), omitting the calculator's rich extras (surveyor +description, dry-lining, lodged `wall_u_value`). The omissions bias the gate +toward OFFERING — both sides are computed identically, so a genuine no-op still +compares equal — never toward suppressing a real measure. +""" + +from typing import Any, Final, Optional + +from datatypes.epc.domain.epc_property_data import SapBuildingPart +from domain.sap10_ml.rdsap_uvalues import WALL_UNKNOWN, Country, u_wall + +# Improvements below this are float noise, not a physical change. NOT a +# materiality threshold — how much improvement is worth the cost stays with the +# Optimiser (ADR-0016/0024). +_NOISE_FLOOR_W_PER_M2K: Final[float] = 0.01 + +# RdSAP `wall_insulation_type` 4 = as-built / assumed (no added insulation). +_WALL_INSULATION_NONE: Final[int] = 4 + + +def _int_or_none(value: Any) -> Optional[int]: + return value if isinstance(value, int) else None + + +def _parse_thickness_mm(value: Any) -> Optional[int]: + if value is None or isinstance(value, int): + return value + if isinstance(value, str) and value.strip().isdigit(): + return int(value.strip()) + return None # "NI" / free text — thickness not known + + +def wall_insulation_lowers_u( + main: SapBuildingPart, + country_code: Optional[str], + *, + insulation_type: int, + insulation_thickness_mm: Optional[int] = None, +) -> bool: + """Whether insulating the main wall to ``insulation_type`` (+ optional + thickness) lowers its derived U-value by more than float noise — the Wall + U-Value Gate (ADR-0051).""" + country: Country = Country.from_code(country_code) + age_band = main.construction_age_band + construction: Optional[int] = _int_or_none(main.wall_construction) + if construction == WALL_UNKNOWN: + construction = None + wall_thickness_mm = main.wall_thickness_mm + current_type: Optional[int] = _int_or_none(main.wall_insulation_type) + current_u: float = u_wall( + country, + age_band, + construction, + _parse_thickness_mm(main.wall_insulation_thickness), + insulation_present=( + current_type is not None and current_type != _WALL_INSULATION_NONE + ), + wall_insulation_type=current_type, + wall_thickness_mm=wall_thickness_mm, + ) + post_u: float = u_wall( + country, + age_band, + construction, + insulation_thickness_mm, + insulation_present=True, + wall_insulation_type=insulation_type, + wall_thickness_mm=wall_thickness_mm, + ) + return current_u - post_u > _NOISE_FLOOR_W_PER_M2K From 5f74c34f9ab610a0d793652d4b46a5f3c4bd31cd Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:41:02 +0000 Subject: [PATCH 67/84] =?UTF-8?q?Cavity=20fill=20is=20withheld=20when=20it?= =?UTF-8?q?=20cannot=20lower=20the=20derived=20wall=20U=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../modelling/test_wall_recommendation.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/domain/modelling/test_wall_recommendation.py b/tests/domain/modelling/test_wall_recommendation.py index 8fe2620d4..993d7a856 100644 --- a/tests/domain/modelling/test_wall_recommendation.py +++ b/tests/domain/modelling/test_wall_recommendation.py @@ -90,6 +90,24 @@ def test_non_cavity_main_wall_yields_no_recommendation() -> None: assert recommendation is None +def test_at_regs_age_band_cavity_yields_no_cavity_fill_recommendation() -> None: + # Arrange — a cavity wall lodged as-built at construction age band L + # (2012-2022): the as-built cascade already assigns the at-regs U-value, so + # filling the cavity cannot lower it. The Wall U-Value Gate withholds the + # Option (ADR-0051); the legacy insulation-state trigger alone would offer + # a paid no-op. + baseline: EpcPropertyData = build_epc() # MAIN: cavity (4), uninsulated (4) + _part(baseline, BuildingPartIdentifier.MAIN).construction_age_band = "L" + + # Act + recommendation: Recommendation | None = recommend_cavity_wall( + baseline, _StubProducts() + ) + + # Assert + assert recommendation is None + + def test_at_regs_age_band_wall_yields_no_solid_wall_recommendation() -> None: # Arrange — a timber-frame wall lodged as-built at construction age band L # (2012-2022). RdSAP's cascade assigns it the at-regs U-value (0.28), and From 7a039d30bc7959de7d54694737a9fc12b6062fde Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:41:33 +0000 Subject: [PATCH 68/84] =?UTF-8?q?Cavity=20fill=20is=20withheld=20when=20it?= =?UTF-8?q?=20cannot=20lower=20the=20derived=20wall=20U=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- domain/modelling/generators/wall_recommendation.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/domain/modelling/generators/wall_recommendation.py b/domain/modelling/generators/wall_recommendation.py index 2c5622413..b3182ba28 100644 --- a/domain/modelling/generators/wall_recommendation.py +++ b/domain/modelling/generators/wall_recommendation.py @@ -12,6 +12,7 @@ from datatypes.epc.domain.epc_property_data import ( EpcPropertyData, ) from domain.building_geometry import gross_heat_loss_wall_area +from domain.modelling.generators.wall_u_value_gate import wall_insulation_lowers_u from domain.modelling.measure_type import MeasureType from domain.modelling.recommendation import Cost, MeasureOption, Recommendation from domain.modelling.simulation import BuildingPartOverlay, EpcSimulation @@ -46,6 +47,14 @@ def recommend_cavity_wall( ): return None + # Wall U-Value Gate (ADR-0051): withhold the fill when it cannot lower the + # wall's derived U — e.g. an at-regs modern age band, where the as-built and + # filled-cavity cascades resolve to the same (or a no-better) value. + if not wall_insulation_lowers_u( + main, epc.country_code, insulation_type=_FILLED_CAVITY + ): + return None + product = products.get(_CAVITY_MEASURE_TYPE) wall_area: float = gross_heat_loss_wall_area(epc, BuildingPartIdentifier.MAIN) cost = Cost( From da4aec984000630375135181dac3d3a80db6cb3e Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:41:56 +0000 Subject: [PATCH 69/84] =?UTF-8?q?Treatable=20old-band=20solid=20walls=20ke?= =?UTF-8?q?ep=20their=20EWI=20and=20IWI=20options=20under=20the=20gate=20?= =?UTF-8?q?=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../modelling/test_wall_recommendation.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/domain/modelling/test_wall_recommendation.py b/tests/domain/modelling/test_wall_recommendation.py index 993d7a856..4734314c9 100644 --- a/tests/domain/modelling/test_wall_recommendation.py +++ b/tests/domain/modelling/test_wall_recommendation.py @@ -130,6 +130,29 @@ def test_at_regs_age_band_wall_yields_no_solid_wall_recommendation() -> None: assert recommendation is None +def test_treatable_old_band_solid_wall_keeps_its_insulation_options() -> None: + # Arrange — solid brick as-built at age band B: the cascade U (~2.1) far + # exceeds what 100 mm EWI/IWI achieves, so the Wall U-Value Gate must let + # both Options through unchanged (the gate is physical possibility only — + # ADR-0051). + baseline: EpcPropertyData = build_epc() # age band B + main: SapBuildingPart = _part(baseline, BuildingPartIdentifier.MAIN) + main.wall_construction = 3 # solid brick — EWI + IWI constructable + main.wall_insulation_type = 4 + + # Act + recommendation: Recommendation | None = recommend_solid_wall( + baseline, _StubProducts() + ) + + # Assert + assert recommendation is not None + assert {option.measure_type for option in recommendation.options} == { + "external_wall_insulation", + "internal_wall_insulation", + } + + def test_park_home_wall_yields_no_solid_wall_recommendation() -> None: # Arrange — a park home (wall_construction code 8) with an uninsulated # as-built wall. Code 8 is NOT system-built (ADR-0019); a park home's From bc39030707bec90fd401aa13cfb4db88c15fdfd0 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 11:42:29 +0000 Subject: [PATCH 70/84] =?UTF-8?q?The=20e2e=20candidate=20menu=20is=20gener?= =?UTF-8?q?ated=20from=20the=20Effective=20EPC,=20not=20the=20lodged=20cer?= =?UTF-8?q?t=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The printed "candidate measures considered" now matches what the orchestrator actually offered — on 711795 the lodged cavity wall printed a cavity-fill candidate the plan (timber-frame effective wall) never saw. Co-Authored-By: Claude Opus 4.8 --- scripts/run_modelling_e2e.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/run_modelling_e2e.py b/scripts/run_modelling_e2e.py index 1a1964cec..6b4225be6 100644 --- a/scripts/run_modelling_e2e.py +++ b/scripts/run_modelling_e2e.py @@ -910,10 +910,12 @@ def main() -> None: print_table=False, ) # The full candidate menu (every Generator Option + its cost), so - # measures the Optimiser did not select are still visible. A predicted - # Property has no lodged cert, so the synthesised Effective EPC is used. + # measures the Optimiser did not select are still visible. Generated + # from the Effective EPC — the same picture the plan above modelled; + # the lodged cert would print a menu the Optimiser never saw (e.g. + # cavity fill on a wall an override moved to timber frame). candidates: list[Recommendation] = candidate_recommendations( - epc if epc is not None else effective_epc, + effective_epc, planning_restrictions=restrictions, solar_insights=solar_insights, considered_measures=considered, From 781251eb07d97aa85f1fd57fec21db68cdc3f5c1 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 11:59:01 +0000 Subject: [PATCH 71/84] updated address list --- .../sharepoint_renamer/sero_address_list.csv | 548 ++++++++++++------ 1 file changed, 366 insertions(+), 182 deletions(-) diff --git a/applications/sharepoint_renamer/sero_address_list.csv b/applications/sharepoint_renamer/sero_address_list.csv index 51cdf2eff..ad84ff0e7 100644 --- a/applications/sharepoint_renamer/sero_address_list.csv +++ b/applications/sharepoint_renamer/sero_address_list.csv @@ -1,182 +1,366 @@ -UPRN,Address,Postcode -U1027392,"26 Silverdale Road, Oprington",BR5 2LT -U1003906,"54 Barnsdale Crescent, Oprington",BR5 2AX -U1034479,"90 Mead Way, Bromley",BR2 9EU -U1005549,"79 Lower Gravel Road, Bromley",BR2 8LP -U1016743,"16 Princes Plain, Bromley",BR2 8LE -U1041937,"75 Turpington Lane, Bromley",BR2 8JD -U1034805,"38 Narrow Way, Bromley",BR2 8JB -U1041933,"31 Turpington Lane, Bromley",BR2 8JA -U1037833,"3 Stiles Close, Bromley",BR2 8EQ -U1042734,"86 Whitebeam Avenue, Bromley",BR2 8DW -U1042575,"90 Whitebeam Avenue, Bromley",BR2 8DW -U1033177,"30 Larch Way, Bromley",BR2 8DU -U1027989,"5 Larch Way, Bromley",BR2 8DT -U1012309,"13 Almond Close, Bromley",BR2 8DS -U1022525,"30 Lovelace Avenue, Bromley",BR2 8DQ -U1047613,"13 Whitebeam Avenue, Bromley",BR2 8DJ -U1027549,"14 Thorn Close, Bromley",BR2 8DH -U1022726,"31 Hornbeam Way, Bromley",BR2 8DB -U1021308,"70 Faringdon Avenue, Bromley",BR2 8BU -U1026958,"77 Faringdon Avenue, Bromley",BR2 8BT -U1007553,"115d Faringdon Avenue, Bromley",BR2 8BT -U1032132,"115f Faringdon Avenue, Bromley",BR2 8BT -U1014627,"81 Faringdon Avenue, Bromley",BR2 8BT -U1009607,"20 Parkfield Way, Bromley",BR2 8AF -U1027838,"15 Holmcroft Way, Bromley",BR2 8AD -U1052376,"3 Shoreham Way, Bromley",BR2 7PU -U1015499,"25 Boughton Avenue, Bromley",BR2 7PL -U1005741,"2 Malling Way, Bromley",BR2 7PJ -U1019906,"26 Eastry Avenue, Bromley",BR2 7PF -U1021769,"49 Eastry Avenue, Bromley",BR2 7PE -U1031121,"32 Laburnum Way, Bromley",BR2 8BZ -U1022281,"35 Kingsdown Way, Bromley",BR2 7PT -U1035115,"30 Thorn Close, Bromley",BR2 8DH -U1027493,"35 Sudbury Crescent, Bromley",BR1 4PY -U1016746,"68 Princes Plain, Bromley",BR2 8LE -U1005168,"38 Holbrook Way, Bromley",BR2 8EE -U1036446,"14 Meath Close, Oprington",BR5 2HF -U1010452,"5 Canbury Path, Oprington",BR5 2EU -U1019785,"50 Cray Valley Road, Oprington",BR5 2EZ -U1024065,"64 Marion Crescent, Oprington",BR5 2HD -U1042248,"16 Stanley Way, Oprington",BR5 2HE -U1029229,"2 Meath Close, Oprington",BR5 2HF -U1037768,"13 Silverdale Road, Oprington",BR5 2LU -U1014589,"71 Empress Drive, Chislehurst",BR7 5BQ -U1024698,"4 Palace View, Bromley",BR1 3EL -U1052536,"12 Thorn Close, Bromley",BR2 8DH -U1022018,"12 Hazel Walk, Bromley",BR2 8DF -U1007728,"2 Hazel Walk, Bromley",BR2 8DF -U1002456,"54 Birch Row, Bromley",BR2 8DA -U1020349,"21 Laburnum Way, Bromley",BR2 8BY -U1032129,"78 Faringdon Avenue, Bromley",BR2 8BU -U1032130,"86 Faringdon Avenue, Bromley",BR2 8BU -U1021824,"115g Faringdon Avenue, Bromley",BR2 8BT -U1021827,"121 Faringdon Avenue, Bromley",BR2 8BT -U1026960,"105 Faringdon Avenue, Bromley",BR2 8BT -U1010578,"6 Cranbrook Close, Bromley",BR2 7QA -U1024709,"3 Parkfield Way, Bromley",BR2 8AE -U1024580,"24 Parkfield Way, Bromley",BR2 8AF -U1011190,"11 Shoreham Way, Bromley",BR2 7PU -U1011191,"32 Shoreham Way, Bromley",BR2 7PU -U1021535,"4 Chilham Way, Bromley",BR2 7PR -U1007556,"11 Farleigh Avenue, Bromley",BR2 7PP -U1010255,"7 Boughton Avenue, Bromley",BR2 7PL -U1034810,"24 Newbury Road, Bromley",BR2 0QW -U1009032,"10 Malling Way, Bromley",BR2 7PJ -U1004686,"55 Baston Road, Bromley",BR2 7BD -U1032061,"30 Eastry Avenue, Bromley",BR2 7PF -U1010582,"13 Cranworth Cottages, Keston",BR2 6DB -U1009511,"27 Newbury Road, Bromley",BR2 0QN -U1037954,"28 Treewall Gardens, Bromley",BR1 5BT -U1014793,"59 Headcorn Road, Bromley",BR1 4SQ -U1005123,"24 Bonville Road, Bromley",BR1 4QA -U1037872,"20 Sudbury Crescent, Bromley",BR1 4PZ -U1022305,"18a Lansdowne Road, Bromley",BR1 3LZ -U1035052,"1 Sudbury Crescent, Bromley",BR1 4PY -U1042298,"39 Sudbury Crescent, Bromley",BR1 4PY -U1019564,"32 Brook Lane, Bromley",BR1 4PU -U1024511,"81 Nightingale Lane, Bromley",BR1 2SA -U1032133,"119 Faringdon Avenue, Bromley",BR2 8BT -U1032134,"125 Faringdon Avenue, Bromley",BR2 8BT -U1032131,"93 Faringdon Avenue, Bromley",BR2 8BT -U1021825,"117a Faringdon Avenue, Bromley",BR2 8BT -U1010107,"42 Birch Row, Bromley",BR2 8DA -U1016880,"25 Almond Way, Bromley",BR2 8DR -U1038107,"152 Whitebeam Avenue, Bromley",BR2 8DW -U1052455,"10 Stiles Close, Bromley",BR2 8EQ -U1028328,"76 Magpie Hall Lane, Bromley",BR2 8ER -U1020064,"28 Green Way, Bromley",BR2 8EY -U1041934,"51 Turpington Lane, Bromley",BR2 8JA -U1005696,"158 Magpie Hall Lane, Bromley",BR2 8JG -U1030892,"140 Poverest Road, Oprington",BR5 1RH -U1011072,"45 Rookery Gardens, Oprington",BR5 4BA -U1031058,"303 Keedonwood Road, Bromley",BR1 4QR -U1052429,"76 Southover, Bromley",BR1 4RY -U1042153,"4 Scotts Road, Bromley",BR1 3QD -U1037814,"42 Stanley Road, Bromley",BR2 9JH -U1008158,"71 Lower Gravel Road, Bromley",BR2 8LP -U1032062,"46 Eastry Avenue, Bromley",BR2 7PF -U1016742,"4 Princes Plain, Bromley",BR2 8LE -U1038106,"84 Whitebeam Avenue, Bromley",BR2 8DW -U1013831,"33 Ash Row, Bromley",BR2 8DZ -U1005742,"18 Malling Way, Bromley",BR2 7PJ -U1042572,"37 Whitebeam Avenue, Bromley",BR2 8DJ -U1005167,"30 Holbrook Way, Bromley",BR2 8EE -U1024581,"30 Parkfield Way, Bromley",BR2 8AF -U1024050,"10 Marden Avenue, Bromley",BR2 7PX -U1020328,"31 Kingsdown Way, Bromley",BR2 7PT -U1020327,"5 Kingsdown Way, Bromley",BR2 7PT -U1005131,"10 Boughton Avenue, Bromley",BR2 7PL -U1023415,"27 Malling Way, Bromley",BR2 7PJ -U1052580,"25 Trentham Drive, Oprington",BR5 2EP -U1026447,"50 Princes Plain, Bromley",BR2 8LE -U1007432,"21 Detling Road, Bromley",BR1 4SH -U1053388,"52 Whitebeam Avenue, Bromley",BR2 8DL -U1022307,"20 Larch Way, Bromley",BR2 8DU -U1027743,"17 Whitebeam Avenue, Bromley",BR2 8DJ -U1022533,"81 Lower Gravel Road, Bromley",BR2 8LP -U1014630,"118 Faringdon Avenue, Bromley",BR2 8BU -U1030897,"60 Princes Plain, Bromley",BR2 8LE -U1022931,"15 Lennard Road, Bromley",BR2 8LN -U1042735,"108 Whitebeam Avenue, Bromley",BR2 8DW -U1013830,"31 Ash Row, Bromley",BR2 8DZ -U1020368,"11 Larch Way, Bromley",BR2 8DT -U1020369,"13 Larch Way, Bromley",BR2 8DT -U1042576,"112 Whitebeam Avenue, Bromley",BR2 8DW -U1027830,"26 Holbrook Way, Bromley",BR2 8EE -U1016744,"18 Princes Plain, Bromley",BR2 8LE -U1041772,"13 Stanley Road, Bromley",BR2 9JE -U1042573,"47 Whitebeam Avenue, Bromley",BR2 8DJ -U1008151,"61 Lovelace Avenue, Bromley",BR2 8EA -U1034985,"272 Southborough Lane, Bromley",BR2 8AS -U1007947,"8 Laburnum Way, Bromley",BR2 8BZ -U1027744,"33 Whitebeam Avenue, Bromley",BR2 8DJ -U1038102,"14 Whitebeam Avenue, Bromley",BR2 8DL -U1027745,"148 Whitebeam Avenue, Bromley",BR2 8DW -U1020208,"16 Holbrook Way, Bromley",BR2 8EE -U1023463,"30 MANOR WAY, Bromley",BR2 8ES -U1032647,"32 Narrow Way, Bromley",BR2 8JB -U1033406,"67 Lower Gravel Road, Bromley",BR2 8LP -U1000649,"42 Barnsdale Crescent, Oprington",BR5 2AX -U1036332,"50 Marion Crescent, Oprington",BR5 2HD -U1038103,"29 Whitebeam Avenue, Bromley",BR2 8DJ -U1042574,"66 Whitebeam Avenue, Bromley",BR2 8DL -U1042256,"2 Stiles Close, Bromley",BR2 8EQ -U1034017,"48 Princes Plain, Bromley",BR2 8LE -U1041435,"64 Princes Plain, Bromley",BR2 8LE -U1053386,"27 Whitebeam Avenue, Bromley",BR2 8DJ -U1038104,"32 Whitebeam Avenue, Bromley",BR2 8DL -U1019567,"8 Broom Close, Bromley",BR2 8EU -U1023539,"2 Marsham Close, Chislehurst",BR7 6JD -U1037465,"6 Princes Plain, Bromley",BR2 8LE -U1042733,"68 Whitebeam Avenue, Bromley",BR2 8DL -U1004442,"7 Birch Row, Bromley",BR2 8BX -U1005006,"44 Birch Row, Bromley",BR2 8DA -U1035331,"104 Whitebeam Avenue, Bromley",BR2 8DW -U1024017,"13 Manor Way, Bromley",BR2 8ES -U1014078,"43 Aylesbury Road, Bromley",BR2 0QR -U1052186,"4 Ravensleigh Gardens, Bromley",BR1 5SN -U1037450,"70 Pontefract Road, Bromley",BR1 4RB -U1031294,"70 London Lane, Bromley",BR1 4HE -U1014077,"32 Aylesbury Road, Bromley",BR2 0QP -U1030962,"7 Ravensleigh Gardens, Bromley",BR1 5SN -U1042232,"154 Southover, Bromley",BR1 4RZ -U1024484,"55 Mounthurst Road, Bromley",BR2 7PG -U1007701,"46 Harwood Avenue, Bromley",BR1 3DU -U1020199,"78 Hillside Road, Bromley",BR2 0ST -U1036758,"46 Newbury Road, Bromley",BR2 0QW -U1009369,"17 Minster Road, Bromley",BR1 4DY -U1009194,"84 Mays Hill Road, Bromley",BR2 0HT -U1013358,"3 Bird In Hand Lane, Bromley",BR1 2NA -U1009202,"63 Mead Way, Bromley",BR2 9ER -U1022991,"5 Link Way, Bromley",BR2 8JH -U1025820,"46 Princes Plain, Bromley",BR2 8LE -U1020237,"33 Hornbeam Way, Bromley",BR2 8DB -U1021310,"126 Faringdon Avenue, Bromley",BR2 8BU -U1021353,"66 George Lane, Bromley",BR2 7LQ -U1033165,"2 Laburnum Way, Bromley",BR2 8BZ -U1010811,"13 Gilbert Road, Bromley",BR1 3QP -U1027449,"11 Station Road, Bromley",BR1 3LP -U1035326,"2 Whitebeam Avenue, Bromley",BR2 8DL -U1020351,"27 Laburnum Way, Bromley",BR2 8BY +UPRN,Address,Postcode +U1041316,"U1041316_58 Ravensworth Road, Mottingham",SE9 4LW +U2022716,"U2022716_306 Saint Helier Avenue, Morden",SM4 6JX +U2018001,"U2018001_37 Leominster Road, Morden",SM4 6HN +U2019131,"U2019131_34 Middleton Road, Morden",SM4 6RT +U1035331,"104 Whitebeam Avenue, Bromley",BR2 8DW +U1010255,"7 Boughton Avenue, Bromley",BR2 7PL +U1024581,"30 Parkfield Way, Bromley",BR2 8AF +U1032130,"86 Faringdon Avenue, Bromley",BR2 8BU +U1014077,"32 Aylesbury Road, Bromley",BR2 0QP +U1007728,"2 Hazel Walk, Bromley",BR2 8DF +U1020327,"5 Kingsdown Way, Bromley",BR2 7PT +U1032134,"125 Faringdon Avenue, Bromley",BR2 8BT +U1053411,"U1053411_78 Windsor Drive, Orpington",BR6 6HF +U2022615,"U2022615_56 Saint Helier Avenue, Morden",SM4 6LF +U1022991,"5 Link Way, Bromley",BR2 8JH +U1010811,"13 Gilbert Road, Bromley",BR1 3QP +U1020328,"31 Kingsdown Way, Bromley",BR2 7PT +U1005131,"10 Boughton Avenue, Bromley",BR2 7PL +U1021353,"66 George Lane, Bromley",BR2 7LQ +U1034017,"48 Princes Plain, Bromley",BR2 8LE +U1036758,"46 Newbury Road, Bromley",BR2 0QW +U1020351,"27 Laburnum Way, Bromley",BR2 8BY +U1035052,"1 Sudbury Crescent, Bromley",BR1 4PY +U1027073,"U1027073_29 Haddon Road, St Mary Cray",BR5 4BU +U1034887,"U1034887_2 Saltwood Close, Orpington",BR6 9BU +U1035329,"U1035329_79 Whitebeam Avenue, Bromley",BR2 8DN +U1042571,"U1042571_19 Whitebeam Avenue, Bromley",BR2 8DJ +U1035330,"U1035330_87 Whitebeam Avenue, Bromley",BR2 8DN +U1047521,"U1047521_19 Walnuts Road, Orpington",BR6 0RG +U1033037,"U1033037_73 Homefield Rise, Orpington",BR6 0RL +U1027845,"U1027845_92 Homefield Rise, Orpington",BR6 0RW +U1031691,"U1031691_46 Boyland Road, Bromley",BR1 4QF +U1026916,"U1026916_19 Elizabeth Way, St Mary Cray",BR5 4BJ +U1015363,"U1015363_44a Birch Row, Bromley",BR2 8DA +U1010400,"U1010400_42 Brook Lane, Bromley",BR1 4PU +U1052426,"U1052426_49 Southover, Bromley",BR1 4SL +U1019591,"U1019591_18 Buckland Road, Orpington",BR6 9SR +U1011434,"U1011434_24 Upper Elmers End Road, Beckenham",BR3 4AL +U1023417,"U1023417_44 Malling Way, Hayes, Bromley",BR2 7PJ +U1014671,"U1014671_61 George Lane, Hayes, Bromley",BR2 7LG +U1037550,"U1037550_228 Repton Road, Orpington",BR6 9JB +U1014433,"U1014433_57 Cowden Road, Orpington",BR6 0TP +U1015779,"U1015779_21 Beck Lane, Beckenham",BR3 4RD +U1042236,"U1042236_250 Southover, Bromley",BR1 4SE +U1033036,"U1033036_61 Homefield Rise, Orpington",BR6 0RL +U1027951,"U1027951_2 Kingsdown Way, Hayes, Bromley",BR2 7PT +U1032770,"U1032770_18 Pembury Close, Hayes, Bromley",BR2 7PS +U1011129,"U1011129_40 Saltwood Close, Orpington",BR6 9BU +U1023267,"U1023267_47a Mackenzie Road, Beckenham",BR3 4RT +U1016998,"U1016998_68 Arundel Drive, Orpington",BR6 9JG +U1026576,"U1026576_1 Burwash Court, St Mary Cray",BR5 4BG +U1037867,"U1037867_45 Stowe Road, Orpington",BR6 9HG +U1027839,"U1027839_30 Holmcroft Way, Bromley",BR2 8AD +U1005351,"U1005351_2 Leaveland Close, Beckenham",BR3 3PL +U1041968,"U1041968_59 Uplands Road, Orpington",BR6 0RH +U1032149,"U1032149_12 Fordwich Close, Orpington",BR6 0TT +U1047347,"U1047347_30 Sudbury Crescent, Bromley",BR1 4PZ +U1004249,"U1004249_6 Beck Lane, Beckenham",BR3 4RE +U1005772,"U1005772_10 Manor Park Road, West Wickham",BR4 0JZ +U1010810,"U1010810_79 George Lane, Hayes, Bromley",BR2 7LG +U1011008,"U1011008_170 Repton Road, Orpington",BR6 9JA +U1026969,"U1026969_2 Fordwich Close, Orpington",BR6 0TT +U1032000,"U1032000_16 Detling Road, Bromley",BR1 4SH +U1013268,"U1013268_9 Bell Gardens, St Mary Cray",BR5 4DA +U1020217,"U1020217_71 Homefield Rise, Orpington",BR6 0RL +U1033287,"U1033287_12 Lincoln Green Road, St Mary Cray",BR5 2DX +U1041997,"U1041997_31 Walnuts Road, Orpington",BR6 0RG +U1047520,"U1047520_2 Walnuts Road, Orpington",BR6 0RQ +U1019606,"U1019606_20 Burrfield Drive, St Mary Cray",BR5 4BZ +U1007354,"U1007354_30 Cowden Road, Orpington",BR6 0TR +U1015603,"U1015603_1 Barwood Avenue, West Wickham",BR4 0LB +U1035393,"U1035393_18 Yalding Grove, St Mary Cray",BR5 3SE +U1000177,"U1000177_79 Arundel Drive, Orpington",BR6 9JQ +U1011428,"U1011428_21 Uplands Road, Orpington",BR6 0RH +U1024671,"U1024671_115 Oregon Square, Orpington",BR6 8BE +U1021513,"U1021513_18 Chamberlain Crescent, West Wickham",BR4 0LL +U1024663,"U1024663_32b Okemore Gardens, Orpington",BR5 3PJ +U1020879,"U1020879_8 Brockwell Close, St Mary Cray",BR5 1RJ +U1022713,"U1022713_53 Homefield Rise, Orpington",BR6 0RL +U1031157,"U1031157_94 Leesons Hill, St Pauls Cray",BR5 2NH +U1013666,"U1013666_11 Ampleforth Close, Orpington",BR6 9ES +U1052617,"U1052617_44 Uplands Road, Orpington",BR6 0RJ +U1010783,"U1010783_32 Foxbury Drive, Chelsfield, Orpington",BR6 6EL +U1021700,"U1021700_25 Daleside, Orpington",BR6 6EG +U1011163,"U1011163_35 Selwyn Place, St Pauls Cray",BR5 3BA +U1022175,"U1022175_54 Homefield Rise, Orpington",BR6 0RW +U1021461,"U1021461_27 Burrfield Drive, St Mary Cray",BR5 4BZ +U1007184,"U1007184_7 Buckland Road, Orpington",BR6 9SR +U1023112,"U1023112_97 Lower Gravel Road, Bromley",BR2 8LP +U1024516,"U1024516_18 Northolme Rise, Off Tubbenden Lane, Orpington",BR6 9RF +U1023910,"U1023910_40 Moorfield Road, Orpington",BR6 0HQ +U1031342,"U1031342_55 Lower Gravel Road, Bromley",BR2 8LP +U1037905,"U1037905_37 Sweeps Lane, St Mary Cray",BR5 3PE +U2019260,"U2019260_88 Montacute Road, Morden",SM4 6RL +U2019214,"U2019214_11 Missenden Gardens, Morden",SM4 6HW +U2022891,"U2022891_20 Swains Road, Tooting, London",SW17 9HS +U2022684,"U2022684_231 St Helier Avenue, Morden",SM4 6JH +U2023196,"U2023196_210 Tudor Drive, Morden",SM4 4PQ +U2019671,"U2019671_16 Netley Gardens, Morden",SM4 6JW +U2018944,"U2018944_79 Malmesbury Road, Morden",SM4 6HG +U2015873,"U2015873_1 Furness Road, Morden",SM4 6PS +U1041503,"U1041503_103 Ravensworth Road, Mottingham",SE9 4LX +U2023185,"U2023185_157 Tudor Drive, Morden",SM4 4PJ +U1053395,"U1053395_90 Widecombe Road, Mottingham",SE9 4HJ +U2018009,"U2018009_23 Leominster Walk, Morden",SM4 6HB +U2018941,"U2018941_74 Malmesbury Road, Morden",SM4 6HE +U2013950,"U2013950_2 Buckland Walk, Morden",SM4 5RZ +U2018160,"U2018160_6 Llanthony Road, Morden",SM4 6DX +U2015790,"U2015790_12 Flaxley Road, Morden",SM4 6LJ +U2013914,"U2013914_36 Bruton Road, Morden",SM4 5RY +U2022611,"U2022611_50 St Helier Avenue, Morden",SM4 6LF +U2015270,"U2015270_39 Dorchester Road, Morden",SM4 6QE +U1009098,"U1009098_37b Maple Road, Penge",SE20 8LA +U2018926,"U2018926_19 Malmesbury Road, Morden",SM4 6HD +U2023192,"U2023192_195 Tudor Drive, Morden",SM4 4PJ +U1027362,"U1027362_187 Seymour Villas, Penge",SE20 8TP +U2018973,"U2018973_26 Marham Gardens, Morden",SM4 6JJ +U2013913,"U2013913_30 Bruton Road, Morden",SM4 5RY +U1042214,"U1042214_25 Snowdown Close, London",SE20 7RU +U2013911,"U2013911_23 Bruton Road, Morden",SM4 5RY +U2013583,"U2013583_300 Bishopsford Road, Morden",SM4 6BY +U2018925,"U2018925_14 Malmesbury Road, Morden",SM4 6HD +U1037938,"U1037938_5 Torr Road, Penge",SE20 7PS +U1038117,"U1038117_40 Widecombe Road, Mottingham",SE9 4HQ +U1052365,"U1052365_127 Seymour Villas, Penge",SE20 8TP +U1024726,"U1024726_2 Penge Lane, Penge",SE20 7DU +U1026505,"U1026505_7 Bridlington Close, Biggin Hill",TN16 3PD +U2018913,"U2018913_23 Malling Gardens, Morden",SM4 6JG +U2015708,"U2015708_46 Faversham Road, Morden",SM4 6RE +U2019530,"U2019530_30 Neath Gardens, Morden",SM4 6JN +U2015710,"U2015710_49 Faversham Road, Morden",SM4 6RE +U2014478,"U2014478_222 Central Road, Morden",SM4 5PP +U2018922,"U2018922_11 Malmesbury Road, Morden",SM4 6HD +U2013615,"U2013615_47 Blanchland Road, Morden",SM4 5ND +U2022641,"U2022641_127 St Helier Avenue, Morden",SM4 6JD +U2019268,"U2019268_97 Montacute Road, Morden",SM4 6RJ +U2013947,"U2013947_95 Buckfast Road, Morden",SM4 5NA +U2018025,"U2018025_21 Lessness Road, Morden",SM4 6HP +U2013415,"U2013415_51 Bodnant Gardens, Raynes Park, London",SW20 0UD +U2022728,"U2022728_340 St Helier Avenue, Morden",SM4 6JU +U1009623,"U1009623_23 Pawleyne Close, Penge",SE20 8JH +U2015884,"U2015884_30 Furness Road, Morden",SM4 6PR +U2019728,"U2019728_17 Newhouse Walk, Morden",SM4 6BS +U1024719,"U1024719_14 Pawleyne Close, Penge",SE20 8JH +U2013935,"U2013935_43 Buckfast Road, Morden",SM4 5NA +U2013623,"U2013623_4 Bodmin Grove, Morden",SM4 5LU +U2018811,"U2018811_354 Lynmouth Avenue, Morden",SM4 4RT +U2019672,"U2019672_19 Netley Gardens, Morden",SM4 6JW +U2018927,"U2018927_29 Malmesbury Road, Morden",SM4 6HD +U2019237,"U2019237_37 Montacute Road, Morden",SM4 6RJ +U2019730,"U2019730_23 Newhouse Walk, Morden",SM4 6BS +U1038118,"U1038118_46 Widecombe Road, Mottingham",SE9 4HQ +U1000359,"U1000359_5 Avenue Road, Penge",SE20 7RT +U2018164,"U2018164_24 Llanthony Road, Morden",SM4 6DX +U2013982,"U2013982_18 Bury Grove, Morden",SM4 5NG +U1030964,"U1030964_13 Ravensworth Road, Mottingham",SE9 4LN +U2015882,"U2015882_25 Furness Road, Morden",SM4 6PS +U1031105,"U1031105_21 Kingsmead, Biggin Hill, Westerham",TN16 3UB +U1014008,"U1014008_9 Avenue Road, Penge",SE20 7RT +U2015779,"U2015779_57 Flanders Crescent, Tooting, London",SW17 9JB +U2013413,"U2013413_49 Bodnant Gardens, Raynes Park, London",SW20 0UD +U1021199,"U1021199_7 Dittisham Road, Mottingham",SE9 4BJ +U1041705,"U1041705_87 Seymour Villas, Penge",SE20 8TR +U1041706,"U1041706_91 Seymour Villas, Penge",SE20 8TR +U1042213,"U1042213_9 Snowdown Close, London",SE20 7RU +U2014444,"U2014444_86 Central Road, Morden",SM4 5RJ +U2013940,"U2013940_63 Buckfast Road, Morden",SM4 5NA +U1037789,"U1037789_5 Snowdown Close, London",SE20 7RU +U2013630,"U2013630_16 Bodmin Grove, Morden",SM4 5LU +U2014445,"U2014445_88 Central Road, Morden",SM4 5RJ +U2013602,"U2013602_5 Blanchland Road, Morden",SM4 5ND +U1017178,"U1017178_11 Avenue Road, Penge",SE20 7RT +U1013690,"U1013690_74 Anerley Vale, London",SE19 2BG +U2013676,"U2013676_52 Bordesley Road, Morden",SM4 5LR +U1042212,"U1042212_1 Snowdown Close, London",SE20 7RU +U2018810,"U2018810_331 Lynmouth Avenue, Morden",SM4 4RY +U2013476,"U2013476_1 Bristol Road, Morden",SM4 5SA +U1026660,"U1026660_40 Chilham Road, Mottingham",SE9 4BG +U1036877,"U1036877_2 Pawleyne Close, Penge",SE20 8JH +U2018814,"U2018814_364 Lynmouth Avenue, Morden",SM4 4RT +U2013573,"U2013573_264 Bishopsford Road, Morden",SM4 6BZ +U1007236,"U1007236_6 Castledine Road, Penge",SE20 8PL +U1027701,"U1027701_4 Wayside Grove, Mottingham",SE9 4ND +U1047208,"U1047208_83 Seymour Villas, Penge",SE20 8TR +U2013695,"U2013695_111 Bordesley Road, Morden",SM4 5LW +U1004961,"U1004961_36 Beverley Road, Penge",SE20 8SJ +U2015795,"U2015795_24 Flaxley Road, Morden",SM4 6LJ +U2014451,"U2014451_102 Central Road, Morden",SM4 5RJ +U2016606,"U2016606_3 Grayswood Gardens, Raynes Park, London",SW20 0UF +U1035025,"U1035025_29 Steyning Grove, Mottingham",SE9 4NG +U1027588,"U1027588_94 Tovil Close, Penge",SE20 8SZ +U2022632,"U2022632_112 St Helier Avenue, Morden",SM4 6LB +U1037462,"U1037462_68 Prestbury Square, Mottingham",SE9 4NA +U2018027,"U2018027_29 Lessness Road, Morden",SM4 6HP +U2018909,"U2018909_12 Malling Gardens, Morden",SM4 6JG +U1001247,"U1001247_13 Pawleyne Close, Penge",SE20 8JH +U1018547,"U1018547_9b Avenue Road, Penge",SE20 7RT +U1008780,"U1008780_7b Avenue Road, Penge",SE20 7RT +U1007212,"U1007212_2 Calcott Walk, Mottingham",SE9 4BN +U1003650,"U1003650_5b Avenue Road, Penge",SE20 7RT +U1010359,"U1010359_2 Bredhurst Close, Penge",SE20 7BG +U1041772,"13 Stanley Road, Bromley",BR2 9JE +U1011072,"45 Rookery Gardens, Oprington",BR5 4BA +U1020208,"16 Holbrook Way, Bromley",BR2 8EE +U1052580,"25 Trentham Drive, Oprington",BR5 2EP +U1038106,"84 Whitebeam Avenue, Bromley",BR2 8DW +U1010107,"42 Birch Row, Bromley",BR2 8DA +U1022307,"20 Larch Way, Bromley",BR2 8DU +U1020064,"28 Green Way, Bromley",BR2 8EY +U1023463,"30 MANOR WAY, Bromley",BR2 8ES +U1027745,"148 Whitebeam Avenue, Bromley",BR2 8DW +U1008151,"61 Lovelace Avenue, Bromley",BR2 8EA +U1019785,"50 Cray Valley Road, Oprington",BR5 2EZ +U1029229,"2 Meath Close, Oprington",BR5 2HF +U1005696,"158 Magpie Hall Lane, Bromley",BR2 8JG +U1036332,"50 Marion Crescent, Oprington",BR5 2HD +U1027830,"26 Holbrook Way, Bromley",BR2 8EE +U1052455,"10 Stiles Close, Bromley",BR2 8EQ +U1023539,"2 Marsham Close, Chislehurst",BR7 6JD +U1030962,"7 Ravensleigh Gardens, Bromley",BR1 5SN +U1037954,"28 Treewall Gardens, Bromley",BR1 5BT +U1020368,"11 Larch Way, Bromley",BR2 8DT +U1027743,"17 Whitebeam Avenue, Bromley",BR2 8DJ +U1021825,"117a Faringdon Avenue, Bromley",BR2 8BT +U1028328,"76 Magpie Hall Lane, Bromley",BR2 8ER +U1025820,"46 Princes Plain, Bromley",BR2 8LE +U1024580,"24 Parkfield Way, Bromley",BR2 8AF +U1010452,"5 Canbury Path, Oprington",BR5 2EU +U1022018,"12 Hazel Walk, Bromley",BR2 8DF +U1037814,"42 Stanley Road, Bromley",BR2 9JH +U1016744,"18 Princes Plain, Bromley",BR2 8LE +U1021310,"126 Faringdon Avenue, Bromley",BR2 8BU +U1035115,"30 Thorn Close, Bromley",BR2 8DH +U1033165,"2 Laburnum Way, Bromley",BR2 8BZ +U1000649,"42 Barnsdale Crescent, Oprington",BR5 2AX +U1052536,"12 Thorn Close, Bromley",BR2 8DH +U1042298,"39 Sudbury Crescent, Bromley",BR1 4PY +U1053388,"52 Whitebeam Avenue, Bromley",BR2 8DL +U1007556,"11 Farleigh Avenue, Bromley",BR2 7PP +U1007947,"8 Laburnum Way, Bromley",BR2 8BZ +U1019567,"8 Broom Close, Bromley",BR2 8EU +U1013358,"3 Bird In Hand Lane, Bromley",BR1 2NA +U1022533,"81 Lower Gravel Road, Bromley",BR2 8LP +U1021824,"115g Faringdon Avenue, Bromley",BR2 8BT +U1009369,"17 Minster Road, Bromley",BR1 4DY +U1022931,"15 Lennard Road, Bromley",BR2 8LN +U1024065,"64 Marion Crescent, Oprington",BR5 2HD +U1005168,"38 Holbrook Way, Bromley",BR2 8EE +U1038104,"32 Whitebeam Avenue, Bromley",BR2 8DL +U1021827,"121 Faringdon Avenue, Bromley",BR2 8BT +U1030892,"140 Poverest Road, Oprington",BR5 1RH +U1013831,"33 Ash Row, Bromley",BR2 8DZ +U1004442,"7 Birch Row, Bromley",BR2 8BX +U1019564,"32 Brook Lane, Bromley",BR1 4PU +U1032131,"93 Faringdon Avenue, Bromley",BR2 8BT +U1026960,"105 Faringdon Avenue, Bromley",BR2 8BT +U1005006,"44 Birch Row, Bromley",BR2 8DA +U1005742,"18 Malling Way, Bromley",BR2 7PJ +U1022281,"35 Kingsdown Way, Bromley",BR2 7PT +U1042574,"66 Whitebeam Avenue, Bromley",BR2 8DL +U1011191,"32 Shoreham Way, Bromley",BR2 7PU +U1032129,"78 Faringdon Avenue, Bromley",BR2 8BU +U1009032,"10 Malling Way, Bromley",BR2 7PJ +U1031121,"32 Laburnum Way, Bromley",BR2 8BZ +U1022305,"18a Lansdowne Road, Bromley",BR1 3LZ +U1042248,"16 Stanley Way, Oprington",BR5 2HE +U1038102,"14 Whitebeam Avenue, Bromley",BR2 8DL +U1007432,"21 Detling Road, Bromley",BR1 4SH +U1041934,"51 Turpington Lane, Bromley",BR2 8JA +U1032647,"32 Narrow Way, Bromley",BR2 8JB +U1052429,"76 Southover, Bromley",BR1 4RY +U1007701,"46 Harwood Avenue, Bromley",BR1 3DU +U1042572,"37 Whitebeam Avenue, Bromley",BR2 8DJ +U1042576,"112 Whitebeam Avenue, Bromley",BR2 8DW +U1020349,"21 Laburnum Way, Bromley",BR2 8BY +U1021535,"4 Chilham Way, Bromley",BR2 7PR +U1004686,"55 Baston Road, Bromley",BR2 7BD +U1027744,"33 Whitebeam Avenue, Bromley",BR2 8DJ +U1016880,"25 Almond Way, Bromley",BR2 8DR +U1023415,"27 Malling Way, Bromley",BR2 7PJ +U1011190,"11 Shoreham Way, Bromley",BR2 7PU +U1042256,"2 Stiles Close, Bromley",BR2 8EQ +U1053386,"27 Whitebeam Avenue, Bromley",BR2 8DJ +U1020237,"33 Hornbeam Way, Bromley",BR2 8DB +U1005167,"30 Holbrook Way, Bromley",BR2 8EE +U1014630,"118 Faringdon Avenue, Bromley",BR2 8BU +U1034810,"24 Newbury Road, Bromley",BR2 0QW +U1037768,"13 Silverdale Road, Oprington",BR5 2LU +U1024709,"3 Parkfield Way, Bromley",BR2 8AE +U1010582,"13 Cranworth Cottages, Keston",BR2 6DB +U1010578,"6 Cranbrook Close, Bromley",BR2 7QA +U1031058,"303 Keedonwood Road, Bromley",BR1 4QR +U1026447,"50 Princes Plain, Bromley",BR2 8LE +U1016746,"68 Princes Plain, Bromley",BR2 8LE +U1038107,"152 Whitebeam Avenue, Bromley",BR2 8DW +U1036446,"14 Meath Close, Oprington",BR5 2HF +U1014589,"71 Empress Drive, Chislehurst",BR7 5BQ +U1002456,"54 Birch Row, Bromley",BR2 8DA +U1020369,"13 Larch Way, Bromley",BR2 8DT +U1034985,"272 Southborough Lane, Bromley",BR2 8AS +U1041435,"64 Prince's Plain, Bromley",BR2 8LE +U1031294,"70 London Lane, Bromley",BR1 4HE +U1033406,"67 Lower Gravel Road, Bromley",BR2 8LP +U1032061,"30 Eastry Avenue, Bromley",BR2 7PF +U1042573,"47 Whitebeam Avenue, Bromley",BR2 8DJ +U1032133,"119 Faringdon Avenue, Bromley",BR2 8BT +U1013830,"31 Ash Row, Bromley",BR2 8DZ +U1009511,"27 Newbury Road, Bromley",BR2 0QN +U1042735,"108 Whitebeam Avenue, Bromley",BR2 8DW +U1024511,"81 Nightingale Lane, Bromley",BR1 2SA +U1024050,"10 Marden Avenue, Bromley",BR2 7PX +U1035326,"2 Whitebeam Avenue, Bromley",BR2 8DL +U1009202,"63 Mead Way, Bromley",BR2 9ER +U1020199,"78 Hillside Road, Bromley",BR2 0ST +U1042232,"154 Southover, Bromley",BR1 4RZ +U1030897,"60 Princes Plain, Bromley",BR2 8LE +U1027989,"5 Larch Way, Bromley",BR2 8DT +U1021308,"70 Faringdon Avenue, Bromley",BR2 8BU +U1019906,"26 Eastry Avenue, Bromley",BR2 7PF +U1022726,"31 Hornbeam Way, Bromley",BR2 8DB +U1024698,"4 Palace View, Bromley",BR1 3EL +U1005549,"79 Lower Gravel Road, Bromley",BR2 8LP +U1052376,"3 Shoreham Way, Bromley",BR2 7PU +U1041937,"75 Turpington Lane, Bromley",BR2 8JD +U1005123,"24 Bonville Road, Bromley",BR1 4QA +U1008158,"71 Lower Gravel Road, Bromley",BR2 8LP +U1042575,"90 Whitebeam Avenue, Bromley",BR2 8DW +U1014793,"59 Headcorn Road, Bromley",BR1 4SQ +U1012309,"13 Almond Close, Bromley",BR2 8DS +U1009194,"84 Mays Hill Road, Bromley",BR2 0HT +U1027838,"15 Holmcroft Way, Bromley",BR2 8AD +U1027449,"11 Station Road, Bromley",BR1 3LP +U1014627,"81 Faringdon Avenue, Bromley",BR2 8BT +U1027493,"35 Sudbury Crescent, Bromley",BR1 4PY +U1032132,"115f Faringdon Avenue, Bromley",BR2 8BT +U1037833,"3 Stiles Close, Bromley",BR2 8EQ +U1016743,"16 Princes Plain, Bromley",BR2 8LE +U1007553,"115d Faringdon Avenue, Bromley",BR2 8BT +U1009607,"20 Parkfield Way, Bromley",BR2 8AF +U1034805,"38 Narrow Way, Bromley",BR2 8JB +U1032062,"46 Eastry Avenue, Bromley",BR2 7PF +U1047613,"13 Whitebeam Avenue, Bromley",BR2 8DJ +U1024484,"55 Mounthurst Road, Bromley",BR2 7PG +U1038103,"29 Whitebeam Avenue, Bromley",BR2 8DJ +U1022525,"30 Lovelace Avenue, Bromley",BR2 8DQ +U1042153,"4 Scotts Road, Bromley",BR1 3QD +U1037465,"6 Princes Plain, Bromley",BR2 8LE +U1041933,"31 Turpington Lane, Bromley",BR2 8JA +U1021769,"49 Eastry Avenue, Bromley",BR2 7PE +U1042734,"86 Whitebeam Avenue, Bromley",BR2 8DW +U1026958,"77 Faringdon Avenue, Bromley",BR2 8BT +U1037872,"20 Sudbury Crescent, Bromley",BR1 4PZ +U1027549,"14 Thorn Close, Bromley",BR2 8DH +U1037450,"70 Pontefract Road, Bromley",BR1 4RB +U1016742,"4 Princes Plain, Bromley",BR2 8LE +U1042733,"68 Whitebeam Avenue, Bromley",BR2 8DL +U1003906,"54 Barnsdale Crescent, Oprington",BR5 2AX +U1027392,"26 Silverdale Road, Oprington",BR5 2LT +U1052186,"4 Ravensleigh Gardens, Bromley",BR1 5SN +U1034479,"90 Mead Way, Bromley",BR2 9EU +U1005741,"2 Malling Way, Bromley",BR2 7PJ +U1024017,"13 Manor Way, Bromley",BR2 8ES +U1014078,"43 Aylesbury Road, Bromley",BR2 0QR +U1015499,"25 Boughton Avenue, Bromley",BR2 7PL +U1033177,"30 Larch Way, Bromley",BR2 8DU From 6656d8dec203e548778b628ac8853cc5cd9ab77f Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 12:05:04 +0000 Subject: [PATCH 72/84] =?UTF-8?q?A=20full-SAP=20export-capable=20PV=20cert?= =?UTF-8?q?=20reproduces=20its=20lodged=20SAP=2010.2=20score=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../uprn_10094615101/epc.json | 507 ++++++++++++++++++ .../test_real_cert_sap_accuracy.py | 23 + 2 files changed, 530 insertions(+) create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-19.1.0/uprn_10094615101/epc.json diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-19.1.0/uprn_10094615101/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-19.1.0/uprn_10094615101/epc.json new file mode 100644 index 000000000..187b4a17a --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-19.1.0/uprn_10094615101/epc.json @@ -0,0 +1,507 @@ +{ + "der": 3.23, + "ter": 13.27, + "dfee": 35.2, + "dper": 41.21, + "tfee": 36.7, + "tper": 70.27, + "uprn": 10094615101, + "roofs": [ + { + "description": { + "value": "Average thermal transmittance 0.09 W/m\u00b2K", + "language": "1" + }, + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "walls": [ + { + "description": { + "value": "Average thermal transmittance 0.19 W/m\u00b2K", + "language": "1" + }, + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "floors": [ + { + "description": { + "value": "(other premises below)", + "language": "1" + }, + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": "ND", + "windows": { + "description": { + "value": "High performance glazing", + "language": "1" + }, + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "lighting": { + "description": { + "value": "Good lighting efficiency", + "language": "1" + }, + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "TN37 7GF", + "data_type": 2, + "hot_water": { + "description": { + "value": "From main system, waste water heat recovery", + "language": "1" + }, + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "post_town": "ST LEONARDS-ON-SEA", + "built_form": 1, + "created_at": "2025-03-04 11:13:23", + "living_area": 28.88, + "orientation": 2, + "region_code": 14, + "report_type": 3, + "sap_heating": { + "number_baths": 1, + "thermal_store": 1, + "shower_outlets": [ + { + "shower_wwhrs": 2, + "shower_flow_rate": 8, + "shower_outlet_type": 3 + } + ], + "water_fuel_type": 39, + "water_heating_code": 914, + "instantaneous_wwhrs": { + "wwhrs_index_number1": 80140 + }, + "main_heating_details": [ + { + "has_fghrs": "false", + "main_fuel_type": 39, + "storage_heaters": [ + { + "index_number": 230003, + "number_of_heaters": 4, + "high_heat_retention": "true" + } + ], + "main_heating_code": 409, + "main_heating_number": 1, + "is_condensing_boiler": "false", + "main_heating_control": 2404, + "main_heating_category": 7, + "main_heating_fraction": 1, + "main_heating_data_source": 3, + "is_oil_pump_in_heated_space": "false", + "is_main_heating_hetas_approved": "false" + }, + { + "has_fghrs": "false", + "main_fuel_type": 39, + "main_heating_number": 2, + "main_heating_control": 2100, + "main_heating_category": 4, + "main_heating_fraction": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 104014, + "is_oil_pump_in_heated_space": "false", + "is_main_heating_hetas_approved": "false" + } + ], + "has_hot_water_cylinder": "false", + "has_cylinder_thermostat": "true", + "has_fixed_air_conditioning": "false", + "secondary_heating_category": 1, + "is_immersion_for_summer_use": "false", + "is_heat_pump_installed_to_mis": "false", + "is_hot_water_separately_timed": "true", + "main_heating_systems_interaction": 2, + "is_heat_pump_assisted_by_immersion": "false" + }, + "sap_version": 10.2, + "schema_type": "SAP-Schema-19.1.0", + "uprn_source": "Address Matched", + "country_code": "ENG", + "main_heating": [ + { + "description": { + "value": "Electric storage heaters", + "language": "1" + }, + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 5 + } + ], + "sap_lighting": [ + [ + { + "lighting_power": 10, + "lighting_outlets": 18, + "lighting_efficacy": 90 + } + ] + ], + "terrain_type": 2, + "air_tightness": { + "description": { + "value": "Air permeability [AP50] = 4.7 m\u00b3/h.m\u00b2 (as tested)", + "language": "1" + }, + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "dwelling_type": "Top-floor flat", + "language_code": 1, + "property_type": 2, + "pv_connection": 2, + "address_line_1": "7 Tyler House", + "address_line_2": "51 Potter Street", + "assessment_date": "2025-03-04", + "assessment_type": "SAP", + "completion_date": "2025-03-04", + "inspection_date": "2025-03-04", + "sap_ventilation": { + "psv_count": 0, + "wall_type": 1, + "pressure_test": 1, + "wet_rooms_count": 1, + "air_permeability": 4.65, + "open_flues_count": 0, + "ventilation_type": 8, + "has_draught_lobby": "false", + "other_flues_count": 0, + "closed_flues_count": 0, + "extract_fans_count": 0, + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "sheltered_sides_count": 1, + "blocked_chimneys_count": 0, + "flueless_gas_fires_count": 0, + "mechanical_vent_duct_type": 2, + "mechanical_vent_duct_placement": 1, + "mechanical_ventilation_data_source": 1, + "mechanical_vent_system_index_number": 500298, + "mechanical_vent_duct_insulation_level": 2, + "is_mechanical_vent_approved_installer_scheme": "false" + }, + "design_water_use": 1, + "sap_data_version": 10.2, + "sap_flat_details": { + "level": 3, + "storeys": 4 + }, + "total_floor_area": 76, + "transaction_type": 6, + "cold_water_source": 1, + "conservatory_type": 1, + "registration_date": "2025-03-04", + "sap_energy_source": { + "pv_arrays": [ + { + "pitch": 1, + "peak_power": 1.26, + "orientation": 8, + "overshading": 1 + } + ], + "electricity_tariff": 2 + }, + "sap_opening_types": [ + { + "name": "Window", + "type": 4, + "u_value": 1.2, + "data_source": 2, + "frame_factor": 0.7, + "glazing_type": 7, + "isargonfilled": "false", + "solar_transmittance": 0.52 + }, + { + "name": "Apt door", + "type": 1, + "u_value": 0.71, + "data_source": 2, + "glazing_type": 1, + "isargonfilled": "false" + } + ], + "secondary_heating": { + "description": { + "value": "None", + "language": "1" + }, + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "lowest_storey_area": 75.94, + "lzc_energy_sources": [ + 11 + ], + "sap_building_parts": [ + { + "sap_roofs": [ + { + "name": "Roof (1)", + "u_value": 0.09, + "roof_type": 2, + "total_roof_area": 75.94 + }, + { + "name": "Party roof 1", + "u_value": 0, + "roof_type": 4, + "total_roof_area": 20 + } + ], + "sap_walls": [ + { + "name": "Walls (1)", + "u_value": 0.21, + "wall_type": 2, + "total_wall_area": 61.26, + "is_curtain_walling": "false" + }, + { + "name": "Walls (2)", + "u_value": 0.14, + "wall_type": 2, + "total_wall_area": 24.82, + "is_curtain_walling": "false" + } + ], + "sap_openings": [ + { + "name": "Opening 1", + "type": "Window", + "width": 8.28, + "height": 1, + "location": "Walls (1)", + "orientation": 2 + }, + { + "name": "Opening 2", + "type": "Window", + "width": 3.2, + "height": 1, + "location": "Walls (1)", + "orientation": 4 + }, + { + "name": "Opening 4", + "type": "Apt door", + "width": 2.12, + "height": 1, + "location": "Walls (2)", + "orientation": 5 + }, + { + "name": "Opening 3", + "type": "Window", + "width": 2.56, + "height": 1, + "location": "Walls (1)", + "orientation": 8 + } + ], + "construction_year": 2023, + "sap_thermal_bridges": { + "thermal_bridges": [ + { + "length": 10.1, + "psi_value": 0.08, + "psi_value_source": 1, + "thermal_bridge_type": "E2" + }, + { + "length": 5.91, + "psi_value": 0.063, + "psi_value_source": 1, + "thermal_bridge_type": "E3" + }, + { + "length": 24.94, + "psi_value": 0.06, + "psi_value_source": 1, + "thermal_bridge_type": "E4" + }, + { + "length": 0, + "psi_value": 0.107, + "psi_value_source": 1, + "thermal_bridge_type": "E5" + }, + { + "length": 0, + "psi_value": 0.076, + "psi_value_source": 1, + "thermal_bridge_type": "E5" + }, + { + "length": 25.74, + "psi_value": 0.037, + "psi_value_source": 1, + "thermal_bridge_type": "E7" + }, + { + "length": 10.43, + "psi_value": 0.026, + "psi_value_source": 1, + "thermal_bridge_type": "E7" + }, + { + "length": 11.9, + "psi_value": 0.043, + "psi_value_source": 1, + "thermal_bridge_type": "E16" + }, + { + "length": 0, + "psi_value": 0.12, + "psi_value_source": 1, + "thermal_bridge_type": "E25" + }, + { + "length": 0, + "psi_value": 0.045, + "psi_value_source": 1, + "thermal_bridge_type": "P1" + }, + { + "length": 2.38, + "psi_value": -0.044, + "psi_value_source": 1, + "thermal_bridge_type": "E17" + }, + { + "length": 15.34, + "psi_value": 0.064, + "psi_value_source": 1, + "thermal_bridge_type": "E10" + }, + { + "length": 10.4, + "psi_value": 0.053, + "psi_value_source": 1, + "thermal_bridge_type": "E12" + }, + { + "length": 10.43, + "psi_value": 0.038, + "psi_value_source": 1, + "thermal_bridge_type": "E12" + }, + { + "length": 0, + "psi_value": 0.05, + "psi_value_source": 1, + "thermal_bridge_type": "E18" + }, + { + "length": 0, + "psi_value": 0.15, + "psi_value_source": 4, + "thermal_bridge_type": "E11" + }, + { + "length": 0, + "psi_value": 0.012, + "psi_value_source": 1, + "thermal_bridge_type": "E13" + }, + { + "length": 0, + "psi_value": 0.24, + "psi_value_source": 1, + "thermal_bridge_type": "P5" + } + ], + "thermal_bridge_code": 5 + }, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "storey": 1, + "u_value": 0, + "floor_type": 4, + "storey_height": 2.38, + "heat_loss_area": 0, + "total_floor_area": 75.94 + } + ] + } + ], + "user_interface_name": "Design SAP 10", + "windows_overshading": 2, + "heating_cost_current": { + "value": 269, + "currency": "GBP" + }, + "co2_emissions_current": 0.2, + "energy_rating_average": 60, + "energy_rating_current": 92, + "lighting_cost_current": { + "value": 51, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": { + "value": "Controls for high heat retention storage heaters", + "language": "1" + }, + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 269, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 94, + "currency": "GBP" + }, + "thermal_mass_parameter": 64, + "user_interface_version": "2.21.9", + "co2_emissions_potential": 0.2, + "energy_rating_potential": 92, + "gas_smart_meter_present": "false", + "lighting_cost_potential": { + "value": 51, + "currency": "GBP" + }, + "schema_version_original": "SAP-Schema-19.1.0", + "hot_water_cost_potential": { + "value": 94, + "currency": "GBP" + }, + "is_in_smoke_control_area": "unknown", + "seller_commission_report": "Y", + "energy_consumption_current": 35, + "has_fixed_air_conditioning": "false", + "is_dwelling_export_capable": "true", + "multiple_glazed_percentage": 100, + "calculation_software_version": "2.21.9", + "energy_consumption_potential": 35, + "environmental_impact_current": 97, + "current_energy_efficiency_band": "A", + "environmental_impact_potential": 97, + "electricity_smart_meter_present": "true", + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "A", + "co2_emissions_current_per_floor_area": 2.6 +} \ No newline at end of file diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index 2bce02247..5604b8015 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -309,6 +309,29 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="0390-3321-6060-2405-7985", sap_score=84, ), + # UPRN 10094615101 → cert 0380-3044-6070-2305-5925. SAP-Schema-19.1.0 — a + # FULL-SAP TOP-FLOOR FLAT (2023 new build, St Leonards-on-Sea, TFA 76 m², + # PRD #1435 WS3 evidence property 741840): PCDB HHRSH (230003 ×4) on an + # off-peak tariff, hot-water heat pump (code 914) + WWHRS, MEV (PCDB + # 500298), measured AP50 4.65, calculated per-junction thermal bridges, and + # a 1.26 kWp EXPORT-CAPABLE PV array (`is_dwelling_export_capable: true`, + # pv_connection 2). Lodged under SAP 10.2 itself (Design SAP 10 2.21.9), so + # the lodged 92 is the same-spec accredited ground truth — no Elmhurst + # rebuild needed. The engine produced 89 until the full-SAP export-capable + # mapping landed: `from_sap_schema_17_1` hardcoded + # `is_dwelling_export_capable=False` (the flag and `pv_connection` are + # top-level full-SAP fields the schema dataclass never parsed), so SAP 10.2 + # Appendix M1 zeroed the PV export credit (~460 kWh × 13.19p ≈ £61/yr). + # Carrying the lodged flag restores the credit and the engine reproduces + # the lodged 92 EXACTLY. Residual CO2/PE deltas (~252 vs ~200 kg CO2/yr; + # PE 41.7 vs 35) are demand-side follow-ups (lodged TMP 64 vs default 250, + # WWHRS, MEV PCDB fan power) — within SAP tolerance, tracked separately. + RealCertExpectation( + schema="SAP-Schema-19.1.0", + sample="uprn_10094615101", + cert_num="0380-3044-6070-2305-5925", + sap_score=92, + ), # UPRN 44012843 → cert 0775-2898-6628-9594-8005. SAP-Schema-16.3 — a # reduced-field (RdSAP-shaped) ground-floor FLAT, band K (2007-2011), cavity # insulated, mains-gas REGULAR boiler (PCDB 9895 Ideal icos HE15) + cylinder, From 787f7731b23fb598ae87a3ecc5e1a32cf211220b Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 12:09:02 +0000 Subject: [PATCH 73/84] =?UTF-8?q?UPRN-prefixed=20property=20folders=20rena?= =?UTF-8?q?me=20to=20a=20single-UPRN=20filename=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- tests/scripts/test_rename_sharepoint_files.py | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/scripts/test_rename_sharepoint_files.py b/tests/scripts/test_rename_sharepoint_files.py index b9d56562b..c732383c7 100644 --- a/tests/scripts/test_rename_sharepoint_files.py +++ b/tests/scripts/test_rename_sharepoint_files.py @@ -124,6 +124,33 @@ def test_run_renames_files_for_property_under_batch_root(tmp_path: Path) -> None sp.rename_file.assert_called_once_with("id-1", "100_1 High St AB1 2CD_Survey.pdf") +def test_run_uprn_prefixed_address_yields_single_uprn_filename( + tmp_path: Path, +) -> None: + # Arrange + csv_path = _write_csv(tmp_path, [("100", "100_1 High St", "AB1 2CD")]) + batch_assessment = _assessment_path( + f"{BASE_PATH}/_Sero Batch 2", "100_1 High St", "AB1 2CD" + ) + + sp = MagicMock() + + def fake_get(path: str) -> dict[str, Any]: + if path == BASE_PATH: + return {"value": [_make_folder("_Sero Batch 2")]} + if path == batch_assessment: + return {"value": [_make_file("Survey.pdf", "id-1")]} + raise ValueError("not found") + + sp.get_folders_in_path.side_effect = fake_get + + # Act + SharepointRenamerOrchestrator(sp, csv_path).run() + + # Assert + sp.rename_file.assert_called_once_with("id-1", "100_1 High St AB1 2CD_Survey.pdf") + + # --------------------------------------------------------------------------- # _process_folder — files only at root level # --------------------------------------------------------------------------- From c5b55197b4820cd2efb8318db5e1ac9a26c45dd9 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 12:09:04 +0000 Subject: [PATCH 74/84] =?UTF-8?q?Full-SAP=20certs=20carry=20their=20lodged?= =?UTF-8?q?=20PV=20export-capability=20flag=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `from_sap_schema_17_1` hardcoded is_dwelling_export_capable=False, so SAP 10.2 Appendix M1 zeroed the PV export credit on every export-capable full-SAP cert. Cert 0380-3044-6070-2305-5925 (property 741840, PRD #1435 WS3) now reproduces its lodged 92 exactly (was 89); the existing 19.1.0 pin 10096028301 closes its documented -1 residual (84 -> 85 = lodged). The full-SAP top-level pv_connection is deliberately NOT carried: its enum disagrees with the RdSAP one the calculator gates on. Co-Authored-By: Claude Opus 4.8 --- datatypes/epc/domain/mapper.py | 10 +++++++++- datatypes/epc/schema/sap_schema_17_1.py | 10 ++++++++++ .../sap10_calculator/test_real_cert_sap_accuracy.py | 7 ++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/datatypes/epc/domain/mapper.py b/datatypes/epc/domain/mapper.py index 26b424e70..80a650515 100644 --- a/datatypes/epc/domain/mapper.py +++ b/datatypes/epc/domain/mapper.py @@ -986,7 +986,15 @@ class EpcPropertyDataMapper: pv_battery_count=0, wind_turbines_count=schema.sap_energy_source.wind_turbines_count or 0, gas_smart_meter_present=False, - is_dwelling_export_capable=False, + # Top-level full-SAP export flag (SAP 10-era lodgements; None + # on the SAP 2012 family → False, unchanged). Appendix M1 zeroes + # the PV export credit without the flag, under-rating any + # export-capable PV cert (PRD #1435 WS3). `pv_connection` is NOT + # carried — the full-SAP enum disagrees with the RdSAP one the + # calculator's connection gate reads (see SapSchema17_1). + is_dwelling_export_capable=( + schema.is_dwelling_export_capable == "true" + ), wind_turbines_terrain_type=str( schema.sap_energy_source.wind_turbine_terrain_type or "" ), diff --git a/datatypes/epc/schema/sap_schema_17_1.py b/datatypes/epc/schema/sap_schema_17_1.py index e4f41d9e9..656a28b25 100644 --- a/datatypes/epc/schema/sap_schema_17_1.py +++ b/datatypes/epc/schema/sap_schema_17_1.py @@ -247,3 +247,13 @@ class SapSchema17_1: has_hot_water_cylinder: Optional[str] = None # Present for flat-type dwellings; absence means not a flat. sap_flat_details: Optional[SapFlatDetails] = None + # Top-level PV export-capability flag (lodged by the SAP 10-era full-SAP + # schemas; absent on the SAP 2012 family, where SEG export did not exist). + # SAP 10.2 Appendix M1 zeroes the PV export credit unless the dwelling is + # connected to an export-capable meter, so dropping the flag under-rates + # any export-capable PV cert (~3 SAP on cert 0380-3044-6070-2305-5925). + # The sibling top-level `pv_connection` is deliberately NOT parsed: the + # full-SAP enum disagrees with the RdSAP/gov-API one the calculator gates + # on (full-SAP certs lodge 1 with a PV credit included; RdSAP 1 = "not + # connected" = no credit), so carrying it across would zero real arrays. + is_dwelling_export_capable: Optional[str] = None diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index 5604b8015..70a93637b 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -303,11 +303,16 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( # the schema dropped at parse, so the Appendix-M generation credit was lost. # Carrying it (mapper `_sap_17_1_pv_arrays`) credits the generation and lifts # this flat 82→84, closing most of the gap to the lodged 85 the array explains. + # WAS 84 until the full-SAP export-capable mapping landed (PRD #1435 WS3): + # this cert lodges `is_dwelling_export_capable: true`, which the mapper + # hardcoded False, so Appendix M1 zeroed the array's export credit. Carrying + # the lodged flag restores it and the engine now reproduces the lodged 85 + # EXACTLY — the last −1 was the missing export credit, not a methodology gap. RealCertExpectation( schema="SAP-Schema-19.1.0", sample="uprn_10096028301", cert_num="0390-3321-6060-2405-7985", - sap_score=84, + sap_score=85, ), # UPRN 10094615101 → cert 0380-3044-6070-2305-5925. SAP-Schema-19.1.0 — a # FULL-SAP TOP-FLOOR FLAT (2023 new build, St Leonards-on-Sea, TFA 76 m², From e5333167719388ecf82a3d4b0ff75eb69794c469 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 12:09:32 +0000 Subject: [PATCH 75/84] =?UTF-8?q?UPRN-prefixed=20property=20folders=20rena?= =?UTF-8?q?me=20to=20a=20single-UPRN=20filename=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- orchestration/sharepoint_renamer_orchestrator.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/orchestration/sharepoint_renamer_orchestrator.py b/orchestration/sharepoint_renamer_orchestrator.py index 15a2bd081..3c7d3e8d3 100644 --- a/orchestration/sharepoint_renamer_orchestrator.py +++ b/orchestration/sharepoint_renamer_orchestrator.py @@ -97,12 +97,15 @@ class SharepointRenamerOrchestrator: def _process_row( self, roots: list[str], uprn: str, address: str, postcode: str ) -> None: + # Batch folders name properties "{uprn}_{address}"; filenames must not + # repeat the UPRN, so the folder lookup and the canonical name diverge. + display_address = address.removeprefix(f"{uprn}_") for root in roots: folder_path = ( f"{root}/{address}, {postcode}" f"/{SharepointSubfolders.ASSESSMENT.value}/{ASSESSMENT_SUBFOLDER}" ) - if self._process_folder(folder_path, uprn, address, postcode): + if self._process_folder(folder_path, uprn, display_address, postcode): return logger.warning( f"Missing folder for UPRN {uprn} in any root: {address}, {postcode}" From 87ac00d499d63a2fdfcf7a4921278c11faadb258 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 12:14:46 +0000 Subject: [PATCH 76/84] Correct St Helier Avenue spelling to match SharePoint folder names Co-Authored-By: Claude Fable 5 --- applications/sharepoint_renamer/sero_address_list.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/sharepoint_renamer/sero_address_list.csv b/applications/sharepoint_renamer/sero_address_list.csv index ad84ff0e7..ae1d2f157 100644 --- a/applications/sharepoint_renamer/sero_address_list.csv +++ b/applications/sharepoint_renamer/sero_address_list.csv @@ -1,6 +1,6 @@ UPRN,Address,Postcode U1041316,"U1041316_58 Ravensworth Road, Mottingham",SE9 4LW -U2022716,"U2022716_306 Saint Helier Avenue, Morden",SM4 6JX +U2022716,"U2022716_306 St Helier Avenue, Morden",SM4 6JX U2018001,"U2018001_37 Leominster Road, Morden",SM4 6HN U2019131,"U2019131_34 Middleton Road, Morden",SM4 6RT U1035331,"104 Whitebeam Avenue, Bromley",BR2 8DW @@ -12,7 +12,7 @@ U1007728,"2 Hazel Walk, Bromley",BR2 8DF U1020327,"5 Kingsdown Way, Bromley",BR2 7PT U1032134,"125 Faringdon Avenue, Bromley",BR2 8BT U1053411,"U1053411_78 Windsor Drive, Orpington",BR6 6HF -U2022615,"U2022615_56 Saint Helier Avenue, Morden",SM4 6LF +U2022615,"U2022615_56 St Helier Avenue, Morden",SM4 6LF U1022991,"5 Link Way, Bromley",BR2 8JH U1010811,"13 Gilbert Road, Bromley",BR1 3QP U1020328,"31 Kingsdown Way, Bromley",BR2 7PT From 4a71c555fa6c17d1e8a5c0b2f2683517de9702f1 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 12:22:26 +0000 Subject: [PATCH 77/84] =?UTF-8?q?SharePoint=20404s=20raise=20ResourceNotFo?= =?UTF-8?q?undError=20without=20error-level=20logging=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- tests/utils/__init__.py | 0 .../test_sharepoint_client_error_handling.py | 58 +++++++++++++++++++ utils/sharepoint/sharepoint_client.py | 4 ++ 3 files changed, 62 insertions(+) create mode 100644 tests/utils/__init__.py create mode 100644 tests/utils/test_sharepoint_client_error_handling.py diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/utils/test_sharepoint_client_error_handling.py b/tests/utils/test_sharepoint_client_error_handling.py new file mode 100644 index 000000000..aa52d4bd7 --- /dev/null +++ b/tests/utils/test_sharepoint_client_error_handling.py @@ -0,0 +1,58 @@ +import logging +from typing import Any, Optional + +import pytest + +from utils.sharepoint.sharepoint_client import ( + ResourceNotFoundError, + api_call_decorator, +) + + +class _FakeResponse: + def __init__(self, status_code: int, error_code: str, message: str) -> None: + self.status_code = status_code + self._error_code = error_code + self._message = message + self.headers: dict[str, str] = {} + + def json(self) -> dict[str, Any]: + return {"error": {"code": self._error_code, "message": self._message}} + + +class _FakeClient: + headers: Optional[dict[str, str]] = {} + + def is_access_token_expired(self) -> bool: + return False + + @api_call_decorator + def fetch(self, path: str) -> Any: + return "GET", f"https://graph.example.invalid/root:/{path}:/children", None + + +def _patch_response( + monkeypatch: pytest.MonkeyPatch, response: _FakeResponse +) -> None: + monkeypatch.setattr( + "utils.sharepoint.sharepoint_client.requests.request", + lambda *args, **kwargs: response, + ) + + +def test_404_raises_resource_not_found_without_error_logs( + monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture +) -> None: + # Arrange + _patch_response( + monkeypatch, + _FakeResponse(404, "itemNotFound", "The resource could not be found."), + ) + + # Act + with pytest.raises(ResourceNotFoundError): + _FakeClient().fetch("missing/folder") + + # Assert + error_records = [r for r in caplog.records if r.levelno >= logging.ERROR] + assert error_records == [] diff --git a/utils/sharepoint/sharepoint_client.py b/utils/sharepoint/sharepoint_client.py index 38107dbfc..976b47831 100644 --- a/utils/sharepoint/sharepoint_client.py +++ b/utils/sharepoint/sharepoint_client.py @@ -21,6 +21,10 @@ from utils.logger import setup_logger logger = setup_logger() +class ResourceNotFoundError(ValueError): + """Raised when the API returns 404 — an expected miss, not a failure.""" + + def handle_error(response): """ Handle errors based on HTTP status codes and log detailed information. From 4fcd23455bafeef53aaacfe1782dc01ba6c8c6a3 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 12:25:03 +0000 Subject: [PATCH 78/84] =?UTF-8?q?The=20multi-measure=20trigger=20fixture?= =?UTF-8?q?=20is=20a=20cert=20the=20sized=20ASHP=20alone=20cannot=20clear?= =?UTF-8?q?=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Golden cert 0330 now reaches band C on the dwelling-sized ASHP alone (ADR-0049), dropping its solid_floor_insulation companion; cert 0390 still fires three measures, so the per-measure trigger-attribute assertions move there (and gain the lighting triggers). Co-Authored-By: Claude Opus 4.8 --- tests/harness/test_report.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/tests/harness/test_report.py b/tests/harness/test_report.py index 7aa820a64..84330584e 100644 --- a/tests/harness/test_report.py +++ b/tests/harness/test_report.py @@ -30,9 +30,13 @@ _GOLDEN = ( _WITHIN_TOLERANCE = "0036-6325-1100-0063-1226" _DIVERGENT = "0240-0200-5706-2365-8010" -# 0330 fires all three trigger kinds: an uninsulated cavity wall (cavity fill), -# its dependent mechanical ventilation, and an uninsulated solid floor. -_THREE_MEASURES = "0330-2249-8150-2326-4121" +# 0390 fires three measures — an uninsulated solid floor, low-energy lighting, +# and the ASHP bundle — so every fired measure's trigger attributes are +# exercised together. (0330, the previous fixture, now reaches band C on the +# correctly-sized ASHP alone: ADR-0049 sizes the pump to the dwelling's design +# heat loss, so the undersized-pump-era companion solid_floor_insulation is no +# longer needed there.) +_THREE_MEASURES = "0390-2254-6420-2126-5561" def _triggers_by_measure(report: PropertyReport) -> dict[str, MeasureTrigger]: @@ -80,17 +84,12 @@ def test_each_fired_measure_carries_the_attributes_that_triggered_it() -> None: # Assert — the Plan ran and every fired measure names its trigger fields. assert report.plan is not None assert report.plan_error is None - # The gain-maximising package: the efficient representative ASHP (ADR-0025) - # plus solid-floor insulation. The cavity wall + its forced mechanical - # ventilation (ADR-0016) are NOT selected — the wall earns +SAP alone but - # the forced-ventilation penalty makes the pair net-negative, so the - # Optimiser correctly leaves them out (see test_measure_dependency / - # test_optimiser for the forced-edge unit coverage; cavity_wall + - # mechanical_ventilation trigger fields are exercised in - # test_cavity_wall_recommendation / the ventilation generator tests). + # The selected package: the dwelling-sized ASHP (ADR-0025/ADR-0049) plus + # solid-floor insulation and low-energy lighting. triggers: dict[str, MeasureTrigger] = _triggers_by_measure(report) assert set(triggers) == { "solid_floor_insulation", + "low_energy_lighting", "air_source_heat_pump", } # Solid-floor insulation fired off an uninsulated solid ground floor. @@ -98,6 +97,12 @@ def test_each_fired_measure_carries_the_attributes_that_triggered_it() -> None: "floor_insulation_thickness": None, "floor_construction_type": "Solid", } + # Low-energy lighting fired off the dwelling's lodged bulb counts. + assert triggers["low_energy_lighting"].triggers == { + "incandescent_fixed_lighting_bulbs_count": 0, + "cfl_fixed_lighting_bulbs_count": 0, + "low_energy_fixed_lighting_bulbs_count": 9, + } # The ASHP bundle fired off the gas-dwelling main it replaces. assert triggers["air_source_heat_pump"].triggers == { "property_type": "0", From dc188ca3c52f367f1623482a834702d25486dbf7 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 12:26:33 +0000 Subject: [PATCH 79/84] =?UTF-8?q?SharePoint=20404s=20raise=20ResourceNotFo?= =?UTF-8?q?undError=20without=20error-level=20logging=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- .../test_sharepoint_client_error_handling.py | 33 ++++++++++++++++--- utils/sharepoint/sharepoint_client.py | 10 ++++-- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/tests/utils/test_sharepoint_client_error_handling.py b/tests/utils/test_sharepoint_client_error_handling.py index aa52d4bd7..4cae1578e 100644 --- a/tests/utils/test_sharepoint_client_error_handling.py +++ b/tests/utils/test_sharepoint_client_error_handling.py @@ -1,11 +1,16 @@ import logging -from typing import Any, Optional +from typing import Any, Callable, Optional, cast import pytest from utils.sharepoint.sharepoint_client import ( ResourceNotFoundError, - api_call_decorator, + api_call_decorator, # pyright: ignore[reportUnknownVariableType] +) + +# The legacy decorator is untyped; cast so this module stays pyright-strict. +_decorate = cast( + Callable[[Callable[..., Any]], Callable[..., Any]], api_call_decorator ) @@ -26,7 +31,7 @@ class _FakeClient: def is_access_token_expired(self) -> bool: return False - @api_call_decorator + @_decorate def fetch(self, path: str) -> Any: return "GET", f"https://graph.example.invalid/root:/{path}:/children", None @@ -34,9 +39,11 @@ class _FakeClient: def _patch_response( monkeypatch: pytest.MonkeyPatch, response: _FakeResponse ) -> None: + def fake_request(*args: Any, **kwargs: Any) -> _FakeResponse: + return response + monkeypatch.setattr( - "utils.sharepoint.sharepoint_client.requests.request", - lambda *args, **kwargs: response, + "utils.sharepoint.sharepoint_client.requests.request", fake_request ) @@ -56,3 +63,19 @@ def test_404_raises_resource_not_found_without_error_logs( # Assert error_records = [r for r in caplog.records if r.levelno >= logging.ERROR] assert error_records == [] + + +def test_other_client_errors_still_log_at_error_level( + monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture +) -> None: + # Arrange + _patch_response( + monkeypatch, _FakeResponse(403, "accessDenied", "Access denied.") + ) + + # Act + with pytest.raises(ValueError): + _FakeClient().fetch("forbidden/folder") + + # Assert + assert any(r.levelno >= logging.ERROR for r in caplog.records) diff --git a/utils/sharepoint/sharepoint_client.py b/utils/sharepoint/sharepoint_client.py index 976b47831..0364320f4 100644 --- a/utils/sharepoint/sharepoint_client.py +++ b/utils/sharepoint/sharepoint_client.py @@ -39,6 +39,12 @@ def handle_error(response): inner_error = error_json.get("innererror", {}) details = error_json.get("details", []) + if response.status_code == 404: + logger.debug(f"Not found ({error_code}): {error_message}") + raise ResourceNotFoundError( + f"API request failed with status code 404 - {error_message}" + ) + logger.error(f"Error Code: {error_code}") logger.error(f"Error Message: {error_message}") if inner_error: @@ -50,8 +56,6 @@ def handle_error(response): logger.error("Unauthorized. Token might be invalid.") elif response.status_code == 403: logger.error("Forbidden. Access denied to the requested resource.") - elif response.status_code == 404: - logger.error("Not Found. The requested resource doesn’t exist.") elif response.status_code == 429: retry_after = int( response.headers.get("Retry-After", 5) @@ -125,6 +129,8 @@ def api_call_decorator(func): return response_data + except ResourceNotFoundError: + raise except Exception as e: logger.exception("An error occurred during the API call.") raise e From 1144b1e7b193f1b58d91a701363a25f343d2c545 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 13:09:17 +0000 Subject: [PATCH 80/84] Make nested SapHeating.has_fixed_air_conditioning optional across all RdSAP schemas Some lodged certs omit the sap_heating.has_fixed_air_conditioning key, which the generic from_dict loader treats as a required field and rejects outright. Two prior commits (26651ca71, 8074f4152) fixed the duplicate top-level field of the same name but left this nested copy untouched; a third pass (44991bed0) missed it too. The mapper already reads it defensively (== "true", which is False on None), so this is a safe default. Surfaced by 7 failed modelling_e2e subtasks on portfolio 817. --- datatypes/epc/schema/rdsap_schema_17_0.py | 4 +++- datatypes/epc/schema/rdsap_schema_17_1.py | 6 ++++-- datatypes/epc/schema/rdsap_schema_18_0.py | 6 ++++-- datatypes/epc/schema/rdsap_schema_19_0.py | 6 ++++-- datatypes/epc/schema/rdsap_schema_20_0_0.py | 4 +++- datatypes/epc/schema/rdsap_schema_21_0_0.py | 6 ++++-- datatypes/epc/schema/rdsap_schema_21_0_1.py | 10 +++++++--- 7 files changed, 29 insertions(+), 13 deletions(-) diff --git a/datatypes/epc/schema/rdsap_schema_17_0.py b/datatypes/epc/schema/rdsap_schema_17_0.py index d66f9c699..445d51a77 100644 --- a/datatypes/epc/schema/rdsap_schema_17_0.py +++ b/datatypes/epc/schema/rdsap_schema_17_0.py @@ -44,7 +44,9 @@ class SapHeating: instantaneous_wwhrs: Optional[InstantaneousWwhrs] main_heating_details: List[MainHeatingDetail] immersion_heating_type: Union[int, str] - has_fixed_air_conditioning: str + # Nested duplicate of the outer schema's has_fixed_air_conditioning + # (already Optional below) — some certs omit it here too. + has_fixed_air_conditioning: Optional[str] = None # ADR-0028: cylinder_insulation_type is absent in 308/1000 17.0 certs. cylinder_insulation_type: Optional[int] = None cylinder_thermostat: Optional[str] = None diff --git a/datatypes/epc/schema/rdsap_schema_17_1.py b/datatypes/epc/schema/rdsap_schema_17_1.py index bbd04b791..c0a4c8e62 100644 --- a/datatypes/epc/schema/rdsap_schema_17_1.py +++ b/datatypes/epc/schema/rdsap_schema_17_1.py @@ -44,7 +44,9 @@ class SapHeating: instantaneous_wwhrs: Optional[InstantaneousWwhrs] main_heating_details: List[MainHeatingDetail] immersion_heating_type: Union[int, str] - has_fixed_air_conditioning: str + # Nested duplicate of the outer schema's has_fixed_air_conditioning + # (also made Optional below) — some certs omit it here too. + has_fixed_air_conditioning: Optional[str] = None # ADR-0028: 325/1000 omit cylinder_insulation_type — default it. cylinder_insulation_type: Optional[int] = None cylinder_thermostat: Optional[str] = None @@ -247,7 +249,7 @@ class RdSapSchema17_1: hot_water_cost_potential: CostAmount renewable_heat_incentive: RenewableHeatIncentive energy_consumption_current: int - has_fixed_air_conditioning: str + has_fixed_air_conditioning: Optional[str] = None multiple_glazed_proportion: int calculation_software_version: str energy_consumption_potential: int diff --git a/datatypes/epc/schema/rdsap_schema_18_0.py b/datatypes/epc/schema/rdsap_schema_18_0.py index f35f0733c..a7a9d8702 100644 --- a/datatypes/epc/schema/rdsap_schema_18_0.py +++ b/datatypes/epc/schema/rdsap_schema_18_0.py @@ -44,7 +44,9 @@ class SapHeating: instantaneous_wwhrs: Optional[InstantaneousWwhrs] main_heating_details: List[MainHeatingDetail] immersion_heating_type: Union[int, str] - has_fixed_air_conditioning: str + # Nested duplicate of the outer schema's has_fixed_air_conditioning + # (also made Optional below) — some certs omit it here too. + has_fixed_air_conditioning: Optional[str] = None cylinder_insulation_type: Optional[int] = None cylinder_thermostat: Optional[str] = None secondary_fuel_type: Optional[int] = None @@ -266,7 +268,7 @@ class RdSapSchema18_0: hot_water_cost_potential: CostAmount renewable_heat_incentive: RenewableHeatIncentive energy_consumption_current: int - has_fixed_air_conditioning: str + has_fixed_air_conditioning: Optional[str] = None multiple_glazed_proportion: int calculation_software_version: str energy_consumption_potential: int diff --git a/datatypes/epc/schema/rdsap_schema_19_0.py b/datatypes/epc/schema/rdsap_schema_19_0.py index 2ba0f3cbb..4e0c21414 100644 --- a/datatypes/epc/schema/rdsap_schema_19_0.py +++ b/datatypes/epc/schema/rdsap_schema_19_0.py @@ -44,7 +44,9 @@ class SapHeating: instantaneous_wwhrs: Optional[InstantaneousWwhrs] main_heating_details: List[MainHeatingDetail] immersion_heating_type: Union[int, str] - has_fixed_air_conditioning: str + # Nested duplicate of the outer schema's has_fixed_air_conditioning + # (also made Optional below) — some certs omit it here too. + has_fixed_air_conditioning: Optional[str] = None cylinder_insulation_type: Optional[int] = None cylinder_thermostat: Optional[str] = None secondary_fuel_type: Optional[int] = None @@ -281,7 +283,7 @@ class RdSapSchema19_0: # 19.0-specific block, absent in 713/1000 — Optional + default. windows_transmission_details: Optional[WindowsTransmissionDetails] = None energy_consumption_current: int - has_fixed_air_conditioning: str + has_fixed_air_conditioning: Optional[str] = None multiple_glazed_proportion: int calculation_software_version: str energy_consumption_potential: int diff --git a/datatypes/epc/schema/rdsap_schema_20_0_0.py b/datatypes/epc/schema/rdsap_schema_20_0_0.py index 395fb9b92..8fae99371 100644 --- a/datatypes/epc/schema/rdsap_schema_20_0_0.py +++ b/datatypes/epc/schema/rdsap_schema_20_0_0.py @@ -56,7 +56,9 @@ class SapHeating: instantaneous_wwhrs: Optional[InstantaneousWwhrs] main_heating_details: List[MainHeatingDetail] immersion_heating_type: Union[int, str] - has_fixed_air_conditioning: str + # Nested duplicate of the outer schema's has_fixed_air_conditioning + # (already Optional below) — some certs omit it here too. + has_fixed_air_conditioning: Optional[str] = None cylinder_insulation_type: Optional[int] = None cylinder_thermostat: Optional[str] = None secondary_fuel_type: Optional[int] = None diff --git a/datatypes/epc/schema/rdsap_schema_21_0_0.py b/datatypes/epc/schema/rdsap_schema_21_0_0.py index 2f5c8e69b..4588ee7f6 100644 --- a/datatypes/epc/schema/rdsap_schema_21_0_0.py +++ b/datatypes/epc/schema/rdsap_schema_21_0_0.py @@ -63,7 +63,9 @@ class SapHeating: water_heating_fuel: int main_heating_details: List[MainHeatingDetail] immersion_heating_type: Union[int, str] - has_fixed_air_conditioning: str + # Nested duplicate of the outer schema's has_fixed_air_conditioning + # (also made Optional below) — some certs omit it here too. + has_fixed_air_conditioning: Optional[str] = None instantaneous_wwhrs: Optional[InstantaneousWwhrs] = None # Real-API certs carry shower_outlets as a list, not the synthetic # single-object form; list elements are normalised to the wrapped @@ -459,7 +461,7 @@ class RdSapSchema21_0_0: windows_transmission_details: Optional[WindowsTransmissionDetails] = None cfl_fixed_lighting_bulbs_count: Optional[int] = None energy_consumption_current: int - has_fixed_air_conditioning: str + has_fixed_air_conditioning: Optional[str] = None multiple_glazed_proportion: int calculation_software_version: str energy_consumption_potential: int diff --git a/datatypes/epc/schema/rdsap_schema_21_0_1.py b/datatypes/epc/schema/rdsap_schema_21_0_1.py index 45f1ee465..4b814d7fb 100644 --- a/datatypes/epc/schema/rdsap_schema_21_0_1.py +++ b/datatypes/epc/schema/rdsap_schema_21_0_1.py @@ -1,4 +1,4 @@ -from dataclasses import dataclass +from dataclasses import dataclass, field from typing import List, Optional, Union from .common import DescriptionV1, Measurement @@ -64,7 +64,9 @@ class SapHeating: water_heating_fuel: int main_heating_details: List[MainHeatingDetail] immersion_heating_type: Union[int, str] - has_fixed_air_conditioning: str + # Nested duplicate of the outer schema's has_fixed_air_conditioning + # (also made Optional below) — some certs omit it here too. + has_fixed_air_conditioning: Optional[str] = None instantaneous_wwhrs: Optional[InstantaneousWwhrs] = None # Real-API certs carry shower_outlets as a list, not the synthetic single-object form; # accept both shapes so older fixtures keep parsing. List elements @@ -510,7 +512,9 @@ class RdSapSchema21_0_1: renewable_heat_incentive: RenewableHeatIncentive draughtproofed_door_count: int energy_consumption_current: int - has_fixed_air_conditioning: str + # kw_only on just this field: the class isn't kw_only overall, and several + # required fields (calculation_software_version etc.) already follow it. + has_fixed_air_conditioning: Optional[str] = field(default=None, kw_only=True) calculation_software_version: str energy_consumption_potential: int environmental_impact_current: int From 71b970a697409d6741104939d335db77f1a29219 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 13:24:10 +0000 Subject: [PATCH 81/84] Map API roof_construction code 9 ("another premises above") to None MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same party-ceiling semantics as the already-mapped code 7 ("another dwelling above" / "same dwelling above") — the unit has no exposed roof, so there's nothing for the cascade to compute a U-value for. Confirmed against the live cert (uprn 10013320122): roofs[].description = "(another premises above)", roof_insulation_location = "ND" (the codebase's established "no exposed roof" signal). Surfaced by 1 failed modelling_e2e subtask on portfolio 817 (task_source='modelling_e2e', job_completed > '2026-07-03 12:50:37.555+01:00'). --- datatypes/epc/domain/mapper.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/datatypes/epc/domain/mapper.py b/datatypes/epc/domain/mapper.py index 80a650515..6c12b6e55 100644 --- a/datatypes/epc/domain/mapper.py +++ b/datatypes/epc/domain/mapper.py @@ -4445,6 +4445,9 @@ _API_ROOF_CONSTRUCTION_TO_STR: Dict[int, Optional[str]] = { 6: None, 7: None, 8: "Pitched, sloping ceiling", + # "(another premises above)" per a live cert (uprn 10013320122) — same + # party-ceiling semantics as code 7, just "premises" not "dwelling". + 9: None, } From 0c3fbe5853376a4bcc50aace26973d05e54c3adb Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 13:37:58 +0000 Subject: [PATCH 82/84] rename dodgy address --- applications/sharepoint_renamer/handler.py | 4 +++- applications/sharepoint_renamer/sero_address_list.csv | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/applications/sharepoint_renamer/handler.py b/applications/sharepoint_renamer/handler.py index dfaa510ce..f55f54741 100644 --- a/applications/sharepoint_renamer/handler.py +++ b/applications/sharepoint_renamer/handler.py @@ -8,7 +8,9 @@ from orchestration.sharepoint_renamer_orchestrator import SharepointRenamerOrche from utils.sharepoint.domna_sharepoint_client import DomnaSharepointClient from utils.sharepoint.domna_sites import DomnaSites -CSV_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "sero_address_list.csv") +CSV_PATH = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "sero_address_list.csv" +) def handler(event: dict[str, Any], context: Any) -> None: diff --git a/applications/sharepoint_renamer/sero_address_list.csv b/applications/sharepoint_renamer/sero_address_list.csv index ae1d2f157..604387747 100644 --- a/applications/sharepoint_renamer/sero_address_list.csv +++ b/applications/sharepoint_renamer/sero_address_list.csv @@ -299,7 +299,7 @@ U1014589,"71 Empress Drive, Chislehurst",BR7 5BQ U1002456,"54 Birch Row, Bromley",BR2 8DA U1020369,"13 Larch Way, Bromley",BR2 8DT U1034985,"272 Southborough Lane, Bromley",BR2 8AS -U1041435,"64 Prince's Plain, Bromley",BR2 8LE +U1041435,"64 Princes Plain, Bromley",BR2 8LE U1031294,"70 London Lane, Bromley",BR1 4HE U1033406,"67 Lower Gravel Road, Bromley",BR2 8LP U1032061,"30 Eastry Avenue, Bromley",BR2 7PF From 785292818102c7204f39be8331f551b24a4210b6 Mon Sep 17 00:00:00 2001 From: Daniel Roth Date: Fri, 3 Jul 2026 13:38:09 +0000 Subject: [PATCH 83/84] delete test data file --- applications/sharepoint_renamer/sero_address_list_test.csv | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 applications/sharepoint_renamer/sero_address_list_test.csv diff --git a/applications/sharepoint_renamer/sero_address_list_test.csv b/applications/sharepoint_renamer/sero_address_list_test.csv deleted file mode 100644 index 72b280477..000000000 --- a/applications/sharepoint_renamer/sero_address_list_test.csv +++ /dev/null @@ -1,2 +0,0 @@ -UPRN,Address,Postcode -U1014630,"118 Faringdon Avenue, Bromley",BR2 8BU \ No newline at end of file From d769f4488a572a019764302094af2130865b60ee Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 14:44:01 +0000 Subject: [PATCH 84/84] Suppress roof heat loss for API roof_construction codes 7 and 9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RdSAP 10 Specification (10-06-2025) §5.2.5: "If a dwelling or part of a dwelling has commercial premises above record as another dwelling above" — so code 9 ("another premises above") must get the same zero-heat-loss treatment as code 7 ("another dwelling above"), per the spec's own "there is no heat loss through the roof of a building part that has the same dwelling above or another dwelling above." The previous fix mapped both to None, which only avoided the mapper crash — it didn't achieve zero heat loss. heat_transmission.py's per-part suppression (part_roof_is_party) only fires when roof_construction_type CONTAINS the literal string "another dwelling above"; that string was only ever set on the Elmhurst ingestion path. The API path mapped 7 (and, until now, 9) to None, so the suppression never fired for any API-derived cert — has_exposed_roof (the dwelling_type-label-only fallback) was the sole gate, with no way to know about a per-part party-ceiling lodgement. Both codes now map to "(another dwelling above)" so the existing suppression logic fires on both ingestion paths, matching what domain/epc/property_overrides/roof_party_ceiling_guard.py already does independently for the landlord-override pipeline (same spec citation). Verified against the motivating cert (uprn 10013320122): roof_w_per_k now correctly computes to 0.0. Full RdSAP-21.0.1 corpus (1000 certs) re-run: within-0.5 unchanged at 77.8%, MAE improves marginally (0.6364 vs 0.637 ceiling) — no regression. --- datatypes/epc/domain/mapper.py | 50 ++++++++++++------- .../domain/tests/test_from_rdsap_schema.py | 41 +++++++++------ 2 files changed, 60 insertions(+), 31 deletions(-) diff --git a/datatypes/epc/domain/mapper.py b/datatypes/epc/domain/mapper.py index 6c12b6e55..5a04e5165 100644 --- a/datatypes/epc/domain/mapper.py +++ b/datatypes/epc/domain/mapper.py @@ -4423,31 +4423,47 @@ _API_FLOOR_CONSTRUCTION_TO_STR: Dict[int, Optional[str]] = { # enum (1=Flat, 3=Pitched no-access, 5=Vaulted, etc.) is mapped as # best-effort against SAP10 nomenclature. # -# Codes 6 and 7 → None. This field is read ONLY for the sloping-ceiling -# inclined factor; the base roof U-value comes from the global -# roofs[].description, so a non-sloping code carries no information the -# cascade consumes here, and None correctly avoids the cos(30°) false- -# trigger: +# Code 6 → None. This field is read ONLY for the sloping-ceiling inclined +# factor; the base roof U-value comes from the global roofs[].description, +# so a non-sloping code carries no information the cascade consumes here: # 6 = "Thatched, with additional insulation" — its U is set by the -# global description; not a sloping ceiling. -# 7 = "(same dwelling above)" / "(another dwelling above)" — an -# internal ceiling with no roof heat loss (the roof-side analogue -# of floor_construction code 0). Heat loss is governed by the -# roof_heat_loss / description path, not this field. -# Empirically inert: roof W/K is identical whether 6/7 map to None or to -# an explicit pitched string across all code-6/7 certs in the 2026 -# sample (were raising UnmappedApiCode, blocking the cert). +# global description; not a sloping ceiling. None correctly avoids +# the cos(30°) false-trigger. +# +# Codes 7 and 9 → "(another dwelling above)", NOT None. RdSAP 10 +# Specification (10-06-2025) §5.2.5 (p.31): "If a dwelling or part of a +# dwelling has commercial premises above record as another dwelling +# above" — i.e. premises-above (code 9) gets the SAME treatment as +# dwelling-above (code 7), not the semi-exposed "partially heated space" +# treatment used for premises *below* (see `_API_FLOOR_HEAT_LOSS_ABOVE_ +# PARTIALLY_HEATED`) — the spec's above/below split is asymmetric. Per +# spec p.~55: "There is no heat loss through the roof of a building part +# that has the same dwelling above or another dwelling above" — zero +# heat loss, mirrored by the landlord-override system's independent +# `roof_party_ceiling_guard` (`domain/epc/property_overrides/`), which +# already resolves this exact "(another premises above)" marker to a +# ~0-heat-loss RoofType citing the same spec line. +# +# `heat_transmission.py`'s per-part suppression (`part_roof_is_party = +# "another dwelling above" in roof_type`) only fires when this field +# CONTAINS that literal substring — it existed already for the Elmhurst +# path (which sets it via `_strip_code(roof.roof_type)`) but the API path +# previously mapped 7 (and, before this fix, 9) to None, so the +# suppression never fired for ANY API-derived cert: `has_exposed_roof` +# (the dwelling_type-label-only fallback) was the sole gate, and it has +# no way to know about a per-part party-ceiling lodgement. Surfaced by +# live cert uprn 10013320122 ("44 Regent House", code 9); code 7 has the +# same latent gap (11 building parts in the RdSAP-21.0.1 corpus), fixed +# here too rather than left half-fixed. _API_ROOF_CONSTRUCTION_TO_STR: Dict[int, Optional[str]] = { 1: "Flat", 3: "Pitched (slates/tiles), no access to loft", 4: "Pitched (slates/tiles), access to loft", 5: "Pitched (vaulted ceiling)", 6: None, - 7: None, + 7: "(another dwelling above)", 8: "Pitched, sloping ceiling", - # "(another premises above)" per a live cert (uprn 10013320122) — same - # party-ceiling semantics as code 7, just "premises" not "dwelling". - 9: None, + 9: "(another dwelling above)", } diff --git a/datatypes/epc/domain/tests/test_from_rdsap_schema.py b/datatypes/epc/domain/tests/test_from_rdsap_schema.py index 7d68b4a1f..f6ce46bfb 100644 --- a/datatypes/epc/domain/tests/test_from_rdsap_schema.py +++ b/datatypes/epc/domain/tests/test_from_rdsap_schema.py @@ -1339,18 +1339,18 @@ class TestDefaultMissingPostTown: class TestApiRoofConstructionCode: """`_api_roof_construction_str` maps the GOV.UK API integer - roof_construction code to the string the cascade reads ONLY for the - "sloping ceiling" cos(30°) inclined-surface factor (Slice 89). Codes - 6 and 7 are neither sloping ceilings nor base-U drivers (the roof - U-value comes from the global roofs[].description), so both map to - None: code 6 = "Thatched" (its U is set by the description, not this - field) and code 7 = "(same/another dwelling above)" — an internal - ceiling with no roof heat loss, the roof-side analogue of - floor_construction code 0. Empirically inert: roof W/K is identical - whether 6/7 map to None or to an explicit pitched string across all - code-6/7 certs in the 2026 sample.""" + roof_construction code to the string `heat_transmission.py` reads for + two purposes: the "sloping ceiling" cos(30°) inclined-surface factor + (Slice 89), and — for codes 7/9 — the "another dwelling above" + substring that suppresses that building part's roof entirely (zero + heat loss). Code 6 = "Thatched" is neither: its U-value comes from + the global roofs[].description, not this field, so it maps to None + (avoids the cos(30°) false-trigger). Codes 7 and 9 both map to + "(another dwelling above)" per RdSAP 10 Specification (10-06-2025) + §5.2.5: commercial premises above (code 9) is recorded identically to + another dwelling above (code 7) — both zero heat loss.""" - def test_code_7_same_dwelling_above_maps_to_none(self) -> None: + def test_code_7_same_dwelling_above_suppresses_roof_heat_loss(self) -> None: # Arrange from datatypes.epc.domain.mapper import ( _api_roof_construction_str, @@ -1359,9 +1359,22 @@ class TestApiRoofConstructionCode: # Act result = _api_roof_construction_str(7) - # Assert — None: no sloping-ceiling signal (avoids the cos(30°) - # false-trigger); the internal ceiling has no roof heat loss. - assert result is None + # Assert — the party-ceiling marker, so heat_transmission.py's + # per-part "another dwelling above" suppression fires. + assert result == "(another dwelling above)" + + def test_code_9_another_premises_above_suppresses_roof_heat_loss(self) -> None: + # Arrange — RdSAP 10 Spec §5.2.5: commercial premises above is + # recorded as "another dwelling above", same as code 7. + from datatypes.epc.domain.mapper import ( + _api_roof_construction_str, + ) # pyright: ignore[reportPrivateUsage] + + # Act + result = _api_roof_construction_str(9) + + # Assert + assert result == "(another dwelling above)" def test_code_6_thatched_maps_to_none(self) -> None: # Arrange

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", _pick(page, f"{WALL}DropDownListInsulation", "external")) print("party ->", _pick(page, f"{PWALL}DropDownListPartyWallType", "determine") or _pick(page, f"{PWALL}DropDownListPartyWallType", "masonry")) + # wall thickness (cert lodges 400 mm; Elmhurst else defaults 260) + for suf in (f"{WALL}TextBoxThickness", f"{WALL}TextBoxWallThickness"): + if page.locator(f"#{E.FP}{suf}").count(): + E.set_text(page, suf, "400"); print("wall thickness set 400 via", suf); break + else: + print("thickness field not found; wall fields:", [i for i in page.evaluate("()=>Array.from(document.querySelectorAll('[id*=Wall]')).map(e=>e.id)")][:20]) E.save_close(page) @@ -129,8 +135,8 @@ def ventilation(page): E.click_tab(page, "TabContainer_TabPanelAirPressureTest") E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") E.click_tab(page, "TabContainer_TabPanelLighting") - E.set_text(page, f"{LP}TextBoxLightsTotal", "6") - E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxLightsTotal", "5") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "5") E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") E.save_close(page) From 8b8cc96d43685a9b65452a5c8394f8f64151e369 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 06:18:02 +0000 Subject: [PATCH 22/84] =?UTF-8?q?chore(corpus):=20mapper=20faithfulness=20?= =?UTF-8?q?audit=20=E2=80=94=20EPC-API->EpcPropertyData=20is=20faithful?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audits identity pass-through fields (dims, counts, thicknesses) raw cert vs EpcPropertyData across all 1000 certs. All apparent mismatches are legitimate mapper behavior the first-pass audit didn't model: window_wall_type=4 windows correctly split to sap_roof_windows (not dropped); empty placeholder building parts correctly discarded; 'measured' insulation-thickness sentinel resolved to the wall_insulation_thickness_measured value. Remaining per-BP diffs were an index-misalignment artifact (raw BP[i] vs epc BP[i] after empty BP0 dropped). Conclusion: mapper is faithful; divergences are Playwright-entry or calc-side. Co-Authored-By: Claude Opus 4.8 --- scripts/corpus_1000/mapper_audit.py | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 scripts/corpus_1000/mapper_audit.py diff --git a/scripts/corpus_1000/mapper_audit.py b/scripts/corpus_1000/mapper_audit.py new file mode 100644 index 000000000..6d82c5f1d --- /dev/null +++ b/scripts/corpus_1000/mapper_audit.py @@ -0,0 +1,56 @@ +"""Mapper faithfulness audit: for identity pass-through fields (dims, counts, +thicknesses) compare the RAW cert value to what EpcPropertyDataMapper produced. +Any mismatch is a mapper bug silently feeding the SAP engine wrong inputs.""" +from __future__ import annotations +import json +from collections import defaultdict +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +CORPUS="backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl" +def gv(x): return x.get('value') if isinstance(x,dict) else x +def num(x): + x=gv(x) + if x is None: return None + s=str(x).lower().replace('mm','').replace('m2','').strip() + try: return float(s) + except: return s # keep strings like 'measured'/'NI' for equality +mism=defaultdict(list) +n=0 +for line in open(CORPUS): + d=json.loads(line) + try: epc=EpcPropertyDataMapper.from_api_response(d) + except Exception: continue + n+=1; u=d.get('uprn') + # top-level counts + checks=[('door_count', d.get('door_count'), epc.door_count), + ('habitable', d.get('habitable_room_count'), getattr(epc,'habitable_room_count',None)), + ('led', d.get('led_fixed_lighting_bulbs_count'), epc.led_fixed_lighting_bulbs_count), + ('cfl', d.get('cfl_fixed_lighting_bulbs_count'), epc.cfl_fixed_lighting_bulbs_count), + ('incand', d.get('incandescent_fixed_lighting_bulbs_count'), epc.incandescent_fixed_lighting_bulbs_count)] + for name,rv,ev in checks: + if rv is not None and ev is not None and num(rv)!=num(ev): + mism[name].append((u,rv,ev)) + # per-building-part fabric + rbps=d.get('sap_building_parts') or []; ebps=epc.sap_building_parts or [] + for i,rbp in enumerate(rbps): + if i>=len(ebps): + mism['DROPPED_building_part'].append((u,len(rbps),len(ebps))); break + ebp=ebps[i] + for name,rv,ev in [('wall_thick',rbp.get('wall_thickness'),getattr(ebp,'wall_thickness_mm',None)), + ('wall_ins_thick',rbp.get('wall_insulation_thickness'),getattr(ebp,'wall_insulation_thickness',None)), + ('roof_ins_thick',rbp.get('roof_insulation_thickness'),getattr(ebp,'roof_insulation_thickness',None)), + ('wall_con',rbp.get('wall_construction'),getattr(ebp,'wall_construction',None)), + ('wall_ins_type',rbp.get('wall_insulation_type'),getattr(ebp,'wall_insulation_type',None))]: + if rv is not None and ev is not None and num(rv)!=num(ev): + mism[name].append((u,rv,ev)) + # windows: count + total area + rw=d.get('sap_windows') or []; ew=epc.sap_windows or [] + if len(rw)!=len(ew): mism['window_count'].append((u,len(rw),len(ew))) + ra=sum((gv(w.get('window_width')) or 0)*(gv(w.get('window_height')) or 0) for w in rw) + ea=sum((float(w.window_width) if w.window_width else 0)*(float(w.window_height) if w.window_height else 0) for w in ew) + if abs(ra-ea)>0.02: mism['window_area'].append((u,round(ra,2),round(ea,2))) +print(f"audited {n} certs") +print("=== field mismatches (raw cert vs EpcPropertyData) ===") +for k,v in sorted(mism.items(), key=lambda x:-len(x[1])): + print(f"\n[{len(v):4d}] {k}") + for u,rv,ev in v[:5]: print(f" {u}: raw={rv} epc={ev}") +if not mism: print(" (no mismatches — mapper is identity-faithful on all checked fields)") From ad8d6534bb95cff88f02b44bafe7996883494685 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 06:29:37 +0000 Subject: [PATCH 23/84] chore(hyde): fix 100061275133 draught-proofing (doors draught-proofed, cert=100%) Third Playwright-entry error found via input reconciliation: my build left draught-proofed doors at 0 (Elmhurst computed 33% draught proofing), but the cert lodges percent_draughtproofed=100. Our calculator correctly uses 100% -> infiltration 42.66 W/K; the ~19 W/K ventilation gap to Elmhurst was purely my build error. On matched inputs our fabric+TB (109.38) equals Elmhurst's total fabric (37) EXACTLY, confirming the calculator is RdSAP-faithful. Committed for build-faithfulness record; the engine's +1.24 vs lodged 76 is not a bug. Co-Authored-By: Claude Opus 4.8 --- scripts/hyde/build_100061275133.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/hyde/build_100061275133.py b/scripts/hyde/build_100061275133.py index dc0a88d8b..93ddab7b7 100644 --- a/scripts/hyde/build_100061275133.py +++ b/scripts/hyde/build_100061275133.py @@ -112,7 +112,7 @@ def openings(page): E.click_tab(page, "TabContainer_TabPanelDoorsPanel") E.set_text(page, f"{DP}TextBoxDoors", "2") E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") - E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "2") # cert: percent_draughtproofed=100 E.save_close(page) From b9d36f72cb4211036e71562163947783680fb498 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 07:45:58 +0000 Subject: [PATCH 24/84] chore(hyde): refresh 100061275133 Elmhurst PDFs after draught-proofing rebuild Co-Authored-By: Claude Fable 5 --- .../uprn_100061275133/elmhurst_summary.pdf | Bin 79069 -> 64270 bytes .../uprn_100061275133/elmhurst_worksheet.pdf | Bin 44098 -> 44442 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf index fe9d91f0f7aed371068601896182c64ece79c715..2d86d5cee0da69bd02e725ce050234620988a2fb 100644 GIT binary patch delta 5855 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 Q2@)m(fs=4@%4;h85B4aG;{X5v delta 6526 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 delta 41431 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 Date: Fri, 3 Jul 2026 07:49:23 +0000 Subject: [PATCH 25/84] feat(hyde): PCDB exact-boiler entry (set_pcdb_boiler + clear_main_heating_code) Cracks the 'PCDB disabled' blocker. The PCDF boiler reference resolves the exact lodged boiler (e.g. 18908 -> Worcester Greenstar 4000, 88.70%) when: (1) the main heating CODE is empty server-side (else the field + magnifying glass are aspNetDisabled), and (2) the index is entered via REAL keyboard + Tab (a JS-set .value doesn't survive the AutoPostBack). Now Elmhurst uses the same boiler efficiency as the SAP engine, so worksheet vs calculator compare like-for-like. Verified on 100061275133: Elmhurst now shows 'Efficiency of main space heating system 1 = 88.70%' (was generic 84%). Includes updated worksheet evidence. Co-Authored-By: Claude Opus 4.8 --- scripts/hyde/elmhurst_lib.py | 57 ++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/scripts/hyde/elmhurst_lib.py b/scripts/hyde/elmhurst_lib.py index fb99966fb..72f2fb9bc 100644 --- a/scripts/hyde/elmhurst_lib.py +++ b/scripts/hyde/elmhurst_lib.py @@ -467,6 +467,63 @@ def select_boiler(page: Page, query: str, ref: str) -> str: return "ok" +def clear_main_heating_code(page: Page) -> None: + """Empty Main Heating 1's SAP code via a real server postback (set the + cascade's top-level dropdown to '' + OK). REQUIRED before `set_pcdb_boiler`: + while any code is set, the PCDF reference textbox and the boiler-search + magnifying glass both render `aspNetDisabled`. They only enable when the + code is empty server-side (a JS-clear alone flips the class cosmetically but + leaves the postback unwired).""" + page.evaluate( + "(id)=>{const e=document.getElementById(id); if(e)e.click();}", + f"{MH1}ButtonMainHeatingCode", + ) + page.wait_for_timeout(SETTLE_MS * 3) + page.evaluate( + """(id)=>{const s=document.getElementById(id);if(s){s.value=''; + s.dispatchEvent(new Event('change',{bubbles:true}));}}""", + f"{HEATING_DIALOG}DropDownList1", + ) + page.wait_for_timeout(SETTLE_MS * 3) + dialog_commit(page, "OK") + page.wait_for_timeout(SETTLE_MS * 2) + + +def set_pcdb_boiler(page: Page, pcdb_index: "int | str") -> str: + """Set Main Heating 1 to the EXACT PCDB boiler by its EPC + `main_heating_index_number` (e.g. 18908 = Worcester Greenstar 4000, + GR4700iW 25 C NG, 88.70%). Elmhurst resolves it to the product's PCDB + winter efficiency — the same value the SAP engine uses — so the worksheet + and our calculator compare like-for-like (not against the generic BGW + SAP-Table 84%). Returns the resolved boiler description. + + Hard-won mechanism (supersedes the old "PCDB disabled" note): + 1. The PCDF reference textbox is only writable while the main heating CODE + is empty — call `clear_main_heating_code(page)` first. + 2. The index must be entered via REAL keyboard + Tab. A JS-set `.value` + does NOT survive the field's AutoPostBack, so the boiler never + resolves (the original failure mode). Ctrl-A + type + Tab works. + 3. The `TextBoxPCDFBoilerReference` direct-entry path is far simpler than + the magnifying-glass grid (whose modal has no layout box, so + mouse/Playwright clicks can't target rows). The grid search DOES work + (JS-focus the FullSearch box + `keyboard.type` + fire + HyperLinkActionBoilerSearch → "Ref No" column == the PCDB index) if a + name lookup is ever needed, but direct entry is preferred.""" + fld = f"{MH1}TextBoxPCDFBoilerReference" + page.evaluate( + "(id)=>{const e=document.getElementById(id);if(e){e.focus();e.select();}}", fld + ) + page.wait_for_timeout(SETTLE_MS) + page.keyboard.press("Control+a") + page.keyboard.type(str(pcdb_index), delay=40) + page.keyboard.press("Tab") + page.wait_for_timeout(SETTLE_MS * 5) # AutoPostBack resolves the PCDB record + return page.evaluate( + """()=>{const e=document.querySelector('[id*=LabelMHSSapCodeDescription]'); + return e?e.innerText.trim():'';}""" + ) + + def read_default_uvalue( page: Page, suffix: Optional[str] = None, label_regex: str = r"Default U-value" ) -> Optional[float]: From 5e7e51d8b2e12262c27bc84c66c4a148f2969363 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 09:11:38 +0000 Subject: [PATCH 26/84] =?UTF-8?q?An=20electric=20room=20heaters=20override?= =?UTF-8?q?=20sets=20the=20room-heater=20heating=20category=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../epc/test_main_heating_system_overlay.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/domain/epc/test_main_heating_system_overlay.py b/tests/domain/epc/test_main_heating_system_overlay.py index dae992cba..27eb6625b 100644 --- a/tests/domain/epc/test_main_heating_system_overlay.py +++ b/tests/domain/epc/test_main_heating_system_overlay.py @@ -58,6 +58,22 @@ def test_electric_room_heaters_assume_a_dual_economy7_meter() -> None: assert simulation.heating.meter_type == "Dual" +def test_electric_room_heaters_overlay_the_room_heater_category() -> None: + # A landlord "Electric room heaters" override replaces the lodged system, so + # the overlay must stamp the room-heater heating category (SAP Table 4a + # Category 10). Leaving it unset lets a replaced storage heater's category 7 + # survive onto the effective cert, which the SAP 10.2 Table 12a resolver + # (keyed on category) mis-reads as off-peak storage and bills the peaky room + # heaters at the all-night low rate. + # Act + simulation = main_heating_overlay_for("Electric room heaters", 0) + + # Assert — SAP Table 4a Category 10 (Room heaters). + assert simulation is not None + assert simulation.heating is not None + assert simulation.heating.main_heating_category == 10 + + @pytest.mark.parametrize( ("main_heating_value", "code"), [ From bf032d17d09d571ba1ef10804f6c23011993c666 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 09:12:19 +0000 Subject: [PATCH 27/84] =?UTF-8?q?An=20electric=20room=20heaters=20override?= =?UTF-8?q?=20sets=20the=20room-heater=20heating=20category=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Category 10 (SAP Table 4a Room heaters) now overlaid for electric room heaters (691-701), so a replaced storage heater's category 7 no longer survives onto the effective cert and mis-bills via the Table 12a resolver. Co-Authored-By: Claude Opus 4.8 --- domain/epc/property_overlays/main_heating_system_overlay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/epc/property_overlays/main_heating_system_overlay.py b/domain/epc/property_overlays/main_heating_system_overlay.py index 466466594..2e046dd90 100644 --- a/domain/epc/property_overlays/main_heating_system_overlay.py +++ b/domain/epc/property_overlays/main_heating_system_overlay.py @@ -280,7 +280,7 @@ def _category_for(code: int) -> Optional[int]: category 7); without it a storage override left a stale category behind, which the SAP 10.2 Table 12a resolver (keyed on category) could misread as a non-storage system and price the off-peak storage heating at the peak rate.""" - if code in _CATEGORY_10_ROOM_HEATER_CODES: + if code in _CATEGORY_10_ROOM_HEATER_CODES or code in _ELECTRIC_ROOM_HEATER_CODES: return _ROOM_HEATER_CATEGORY if code in _STORAGE_HEATER_CODES: return _STORAGE_HEATER_CATEGORY From dee72bbdfa34a83f00ab0307a789a73a55d26f9c Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 09:12:19 +0000 Subject: [PATCH 28/84] =?UTF-8?q?fix(rdsap):=20=C2=A75=20(12)=20floor=20in?= =?UTF-8?q?filtration=20falls=20back=20to=20floors[].description?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _has_suspended_timber_floor_per_spec only read the Main bp's per-part floor_construction_type lodgement; the gov-API mapper frequently leaves that None even when the global epc.floors[].description carries an explicit "Suspended, ..." observation. _main_floor_u_value already fell back to this joined description for the U-value calc — the infiltration rule did not, so a genuinely suspended-timber floor silently entered (12)=0 instead of 0.2 unsealed. Extracted the shared _effective_floor_description helper and added a tri-state resolver (explicit lodgement -> description, excluding "not timber" -> Table 19 footnote-1 age-A/B default) so both paths agree. Cert 100061275133 (Elmhurst-validated build, PR #1439 handoff): engine 77.24 -> 76.33, now an exact match to lodged (76). Corpus gauge 77.7% -> 77.8% within-0.5, MAE 0.637 -> 0.636; floors ratcheted. Co-Authored-By: Claude Fable 5 --- .../sap10_calculator/rdsap/cert_to_inputs.py | 97 +++++++++++++++---- .../rdsap/test_cert_to_inputs.py | 74 ++++++++++++++ .../test_real_cert_sap_accuracy.py | 34 ++++--- .../epc_client/test_sap_accuracy_corpus.py | 15 ++- 4 files changed, 185 insertions(+), 35 deletions(-) diff --git a/domain/sap10_calculator/rdsap/cert_to_inputs.py b/domain/sap10_calculator/rdsap/cert_to_inputs.py index 27451560e..5d87f80cd 100644 --- a/domain/sap10_calculator/rdsap/cert_to_inputs.py +++ b/domain/sap10_calculator/rdsap/cert_to_inputs.py @@ -5321,6 +5321,35 @@ _AGE_BANDS_A_TO_E: Final[frozenset[str]] = frozenset({"A", "B", "C", "D", "E"}) _SUSPENDED_TIMBER_FLOOR_TYPE: Final[str] = "Suspended timber" _GROUND_FLOOR_TYPE: Final[str] = "Ground floor" _FLOOR_U_SEALED_THRESHOLD: Final[float] = 0.5 +# Table 19 footnote (1): age bands whose default floor_construction is +# suspended timber when the construction is unknown. Mirrors +# `_SUSPENDED_TIMBER_DEFAULT_BANDS` in rdsap_uvalues.py — duplicated +# locally rather than cross-imported (private symbol) per this module's +# existing convention (see `_main_floor_u_value`). +_TABLE_19_FOOTNOTE_1_SUSPENDED_TIMBER_BANDS: Final[frozenset[str]] = frozenset({"A", "B"}) + + +def _effective_floor_description( + epc: EpcPropertyData, main: SapBuildingPart, +) -> Optional[str]: + """Mirror `heat_transmission_section_from_cert`'s + `effective_floor_description` rule: the per-bp `floor_construction_type` + lodgement ("Suspended timber" / "Solid") takes precedence over the + global `epc.floors[].description` since it's the explicit per-part + Elmhurst Summary §3/§9 lodgement. Falls back to the joined global + description when the per-bp field is unlodged (the gov-API mapper + often leaves it `None`). Inlined (vs importing from + heat_transmission) to keep cert_to_inputs free of cross-module + private symbol imports. + """ + if main.floor_construction_type: + return main.floor_construction_type + descs = [ + d for d in + (getattr(f, "description", None) for f in (epc.floors or [])) + if d + ] + return " | ".join(descs) if descs else None def _main_floor_u_value(epc: EpcPropertyData) -> Optional[float]: @@ -5357,21 +5386,6 @@ def _main_floor_u_value(epc: EpcPropertyData) -> Optional[float]: int(raw_floor_ins) if isinstance(raw_floor_ins, (int, float)) else (0 if raw_floor_ins == "NI" else None) ) - # Mirror heat_transmission's `effective_floor_description`: the per-bp - # `floor_construction_type` takes precedence over a joined - # `epc.floors[].description` since the per-part lodgement is the - # explicit Elmhurst Summary §3/§9 surface. Inline the join (vs - # importing from heat_transmission) to keep cert_to_inputs free of - # cross-module private symbol imports. - if main.floor_construction_type: - effective_floor_description = main.floor_construction_type - else: - descs = [ - d for d in - (getattr(f, "description", None) for f in (epc.floors or [])) - if d - ] - effective_floor_description = " | ".join(descs) if descs else None return u_floor( country=Country.from_code(epc.country_code) if epc.country_code else None, age_band=main.construction_age_band, @@ -5380,10 +5394,49 @@ def _main_floor_u_value(epc: EpcPropertyData) -> Optional[float]: area_m2=ground_fd.total_floor_area_m2, perimeter_m=ground_fd.heat_loss_perimeter_m, wall_thickness_mm=main.wall_thickness_mm, - description=effective_floor_description, + description=_effective_floor_description(epc, main), ) +def _floor_construction_is_suspended_timber( + epc: EpcPropertyData, main: SapBuildingPart, +) -> bool: + """RdSAP 10 Table 19 footnote (1) construction resolution for the §5 + (12) floor-infiltration rule. Tri-state, mirroring `u_floor`'s + `_floor_is_suspended_from_description` / `_SUSPENDED_TIMBER_DEFAULT_ + BANDS` cascade (rdsap_uvalues.py) so the (12) infiltration rule and + the floor U-value calc agree on which floors are suspended timber: + + 1. An explicit construction lodgement (`_effective_floor_description` + — per-bp `floor_construction_type` else the joined + `epc.floors[].description`) decides: "Suspended, ..." is timber + UNLESS it's "Suspended, not timber" (suspended concrete etc. has + no floorboard-gap infiltration); "Solid, ..." is not suspended. + 2. No description signal AND no lodged `floor_construction` code at + all → Table 19 footnote (1): unknown construction defaults to + suspended timber only for age bands A/B. + """ + desc = _effective_floor_description(epc, main) + if desc is not None: + d = desc.strip().lower() + if d.startswith("suspended"): + return "not timber" not in d + if d.startswith("solid"): + return False + ground_fd = next( + (fd for fd in main.sap_floor_dimensions if fd.floor == 0), + main.sap_floor_dimensions[0] if main.sap_floor_dimensions else None, + ) + construction_known = ( + ground_fd is not None + and _int_or_none(ground_fd.floor_construction) is not None + ) + if construction_known: + return False + age = (main.construction_age_band or "").strip().upper() + return age in _TABLE_19_FOOTNOTE_1_SUSPENDED_TIMBER_BANDS + + def _has_suspended_timber_floor_per_spec( epc: EpcPropertyData, ) -> tuple[bool, bool]: @@ -5409,9 +5462,13 @@ def _has_suspended_timber_floor_per_spec( infiltration 0.2. The rule only applies when the Main bp's lowest floor is a - "Ground floor" with "Suspended timber" construction. All other - combinations fall through to `(False, False)` and the cascade - enters 0 for (12). + "Ground floor" with "Suspended timber" construction. Construction is + resolved the same tri-state way `u_floor` resolves it (RdSAP 10 + Table 19 footnote 1): the explicit per-bp `floor_construction_type` / + joined `epc.floors[].description` lodgement, else — when neither + lodges a construction signal — the footnote-1 age-band default + (suspended timber for bands A/B only). All other combinations fall + through to `(False, False)` and the cascade enters 0 for (12). """ if not epc.sap_building_parts: return False, False @@ -5421,7 +5478,7 @@ def _has_suspended_timber_floor_per_spec( return True, False if main.floor_type != _GROUND_FLOOR_TYPE: return False, False - if main.floor_construction_type != _SUSPENDED_TIMBER_FLOOR_TYPE: + if not _floor_construction_is_suspended_timber(epc, main): return False, False age = (main.construction_age_band or "").strip().upper() if age in _AGE_BANDS_F_TO_M: diff --git a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py index d6a3c1cdc..e387c73c9 100644 --- a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py +++ b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py @@ -27,6 +27,7 @@ from datatypes.epc.surveys.elmhurst_site_notes import ( ) from datatypes.epc.domain.epc_property_data import ( + EnergyElement, EpcPropertyData, MainHeatingDetail, PhotovoltaicArray, @@ -1891,6 +1892,79 @@ def test_main_floor_u_value_routes_suspended_timber_via_floor_construction_type( assert sealed is False +def test_has_suspended_timber_floor_per_spec_falls_back_to_floors_description() -> None: + """RdSAP 10 §5 (12) reads the Main bp's `floor_construction_type` + lodgement, but the gov-API mapper often leaves that field `None` + while the global `epc.floors[].description` still carries the + assessor's "Suspended, ..." observation (cert 100061275133: Main bp + `floor_construction_type=None`, `epc.floors[0].description= + "Suspended, no insulation (assumed)"`). `_main_floor_u_value` already + falls back to this joined description (`effective_floor_description`); + the (12) infiltration rule must apply the same fallback so a + suspended-timber ground floor doesn't silently enter (12)=0.""" + from dataclasses import replace + # Arrange + main = replace( + make_building_part( + construction_age_band="B", + floor_dimensions=[make_floor_dimension(floor=0)], + ), + floor_type="Ground floor", + floor_construction_type=None, + ) + epc = make_minimal_sap10_epc(sap_building_parts=[main]) + epc.floors = [ + EnergyElement( + description="Suspended, no insulation (assumed)", + energy_efficiency_rating=0, + environmental_efficiency_rating=0, + ), + ] + + # Act + has_susp, sealed = _has_suspended_timber_floor_per_spec(epc) + + # Assert — description signal routes to the suspended-timber branch; + # band B is A-E with no supplied U-value and no retrofit insulation + # signal, so rule (b) applies "unsealed" → (12) = 0.2. + assert has_susp is True + assert sealed is False + + +def test_has_suspended_timber_floor_per_spec_excludes_suspended_not_timber() -> None: + """"Suspended, not timber" (e.g. suspended concrete) starts with the + same "Suspended" prefix as timber floors but must NOT trigger the + §5 (12) rule — the rule is specifically about air infiltration + through timber floorboard gaps (see the API mapper's + `_API_FLOOR_CONSTRUCTION_TO_STR` comment: "only 'Suspended timber' + triggers the §5 (12)... adjustment").""" + from dataclasses import replace + # Arrange + main = replace( + make_building_part( + construction_age_band="B", + floor_dimensions=[make_floor_dimension(floor=0)], + ), + floor_type="Ground floor", + floor_construction_type=None, + ) + epc = make_minimal_sap10_epc(sap_building_parts=[main]) + epc.floors = [ + EnergyElement( + description="Suspended, not timber", + energy_efficiency_rating=0, + environmental_efficiency_rating=0, + ), + ] + + # Act + has_susp, sealed = _has_suspended_timber_floor_per_spec(epc) + + # Assert + assert has_susp is False + assert sealed is False + + def test_rdsap_extract_fans_default_per_table_5() -> None: # Arrange — RdSAP 10 §4.1 Table 5 (PDF p.28) "Extract fans" default # when the lodged number is unknown. The Summary §12.0 "No. of diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index e57859941..e1877c598 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -867,23 +867,31 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( # 2-storey SEMI-DETACHED HOUSE, band B, SOLID BRICK 400 mm with EXTERNAL # insulation, pitched 300 mm loft, SUSPENDED uninsulated ground floor, # mains-gas COMBI, double glazing (glazed_type 13, 2022+), TFA 78. - # Lodged 76 / engine 77 (77.24). Built in accredited Elmhurst RdSAP10 - # (evidence saved: elmhurst_summary.pdf / elmhurst_worksheet.pdf): the - # checkable FABRIC matches the engine closely — ROOF (300 mm loft, U 0.14) - # and WINDOWS (15.32 m² × eff U 1.3258 = 20.3106 W/K) match EXACTLY; the - # externally-insulated WALL is U 0.29 (engine) vs 0.30 (Elmhurst) — which - # VALIDATES the slice-5 external-insulation default (100 mm added over solid - # brick, `_WALL_ADDED_INSULATION_UNKNOWN_THICKNESS_MM`); the suspended - # ground floor is U 0.68 (engine) vs 0.70 (Elmhurst). (Elmhurst''s overall - # worksheet SAP 67 is NOT comparable — the reused-assessment combi entered - # as a "Standard Combi" carries a ~50 kWh/month Table-3a keep-hot loss the - # lodged assessment did not, a build-side heating artifact, not an engine - # gap.) Engine 77 sits within 1.24 of lodged; PINNED to the observed 77. + # Lodged 76 / engine 76 (76.33, was 77.24 before the §5 (12) fix below). + # Built in accredited Elmhurst RdSAP10 (evidence saved: elmhurst_summary.pdf + # / elmhurst_worksheet.pdf): the checkable FABRIC matches the engine + # closely — ROOF (300 mm loft, U 0.14) and WINDOWS (15.32 m² × eff U + # 1.3258 = 20.3106 W/K) match EXACTLY; the externally-insulated WALL is + # U 0.29 (engine) vs 0.30 (Elmhurst) — which VALIDATES the slice-5 + # external-insulation default (100 mm added over solid brick, + # `_WALL_ADDED_INSULATION_UNKNOWN_THICKNESS_MM`); the suspended ground + # floor is U 0.68 (engine) vs 0.70 (Elmhurst). (Elmhurst''s overall + # worksheet SAP is NOT comparable — the reused-assessment combi entered + # as a "Standard Combi" carries a Table-3a keep-hot loss the lodged + # assessment did not, a build-side heating artifact, not an engine gap.) + # §5 (12) fix: the Main bp lodges no `floor_construction_type` (gov-API + # leaves it None), but `epc.floors[0].description` = "Suspended, no + # insulation (assumed)" — `_has_suspended_timber_floor_per_spec` was + # only reading the per-bp field and silently entered (12)=0 for a + # genuinely suspended-timber floor. Now falls back to the joined + # description (mirroring `_main_floor_u_value`'s existing fallback), + # applying (12)=0.2 unsealed; engine converges EXACTLY on lodged (76). + # PINNED to the observed exact match. RealCertExpectation( schema="RdSAP-Schema-21.0.1", sample="uprn_100061275133", cert_num="uprn-100061275133", - sap_score=77, + sap_score=76, ), # UPRN 100051051866 (corpus; no cert number lodged). RdSAP-21.0.1 native — # DETACHED BUNGALOW, band I, CAVITY wall as-built insulated, pitched diff --git a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py index 345f426e5..ff14c1fa7 100644 --- a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py +++ b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py @@ -237,7 +237,9 @@ _CORPUS = Path( # 69.51 -> 74.34 = lodged 74, VALIDATED against the accredited Elmhurst # worksheet ("insulated flat roof" U 0.5). within 77.3% -> 77.7%, PE 3.1 -> # 2.97, CO2 0.074 -> 0.072. -_MIN_WITHIN_HALF_SAP = 0.777 +# 77.7% -> 77.8% via the §5 (12) suspended-timber floor-infiltration +# fallback (see the `_MAX_SAP_MAE` note below for the mechanism). +_MIN_WITHIN_HALF_SAP = 0.778 # 0.793 -> 0.789 via the §12 Unknown-meter + dual-electric-immersion off-peak # trigger (RdSAP 10 PDF p.62): Apartment 241 (main 691 + 903 dual immersion) # -5.38 -> -1.05. Worksheet-validated on "simulated case 48" (Elmhurst SAP 57, @@ -323,7 +325,16 @@ _MIN_WITHIN_HALF_SAP = 0.777 # (U~1.4) -> ~0.29, PE +59.6 -> ~0, SAP 64.35 -> 71.74 (lodged 71). Scoped to # brick/stone (the only §5.8 R-value path); within-0.5 held at 77.0%, MAE # 0.658 -> 0.647, PE 3.2 -> 3.1. Unit-pinned in test_rdsap_uvalues. -_MAX_SAP_MAE = 0.641 +# 77.7% -> 77.8% (MAE 0.637 -> 0.636) via the §5 (12) suspended-timber +# floor-infiltration fallback: `_has_suspended_timber_floor_per_spec` +# only read the Main bp's per-part `floor_construction_type` lodgement, +# which the gov-API mapper frequently leaves `None` even when the global +# `epc.floors[].description` carries an explicit "Suspended, ..." +# observation (`_main_floor_u_value` already fell back to this joined +# description for the U-value calc — the infiltration rule did not). +# Cert 100061275133 (Elmhurst-validated build): SAP 77.24 -> 76.33, now +# an EXACT match to lodged (76). Unit-pinned in test_cert_to_inputs. +_MAX_SAP_MAE = 0.637 _MAX_CO2_MAE_TONNES = 0.072 # t CO2 / yr vs co2_emissions_current _MAX_PE_PER_M2_MAE = 3.0 # kWh / m2 / yr vs energy_consumption_current From cfd979950015bb61324337b7ce19078cc8381007 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 09:13:03 +0000 Subject: [PATCH 29/84] =?UTF-8?q?An=20electric=20room=20heaters=20override?= =?UTF-8?q?=20sets=20the=20room-heater=20charge=20control=20=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../epc/test_main_heating_system_overlay.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/domain/epc/test_main_heating_system_overlay.py b/tests/domain/epc/test_main_heating_system_overlay.py index 27eb6625b..dff74bccf 100644 --- a/tests/domain/epc/test_main_heating_system_overlay.py +++ b/tests/domain/epc/test_main_heating_system_overlay.py @@ -74,6 +74,22 @@ def test_electric_room_heaters_overlay_the_room_heater_category() -> None: assert simulation.heating.main_heating_category == 10 +def test_electric_room_heaters_overlay_the_room_heater_charge_control() -> None: + # A system-replacing override must stamp its own control, not inherit the + # replaced system's. Electric room heaters take the Table 4e Group 6 + # room-heater control 2601 (+0.3 C, the conservative no-thermostat default, + # matching the gas/oil/solid room heaters). Leaving it unset lets a replaced + # storage heater's manual charge control 2401 (+0.7 C) survive and over-warm + # the modelled dwelling. + # Act + simulation = main_heating_overlay_for("Electric room heaters", 0) + + # Assert — SAP Table 4e Group 6 room-heater control. + assert simulation is not None + assert simulation.heating is not None + assert simulation.heating.main_heating_control == 2601 + + @pytest.mark.parametrize( ("main_heating_value", "code"), [ From ffd21689fd96d05b82c2cd127d2097c06f8f1d22 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 09:13:32 +0000 Subject: [PATCH 30/84] =?UTF-8?q?An=20electric=20room=20heaters=20override?= =?UTF-8?q?=20sets=20the=20room-heater=20charge=20control=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Control 2601 (SAP Table 4e Group 6 room-heater, +0.3 C conservative default) now overlaid for electric room heaters, matching the gas/oil/ solid siblings, so a replaced storage heater's manual charge control 2401 (+0.7 C) no longer survives and over-warms the modelled dwelling. Co-Authored-By: Claude Opus 4.8 --- domain/epc/property_overlays/main_heating_system_overlay.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain/epc/property_overlays/main_heating_system_overlay.py b/domain/epc/property_overlays/main_heating_system_overlay.py index 2e046dd90..9782174e3 100644 --- a/domain/epc/property_overlays/main_heating_system_overlay.py +++ b/domain/epc/property_overlays/main_heating_system_overlay.py @@ -266,7 +266,7 @@ def _control_for(code: int) -> Optional[int]: return _MANUAL_CHARGE_CONTROL if code in _GAS_BOILER_CODES: return _FULL_BOILER_CONTROL - if code in _CATEGORY_10_ROOM_HEATER_CODES: + if code in _CATEGORY_10_ROOM_HEATER_CODES or code in _ELECTRIC_ROOM_HEATER_CODES: return _ROOM_HEATER_CONTROL return None From ea113b58fbb03380d701116041a562975cd872cb Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 09:15:31 +0000 Subject: [PATCH 31/84] =?UTF-8?q?The=20overlay=20logs=20an=20error=20when?= =?UTF-8?q?=20it=20cannot=20complete=20a=20heating=20companion=20set=20?= =?UTF-8?q?=F0=9F=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../epc/test_main_heating_system_overlay.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/domain/epc/test_main_heating_system_overlay.py b/tests/domain/epc/test_main_heating_system_overlay.py index dff74bccf..266e14415 100644 --- a/tests/domain/epc/test_main_heating_system_overlay.py +++ b/tests/domain/epc/test_main_heating_system_overlay.py @@ -6,6 +6,8 @@ calculator reads from the primary system; the overlay is whole-dwelling. from __future__ import annotations +import logging + import pytest from domain.epc.property_overrides.main_heating_system_type import MainHeatingSystemType @@ -90,6 +92,22 @@ def test_electric_room_heaters_overlay_the_room_heater_charge_control() -> None: assert simulation.heating.main_heating_control == 2601 +def test_overlay_logs_when_it_cannot_complete_a_companion_set( + caplog: pytest.LogCaptureFixture, +) -> None: + # An archetype the overlay cannot yet fully companion — here an air-source + # heat pump, whose Table 4e Group 2 conservative control is not yet mapped — + # is still overlaid (log-and-continue), but the incomplete companion set is + # logged as an error so the known gap is visible (CloudWatch) rather than + # silently inheriting the replaced system's stale value. + # Act + with caplog.at_level(logging.ERROR): + main_heating_overlay_for("Air source heat pump", 0) + + # Assert — the gap is reported and names the archetype. + assert "Air source heat pump" in caplog.text + + @pytest.mark.parametrize( ("main_heating_value", "code"), [ From 390e3e89d791a765ea0dd0be4acffbb313557d6f Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 09:16:25 +0000 Subject: [PATCH 32/84] =?UTF-8?q?The=20overlay=20logs=20an=20error=20when?= =?UTF-8?q?=20it=20cannot=20complete=20a=20heating=20companion=20set=20?= =?UTF-8?q?=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A system-replacing override whose category or control is not yet mapped now logs an error naming the archetype and code, so the incomplete companion set (which otherwise silently inherits the replaced system's value) is visible for review — log-and-continue, matching flag_fuel_mismatch. Co-Authored-By: Claude Opus 4.8 --- .../main_heating_system_overlay.py | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/domain/epc/property_overlays/main_heating_system_overlay.py b/domain/epc/property_overlays/main_heating_system_overlay.py index 9782174e3..d0c498320 100644 --- a/domain/epc/property_overlays/main_heating_system_overlay.py +++ b/domain/epc/property_overlays/main_heating_system_overlay.py @@ -28,6 +28,7 @@ are left UNKNOWN until modelled. Unresolvable values produce no overlay. from __future__ import annotations +import logging from typing import Optional from domain.modelling.simulation import EpcSimulation, HeatingOverlay @@ -35,6 +36,8 @@ from domain.sap10_calculator.tables.table_12a import ( OFF_PEAK_IMPLYING_HEATING_CODES, ) +logger = logging.getLogger(__name__) + # Off-peak (Economy 7) meter. Electric storage / CPSU systems charge overnight at # the low rate and cannot run economically on a single-rate meter; "Dual" lets # the §12 dispatch resolve the specific tariff (storage 7-hour, CPSU 10-hour). @@ -351,13 +354,32 @@ def main_heating_overlay_for( return None if code in _GAS_BOILER_CODES: return EpcSimulation(heating=_gas_boiler_overlay(code)) + category = _category_for(code) + control = _control_for(code) + if category is None or control is None: + # A system-replacing override should stamp a complete, coherent companion + # set; an unmapped category or control leaves the field unset, so the + # effective cert inherits the REPLACED system's value (a silent mis-rating + # — e.g. a room heater keeping a storage heater's category/control). We do + # not yet have confident defaults for every archetype, so log-and-continue + # (matching `flag_fuel_mismatch`) to make the gap visible for review + # rather than raise mid-run. + logger.error( + "Landlord main_heating_system %r (SAP code %d) overlaid with an " + "incomplete companion set (category=%s, control=%s); the effective " + "cert may inherit the replaced system's value — known gap, review", + main_heating_value, + code, + category, + control, + ) return EpcSimulation( heating=HeatingOverlay( sap_main_heating_code=code, - main_heating_category=_category_for(code), + main_heating_category=category, main_fuel_type=_natural_fuel_for(code), meter_type=_meter_for(code), - main_heating_control=_control_for(code), + main_heating_control=control, # A landlord override describes the existing dwelling, so its assumed # off-peak meter must not downgrade a more-off-peak cert meter # (e.g. a 24-hour all-low tariff). Measures, which re-meter for real, From 962a443ed223920205390f8d9d938d74784fb726 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 09:17:06 +0000 Subject: [PATCH 33/84] =?UTF-8?q?A=20complete=20room-heater=20overlay=20do?= =?UTF-8?q?es=20not=20log=20a=20companion=20gap=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../domain/epc/test_main_heating_system_overlay.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/domain/epc/test_main_heating_system_overlay.py b/tests/domain/epc/test_main_heating_system_overlay.py index 266e14415..40998c7d7 100644 --- a/tests/domain/epc/test_main_heating_system_overlay.py +++ b/tests/domain/epc/test_main_heating_system_overlay.py @@ -108,6 +108,20 @@ def test_overlay_logs_when_it_cannot_complete_a_companion_set( assert "Air source heat pump" in caplog.text +def test_complete_room_heater_overlay_does_not_log_a_companion_gap( + caplog: pytest.LogCaptureFixture, +) -> None: + # Electric room heaters now resolve a full companion set (category 10 + + # control 2601), so the overlay must NOT log an incomplete-companion gap — + # guarding that the fix keeps the set complete. + # Act + with caplog.at_level(logging.ERROR): + main_heating_overlay_for("Electric room heaters", 0) + + # Assert + assert "incomplete companion set" not in caplog.text + + @pytest.mark.parametrize( ("main_heating_value", "code"), [ From 6c1828e8bfbef40c37309a141762a0e0ff4e8251 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 09:20:12 +0000 Subject: [PATCH 34/84] =?UTF-8?q?chore(hyde):=20fix=20100061275133=20Elmhu?= =?UTF-8?q?rst=20build=20=E2=80=94=200=20fans=20+=20PCDB=20exact=20boiler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ventilation(): the cert lodges no extract-fan count and RdSAP 10 Table 5's age-band B default is 0, but the build entered 1 — inflating Elmhurst's own (8)/(21) infiltration lines relative to both the cert and our engine. space_heating(): switched from the generic "Combi condens" SAP-Table dialog code (84% efficiency, no PCDB record) to elmhurst_lib.set_pcdb_boiler(18908) via clear_main_heating_code — resolves the exact lodged product (Worcester Greenstar 4000, 88.70%) and its correct keep-hot classification (None), matching the SAP engine's own PCDB lookup and removing the "Standard Combi" keep-hot artifact the reused generic code carried. Also corrected the file's stale docstring (described a different property entirely — mid-terrace/250mm/DUAL meter/11 windows/lodged 63 — left over from a copy-paste). Verified against the refreshed worksheet: (21) shelter-adjusted ACH 0.6938 now EXACT vs our engine's ventilation_from_cert; (61) combi loss monthly kWh matches ours to ~0.01 kWh (was carrying a ~360 kWh/yr keep-hot artifact). Both open items from the PR #1439 handoff are resolved. Co-Authored-By: Claude Fable 5 --- .../uprn_100061275133/elmhurst_summary.pdf | Bin 64270 -> 64269 bytes .../uprn_100061275133/elmhurst_worksheet.pdf | Bin 44442 -> 44397 bytes scripts/hyde/build_100061275133.py | 36 +++++++++--------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf index 2d86d5cee0da69bd02e725ce050234620988a2fb..4a604044ab732415a3a4bc543eb9516f8d87c93d 100644 GIT binary patch delta 2370 zcmZXLc{~#i1BaWVmN_Cdnlg;sW^5Ld-1i+Jxk4G1hM$}>XDa9BJ{MY=B1>Ws>vd(x zm6T|O$Q>rp_I$p;7wl($8Lp|R; zcPXTxv{spfi8a`d4Ldijq}YU4ZP&o=HuG&7H{dr%y`*S2ZE(D6-x4bvtcpRDS+!MH zwPuJU&(v8`D#96G{RU5|>~B{-8-yt3;KLUQnxbZxnLU=p+cfB`@IvO#T}Al-J;g{X z9BnRnwS`U|4#o%>zj*5;Ae%hV%?@*au5Yu-v4ND^N@ZsAC1%$yM1==q`P$E=wa}&V z)+dc>`!{OFOk2Bd@E7Z=WG_w)5T&(cKG)YK5BnNFZLHO85LEQY8}8NfgBCQkmevs( zfj+BR;$XjU8@`tV)>U>FV+0vKda!cR?Y1wDd@nr}OaVu0pkJo*sVa|IEx+28cNj2D z5ix$HP1VuVfq>dB6=_c|={X)%fLIL!bgVI)s24pCfGylJX&)YmJ_Imu$x#^0)7ED$ z1NU#J{^*dPe2cuN9lYn4GMt&5BtfW+Cm94eKj}+VcgZ`s=dvOtWui#3U*SKXWVU1N z2IEr$+kZ{s)2;{yIp+imdyUEhLLckhWThSwS(t2Mmq3W#XFHRhA#k~`<8(h*Lu`NT z#^y`tN6MMY;=;jpqB73!KvkuBdSG7-di0~FI*^=s(9&v|pbM&D?DOyo34$Qm@@W{w z|4LPSE8|sUwGk97yjUG_kxYtPyanU?b1G+NnZ#QvZM}@Tl9jYo-z5i5r^$>y`NN>&!+Q!!r}h9tLjlAtoP8vWrqSiad@kaJ>N!^rh3Z9kzC zmj~ya#dnYQotk@-2?kubWkM*F?)gohc`S<72ymvJ>z==YN57-7I2hn}X3}KigSN~_ zSIOSejP=S&tx&s-{+bx8XVwavj@&bl{1aHebTqeMUXh z^IA9QNvp=iA3d2rKO59`DN#R1$z;J$zfHjW#kzD^_z9}^vw9*Zm@rYBvzc0f5tAr6 z$|9K@@P2)cJBBZ`AQ=`OyJ%L$)2fuUQ!YT;ay06b86Njn-Cd(%hzZcj z+zdn@znXf#iptrWL1Xf3Np7!AD;sVr3xrjKB0k$B+RX;?q{V_flhsdncew^=UBqTh2cXEHZ~g<&xA%S=)>a$@dTKe6f(xcrB%yT+vvhvzCUu9}8joo}OF?s&Ze9 zmt-44P$Ly^01x()oN_fATBxrkZcqjuoIrO8~I(i=ps;;2DC(v7y+ZpQje`$fMjM3LCDH) zaQACgf+4Zo!tQiK`%}MjvuXB>@yiKr(53Qb+^m#xHp)OeLhVR}KpVDmdA=C(C(^f9 zsX9aUIPCkpS3}w)ep~wedHPEXmOf6nxR*$1q5!`>M8!XI*_J;MCnvTO+;Z!=`Waq@ zdNEG=5R_|xFIETV6Jz7uMWU-u*z^u036cW*E}z}=0ID2L;9^SU;V43Xp4iKu#Cuj7 z!5w`93*mQQ^l*KDMz4s!TmGS2gSM@S2HHOLiGI0>UFn6Yu#Ls~^Q?ogy_5$60XX`n zS?9xqvKy^AxHK&D*5HMQ{;O$1jC`Vu(W0%5Fz%c+LN?pZL^& zrObkcEheWOrBZ#~+*fm#rhR1XGo^*QKA6_WiYTVGh8(ZabE#0q1auWJqprH9Qpu$P z_Cwc-RcB;vt2E*NnU;?j`M}i5l*s=2AitfU0VRh>W2cJr{W0hWGgpLGd+LY9d_&;La&cuwPHp9% z!a$43A>MI!R*wdb`)g6t!K1(^nYlExe4eui|hyJ#=K%JGTG3Q8S~T)8(gWMyNqXmRUV8(n6qX-~%AEPKX(^Zz4=N|<)Qb-T1CSMJBbhv;^ekP3_J81wdtGQ2+n{ delta 2370 zcmZXLc|6mN1IKfR94$FU4Re-ACh8$DYdYm!L^|%r_9{IASx!Q;pEk)$WksNbh zqr(}kEw}j1BT9>jkUX#7@6Uekzdo<`>+`;|%}3his~?`@F~}R4lLu7ZTs7H%HhWH8 z`{Svxfmts|)7Z>wO0?4*da+ON0PLVEmV0l z^wX$rXYFzhVIk1OaYg-}X0>7R**CN930|B>JM`cabZT>r5h6^Z9Q=%%CV)Jv_aoj; zYrxg~yZ%W)nrFoO_L5Z%IU^+wDe%5(jD(d5BbHqUp$|8kN%80cU`F$x<}J$U9$c7LHL_utrIw) zN7iL@7Rl(^?Y6I#+s}m_Z%LD=NYAaRP#t&fD$1(AziYtQoh0U#HpRxF_DmjYZ@p)< z$^ysoLyWm40pZ0r+d6u_ms%-8#KBL(E?+72`;wr-{}Y_c{*ou;Sz!MK?nA~-MhT93 zUHCQb9!N3IzecsM%R~zEtj>t}X^;nz9#?WS#J0M9O7y=(@LS@SbOuE&LiyP*B+!KR z=R;uh?uO!|=a`JE)E@K=nE8$@!*es<2B1Q2zieEoJ&w>>_J3}y$_|f4=t#G55+p~6 z0xekT8r)!)o;dGBIQ;og{%_Z8+pLQBKLQ#gnVb@4LX}-aI<$W|Pu&z0Rk~hUHByjo zqJNsL7s7ZId)2(~!M@d>$+NO=`_bT{=pk#!lAB*1*~$Ix3!}5V=xYx5{O=^W0T`;) zSWw`Wy>GA@%mu`iAj~|o)JRfxwhgx$H%=8{S0I*l&eZ7H2$!VTc;+$JK;Fi4HwWIp zyB}vt?WOuz*-lTZHnoQURA9J)sR&OzlB3*LZME4cTM*k4VR;>O*DM{FwL7Y&Z&L#gH%A$g&Ib8_J} z^(l94otCMqIVsxh1Ccu(hzie{=Wm{wep{4Wyri(c&7;Jp@8U8mY4{)kz=-rM3y$_B ze^l(Oh-9MF78d*DMQgJC*@GOpXdkKTE;MQFq)Cm)$?O}3 zo6cpm`6$;YITyFaQ(ph9oiX+-n@aVX3eD~{G8v_&Y)qWMzCG%wVTKi6=#*!rZ-=K; zo6sg0y@6F+T#B9Zqzns^NE-6~MSO{HJDAeSj)x5hFI zv|MsfWHDdruFBwoR_G;uXH?k~x(_x`HSQJt<*i|crg8#x$x5$Se3`NoH_bGwIB(=7 za3-23!+=9g@`$x?Cqy!2m9s28A!-xP{=|+4*VQG&WsvSp+sSJCxqTjS!wWqej29J- z0}k~U1Z6qJ03k$c$_IdRXp7=Qu;QY}wFqwS&ljm%SwUPuQ6*tJkE2TDMoHe&AxeaE z!6l;=2q#t{h>v>p5VwIH&wGVcSXyJ$#8M#AgNZ@4^2Wp=|1T0^-ovRCcp4bClkg81 z@NU001b#AjG-J1oQ61_z_N%l#h;rXv>;c#zv>gLCm9e)?k-3Ju}V6!bMFpd(>yMi8nGy z@mA(fkC9E#-b207IWLK+uN!=;I%kfYlc7E6g9yS<=ZzivJ{~xhr+1oEOK>fi972-_ zu5prmSrAAU?det%-{mYlbKt193nd$&`fsC0c&6?p7bX{WWK_e~=hDTjQ3IVa&$(Ob zVe4#dR2in($)TUXK*Mkolo~QKED%_fAb$L;%<2-#r+d+a-xZy4Ir*r;*Kx5!x0;R~ za!ynK)aXRHma8@{E9=JrnXLY`SZJI5I*Ks_%*#kR&?K58Mo#OURtS|kRiXN@D~CM( zpt!2W>omoFl5_8NZ#&bmxn~7Via3#26)Lsxy8e9q%->H`7q|8WLm{I-D}>OI6KxGOZQq#E%*--Q1k7&$D1GNsp)1FtAAeN> z-flIt34~2Xi4^3XdT25p6xFa20xgN>jFFgpCT9Z@{7=?Wrs~;Je~`BIDv-Q?YgG>{ zYlRMO+;D8gn8(}g`j#fqJOa-JQ#Kxfp&G$+zLFL`2iJMxHy|d%n>aLHxrQa_Jl!*c zxfmBU)UULKnJFmKra diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_worksheet.pdf index 01308a94409d5c4dcc9e729c442ff7d1dd3727c8..9bb10c0082f2d7cef9a1b42bbb381e0be83d0ff8 100644 GIT binary patch delta 38809 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�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 diff --git a/scripts/hyde/build_100061275133.py b/scripts/hyde/build_100061275133.py index 93ddab7b7..106488c79 100644 --- a/scripts/hyde/build_100061275133.py +++ b/scripts/hyde/build_100061275133.py @@ -1,7 +1,9 @@ -"""Elmhurst build for UPRN 100061275133 (RdSAP-21.0.1, MID-TERRACE HOUSE, band B, -SOLID BRICK 250 mm uninsulated, pitched insulated (assumed) loft, floor to -UNHEATED space, mains-gas COMBI (PCDB 19008) + gas room-heater SECONDARY, DUAL -meter, 11 DG windows ~18.32 m², TFA 116. Lodged SAP 63; engine 65.0 (Δ +2.0). +"""Elmhurst build for UPRN 100061275133 (RdSAP-21.0.1, SEMI-DETACHED HOUSE, band B, +SOLID BRICK 400 mm with EXTERNAL insulation, pitched 300 mm loft, ground floor +SUSPENDED, no insulation (assumed) — no per-bp floor_construction_type lodged, +mains-gas COMBI (PCDB 18908, Worcester Greenstar 4000 88.70%), no secondary +heating, single meter, 12 DG windows ~15.32 m², TFA 78. Lodged SAP 76; engine +76 (76.33, exact match after the §5 (12) floor-infiltration fix). Per-cert Elmhurst validation. Uses set_single_window (deletes the shared assessment's carried-over window rows) + reset_transient_state at the end so the @@ -124,7 +126,10 @@ def _glazing(page): def ventilation(page): E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") E.click_tab(page, "TabContainer_TabPanelVentilationPanel") - E.set_text(page, f"{VP}TextBoxIntermittentFans", "1") + # Cert lodges no extract-fan count; RdSAP 10 Table 5 age-band default for + # band B (A-E) is 0, and our engine's ventilation_from_cert computes 0 — + # was wrongly entered as 1 here, inflating Elmhurst's (8)/(21) ACH vs ours. + E.set_text(page, f"{VP}TextBoxIntermittentFans", "0") cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") if cool.count() and cool.is_checked(): E.commit(page, cool.uncheck) @@ -142,21 +147,16 @@ def ventilation(page): def space_heating(page): + # PCDB exact-boiler entry (elmhurst_lib.set_pcdb_boiler): the cert's + # main_heating_index_number 18908 resolves to Worcester Greenstar 4000 + # GR4700iW 25 C NG, 88.70% winter efficiency — matching the SAP engine's + # PCDB lookup exactly, vs the generic "Combi condens" SAP-Table code + # (84%) the old dialog-driven entry carried a keep-hot artifact from. E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") page.wait_for_timeout(1000) - mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") - code = mhc.input_value() if mhc.count() else "" - if code and code not in ("0",): - print(f"clearing leftover MainHeatingCode {code}") - page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; - e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") - page.wait_for_timeout(400) - E.save_close(page) - return - E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", - "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", - "Combi condens") - print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.clear_main_heating_code(page) + desc = E.set_pcdb_boiler(page, 18908) + print("PCDB boiler ->", desc) E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) From 244c5b65edf0b0561cd04f7e0bb5eacb738bee5e Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Fri, 3 Jul 2026 09:21:47 +0000 Subject: [PATCH 35/84] Document heating-companion coherence: category/control forced, fuel/meter deferred (ADR-0048) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADR-0048 records why a system-replacing heating override must emit a complete companion set — category and control archetype-forced for coherence, fuel and meter deferred where multiple values are valid, and an unmapped companion logged rather than silently inherited. Adds the Heating Companion Set glossary term to CONTEXT.md. Co-Authored-By: Claude Opus 4.8 --- CONTEXT.md | 4 + ...egory-and-control-defers-fuel-and-meter.md | 132 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 docs/adr/0048-heating-override-forces-category-and-control-defers-fuel-and-meter.md diff --git a/CONTEXT.md b/CONTEXT.md index e0b4a8493..182959e66 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -103,6 +103,10 @@ _Avoid_: patches (deprecated), corrections, manual EPC, edits **Landlord-Description Classification**: Resolving a **Landlord Description** (unbounded free-text a landlord supplies for one component — "CWI" / "Cav filled" / "cavity insulated" all name one thing) onto a **Recognised Internal Description** via an LLM classifier, persisted in the `landlord_*_overrides` table (`source=classifier`) as a reviewed cache. Four vocabularies are kept **distinct** and must not be conflated: a **Landlord Description** (unbounded input); a **Recognised Internal Description** (the closed target taxonomy — e.g. a `MainHeatingSystemType` archetype — each binding to a Simulation Overlay); a **Lodged Description** (the gov-EPC `main_heating[].description` rendering, e.g. "Room heaters, electric" — only an example of which system *types* occur, never a map key); and the **SAP main heating code** (Table 4a/4b, what the calculator consumes). The classifier maps Landlord → Recognised Internal → SAP code. When it cannot confidently place the text it emits **`None`** (no overlay → the lodged EPC stands, surfaced to the user as "no suitable match"), **never the nearest wrong archetype** — the target taxonomy must be complete enough that a real system always has a correct home, so the classifier never overflows into a garbage-drawer archetype (ADR-0041). + +**Heating Companion Set**: +The coherent SAP inputs a **main heating system** override drags alongside the **SAP main heating code** so the **Effective EPC** reads as one internally-consistent system, not a hybrid of the new code and the *replaced* system's leftovers — heating **category** (SAP Table 4a group: gas→2, heat pump→4, network→6, storage→7, electric underfloor→8, warm air→9, room heater→10), **charge/heating control** (Table 4e group), **natural fuel**, and **meter** (see **Off-Peak Meter**). Companions divide by how firmly the archetype fixes them (ADR-0048): **category and control are archetype-forced** — always written, never inherited, because a wrong value silently mis-scores or mis-bills (a leftover storage **category 7** makes the Table 12a resolver bill peaky room heaters at the all-night rate; a leftover storage **control 2401** adds a +0.7 °C Table-4e penalty a room heater should not carry). **Fuel and meter defer** only where multiple values are genuinely coherent — fuel for an ambiguous carrier (community heating: gas CHP / biomass / waste heat), meter for a meter-flexible system (room heaters run on either; screed underfloor per ADR-0046) — while a meter-*locked* system still forces (storage/CPSU/HHRSH→Dual, non-electric→Single, ADR-0035). Because the overlay composes last-wins, an **unset (`None`)** forced companion is *inherited from the replaced system*, not cleared — so an archetype the overlay cannot yet fully companion (heat pump / community / underfloor / electric boiler control defaults are unmapped) is **logged as an error and continues** (log-not-raise, matching `flag_fuel_mismatch`), making the gap visible for review rather than shipping a silently-incoherent cert; the intended end-state is to fill each and flip the log to a raise. +_Avoid_: coherent companions (informal), dragged fields, heating defaults _Avoid_: "the LLM mapper is unreliable" (the failure mode is a too-small target taxonomy, not LLM language ability); conflating the landlord input vocabulary with the gov-EPC lodged rendering or the RdSAP entry-tool catalogue; treating a deterministic dict as a *replacement* for the LLM rather than a reviewed cache of its output **Lodgement Sentinels (ND / NI / AB)**: diff --git a/docs/adr/0048-heating-override-forces-category-and-control-defers-fuel-and-meter.md b/docs/adr/0048-heating-override-forces-category-and-control-defers-fuel-and-meter.md new file mode 100644 index 000000000..5b2a1870f --- /dev/null +++ b/docs/adr/0048-heating-override-forces-category-and-control-defers-fuel-and-meter.md @@ -0,0 +1,132 @@ +# A system-replacing heating override forces category and control for coherence, and defers fuel and meter where multiple values are valid + +## Status + +accepted + +## Context + +A **Landlord Override** naming a main heating system resolves to a SAP Table 4a +code, and `main_heating_system_overlay` synthesises the **coherent companions** +that code implies (ADR-0035): heating category, charge control, natural fuel, +meter. The overlay is applied over the lodged cert by last-wins composition, so a +companion the overlay leaves **unset (`None`)** is *inherited from the replaced +system* — not cleared. + +That inheritance is a silent mis-rating when the archetype genuinely determines +the companion. A portfolio-796 audit found the case end-to-end on **86+ +properties**: a lodged **slimline storage heater** (SAP 402, category 7, control +2401, off-peak) overridden to **"Electric room heaters"** (SAP 691). The overlay +stamped code 691, fuel, and a Dual meter — but `_category_for(691)` and +`_control_for(691)` both returned `None`, because their room-heater branch keyed +on `_CATEGORY_10_ROOM_HEATER_CODES`, a set that held only the *fuel-burning* +(gas/oil/solid) room heaters and **excluded electric 691–701** despite electric +room heaters also being Table 4a **Category 10**. + +Two independent mis-ratings followed from the surviving storage companions: + +1. **Category 7 survived.** The SAP 10.2 Table 12a resolver keys on category + first, read `OTHER_STORAGE_HEATERS`, and — with the dwelling on the §12 Rule 3 + 10-hour tariff — hit `(OTHER_STORAGE_HEATERS, TEN_HOUR)`, a combination the + Grid-1 table does not carry, so it fell to the all-low-rate fallback. The + peaky room heaters were billed **100% at the night rate** — the precise + "all-low over-credit" the overlay's own Dual-meter comment claims to avoid. + Effect: baseline SAP over-rated **64.1 vs the spec-correct 56.4**; the HHRSH + upgrade measure showed a **negative** bill saving (−£13/yr) because the + baseline it was compared against was itself under-billed. +2. **Control 2401 survived.** `main_heating_control` fed Table 4e as the storage + **manual charge control → +0.7 °C** mean-internal-temperature adjustment — the + largest in the table — riding on a direct-acting room heater, which should + carry the Group 6 room-heater control **2601 → +0.3 °C**. + +The companions are **not uniform** in how strongly the archetype determines +them, which is the crux of the decision: + +- **Category is deterministic** — SAP Table 4a assigns exactly one category per + code (gas→2, heat pump→4, network→6, storage→7, **electric underfloor→8**, + warm-air→9, **room heater→10**). A `None` category is never valid. +- **Control is an assumption but always archetype-supplied** — the Table 4e + *Group* is fixed by category; the specific conservative default within the + group is a modelling choice (storage→manual 2401, HHRSH→2404 per + [ADR-0044](0044-hhrsh-baseline-archetype-drags-its-intrinsic-controls.md), + room heater→2601, gas boiler→full controls). It is never "inherit the replaced + system". +- **Fuel is sometimes genuinely ambiguous** — electric/gas/storage/heat-pump + archetypes pin their fuel, but **community heating** could be gas CHP, biomass, + or waste heat, so its fuel legitimately **defers** to a `main_fuel` override, + else the lodged value (ADR-0041 last-wins). +- **Meter is physics-locked for some systems, flexible for others** — storage / + CPSU / HHRSH **require** Dual (they charge overnight); non-electric systems are + stamped Single to stop an Economy-7 split bleeding onto a gas boiler + ([ADR-0035](0035-coherent-heating-system-synthesis.md)); screed underfloor + defers to the cert ([ADR-0046](0046-electric-underfloor-scored-by-its-own-codes-meter-deferred-when-tariff-ambiguous.md)). + +## Decision + +A system-replacing heating override must emit a **complete, coherent companion +set**. Companions split by whether the archetype *determines* the value: + +1. **Category and control are archetype-forced** — always written, never + inherited, because a wrong value mis-scores or mis-bills the cert. Electric + room heaters (Table 4a 691–701) join the Category-10 room-heater branch of + both `_category_for` (→ category **10**) and `_control_for` (→ control + **2601**, the Group 6 conservative no-thermostat default, matching the + gas/oil/solid siblings). Their fuel (electricity 29) and Dual meter were + already correct and are unchanged. + +2. **Fuel and meter defer where multiple values are coherent** — this is *not* + a gap. Fuel defers only for genuinely ambiguous carriers (community heating); + meter defers only for meter-flexible systems (room heaters run coherently on + either meter; screed underfloor per ADR-0046). Meter-locked systems still + force (storage/CPSU/HHRSH → Dual; non-electric → Single). + +3. **An incomplete companion set is logged, not raised (for now).** Where the + overlay cannot yet supply a confident category or control — heat pumps + (Group 2), community (Group 3), electric underfloor (Group 7), electric + boiler / CPSU (Group 1) — `main_heating_overlay_for` **logs an error** naming + the archetype and code and continues, matching the `flag_fuel_mismatch` + log-not-raise convention. Log-and-continue keeps a mid-portfolio run alive + and surfaces the gap (CloudWatch) for review, rather than turning a latent + inheritance bug into an outage. The intended end-state is to fill each + archetype's category/control with spec sight and then **flip the log to a + raise**, so the coherence invariant is enforced. + +Category expansion for the still-`None` archetypes (electric boiler/CPSU→2, +underfloor→8) is deterministic from Table 4a but **deferred** to its own change: +it flows into the category-keyed Table 12a resolver and needs a corpus check, so +it does not ride on the room-heater fix. + +## Consequences + +- The 86+ room-heater dwellings score against a correctly-billed baseline: the + space-heating high-rate fraction is the spec **0.50** (10-hour direct-acting), + not 0.0; baseline SAP corrects **64.1 → 56.4**; the HHRSH measure's bill saving + flips **−£13/yr → +£235/yr** (property 710788, uprn 22003310, scenario 1268). +- The `refetch_solar`-corrected portfolio's `negative-bill-savings` audit group + loses its ~86-property HHRSH-on-room-heater cluster after re-model. +- The overlay now emits a visible error for any archetype it cannot fully + companion — a standing signal (wire a CloudWatch metric filter on the log + string) for which control default to fill next. +- Extends [ADR-0035](0035-coherent-heating-system-synthesis.md) (companions drag + from the code) and [ADR-0041](0041-landlord-heating-classification-targets-a-complete-modellable-taxonomy.md) + (complete taxonomy); sits beside + [ADR-0044](0044-hhrsh-baseline-archetype-drags-its-intrinsic-controls.md) + (a control named by the archetype) and + [ADR-0046](0046-electric-underfloor-scored-by-its-own-codes-meter-deferred-when-tariff-ambiguous.md) + (meter deferred where the tariff is ambiguous). + +### Alternatives rejected + +- **Make every companion total (force fuel and meter too).** Rejected: it breaks + the deliberate deferrals — community-heating fuel (ambiguous carrier) and the + ADR-0046 screed-underfloor meter — whose `None` is a load-bearing "defer to the + cert/override" signal, not a gap. +- **Fix the Table 12a resolver to prefer the SAP code over a stale category.** + A sound defence-in-depth follow-up, but it treats the symptom; the overlay + emitting an incoherent cert is the root cause, and category/control coherence + must hold for every consumer (predicted EPCs, raw lodged certs), not only the + billing resolver. +- **Raise on an incomplete companion set now.** Rejected for this change: heat + pump / community / underfloor overrides model today (by luck of inheritance), + so an immediate raise is a blast-radius change mid-campaign. Log now, raise once + the common archetypes are filled. From 5abc87ea18e1c736cf12f82e22d764e88dd5cf64 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Fri, 3 Jul 2026 09:26:05 +0000 Subject: [PATCH 36/84] chore(corpus): reconciliation pass over the 1-2 SAP band, no new bug found MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the PR #1439 handoff: swept every cert now sitting at |Δ| in [1.0, 2.0) (58 certs) using the cost-vs-demand signature bucketer (why_diverge.py's logic) plus field_bias.py's full-corpus subgroup scan (re-run clean after the two engine fixes above — no |meanΔ|>=0.5 systematic subgroup with coherent median). Breakdown: 17 room-in-roof (already spec-mandated/worksheet-validated per PRs #1440/#1441), 7 electric cost/tariff variants (spec-faithful vs lodged, consistent with the diagnosed electric cluster), 4 non-electric cost residuals (spec-faithful), ~26 non-electric fabric/demand certs. Manually inspected geometry (floor areas/perimeters/heights, wall/roof codes, window/door counts) for the 4 largest fabric/demand outliers in the band (100031768368, 100070450818, 100110097281, 100051051866) — no data-entry anomaly comparable to the earlier 12109191 decimal-floor-area bug. This confirms the handoff's "our calc faithful, lodged differs" pattern holds across the band; no engine bug survived the pass. Notes appended per-cert in worklist.md (`<-`, preserved by build_worklist.py reruns). Co-Authored-By: Claude Fable 5 --- scripts/corpus_1000/worklist.md | 490 ++++++++++++++++---------------- 1 file changed, 245 insertions(+), 245 deletions(-) diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md index 4941bcc1f..66fc7797b 100644 --- a/scripts/corpus_1000/worklist.md +++ b/scripts/corpus_1000/worklist.md @@ -1,10 +1,10 @@ # RdSAP-21.0.1 corpus campaign ledger -**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.7%** · MAE = **0.641** (floors in test_sap_accuracy_corpus.py) +**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.8%** · MAE = **0.636** (floors in test_sap_accuracy_corpus.py) Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail engine bug · ⛔ unbuildable. Line: `uprn · lodged L / eng E / Δ · signature`. Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` (preserves statuses & `<-` notes). -## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 223 certs in 216 clusters +## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 222 certs in 216 clusters ### C001 · Σ|Δ| 23.9 · 1 certs · `hpcdb100053/elec | solid brick | (another dwelling | sec:room heaters` - ⚠ `4510053280` · L 51 / E 74.94 / Δ +23.94 <- lodged software billed out-of-range-PSR (2.031 > 2.0) PCDB 100053 as 100% direct electric; engine follows SAP10.2 N2 extension (305%), Elmhurst-validated on case 56. Pinned engine 75 in test_real_cert_sap_accuracy. @@ -72,562 +72,561 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C021 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` - [ ] `10093342182` · L 82 / E 77.51 / Δ -4.49 -### C022 · Σ|Δ| 4.4 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` -- [ ] `5117280` · L 76 / E 71.56 / Δ -4.44 <- 🔧 thin-internal-insulation bucket-0 fix: present insulation + known <25mm thickness was mapped to uninsulated (U 1.7); now routes to 50mm row like unknown-thickness. Δ-4.44 -> +1.08. - -### C023 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` +### C022 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` - [ ] `217060420` · L 42 / E 37.58 / Δ -4.42 -### C024 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` +### C023 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` - [ ] `72399971` · L 69 / E 64.60 / Δ -4.40 -### C025 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` +### C024 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` - [ ] `10007016314` · L 57 / E 52.64 / Δ -4.36 -### C026 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` +### C025 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` - [ ] `100052159386` · L 56 / E 51.92 / Δ -4.08 -### C027 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` +### C026 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` - [ ] `100040767294` · L 43 / E 47.04 / Δ +4.04 -### C028 · Σ|Δ| 3.6 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` +### C027 · Σ|Δ| 3.6 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` - [ ] `10002188054` · L 68 / E 64.42 / Δ -3.58 -### C029 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` +### C028 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` - [ ] `39066537` · L 78 / E 81.49 / Δ +3.49 -### C030 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` +### C029 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` - [ ] `100100137438` · L 69 / E 72.48 / Δ +3.48 -### C031 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C030 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100080122910` · L 60 / E 63.45 / Δ +3.45 -### C032 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` +### C031 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` - [ ] `452010022` · L 42 / E 38.67 / Δ -3.33 -### C033 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` +### C032 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` - [ ] `200004818752` · L 34 / E 30.73 / Δ -3.27 -### C034 · Σ|Δ| 3.2 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` +### C033 · Σ|Δ| 3.2 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` - [ ] `200004522639` · L 37 / E 33.77 / Δ -3.23 -### C035 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` +### C034 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` - [ ] `72351021` · L 64 / E 60.85 / Δ -3.15 -### C036 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` +### C035 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` - [ ] `22077224` · L 37 / E 33.90 / Δ -3.10 -### C037 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` +### C036 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` - [ ] `10011740578` · L 70 / E 67.00 / Δ -3.00 -### C038 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +### C037 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` - [ ] `100110680822` · L 79 / E 76.07 / Δ -2.93 -### C039 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` +### C038 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` - [ ] `452032915` · L 75 / E 72.09 / Δ -2.91 -### C040 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` +### C039 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` - [ ] `100071306639` · L 73 / E 70.14 / Δ -2.86 -### C041 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` +### C040 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` - [ ] `100061346049` · L 55 / E 52.15 / Δ -2.85 -### C042 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` +### C041 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` - [ ] `10013008238` · L 41 / E 38.26 / Δ -2.74 -### C043 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` -- [ ] `10033187652` · L 70 / E 71.21 / Δ +1.21 +### C042 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` +- [ ] `10033187652` · L 70 / E 71.21 / Δ +1.21 <- non-electric cost (secondary fuel/cylinder/tariff); spec-faithful vs lodged - [ ] `200002730` · L 65 / E 64.13 / Δ -0.87 - [ ] `10023328117` · L 78 / E 78.64 / Δ +0.64 -### C044 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` +### C043 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` - [ ] `10004873253` · L 65 / E 62.29 / Δ -2.71 -### C045 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` +### C044 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` - [ ] `10090793715` · L 73 / E 75.71 / Δ +2.71 -### C046 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` +### C045 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100120745600` · L 65 / E 67.69 / Δ +2.69 -### C047 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` +### C046 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` - [ ] `100051178830` · L 63 / E 65.66 / Δ +2.66 -### C048 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` +### C047 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` - [ ] `100120018282` · L 64 / E 61.36 / Δ -2.64 -### C049 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +### C048 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` - [ ] `83035979` · L 65 / E 67.60 / Δ +2.60 -### C050 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` +### C049 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` - [ ] `10014073761` · L 75 / E 72.52 / Δ -2.48 -### C051 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` +### C050 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` - [ ] `100050964834` · L 60 / E 62.47 / Δ +2.47 -### C052 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` +### C051 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` - [ ] `100120752995` · L 71 / E 73.42 / Δ +2.42 -### C053 · Σ|Δ| 2.4 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` +### C052 · Σ|Δ| 2.4 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` - [ ] `100062174575` · L 46 / E 48.40 / Δ +2.40 -### C054 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` +### C053 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` - [ ] `100000034023` · L 73 / E 70.71 / Δ -2.29 -### C055 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` +### C054 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` - [ ] `100020377671` · L 62 / E 64.23 / Δ +2.23 -### C056 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` +### C055 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` - [ ] `22027335` · L 76 / E 73.77 / Δ -2.23 -### C057 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` +### C056 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` - [ ] `48056153` · L 65 / E 62.89 / Δ -2.11 -### C058 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` -- [ ] `100021924710` · L 63 / E 65.00 / Δ +2.00 +### C057 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` +- [ ] `100021924710` · L 63 / E 65.00 / Δ +2.00 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C059 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` -- [ ] `100031270375` · L 69 / E 70.93 / Δ +1.93 +### C058 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` +- [ ] `100031270375` · L 69 / E 70.93 / Δ +1.93 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C060 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` -- [ ] `10001118522` · L 80 / E 78.07 / Δ -1.93 +### C059 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` +- [ ] `10001118522` · L 80 / E 78.07 / Δ -1.93 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C061 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` -- [ ] `10010234711` · L 81 / E 79.08 / Δ -1.92 +### C060 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` +- [ ] `10010234711` · L 81 / E 79.08 / Δ -1.92 <- electric other (per-cert cost noise) -### C062 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` -- [ ] `100031768368` · L 61 / E 59.12 / Δ -1.88 +### C061 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` +- [ ] `100031768368` · L 61 / E 59.12 / Δ -1.88 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C063 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` -- [ ] `4510729926` · L 73 / E 71.15 / Δ -1.85 +### C062 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` +- [ ] `4510729926` · L 73 / E 71.15 / Δ -1.85 <- electric + fabric/demand mismatch (per-cert; not a coherent cluster) -### C064 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` -- [ ] `100091329112` · L 49 / E 50.82 / Δ +1.82 +### C063 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` +- [ ] `100091329112` · L 49 / E 50.82 / Δ +1.82 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C065 · Σ|Δ| 1.8 · 2 certs · `hpcdb18908/gas | solid brick | pitched 300` -- [ ] `100061275133` · L 76 / E 77.24 / Δ +1.24 -- [ ] `207032630` · L 74 / E 73.47 / Δ -0.53 +### C064 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` +- [ ] `10011797347` · L 47 / E 48.77 / Δ +1.77 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C066 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` -- [ ] `10011797347` · L 47 / E 48.77 / Δ +1.77 +### C065 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` +- [ ] `100022668387` · L 68 / E 66.25 / Δ -1.75 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C067 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` -- [ ] `100022668387` · L 68 / E 66.25 / Δ -1.75 +### C066 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` +- [ ] `100100892216` · L 69 / E 67.28 / Δ -1.72 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C068 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` -- [ ] `100100892216` · L 69 / E 67.28 / Δ -1.72 +### C067 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` +- [ ] `100060878876` · L 49 / E 50.71 / Δ +1.71 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C069 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` -- [ ] `100060878876` · L 49 / E 50.71 / Δ +1.71 +### C068 · Σ|Δ| 1.7 · 1 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` +- [ ] `12126160` · L 69 / E 70.71 / Δ +1.71 <- electric + fabric/demand mismatch (per-cert; not a coherent cluster) -### C070 · Σ|Δ| 1.7 · 1 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` -- [ ] `12126160` · L 69 / E 70.71 / Δ +1.71 +### C069 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` +- [ ] `22032926` · L 61 / E 62.71 / Δ +1.71 <- electric + fabric/demand mismatch (per-cert; not a coherent cluster) -### C071 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` -- [ ] `22032926` · L 61 / E 62.71 / Δ +1.71 +### C070 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` +- [ ] `100010942905` · L 72 / E 73.70 / Δ +1.70 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C072 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` -- [ ] `100010942905` · L 72 / E 73.70 / Δ +1.70 +### C071 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` +- [ ] `100030307976` · L 71 / E 69.37 / Δ -1.63 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C073 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` -- [ ] `100030307976` · L 71 / E 69.37 / Δ -1.63 +### C072 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` +- [ ] `100061404488` · L 70 / E 68.38 / Δ -1.62 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C074 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` -- [ ] `100061404488` · L 70 / E 68.38 / Δ -1.62 +### C073 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` +- [ ] `21067296` · L 67 / E 68.60 / Δ +1.60 <- electric + fabric/demand mismatch (per-cert; not a coherent cluster) -### C075 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` -- [ ] `21067296` · L 67 / E 68.60 / Δ +1.60 +### C074 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` +- [ ] `5870047440` · L 58 / E 59.58 / Δ +1.58 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C076 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` -- [ ] `5870047440` · L 58 / E 59.58 / Δ +1.58 +### C075 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` +- [ ] `100070450818` · L 65 / E 63.43 / Δ -1.57 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C077 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` -- [ ] `100070450818` · L 65 / E 63.43 / Δ -1.57 +### C076 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` +- [ ] `100050881708` · L 70 / E 71.55 / Δ +1.55 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C078 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` -- [ ] `100050881708` · L 70 / E 71.55 / Δ +1.55 +### C077 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` +- [ ] `10010254955` · L 79 / E 77.46 / Δ -1.54 <- electric other (per-cert cost noise) -### C079 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` -- [ ] `10010254955` · L 79 / E 77.46 / Δ -1.54 +### C078 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` +- [ ] `3455011834` · L 69 / E 67.48 / Δ -1.52 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C080 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` -- [ ] `3455011834` · L 69 / E 67.48 / Δ -1.52 +### C079 · Σ|Δ| 1.5 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` +- [ ] `100100274789` · L 60 / E 61.51 / Δ +1.51 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C081 · Σ|Δ| 1.5 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` -- [ ] `100100274789` · L 60 / E 61.51 / Δ +1.51 +### C080 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` +- [ ] `100050852755` · L 65 / E 66.49 / Δ +1.49 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C082 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` -- [ ] `100050852755` · L 65 / E 66.49 / Δ +1.49 +### C081 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` +- [ ] `100021326422` · L 70 / E 68.51 / Δ -1.49 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C083 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` -- [ ] `100021326422` · L 70 / E 68.51 / Δ -1.49 +### C082 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` +- [ ] `100050988345` · L 61 / E 59.51 / Δ -1.49 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C084 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` -- [ ] `100050988345` · L 61 / E 59.51 / Δ -1.49 +### C083 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` +- [ ] `100030285758` · L 54 / E 55.48 / Δ +1.48 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C085 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` -- [ ] `100030285758` · L 54 / E 55.48 / Δ +1.48 - -### C086 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` +### C084 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` - [ ] `line80` · L 72 / E 70.56 / Δ -1.44 -### C087 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` -- [ ] `100080518673` · L 57 / E 58.42 / Δ +1.42 +### C085 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` +- [ ] `100080518673` · L 57 / E 58.42 / Δ +1.42 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C088 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` -- [ ] `235025284` · L 69 / E 67.59 / Δ -1.41 +### C086 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` +- [ ] `235025284` · L 69 / E 67.59 / Δ -1.41 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C089 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` -- [ ] `250063088` · L 73 / E 71.60 / Δ -1.40 +### C087 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` +- [ ] `250063088` · L 73 / E 71.60 / Δ -1.40 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C090 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` -- [ ] `100110097281` · L 64 / E 65.37 / Δ +1.37 +### C088 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` +- [ ] `100110097281` · L 64 / E 65.37 / Δ +1.37 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C091 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` -- [ ] `10091630692` · L 58 / E 56.63 / Δ -1.37 +### C089 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` +- [ ] `10091630692` · L 58 / E 56.63 / Δ -1.37 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C092 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` -- [ ] `100012368622` · L 39 / E 40.32 / Δ +1.32 +### C090 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` +- [ ] `100012368622` · L 39 / E 40.32 / Δ +1.32 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C093 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` -- [ ] `90077194` · L 65 / E 63.69 / Δ -1.31 +### C091 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +- [ ] `90077194` · L 65 / E 63.69 / Δ -1.31 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C094 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` -- [ ] `100031461986` · L 70 / E 71.29 / Δ +1.29 +### C092 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` +- [ ] `100031461986` · L 70 / E 71.29 / Δ +1.29 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C095 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` -- [ ] `30095054` · L 46 / E 44.74 / Δ -1.26 +### C093 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` +- [ ] `30095054` · L 46 / E 44.74 / Δ -1.26 <- non-electric cost (secondary fuel/cylinder/tariff); spec-faithful vs lodged -### C096 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` -- [ ] `100100055589` · L 58 / E 59.26 / Δ +1.26 +### C094 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` +- [ ] `100100055589` · L 58 / E 59.26 / Δ +1.26 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C097 · Σ|Δ| 1.2 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` +### C095 · Σ|Δ| 1.2 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` - [ ] `74061136` · L 73 / E 71.75 / Δ -1.25 <- electric storage cat7 E7: over-rate = off-peak rate/fraction too generous; needs Elmhurst tariff arbitration -### C098 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` -- [ ] `100091435353` · L 65 / E 66.23 / Δ +1.23 +### C096 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` +- [ ] `100091435353` · L 65 / E 66.23 / Δ +1.23 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C099 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` +### C097 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` - [ ] `10091070164` · L 69 / E 69.60 / Δ +0.60 - [ ] `10090927185` · L 79 / E 79.60 / Δ +0.60 -### C100 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` -- [ ] `100100614412` · L 53 / E 51.81 / Δ -1.19 +### C098 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` +- [ ] `100100614412` · L 53 / E 51.81 / Δ -1.19 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C101 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` -- [ ] `217091901` · L 62 / E 60.82 / Δ -1.18 +### C099 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` +- [ ] `217091901` · L 62 / E 60.82 / Δ -1.18 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C102 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` +### C100 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` - [x] `line768` · L 57 / E 55.84 / Δ -1.16 -### C103 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` -- [ ] `217061895` · L 61 / E 59.84 / Δ -1.16 +### C101 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` +- [ ] `217061895` · L 61 / E 59.84 / Δ -1.16 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C104 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` -- [ ] `10002349227` · L 76 / E 77.14 / Δ +1.14 +### C102 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` +- [ ] `10002349227` · L 76 / E 77.14 / Δ +1.14 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C105 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` -- [ ] `200001634005` · L 66 / E 67.11 / Δ +1.11 +### C103 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` +- [ ] `200001634005` · L 66 / E 67.11 / Δ +1.11 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C106 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` -- [ ] `100071059081` · L 63 / E 64.09 / Δ +1.09 +### C104 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [ ] `100071059081` · L 63 / E 64.09 / Δ +1.09 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C107 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` -- [ ] `100011820199` · L 55 / E 56.06 / Δ +1.06 +### C105 · Σ|Δ| 1.1 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` +- [ ] `5117280` · L 76 / E 77.08 / Δ +1.08 <- 🔧 thin-internal-insulation bucket-0 fix: present insulation + known <25mm thickness was mapped to uninsulated (U 1.7); now routes to 50mm row like unknown-thickness. Δ-4.44 -> +1.08. -### C108 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` -- [ ] `90214753` · L 83 / E 81.95 / Δ -1.05 +### C106 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` +- [ ] `100011820199` · L 55 / E 56.06 / Δ +1.06 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C109 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` -- [ ] `100051051866` · L 70 / E 71.04 / Δ +1.04 +### C107 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` +- [ ] `90214753` · L 83 / E 81.95 / Δ -1.05 <- non-electric cost (secondary fuel/cylinder/tariff); spec-faithful vs lodged -### C110 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` -- [ ] `10013836852` · L 100 / E 98.97 / Δ -1.03 +### C108 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` +- [ ] `100051051866` · L 70 / E 71.04 / Δ +1.04 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C111 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` +### C109 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` +- [ ] `10013836852` · L 100 / E 98.97 / Δ -1.03 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C110 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` - [ ] `line899` · L 73 / E 71.97 / Δ -1.03 -### C112 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` -- [ ] `40037847` · L 81 / E 79.98 / Δ -1.02 +### C111 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` +- [ ] `40037847` · L 81 / E 79.98 / Δ -1.02 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C113 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` -- [ ] `10070056075` · L 80 / E 78.99 / Δ -1.01 +### C112 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` +- [ ] `10070056075` · L 80 / E 78.99 / Δ -1.01 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) -### C114 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` -- [ ] `200131078` · L 86 / E 85.00 / Δ -1.00 +### C113 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` +- [ ] `200131078` · L 86 / E 85.00 / Δ -1.00 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) -### C115 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` -- [ ] `10000245212` · L 101 / E 100.00 / Δ -1.00 +### C114 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` +- [ ] `10000245212` · L 101 / E 100.00 / Δ -1.00 <- non-electric cost (secondary fuel/cylinder/tariff); spec-faithful vs lodged -### C116 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` +### C115 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` - [ ] `15129162` · L 62 / E 61.00 / Δ -1.00 -### C117 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` +### C116 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` - [ ] `23032873` · L 73 / E 72.00 / Δ -1.00 -### C118 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` +### C117 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` - [ ] `45019020` · L 62 / E 61.01 / Δ -0.99 -### C119 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` +### C118 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` - [ ] `42065028` · L 59 / E 58.02 / Δ -0.98 -### C120 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` +### C119 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` - [ ] `10032928147` · L 77 / E 76.04 / Δ -0.96 -### C121 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` +### C120 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` - [ ] `10010678937` · L 78 / E 77.04 / Δ -0.96 -### C122 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` +### C121 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` - [ ] `100011010151` · L 62 / E 62.96 / Δ +0.96 -### C123 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` +### C122 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` - [ ] `100050477371` · L 65 / E 64.04 / Δ -0.96 -### C124 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` +### C123 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` - [ ] `10002945522` · L 61 / E 61.94 / Δ +0.94 -### C125 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` +### C124 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` - [ ] `10032957680` · L 45 / E 45.94 / Δ +0.94 -### C126 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` +### C125 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` - [ ] `2465057465` · L 81 / E 81.93 / Δ +0.93 -### C127 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` +### C126 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` - [ ] `100090616327` · L 63 / E 63.93 / Δ +0.93 -### C128 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` +### C127 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` - [ ] `100012753833` · L 74 / E 73.07 / Δ -0.93 -### C129 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` +### C128 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` - [ ] `100031269525` · L 53 / E 53.91 / Δ +0.91 -### C130 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` +### C129 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` - [ ] `200003725358` · L 75 / E 74.09 / Δ -0.91 -### C131 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` +### C130 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` - [ ] `100050986162` · L 62 / E 61.10 / Δ -0.90 -### C132 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` +### C131 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` - [ ] `5300000141` · L 78 / E 77.10 / Δ -0.90 -### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` +### C132 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` - [ ] `100050618404` · L 73 / E 73.89 / Δ +0.89 -### C134 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` +### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` - [ ] `100090476016` · L 81 / E 81.89 / Δ +0.89 -### C135 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` +### C134 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` - [ ] `10012119141` · L 45 / E 45.89 / Δ +0.89 -### C136 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` +### C135 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` - [ ] `100040938206` · L 75 / E 75.89 / Δ +0.89 -### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` +### C136 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `38188474` · L 76 / E 76.87 / Δ +0.87 -### C138 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` - [ ] `100061194957` · L 69 / E 69.87 / Δ +0.87 -### C139 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` +### C138 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` - [ ] `100021236527` · L 72 / E 71.13 / Δ -0.87 -### C140 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` +### C139 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` - [ ] `100040193752` · L 71 / E 71.86 / Δ +0.86 -### C141 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` +### C140 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` - [ ] `100060701552` · L 74 / E 74.86 / Δ +0.86 -### C142 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` +### C141 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` - [ ] `10070396146` · L 61 / E 60.14 / Δ -0.86 -### C143 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` +### C142 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` - [ ] `100030528930` · L 74 / E 73.16 / Δ -0.84 -### C144 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` +### C143 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` - [ ] `100020982570` · L 72 / E 71.17 / Δ -0.83 -### C145 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` +### C144 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` - [ ] `394024487` · L 75 / E 74.17 / Δ -0.83 -### C146 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` +### C145 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` - [ ] `217070698` · L 78 / E 78.83 / Δ +0.83 -### C147 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` +### C146 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` - [ ] `77022508` · L 69 / E 68.18 / Δ -0.82 -### C148 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` +### C147 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` - [ ] `100040259104` · L 68 / E 68.82 / Δ +0.82 -### C149 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` +### C148 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` - [ ] `100031399026` · L 70 / E 70.81 / Δ +0.81 -### C150 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` +### C149 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` - [ ] `10009645698` · L 67 / E 67.81 / Δ +0.81 -### C151 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` +### C150 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` - [ ] `100080818887` · L 56 / E 55.19 / Δ -0.81 -### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` +### C151 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` - [ ] `100012374381` · L 69 / E 69.80 / Δ +0.80 -### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` +### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` - [ ] `100012350270` · L 78 / E 77.20 / Δ -0.80 -### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` +### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` - [ ] `100051109723` · L 60 / E 60.78 / Δ +0.78 -### C155 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` +### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` - [ ] `100061616915` · L 63 / E 62.22 / Δ -0.78 -### C156 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` +### C155 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` - [ ] `line71` · L 74 / E 74.77 / Δ +0.77 -### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` +### C156 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` - [ ] `100011603934` · L 72 / E 71.23 / Δ -0.77 -### C158 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` +### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` - [ ] `24030987` · L 73 / E 73.76 / Δ +0.76 -### C159 · Σ|Δ| 0.8 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` +### C158 · Σ|Δ| 0.8 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` - [ ] `100032043038` · L 74 / E 73.24 / Δ -0.76 -### C160 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` +### C159 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` - [ ] `100010866608` · L 71 / E 70.24 / Δ -0.76 -### C161 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` +### C160 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` - [ ] `100090399615` · L 67 / E 67.75 / Δ +0.75 -### C162 · Σ|Δ| 0.7 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` +### C161 · Σ|Δ| 0.7 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` - [ ] `200004296092` · L 71 / E 71.74 / Δ +0.74 -### C163 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` +### C162 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` - [ ] `10012341135` · L 79 / E 79.73 / Δ +0.73 -### C164 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +### C163 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` - [ ] `100091005853` · L 70 / E 69.27 / Δ -0.73 -### C165 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` +### C164 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` - [ ] `100021533514` · L 71 / E 71.73 / Δ +0.73 -### C166 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` +### C165 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` - [ ] `5062075` · L 69 / E 69.72 / Δ +0.72 -### C167 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` +### C166 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100040813308` · L 62 / E 62.72 / Δ +0.72 -### C168 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` +### C167 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` - [ ] `38105600` · L 68 / E 67.28 / Δ -0.72 -### C169 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` +### C168 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` - [ ] `line255` · L 72 / E 71.29 / Δ -0.71 -### C170 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` +### C169 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` - [ ] `5300047580` · L 69 / E 68.30 / Δ -0.70 -### C171 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` +### C170 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` - [ ] `100110433403` · L 69 / E 68.32 / Δ -0.68 -### C172 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` +### C171 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` - [ ] `10093416558` · L 79 / E 78.32 / Δ -0.68 -### C173 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` +### C172 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` - [ ] `100050958217` · L 68 / E 68.68 / Δ +0.68 -### C174 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` +### C173 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` - [ ] `100022667797` · L 68 / E 67.32 / Δ -0.68 -### C175 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` +### C174 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` - [ ] `100030528925` · L 78 / E 78.65 / Δ +0.65 -### C176 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` +### C175 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` - [ ] `100110300037` · L 74 / E 73.35 / Δ -0.65 -### C177 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` +### C176 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` - [ ] `217092450` · L 52 / E 52.64 / Δ +0.64 -### C178 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` +### C177 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` - [ ] `100061164545` · L 72 / E 71.36 / Δ -0.64 -### C179 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` +### C178 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` - [ ] `100051075936` · L 71 / E 70.36 / Δ -0.64 -### C180 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` +### C179 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` - [ ] `100011565830` · L 72 / E 72.64 / Δ +0.64 -### C181 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` +### C180 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` - [ ] `61010956` · L 75 / E 74.37 / Δ -0.63 -### C182 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` +### C181 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` - [ ] `100110752514` · L 67 / E 67.62 / Δ +0.62 -### C183 · Σ|Δ| 0.6 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` +### C182 · Σ|Δ| 0.6 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` - [ ] `100070295212` · L 75 / E 74.38 / Δ -0.62 -### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` +### C183 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` - [ ] `100012534027` · L 65 / E 64.38 / Δ -0.62 -### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` +### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` - [x] `10009812472` · L 40 / E 39.40 / Δ -0.60 -### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` +### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` - [ ] `34080035` · L 77 / E 76.41 / Δ -0.59 -### C187 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` +### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` - [ ] `21032732` · L 69 / E 69.59 / Δ +0.59 -### C188 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` +### C187 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` - [ ] `100060562056` · L 66 / E 65.41 / Δ -0.59 -### C189 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` +### C188 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` - [ ] `100091086558` · L 79 / E 79.58 / Δ +0.58 -### C190 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` +### C189 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` - [ ] `line599` · L 74 / E 73.42 / Δ -0.58 -### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` +### C190 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` - [ ] `100020407741` · L 72 / E 71.42 / Δ -0.58 -### C192 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` +### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` - [ ] `100050839457` · L 70 / E 70.57 / Δ +0.57 -### C193 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` +### C192 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` - [ ] `42105250` · L 59 / E 59.57 / Δ +0.57 -### C194 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` +### C193 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` - [ ] `77200509` · L 69 / E 69.57 / Δ +0.57 -### C195 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` +### C194 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` - [ ] `200040534` · L 65 / E 65.56 / Δ +0.56 -### C196 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` +### C195 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` - [ ] `200049463` · L 69 / E 69.56 / Δ +0.56 -### C197 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` +### C196 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` - [ ] `100062527568` · L 61 / E 61.56 / Δ +0.56 -### C198 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` +### C197 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` - [ ] `100100268900` · L 69 / E 69.56 / Δ +0.56 -### C199 · Σ|Δ| 0.6 · 1 certs · `hpcdb17004/fuel27+2mains | sandstone as | pitched no | ext3,sec:room heaters` +### C198 · Σ|Δ| 0.6 · 1 certs · `hpcdb17004/fuel27+2mains | sandstone as | pitched no | ext3,sec:room heaters` - [x] `200003110548` · L 29 / E 28.45 / Δ -0.55 -### C200 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` +### C199 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` - [ ] `90036914` · L 60 / E 60.55 / Δ +0.55 -### C201 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` +### C200 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` - [ ] `10004742671` · L 70 / E 69.46 / Δ -0.54 -### C202 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` +### C201 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` - [ ] `100010657450` · L 75 / E 75.54 / Δ +0.54 -### C203 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` +### C202 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` - [ ] `100061834344` · L 71 / E 70.46 / Δ -0.54 -### C204 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` +### C203 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` - [ ] `4510097194` · L 70 / E 70.53 / Δ +0.53 -### C205 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` +### C204 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` - [ ] `100010913220` · L 72 / E 72.53 / Δ +0.53 +### C205 · Σ|Δ| 0.5 · 1 certs · `hpcdb18908/gas | solid brick | pitched 300` +- [ ] `207032630` · L 74 / E 73.47 / Δ -0.53 + ### C206 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` - [ ] `43074051` · L 63 / E 62.48 / Δ -0.52 @@ -661,7 +660,7 @@ Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail en ### C216 · Σ|Δ| 0.5 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` - [ ] `10091707271` · L 41 / E 41.50 / Δ +0.50 -## Resolved ≤0.5 (777 certs — no action) +## Resolved ≤0.5 (778 certs — no action)