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 2d86d5cee..4a604044a 100644 Binary files a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf differ 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 01308a944..9bb10c008 100644 Binary files a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_worksheet.pdf and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_worksheet.pdf differ 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())