mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-19 17:03:02 +00:00
Built UPRN 100010086084 (the largest gov-API-vs-lodged outlier from the 20-cert batch) in Elmhurst's accredited RdSAP10 tool to get real ground truth, per feedback that lodged rating isn't a valid comparison target. Elmhurst worksheet: SAP 46-48 (orientation-dependent), vs this engine's 53 on gov-API inputs -- a real ~5-7pt residual gap. Ruled out with direct empirical tests: total_floor_area, missing party_wall_length, region/climate (SAP rating always uses UK-average weather per Appendix U -- confirmed inert), boiler/secondary efficiency (exact match, 66%/ 63% both sides). Confirmed real but NOT blind-fixed (need more than one cert's evidence, and a wall-U-value patch tested the wrong direction in isolation): a wall-thickness-unknown U-value fallback mismatch (this engine 1.70, Elmhurst's own "unknown" resolution 1.40) and a window U-value divergence (1.85 vs 2.52 W/m2K for the same nominal glazing pick). Single-window orientation confirmed a ~2pt partial contributor. Also fixes a small, separate, evidenced gap the build surfaced: the Elmhurst summary parser didn't recognise the live tool's "Medium (131-170L)" cylinder-size label (only the bare "Medium"). Full write-up is in the RealCertExpectation comment for this cert in test_real_cert_sap_accuracy.py and the worklist. Residual gap is intentionally left open for follow-up, not force-closed.
71 lines
2.8 KiB
Python
71 lines
2.8 KiB
Python
"""Download the Input Summary + SAP Worksheets PDFs for UPRN 100010086084,
|
|
via a fresh-login `E.session()` (elmhurst_download.py's persistent-context
|
|
login is stale per elmhurst_lib's own documented auth gotcha).
|
|
|
|
SAFETY: clicks ONLY the two allow-listed report buttons below. NEVER clicks
|
|
Submit (`LinkButtonSubmitEPR`).
|
|
|
|
DISPLAY=:99 python scripts/hyde/download_100010086084.py
|
|
"""
|
|
from __future__ import annotations
|
|
from pathlib import Path
|
|
import elmhurst_lib as E
|
|
from playwright.sync_api import TimeoutError as PlaywrightTimeoutError
|
|
|
|
SAMPLE_DIR = (
|
|
Path(__file__).parent.parent.parent
|
|
/ "backend/epc_api/json_samples/real_life_examples"
|
|
/ "SAP-Schema-15.0/uprn_100010086084"
|
|
)
|
|
|
|
REPORTS = [
|
|
("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"),
|
|
("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf"),
|
|
]
|
|
_FORBIDDEN = {"ContentBody_ContentPlaceHolder1_LinkButtonSubmitEPR"}
|
|
|
|
|
|
def _download_one(page, button_id, out):
|
|
assert button_id not in _FORBIDDEN, f"refusing to click forbidden {button_id}"
|
|
print(f" clicking {button_id} -> {out.name} ...", flush=True)
|
|
try:
|
|
with page.expect_download(timeout=60_000) as dl:
|
|
page.click(f"#{button_id}", timeout=20_000)
|
|
dl.value.save_as(str(out))
|
|
except PlaywrightTimeoutError:
|
|
try:
|
|
with page.expect_popup(timeout=10_000) as pop:
|
|
page.click(f"#{button_id}", timeout=20_000)
|
|
popup = pop.value
|
|
with popup.expect_download(timeout=30_000) as dl2:
|
|
pass
|
|
dl2.value.save_as(str(out))
|
|
except PlaywrightTimeoutError:
|
|
print(f" !! no download/popup for {button_id}", flush=True)
|
|
return False
|
|
size = out.stat().st_size if out.exists() else 0
|
|
print(f" saved {out} ({size:,} bytes)", flush=True)
|
|
return out.exists() and size > 0
|
|
|
|
|
|
def main():
|
|
SAMPLE_DIR.mkdir(parents=True, exist_ok=True)
|
|
ok = True
|
|
with E.session() as (ctx, page):
|
|
print("navigating via Recommendations ...", flush=True)
|
|
with page.expect_navigation(wait_until="networkidle", timeout=60_000):
|
|
page.click("#ContentBody_buttonActionRecommendations_Link", timeout=15_000)
|
|
page.wait_for_timeout(600)
|
|
print("navigating to Energy Report Summary ...", flush=True)
|
|
with page.expect_navigation(wait_until="networkidle", timeout=60_000):
|
|
page.click("#ContentBody_buttonActionSummary_Link", timeout=15_000)
|
|
page.wait_for_timeout(600)
|
|
for button_id, fname in REPORTS:
|
|
ok = _download_one(page, button_id, SAMPLE_DIR / fname) and ok
|
|
page.wait_for_timeout(600)
|
|
print("DONE." if ok else "DONE (with errors).", flush=True)
|
|
return 0 if ok else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|