Model/scripts/hyde/elmhurst_README.md
Jun-te Kim 2f0eb49eee Checkpoint: UPRN 10093116543 Elmhurst build + devcontainer VNC/Playwright + perms
- Add SAP-accuracy sample for uprn_10093116543 (epc.json, elmhurst_inputs.md,
  summary/worksheet PDFs)
- Persist hyde viewer stack (xvfb/fluxbox/x11vnc/novnc/websockify) and Playwright
  chromium in the backend devcontainer; forward noVNC 6080
- Broaden .claude/settings.local.json allowlist (display/python/grep/tail)
- In-progress campaign mapper/cert_to_inputs work carried from prior cert

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 15:21:56 +00:00

4 KiB

Elmhurst RdSAP entry-tool automation (POC)

Automates most of the one manual step in validate-cert-sap-accuracy: re-keying elmhurst_inputs.md into Elmhurst's web RdSAP entry tool and exporting the Input Summary + SAP Worksheets PDFs (which compare_epc_paths.py then consumes). Built on Playwright (Python).

Proven end-to-end on UPRN 10092973954: filled most pages automatically, downloaded both PDFs, and compare_epc_paths.py reconciled to our engine 77 vs Elmhurst worksheet 78 (engine-on-Elmhurst-inputs 79 — the calculator reproduces accredited Elmhurst within ~1 SAP on identical inputs).

Scripts

Script Does
start_viewer.sh Xvfb→x11vnc→noVNC desktop on port 6080 so you can SEE/click the headed browser (DISPLAY=:99). bash scripts/hyde/start_viewer.sh
elmhurst_session.py login / open / status — persistent login (MFA by hand once; session in .elmhurst-session/, gitignored)
elmhurst_explore.py dump a page's DOM (field ids, options, autopostback) or --all sections — how specs are built
elmhurst_fill.py --page <name> [--commit] [--commit-mode saveclose|next] — fill/clear a page from its PageSpec
elmhurst_download.py downloads Input Summary + SAP Worksheets → the cert's corpus dir. Never clicks Submit (code-enforced)

Typical run (browser appears on the noVNC desktop at port 6080):

bash scripts/hyde/start_viewer.sh
DISPLAY=:99 python scripts/hyde/elmhurst_session.py login --url https://members.elmhurstenergy.co.uk/
DISPLAY=:99 python scripts/hyde/elmhurst_fill.py --page property_description --commit
DISPLAY=:99 python scripts/hyde/elmhurst_download.py

Hard-won mechanics (ASP.NET WebForms)

  • Enter via the Guid URL (…online…/WebFormAddress.aspx?Guid=…); section nav is full-form __doPostBack to a Guid-less subdomain — use expect_navigation.
  • Almost every field AutoPostBacks (whole-page reload): set one field, wait, re-locate the next. A 600 ms settle after each interaction stops flake.
  • Never re-click the active tab (double-postback misbehaves) — goto_section is current-page-aware.
  • Navigating away saves; Save & Close commits to the DATABASE (visible to other sessions). Next > only saves the in-progress session.
  • Fields auto-disable when an upstream choice removes them (Room-in-Roof once no room-in-roof; cylinder once combi) — skip them, don't fight them.
  • Button ids vary per page → match by id suffix ([id$='_ButtonSaveClose']).
  • Setup (done in container): python -m playwright install chromium + sudo python -m playwright install-deps chromium.

What's automated vs manual

Automated (in PAGES + special actions): Property Description, Dimensions, Flats (position/floor/corridor), Walls (main + clear alt-wall), Roofs, Floors, Space Heating (boiler via the cascade dialog → BGW combi, flue, secondary), Water Heating (code; cylinder auto-clears with the combi), New Tech/Conservatory (none) — plus the consolidated clears from the markdown.

The boiler cascade dialog is driven by select_boiler_combi(): open the Main-Heating-code modal, set the leaf dropdown to BGW Post 98 Combi condens., click OK. The generic combi (SAP 104) moves SAP by ~0 vs the cert's exact PCDB model, so it's accurate enough.

Manual (🔸):

  • Exact PCDB boiler model (e.g. 17929) — its search field is disabled (aspNetDisabled) in this UI state; the cascade's generic combi is the automatable substitute (negligible SAP impact).
  • Control code 2110 and the MV unit — same modal-dialog pattern; can be automated the same way as the boiler when wanted (open dialog → select → OK). All 🔸 fields are flagged in elmhurst_inputs.md.

Adding a field/page

  1. elmhurst_explore.py <guid-url> <buttonAction<Section>_Link> to dump ids/options.
  2. Add a Field(...) (or new PageSpec) in elmhurst_fill.py.
  3. --page <name> (dry-run, screenshots to elmhurst_dom/fill_<name>.png), verify, then --commit.