save skills and automation progress

This commit is contained in:
Jun-te Kim 2026-06-16 12:17:43 +00:00
parent b78e9c7768
commit dad3044740
13 changed files with 1420 additions and 3 deletions

View file

@ -53,10 +53,20 @@ mapping reference must be looked up in the cited source file, not invented.
useful the **EES dropdown path** and **SAP code**. Use the lookup tables and
gotchas in [reference/mapping.md](reference/mapping.md).
4. **Save** the file next to the cert json as `elmhurst_inputs.md`
4. **Flag what must NOT be mapped / must be cleared.** Elmhurst pages carry
defaults and (when re-keying into an existing assessment) stale values that
silently survive and corrupt the result — a phantom 1st extension, a
room-in-roof area, a party-wall length, leftover window rows. For every
element the cert does **not** have, say so explicitly with the Elmhurst
field to blank and the value to set (usually empty or 0). The automated
filler (`scripts/hyde/elmhurst_fill.py`) and a human both rely on this list
— an unflagged absent element defaults to "present" and skews SAP. See the
**Fields to clear** section in Output shape below.
5. **Save** the file next to the cert json as `elmhurst_inputs.md`
(e.g. `.../real_life_examples/<schema>/uprn_<uprn>/elmhurst_inputs.md`).
5. **Tell the operator**: key it into Elmhurst, then report the SAP score (and
6. **Tell the operator**: key it into Elmhurst, then report the SAP score (and
heating cost £ if shown). If it differs from our engine's score, that's a
calculator finding — capture it.
@ -70,6 +80,27 @@ Start the file with a header block:
```
Then the page sections as tables: `| Elmhurst field | Value | Notes (SAP code / EES path) |`.
End the file with a **Fields to clear in Elmhurst (do NOT map)** section — one
table listing every element the cert lacks but Elmhurst defaults or stale data
would otherwise assert. This is the explicit "absent" set the filler and the
operator clear:
```
## Fields to clear in Elmhurst (do NOT map)
| Elmhurst field | Set to | Why absent |
|---|---|---|
| Property Description · 1st4th Extension age band | (blank) | no extensions lodged |
| Property Description · Room-in-Roof age band | (blank) | no room-in-roof building part |
| Dimensions · Room(s) in Roof area | (blank) | ditto — leave empty, not 0 |
| Dimensions · 1st4th Ext. sub-tabs | 0 / blank | single building part |
| Walls · Party wall | none/blank | `party_walls_w_per_k` = 0 |
| Openings · surplus window rows | delete | window count from glazed-area band only |
| Water Heating · cylinder | none | combi / instantaneous |
| Conservatory / PV / Wind / Hydro / WWHRS / FGHRS | none | not lodged |
```
Give the **Elmhurst page · field**, the **cleared value** (prefer *blank* over
0 where the field is "not applicable"; some validators reject 0), and the
one-line reason. Absent ≠ zero everywhere — note which.
## Critical gotchas (full detail in reference)
- **Economy-7 / off-peak electricity** (`main_fuel_type`/`water_heating_fuel` 29):
@ -84,6 +115,11 @@ Then the page sections as tables: `| Elmhurst field | Value | Notes (SAP code /
- **Water heating** 903 = Electric immersion off-peak → Elmhurst "Water Heater"
category, not "Boiler Circulator" (901 = from main system).
- **Windows** are synthesised from `glazed_area` band × TFA — not real geometry.
- **Age band — pick by construction YEAR, not the engine's band letter.** The
live RdSAP-10 tool bands differently from `mapping.md`'s older table: it
offers `…K 2007-2011`, **`L 2012-2022`**, **`M 2023 onwards`**. A 2020 build
is **L** even though the engine labels `construction_age_band` "M". Map the
year to Elmhurst's on-screen band; flag the letter divergence.
## Canonical example

View file

@ -0,0 +1,70 @@
---
name: expand-sap-accuracy-corpus
description: Drive the per-UPRN SAP-accuracy corpus campaign. For each UPRN ensure the EPC-API→EpcPropertyData mapping exists (extend the mapper if the schema isn't covered), build the cert in Elmhurst (hyde Playwright automation), download its Input Summary + SAP Worksheets, reconcile our SAP calculator to within 0.5 of Elmhurst's accredited worksheet by fixing mapper gaps (not tuning), and pin a RealCertExpectation regression. Use when expanding SAP-calculator schema coverage/accuracy across many real certs, working the 100-UPRN worklist one at a time, validating the EPC mapper against Elmhurst, or when the user mentions the SAP accuracy corpus / Elmhurst worksheets / the UPRN campaign.
---
# Expand SAP accuracy corpus
A campaign wrapper around **`validate-cert-sap-accuracy`**, run **one UPRN at a
time** over [worklist.md](worklist.md). Why a UPRN at a time: we are rewriting /
extending the mapper incrementally, and each pass should (a) widen EPC-schema
coverage, (b) fix one real mapper gap, (c) leave the skills/tests sharper for the
next UPRN.
**Goal per UPRN:** our SAP calculator within **0.5 SAP** of Elmhurst's
accredited worksheet, the agreed score pinned as a `RealCertExpectation`.
The big picture: an old EPC → `EpcPropertyData` → our SAP calculator predicts the
score the property would get unchanged. Elmhurst is the accredited ground truth;
its Input Summary (parsed back to `EpcPropertyData`) exposes mapper holes, and its
worksheet exposes calculator holes.
## The loop (one UPRN)
1. **Pick** the first `[ ]` UPRN in [worklist.md](worklist.md).
2. **Capture**`PYTHONPATH=/workspaces/model python scripts/fetch_real_life_epc_sample.py <uprn>`
`epc.json` + schema + engine SAP under `…/real_life_examples/<schema>/uprn_<uprn>/`.
- **`NOT MAPPABLE`** (schema uncovered, e.g. full SAP) → this *is* the coverage
work: **extend the mapper** for that schema (`EpcPropertyDataMapper` / per-cert
mapper — Khalim's domain). Mark `🔧 mapper-gap`, build it, re-run. Guard with
the RdSAP-21.0.1 corpus gauge (`test_sap_accuracy_corpus.py`).
3. **Inputs** — run the **`epc-to-elmhurst-rdsap-inputs`** skill on the UPRN →
complete `elmhurst_inputs.md` (+ its **Fields to clear** section).
4. **Build in Elmhurst** (`scripts/hyde/`, mechanics in `elmhurst_README.md`):
`bash scripts/hyde/start_viewer.sh` (noVNC on :99) → log in once
(`elmhurst_session.py login`) → **create a NEW assessment for this UPRN**
fill from `elmhurst_inputs.md`: `elmhurst_fill.py` auto-fills the derivable
pages (incl. the boiler cascade) + the clears; key the 🔸 fields by hand. Then
`elmhurst_download.py` saves **`elmhurst_summary.pdf`** + **`elmhurst_worksheet.pdf`**
into the sample dir. ⚠ The filler hard-codes one assessment + one cert's values
today — see **Limitations**.
5. **Compare**`PYTHONPATH=/workspaces/model python scripts/compare_epc_paths.py <uprn>`
→ deep-diffs gov-API vs Elmhurst-parsed `EpcPropertyData`, runs **both** through
the engine, and prints Elmhurst's own worksheet SAP. Read it: engine-on-Elmhurst-
inputs ≈ worksheet ⇒ calculator faithful; gov-API vs Elmhurst gap ⇒ input diffs.
6. **Reconcile to ≤0.5** — triage every field diff (use the
`epc-to-elmhurst-rdsap-inputs` `reference/mapping.md` for code semantics):
- **Elmhurst data-entry error** → fix in Elmhurst, re-export, re-run step 5.
- **gov-API mapper gap** → the leverage point. Fix the mapper **generically**;
never tune to one cert. Cosmetic diffs (codes vs strings, empty lists) are noise.
- **Genuine ground-truth** → align both sides to the lodged data.
7. **Pin** — add a `RealCertExpectation` to
`tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py`; run it. If a
known engine bug still blocks, use `known_bug_xfail="…"` (strict xfail) — don't widen.
8. **Bank** — fold what you learned into `mapping.md` / this skill / the tests so
the next UPRN is easier, and set the worklist status (see legend).
## Worklist status legend
`[ ]` todo · `[x]` pinned (≤0.5) · `🔧` mapper extended · `⚠` xfail (engine bug) ·
`⛔` blocked. Annotate each done line: `— <schema> · eng <X> / elm <Y> · <note>`.
## Limitations / next improvements (make the campaign scale)
- **Per-assessment GUID**`elmhurst_fill.py` / `elmhurst_download.py` hard-code
`ASSESSMENT_GUID` (the Khalim-test cert). Each UPRN needs its own Elmhurst
assessment; create one and update the GUID, or parameterize it (`--guid`).
- **Cert-specific fill values**`PAGES` in `elmhurst_fill.py` hold one cert's
values. Make it **data-driven** (read field values from each cert's
`elmhurst_inputs.md` or a JSON sidecar) so one filler serves all UPRNs. Until
then, build each cert guided by its `elmhurst_inputs.md` (the filler is a template).
- **More dialogs** — boiler is automated (cascade); apply the same
open→select→OK pattern to the control code (2110) and the MV unit when wanted.

View file

@ -0,0 +1,39 @@
# Start prompt — run the corpus campaign one UPRN at a time
Paste the block below into Claude to process the **next** UPRN. It does exactly
one UPRN and stops; reply **"next"** (or re-paste) to advance. Reuses the single
Elmhurst assessment/GUID and overwrites it each time — the EPC-API ↔ Input-Summary
diff in the Compare step is the safety net for leftover state.
---
```
Run the `expand-sap-accuracy-corpus` skill to process the NEXT UPRN, ONE at a time.
1. Open `.claude/skills/expand-sap-accuracy-corpus/worklist.md` and take the first `[ ]` UPRN.
2. Run that single UPRN through the skill's loop:
- Capture: `PYTHONPATH=/workspaces/model python scripts/fetch_real_life_epc_sample.py <uprn>`.
If it prints NOT MAPPABLE (schema uncovered), that's the job — extend the
EpcPropertyDataMapper for that schema generically, then re-run. Guard with the
RdSAP-21.0.1 corpus gauge.
- Inputs: run the `epc-to-elmhurst-rdsap-inputs` skill on the UPRN → complete
`elmhurst_inputs.md` (with the "Fields to clear" section).
- Build in Elmhurst, REUSING the existing assessment:
GUID B44A0DB4-4C08-4241-B818-86F060172105 (the "Khalim-test" cert).
`bash scripts/hyde/start_viewer.sh` (noVNC on :99). The filler's PAGES values
are from the previous cert — update them to THIS cert's values from the new
`elmhurst_inputs.md` (it's one-at-a-time, so editing the specs is fine), set
AND clear every field (overwrite the prior UPRN's state — use the Fields-to-clear
list), and key the 🔸 dialog fields by hand. Then run `elmhurst_download.py`
to save `elmhurst_summary.pdf` + `elmhurst_worksheet.pdf` into the sample dir.
NEVER click Submit.
- Compare: `PYTHONPATH=/workspaces/model python scripts/compare_epc_paths.py <uprn>`.
- Reconcile to ≤0.5 SAP: fix mapper gaps GENERICALLY (never tune to one cert);
Elmhurst's Input Summary diff localises them. Cosmetic diffs are noise.
- Pin a RealCertExpectation in
tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py and run it.
Use strict known_bug_xfail for a known engine bug instead of widening.
- Update that worklist line: [x]/🔧/⚠/⛔ — <schema> · eng <X> / elm <Y> · <note>.
3. STOP after this one UPRN. Report: schema, any mapper changes, engine vs Elmhurst
SAP and what reconciled them, and the test result. Then wait for me to say "next".
```

View file

@ -0,0 +1,114 @@
# SAP accuracy corpus — UPRN worklist
Process **one at a time**, top to bottom (see [SKILL.md](SKILL.md)). After each
UPRN, tick it and annotate: `— <schema> · eng <X> / elm <Y> · <note>`.
**Legend:** `[ ]` todo · `[x]` pinned (≤0.5) · `🔧` mapper extended · `⚠` xfail
(engine bug) · `⛔` blocked.
**Worked reference (not in the 100):** `uprn_10092973954` (SAP-Schema-17.1,
2020 new-build flat) — full loop proven: eng 77 / elm 78, engine-on-Elmhurst-
inputs 79 (calculator faithful within ~1). Use it to sanity-check the pipeline.
## The 100
- [ ] 10093116528
- [ ] 10093116543
- [ ] 10093116529
- [ ] 100020933699
- [ ] 44012843
- [ ] 10023444324
- [ ] 10092970673
- [ ] 10094601287
- [ ] 10090844932
- [ ] 10090844948
- [ ] 100090182288
- [ ] 10093114053
- [ ] 10091568921
- [ ] 10093718424
- [ ] 10022893721
- [ ] 10023443426
- [ ] 10093412452
- [ ] 10014314798
- [ ] 10094601294
- [ ] 10090343335
- [ ] 10093115480
- [ ] 68151071
- [ ] 100021985993
- [ ] 100020665611
- [ ] 10093388044
- [ ] 10090944225
- [ ] 10090341811
- [ ] 10010215568
- [ ] 10093117227
- [ ] 10023444170
- [ ] 100020980961
- [ ] 200003714056
- [ ] 10094601280
- [ ] 10093386418
- [ ] 100090108846
- [ ] 10093116324
- [ ] 10094895444
- [ ] 10092973960
- [ ] 10012028763
- [ ] 10093049867
- [ ] 10093116336
- [ ] 100020235156
- [ ] 10093116334
- [ ] 10014314853
- [ ] 10013924849
- [ ] 100062116493
- [ ] 10091636116
- [ ] 10093049853
- [ ] 10093390790
- [ ] 10093116330
- [ ] 10093116326
- [ ] 10090317693
- [ ] 10090034872
- [ ] 10093115985
- [ ] 10023230742
- [ ] 10009432998
- [ ] 100022015916
- [ ] 202211170
- [ ] 200003400077
- [ ] 100061795739
- [ ] 10093305101
- [ ] 100020933894
- [ ] 100020937013
- [ ] 10023444320
- [ ] 100062188801
- [ ] 10008048040
- [ ] 10093101966
- [ ] 10093084691
- [ ] 100061086424
- [ ] 10023443568
- [ ] 100090182702
- [ ] 10090342180
- [ ] 200003398613
- [ ] 10093718415
- [ ] 100061850726
- [ ] 10091636031
- [ ] 10014314830
- [ ] 202211161
- [ ] 10094895409
- [ ] 100060930947
- [ ] 10093388053
- [ ] 100020973465
- [ ] 100062190000
- [ ] 10093114178
- [ ] 10093303593
- [ ] 10093303465
- [ ] 10091194525
- [ ] 10093386427
- [ ] 10002917849
- [ ] 100020212302
- [ ] 10012028772
- [ ] 10093083532
- [ ] 10090034761
- [ ] 10070622696
- [ ] 200003725383
- [ ] 10093387673
- [ ] 10093412389
- [ ] 10090343767
- [ ] 10090845805
- [ ] 10013924858

View file

@ -30,6 +30,14 @@ Sample home for every cert: `backend/epc_api/json_samples/real_life_examples/<sc
**Summary PDF** and the **SAP-10.2 worksheet PDF**, saving them in the sample
dir as **`elmhurst_summary.pdf`** and **`elmhurst_worksheet.pdf`**. (This is
the only manual step — Elmhurst is the accredited ground truth.)
- **Clear the absent elements**, not just the present ones. Work the
`elmhurst_inputs.md` **Fields to clear (do NOT map)** section: blank every
phantom extension, room-in-roof, party wall, surplus window row, cylinder,
etc. An element left at an Elmhurst default reads as *present* and skews
SAP — a class of error that hides on collapsed sub-tabs (1st Ext., etc.).
- `scripts/hyde/elmhurst_fill.py` can drive this (Playwright): it sets and
**clears** fields page by page, navigating to persist (Save & Close = DB
commit). It is a re-keying aid; Elmhurst remains the ground truth.
4. **Compare the two paths**:
```

4
.gitignore vendored
View file

@ -307,3 +307,7 @@ backlog/*
# Local EPC debug cache (scripts/eon)
scripts/eon/epc_cache.pkl
# Elmhurst Playwright session (auth cookies) + captured PDFs (scripts/hyde)
scripts/hyde/.elmhurst-session/
scripts/hyde/elmhurst_downloads/

View file

@ -1,3 +1,4 @@
from pathlib import Path
from typing import Any
from applications.sharepoint_renamer.sharepoint_renamer_request import SharepointRenamerRequest
@ -5,7 +6,7 @@ from orchestration.sharepoint_renamer_orchestrator import SharepointRenamerOrche
from utils.sharepoint.domna_sharepoint_client import DomnaSharepointClient
from utils.sharepoint.domna_sites import DomnaSites
CSV_PATH = "applications/sharepoint_renamer/sero_address_list.csv"
CSV_PATH = str(Path(__file__).parent / "sero_address_list.csv")
def handler(event: dict[str, Any], context: Any) -> None:

View file

@ -0,0 +1,182 @@
# Elmhurst RdSAP inputs — UPRN 60027826 (cert 0080-2673-2086-2299-1061, RdSAP-Schema-20.0.0)
**Lodged SAP:** 72 **Our engine:** 70 ← compare Elmhurst against **70** (the production gov-API path)
**Known divergences:** None of the off-peak Economy-7 bugs apply — this is a **mains-gas** boiler with **mains-gas** hot water. Watch instead: (a) RdSAP-20 synthesised-window U translation, (b) the room-in-roof entry, (c) the unlodged party wall defaulting to U=0.25.
10 Kingsland Close, Shoreham-by-Sea, BN43 6NQ · Semi-detached house · inspected 2021-08-17, lodged 2022-04-13.
---
## Property Description
| Elmhurst field | Value | Notes (SAP code / EES path) |
|---|---|---|
| Property Type | House | `property_type` 0 |
| Built Form | Semi-detached | `built_form` 2 |
| Age Band (England & Wales) | **H — 19911995** | `construction_age_band` H |
| Storeys | **3** | ground + first + room-in-roof (intermediate `storey_count`=3.0) |
| Habitable rooms | 6 | `habitable_room_count` |
| Heated rooms | 6 | `heated_room_count` |
| Extensions | 0 | `extensions_count` |
| Rooms in roof | **Yes — 1** | `sap_room_in_roof` lodged (see Roofs) |
## Dimensions (`measurement_type` 1 = Internal)
| Floor | Area m² | Room Height m | Heat-Loss Perimeter m | Party-Wall Length m |
|---|---|---|---|---|
| Ground (floor 0) | **42.85** | 2.3 | 21.7 | 6 |
| First (floor 1) | **36** | 2.3 | 18 | 6 |
| Room-in-roof | **36** | (entered on Rooms-in-Roof page, not as a dimension floor) | — | — |
TFA check: 42.85 + 36 + 36 = **114.85 m²** (lodged `total_floor_area` 115). No heated basement.
## Conservatory
None — `conservatory_type` 1, `has_heated_separate_conservatory` false → leave unchecked.
## Walls
**Main / external wall**
| Elmhurst field | Value | Notes |
|---|---|---|
| Construction | **Cavity wall** | `wall_construction` 4; description "Cavity wall, filled cavity" |
| Insulation | **Filled cavity** | `wall_insulation_type` 2 (retrofit cavity fill) |
| Dry-lined | **Yes** | `wall_dry_lined` Y |
| Wall Thickness | **300 mm** | `wall_thickness` 300; `wall_thickness_measured` Y → "Wall Thickness Unknown" unchecked |
| (cross-check) | lodged `wall_u_value` 0.33; engine `walls_w_per_k` 26.27 | |
No alternative wall lodged.
**Party wall** — `party_wall_construction` **0 (not lodged)**
| Elmhurst field | Value | Notes |
|---|---|---|
| Type | **Unable to determine** | code 0 → engine default **U = 0.25** (NOT the code-1 "Solid" trap — here it is genuinely unlodged, so "Unable to determine" is correct and matches the engine). Engine `party_walls_w_per_k` 7.275 ≈ 29 m² × 0.25. |
## Roofs
| Elmhurst field | Value | Notes |
|---|---|---|
| Type | **Room in roof** (pitched, slates/tiles) | description "Roof room(s), insulated (assumed)"; `roof_construction` 4 |
| Rooms-in-roof area | **36 m²** | `sap_room_in_roof.floor_area` 36 |
| Rooms-in-roof insulation | **As built** | `sap_room_in_roof.insulation` "AB"; age band H; `roof_room_connected` N |
| Roof insulation location | **At joists** | `roof_insulation_location` 2 |
| Roof insulation thickness | **100 mm** | `roof_insulation_thickness` "100mm" (drives default U) |
| (cross-check) | engine `roof_w_per_k` 24.17 | |
## Floors
| Elmhurst field | Value | Notes |
|---|---|---|
| Construction | **Solid** | `floor_construction` 1; description "Solid, no insulation (assumed)" |
| Insulation | **As built** (none) | `floor_insulation_thickness` "NI" |
| (cross-check) | engine `floor_w_per_k` 30.0 | |
## Openings — Windows (RdSAP reduced-data, synthesised)
Glazed-area band = **Normal** (`glazed_area` 1, ×1.00). Synthesised total glazing area
= 0.148 × 114.85 × 1.00 = **17.02 m²**, split 4-way N/E/S/W (4 windows × 4.255 m wide × 1.0 m high).
| Elmhurst field | Value | Notes |
|---|---|---|
| Glazing Type | **Double, unknown install date** | `multiple_glazing_type` 3; "Fully double glazed" |
| Frame Type | **PVC** | `pvc_window_frames` true |
| Glazing Gap | **16 mm** | `glazing_gap` "16+" |
| Orientation | spread evenly N / E / S / W | not lodged — matches engine synth (orients 1,3,5,7) |
| Location | External wall | |
| Draught Proofed | **Yes (100%)** | `percent_draughtproofed` 100 |
| U-value / g-value | leave Elmhurst default; **lodged U = 2.6, g = 0.76** | `windows_transmission_details`; engine effective U = `windows_w_per_k` 42.86 ÷ 17.02 ≈ **2.52**. ⚠️ Report the U Elmhurst assigns — RdSAP-20 glazing-coefficient translation is the most likely source of the lodged-72-vs-engine-70 gap. |
## Openings — Doors
| Elmhurst field | Value | Notes |
|---|---|---|
| Total doors | **2** | `door_count` 2 |
| Insulated | **0** | `insulated_door_count` 0 |
| Draught proofed | 2 | `percent_draughtproofed` 100 → engine `doors_w_per_k` 11.1 ≈ 2 × 1.85 m² × 3.0 |
## Ventilation & Lighting
| Elmhurst field | Value | Notes |
|---|---|---|
| Open chimneys | 0 | `open_fireplaces_count` 0 |
| Open flues / passive vents / flueless gas / extract fans | 0 | none lodged |
| Fixed air conditioning | No | `has_fixed_air_conditioning` false |
| Mechanical Ventilation | **Natural** (unchecked) | `mechanical_ventilation` 0 |
| Air Pressure Test | **Not available** (uses % draughtproofing) | RdSAP cert |
| Lighting — total fixed outlets | **14** | `fixed_lighting_outlets_count` 14 |
| Lighting — low-energy outlets | **12** | `low_energy_fixed_lighting_outlets_count` 12 (86%) |
## Space Heating
**Main Heating 1** — `sap_main_heating_code` **102**
| Elmhurst field | Value | Notes |
|---|---|---|
| System | **Boiler + radiators, mains gas** | "Boiler and radiators, mains gas"; `main_heating_category` 2; `heat_emitter_type` 1 = radiators |
| Boiler type | **Regular condensing, automatic ignition** | code 102 (Table 4b) |
| Efficiency | **84% winter / 74% summer** | Table 4b code 102; engine `main_heating_efficiency` 0.84. `main_heating_data_source` 2 (age-band/Table default, no PCDB record) |
| Fuel | **Mains gas** | `main_fuel_type` 26 (engine space-heat cost 3.48 p/kWh) |
| Flue | Fanned flue present | `boiler_flue_type` 2, `fan_flue_present` Y |
| Controls | **Programmer + room thermostat + TRVs** | `main_heating_control` 2106 |
| % of heat | 100% | `main_heating_fraction` 1 |
| Heat Emitter / Pump Age | leave default (no PCDF) | `central_heating_pump_age` 0 |
**Main Heating 2** — none (single main system).
**Secondary Heating** — leave Elmhurst **default (assumed portable electric heaters)**.
`secondary_heating_type` 691; engine applies fraction **0.1** at **standard-tariff electricity** (fuel 30), `secondary_heating_fuel_kwh` ≈ 976 kWh. (Cert lodges `secondary_fuel_type` 29 but the engine prices the assumed secondary at standard tariff per SAP convention — leave the Elmhurst default and it agrees.)
**Community Heating** — none.
## Meters
| Elmhurst field | Value | Notes |
|---|---|---|
| Mains gas supply available | **Yes** | `sap_energy_source.mains_gas` Y |
| Electricity meter type | **Single (standard)** | `meter_type` 1 — no Economy-7 here; off-peak fuel-cost bug **does not apply** |
## Water Heating
| Elmhurst field | Value | Notes |
|---|---|---|
| Source | **From main heating system** (Boiler Circulator) | `water_heating_code` 901; "From main system" |
| Fuel | **Mains gas** | `water_heating_fuel` 26 (engine HW cost 3.48 p/kWh) |
| Hot Water Cylinder Present | **Yes** | `has_hot_water_cylinder` true |
| Cylinder size | **110 L** (pick the litre value, not "Normal") | `cylinder_size` code 2 = 110 L |
| Cylinder insulation type | **Factory foam** | `cylinder_insulation_type` 1 = Foam |
| Cylinder insulation thickness | **50 mm** | `cylinder_insulation_thickness` 50 |
| Cylinder thermostat | **Yes** | `cylinder_thermostat` Y |
| (cross-check) | engine `hot_water_kwh_per_yr` 3640 | |
- **Number of baths** (Water Heating → **WWHRS sub-tab → "Total no. of Baths"**): **1**
`instantaneous_wwhrs.rooms_with_bath_and_or_shower` 1 + `rooms_with_bath_and_mixer_shower` 0 = 1. Elmhurst defaults to 0; set it to **1** or HW demand diverges.
- **WWHRS**: **No** — the `instantaneous_wwhrs` block is bath/shower ROOM counts (ADR-0028), not a heat-recovery device.
- **Community Hot Water**: none.
- **Solar Water Heating**: No — `solar_water_heating` N.
- **FGHRS**: No — `main_heating_details[].has_fghrs` N.
## New Technologies
| Elmhurst field | Value | Notes |
|---|---|---|
| PV | **None** | `photovoltaic_supply.none_or_no_details` |
| Wind | **None** | `wind_turbines_count` 0 |
| Hydro | None | not lodged |
| Special Features (Appendix Q) | None | not lodged |
---
### Engine reference outputs (the numbers Elmhurst should reproduce)
| Quantity | Engine value |
|---|---|
| SAP score (integer) | **70** (continuous 69.77) |
| Space-heating demand | 9 755 kWh/yr |
| Main-heating fuel (gas) | 10 452 kWh/yr |
| Hot-water | 3 640 kWh/yr |
| Secondary (electric, assumed) | 976 kWh/yr |
| CO₂ | 3 184 kg/yr |
| Total fuel cost | £824.73/yr |
| Heat-transfer coefficient | 245.96 W/K |
| Heat-loss parameter | 2.14 W/m²K |
**Operator: key this into Elmhurst, then export the Summary PDF (`elmhurst_summary.pdf`) and the SAP-10.2 worksheet PDF (`elmhurst_worksheet.pdf`) into this directory, and report the Elmhurst SAP score.** Then re-run `scripts/compare_epc_paths.py 60027826` to diff the two paths.

View file

@ -0,0 +1,343 @@
{
"uprn": 60027826,
"roofs": [
{
"description": {
"value": "Roof room(s), insulated (assumed)",
"language": "1"
},
"energy_efficiency_rating": 4,
"environmental_efficiency_rating": 4
}
],
"walls": [
{
"description": {
"value": "Cavity wall, filled cavity",
"language": "1"
},
"energy_efficiency_rating": 4,
"environmental_efficiency_rating": 4
}
],
"floors": [
{
"description": {
"value": "Solid, no insulation (assumed)",
"language": "1"
},
"energy_efficiency_rating": 0,
"environmental_efficiency_rating": 0
}
],
"status": "entered",
"tenure": 2,
"window": {
"description": {
"value": "Fully double glazed",
"language": "1"
},
"energy_efficiency_rating": 3,
"environmental_efficiency_rating": 3
},
"lighting": {
"description": {
"value": "Low energy lighting in 86% of fixed outlets",
"language": "1"
},
"energy_efficiency_rating": 5,
"environmental_efficiency_rating": 5
},
"postcode": "BN43 6NQ",
"hot_water": {
"description": {
"value": "From main system",
"language": "1"
},
"energy_efficiency_rating": 4,
"environmental_efficiency_rating": 4
},
"post_town": "SHOREHAM-BY-SEA",
"built_form": 2,
"created_at": "2022-04-13 09:33:39.943417",
"door_count": 2,
"glazed_area": 1,
"glazing_gap": "16+",
"region_code": 14,
"report_type": 2,
"sap_heating": {
"cylinder_size": 2,
"water_heating_code": 901,
"water_heating_fuel": 26,
"cylinder_thermostat": "Y",
"instantaneous_wwhrs": {
"rooms_with_bath_and_or_shower": 1,
"rooms_with_mixer_shower_no_bath": 0,
"rooms_with_bath_and_mixer_shower": 0
},
"secondary_fuel_type": 29,
"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,
"sap_main_heating_code": 102,
"central_heating_pump_age": 0,
"main_heating_data_source": 2
}
],
"immersion_heating_type": "NA",
"secondary_heating_type": 691,
"cylinder_insulation_type": 1,
"has_fixed_air_conditioning": "false",
"cylinder_insulation_thickness": 50
},
"sap_version": 9.94,
"schema_type": "RdSAP-Schema-20.0.0",
"uprn_source": "Energy Assessor",
"country_code": "EAW",
"main_heating": [
{
"description": {
"value": "Boiler and radiators, mains gas",
"language": "1"
},
"energy_efficiency_rating": 4,
"environmental_efficiency_rating": 4
}
],
"dwelling_type": {
"value": "Semi-detached house",
"language": "1"
},
"language_code": 1,
"property_type": 0,
"address_line_1": "10 KINGSLAND CLOSE",
"assessment_type": "RdSAP",
"completion_date": "2022-04-13",
"inspection_date": "2021-08-17",
"extensions_count": 0,
"measurement_type": 1,
"total_floor_area": 115,
"transaction_type": 13,
"conservatory_type": 1,
"heated_room_count": 6,
"pvc_window_frames": "true",
"registration_date": "2022-04-13",
"sap_energy_source": {
"mains_gas": "Y",
"meter_type": 1,
"photovoltaic_supply": {
"none_or_no_details": {
"pv_connection": 0,
"percent_roof_area": 0
}
},
"wind_turbines_count": 0,
"wind_turbines_terrain_type": 2
},
"secondary_heating": {
"description": {
"value": "None",
"language": "1"
},
"energy_efficiency_rating": 0,
"environmental_efficiency_rating": 0
},
"sap_building_parts": [
{
"identifier": "Main Dwelling",
"wall_u_value": 0.33,
"wall_dry_lined": "Y",
"wall_thickness": 300,
"floor_heat_loss": 7,
"sap_room_in_roof": {
"floor_area": {
"value": 36,
"quantity": "square metres"
},
"insulation": "AB",
"roof_room_connected": "N",
"construction_age_band": "H"
},
"roof_construction": 4,
"wall_construction": 4,
"building_part_number": 1,
"sap_floor_dimensions": [
{
"floor": 0,
"room_height": {
"value": 2.3,
"quantity": "metres"
},
"floor_insulation": 1,
"total_floor_area": {
"value": 42.85,
"quantity": "square metres"
},
"party_wall_length": {
"value": 6,
"quantity": "metres"
},
"floor_construction": 1,
"heat_loss_perimeter": {
"value": 21.7,
"quantity": "metres"
}
},
{
"floor": 1,
"room_height": {
"value": 2.3,
"quantity": "metres"
},
"total_floor_area": {
"value": 36,
"quantity": "square metres"
},
"party_wall_length": {
"value": 6,
"quantity": "metres"
},
"heat_loss_perimeter": {
"value": 18,
"quantity": "metres"
}
}
],
"wall_insulation_type": 2,
"construction_age_band": "H",
"party_wall_construction": 0,
"wall_thickness_measured": "Y",
"roof_insulation_location": 2,
"roof_insulation_thickness": "100mm",
"floor_insulation_thickness": "NI"
}
],
"low_energy_lighting": 86,
"solar_water_heating": "N",
"habitable_room_count": 6,
"heating_cost_current": {
"value": 522,
"currency": "GBP"
},
"insulated_door_count": 0,
"co2_emissions_current": 3.4,
"energy_rating_average": 60,
"energy_rating_current": 72,
"lighting_cost_current": {
"value": 111,
"currency": "GBP"
},
"main_heating_controls": [
{
"description": {
"value": "Programmer, room thermostat and TRVs",
"language": "1"
},
"energy_efficiency_rating": 4,
"environmental_efficiency_rating": 4
}
],
"multiple_glazing_type": 3,
"open_fireplaces_count": 0,
"has_hot_water_cylinder": "true",
"heating_cost_potential": {
"value": 486,
"currency": "GBP"
},
"hot_water_cost_current": {
"value": 129,
"currency": "GBP"
},
"mechanical_ventilation": 0,
"percent_draughtproofed": 100,
"suggested_improvements": [
{
"sequence": 1,
"typical_saving": {
"value": 37,
"currency": "GBP"
},
"indicative_cost": "\u00a34,000 - \u00a36,000",
"improvement_type": "W2",
"improvement_details": {
"improvement_number": 58
},
"improvement_category": 5,
"energy_performance_rating": 74,
"environmental_impact_rating": 71
},
{
"sequence": 2,
"typical_saving": {
"value": 42,
"currency": "GBP"
},
"indicative_cost": "\u00a34,000 - \u00a36,000",
"improvement_type": "N",
"improvement_details": {
"improvement_number": 19
},
"improvement_category": 5,
"energy_performance_rating": 75,
"environmental_impact_rating": 73
},
{
"sequence": 3,
"typical_saving": {
"value": 400,
"currency": "GBP"
},
"indicative_cost": "\u00a33,500 - \u00a35,500",
"improvement_type": "U",
"improvement_details": {
"improvement_number": 34
},
"improvement_category": 5,
"energy_performance_rating": 84,
"environmental_impact_rating": 81
}
],
"co2_emissions_potential": 1.8,
"energy_rating_potential": 84,
"lighting_cost_potential": {
"value": 111,
"currency": "GBP"
},
"schema_version_original": "LIG-19.0",
"hot_water_cost_potential": {
"value": 85,
"currency": "GBP"
},
"renewable_heat_incentive": {
"water_heating": 2737,
"impact_of_loft_insulation": -71,
"space_heating_existing_dwelling": 8821
},
"energy_consumption_current": 167,
"has_fixed_air_conditioning": "false",
"multiple_glazed_proportion": 100,
"calculation_software_version": "2.1.1.0",
"energy_consumption_potential": 89,
"environmental_impact_current": 69,
"fixed_lighting_outlets_count": 14,
"windows_transmission_details": {
"u_value": 2.6,
"data_source": 2,
"solar_transmittance": 0.76
},
"current_energy_efficiency_band": "C",
"environmental_impact_potential": 81,
"has_heated_separate_conservatory": "false",
"potential_energy_efficiency_band": "B",
"co2_emissions_current_per_floor_area": 29,
"low_energy_fixed_lighting_outlets_count": 12
}

View file

@ -0,0 +1,182 @@
# Elmhurst RdSAP inputs — UPRN 10092973954 (cert 0862-3892-7875-2690-2325, SAP-Schema-17.1)
**Lodged SAP:** 83 (band B) **Our engine:** 77 (continuous 76.85) ← compare Elmhurst against this
**Total fuel cost (engine):** £445.80/yr **Heat transfer coeff:** 112.11 W/K
**Known divergences:** full-SAP cert forced through RdSAP — window area is banded, U-values/thermal-bridging are age-band proxies (see notes). MEV extract is the engine's 4 SAP driver.
> **Complete + filler-ready.** Every row names the **live Elmhurst control id**
> (suffix after `ContentBody_ContentPlaceHolder1_`) from the DOM dumps in
> `scripts/hyde/elmhurst_dom/`, so `scripts/hyde/elmhurst_fill.py` can map each
> directly. Dropdown values are the **exact option labels** (they carry a code
> prefix, e.g. `F Flat`). 🔸 = **assessor-only** field the EPC can't supply.
> The **Fields to clear** table at the bottom is the explicit "absent" set.
---
## Property Details (admin — does NOT affect SAP)
| Elmhurst field (`id`) | Enter | Notes |
|---|---|---|
| `DropDownListPurpose` | None of the above | not a retrofit/modelling job |
| `DropDownListTenure` | Owner-occupied | `tenure` ND; tenure doesn't affect SAP |
| `DropDownListTransactionType` | None of the above | `transaction_type` 6 = new dwelling (no exact option) |
| `TextBoxInspectionDate` | as lodged | admin only |
## Property Description ✅ committed
| Elmhurst field (`id`) | Enter | Notes |
|---|---|---|
| `DropDownListPropertyType1` | **F Flat** | `property_type` 2 |
| `DropDownListPropertyType2` | **D Detached** | `built_form` 1 (block form) |
| `TextBoxStoreys` | **1** | single-storey flat |
| `TextBoxHabitableRooms` | **3** | back-solved from `living_area` 23.45 / TFA |
| `TextBoxHeatedHabitableRooms` | **3** | all heated |
| `DropDownListDateBuiltMain` | **L 2012-2022** | 2020 build — by YEAR (engine band "M"; see gotcha) |
## Dimensions (Type = Internal) — Lowest Floor row only
| Elmhurst field (`id`, under `…DimensionsMain_`) | Enter | Notes |
|---|---|---|
| `RadioButtonDimensionsType` | Internal | `measurement_type` 1 |
| `TextBoxFloorAreaLowestFloor` | **67.84** | engine TFA (cert top-level 68) |
| `TextBoxRoomHeightLowestFloor` | **2.40** | volume 162.816 ÷ 67.84 |
| `TextBoxWallPerimeterLowestFloor` | **38.14** | heat-loss perimeter (= 91.54 m² ÷ 2.4) |
| `TextBoxPartyWallLengthLowestFloor` | **0** | `party_walls_w_per_k` = 0 |
## Conservatory ✅ already correct
| Elmhurst field (`id`) | Enter | Notes |
|---|---|---|
| `CheckBoxIsConservatory` | unchecked | `conservatory_type` 1 = none |
## Flats
| Elmhurst field (`id`) | Enter | Notes |
|---|---|---|
| `DropDownListPositionOfFlat` | **Ground Floor** | `sap_flat_details.level` 1 / ground-floor flat |
| `TextBoxFloor` | **0** | ground = storey 0 |
| 🔸 `TextBoxStoriesInBlock` | *assessor* | EPC doesn't give block height; not in cert |
| 🔸 `RadioButtonListFlatCoridor` | *assessor* | corridor/stairwell adjacency; `sheltered_sides_count` 1 hints 1 sheltered side |
| 🔸 `TextBoxLengthOfShelteredWall` | *assessor* | only if a sheltered/corridor wall is set |
## Walls (Main + alternative + party)
| Elmhurst field (`id`, under `…WallMain_`) | Enter | Notes |
|---|---|---|
| `DropDownListType` | **TI Timber Frame** | new-build timber frame |
| `DropDownListInsulation` | **A As Built** | factory-insulated |
| `TextBoxWallThickness` | as built | — |
| `CheckBoxUvalueKnown` + U-value | **0.17** if override offered | cert "0.17 W/m²K"; engine wall ≈12.60 W/K |
| `CheckBoxAditionalWallSheltered` / `DropDownListAlternativeWall1Type` | **clear** (area 0) | leftover `SO Solid Brick` is placeholder — see Fields to clear |
| `DropDownListPartyWallType` | n/a | party-wall **length 0** on Dimensions makes type irrelevant |
## Roofs ✅ committed
| Elmhurst field (`id`, under `…RoofMain_`) | Enter | Notes |
|---|---|---|
| `DropDownListType` | **A Another dwelling above** | "(other premises above)" → `roof_w_per_k` = 0 (insulation fields disappear) |
## Floors
| Elmhurst field (`id`, under `…FloorsMain_`) | Enter | Notes |
|---|---|---|
| `DropDownListLocation` | **G Ground floor** | already correct |
| `DropDownListType` | **S Solid** | `floor_type` 2 |
| `DropDownListInsulation` | **A As built** | new-build |
| `CheckBoxUValueKnown` + U-value | **0.13** if override offered | cert "0.13 W/m²K"; engine floor ≈8.82 W/K |
## Openings — Windows (Elmhurst uses a per-window GRID)
RdSAP synthesises window area from `glazed_area` band × TFA = **15.16 m²**
("Much more than typical", ×1.51), whole-window **U 1.4**, **g 0.63**, 5 windows,
PVC frame (factor 0.7). Engine windows = **20.68 W/K**.
| Elmhurst grid field (`id`, under `…WindowsPanel_`) | Enter | Notes |
|---|---|---|
| `DropDownListExtGlazing` | **Double post or during 2022** (high-perf low-E) | cert `glazing_type` 7, 100% multiple-glazed |
| `DropDownListExtFrameType` | **PVC** | `frame_type` 2 |
| `TextBoxExtUValue` | **1.4** | manufacturer whole-window U |
| `TextBoxExtGValue` | **0.63** | cert g |
| 🔸 `TextBoxExtWidth` / `TextBoxExtHeight` / per-row geometry | *assessor* | RdSAP has no per-window geometry; enter rows totalling **15.16 m²**, or one combined row |
| `DropDownListExtOrientation` | as RdSAP default | cert orientations 8,2,6,2,4 — RdSAP ignores per-window orientation |
## Openings — Doors
| Elmhurst field (`id`, under `…DoorsPanel_`) | Enter | Notes |
|---|---|---|
| `TextBoxDoors` | **1** | `door_count` 1 |
| `TextBoxDoorsInsulated` | **1** | new-build, cert door U 1.4 (engine `doors_w_per_k` 2.59) |
## Ventilation & Lighting
| Elmhurst field (`id`) | Enter | Notes |
|---|---|---|
| `TabPanelMechVent_CheckBoxMechanicalVentilation` | **checked → dMEV** | 🔶 `ventilation_type` 6, EXTRACT_OR_PIV_OUTSIDE — the **4 SAP driver** |
| 🔸 `SelectMVDialog_*` (MV unit) | *assessor* | pick the dMEV unit; `is_mechanical_vent_approved_installer_scheme` true |
| `TabPanelAirPressureTest_DropDownListTestMethod` | **Blower Door → 2.6** | `air_permeability` 2.6, `pressure_test` 1 (don't leave "Not available") |
| `TabPanelLighting_*` low-energy | **100% LED** (6 of 6) | "Low energy lighting in all fixed outlets" |
| `TabPanelVentilationPanel_TextBox*` chimneys/flues/fans | **0** | none lodged |
| Sheltered sides | **1** | `sheltered_sides_count` 1 (RdSAP defaults 2 — change) |
## Space Heating — Main Heating 1
Cert: "Boiler and radiators, mains gas", `main_fuel_type` 1, combi, **PCDB index 17929**,
efficiency **89%**, controls **2110** (time + temp zone), radiators.
| Elmhurst field (`id`, under `…MainHeating1_`) | Enter | Notes |
|---|---|---|
| 🔸 `TextBoxPCDFBoilerReference` (via `SelectBoilerDialog`) | **17929** | PCDB index; entered through the boiler-search dialog |
| `RadioButtonListHeatEmitter` | **Radiators** | `heat_emitter_type` 1 |
| `RadioButtonListFlueType` | **Balanced** | room-sealed; `is_flue_fan_present` true |
| `RadioButtonListFanAssistedFlue` | **Yes** | `main_heating_flue_type` 2 |
| `RadioButtonListHeatingPumpAge` | **2013 or later** | `central_heating_pump_age` 2, in heated space |
| 🔸 `TextBoxMainHeatingControls` (via `SelectHeatingControlsDialog`) | **2110** | time & temperature zone control; interlocked |
| `TextBoxPercentageOfHeat` | **100** | single main system |
## Space Heating — Meters
| Elmhurst field (`id`, under `TabPanelMeters_`) | Enter | Notes |
|---|---|---|
| `RadioButtonListElectricityType` | **Single** | `electricity_tariff` 1 — **not** Economy 7 (no off-peak bug here) |
| `CheckBoxMainGas` | **checked** | mains gas available |
## Water Heating
Cert: from main system (combi), `water_heating_code` 901, mains gas. Engine HW = **2,271 kWh/yr**.
| Elmhurst field (`id`, under `TabPanelWaterHeating_`) | Enter | Notes |
|---|---|---|
| 🔸 `TextBoxWaterHeatingCode` | **from main system** (901) | combi; **Boiler Circulator / from main** category (not Water Heater) |
| `CheckBoxHotWaterCylinder` | **unchecked** | combi instantaneous — **no cylinder** (clears CylinderSize/Insulated/Thickness/Thermostat) |
| `TabPanelWWHRS_DropDownListWWHRSPresent` | **No** | none lodged (`instantaneous_wwhrs` = bath/shower ROOM count, ADR-0028, not a device) |
| `TabPanelWWHRS_TextBoxRoomsWithBath` | leave default | baths not separately lodged; `design_water_use` 1 |
## New Technologies ✅ already correct (all none)
| Elmhurst field (`id`) | Enter | Notes |
|---|---|---|
| `…PvPanelData` | None | no PV |
| `…CheckBoxWindTurbinePresent` | unchecked | `wind_turbines_count` 0 |
| `…TextBoxElectricityGenerated` (hydro) | 0 | none |
---
## Fields to clear in Elmhurst (do NOT map)
These default/stale values read as **present** and skew SAP. Blank them.
| Elmhurst page · field (`id`) | Set to | Why absent |
|---|---|---|
| Property Description · `DropDownListDateBuiltFirst``Forth` | (blank) | no extensions lodged |
| Property Description · `DropDownListRoomInRoofMain``Forth` | (blank) | no room-in-roof building part |
| Dimensions · `…TextBoxFloorAreaRoomInRoof` | (blank) | leave empty, **not 0** (0 flags ✖) |
| Dimensions · 1st4th Ext. sub-tabs (`TabPanel1stExt_…` etc.) | 0 / blank | single building part — phantom extension otherwise |
| Walls · `…DropDownListAlternativeWall1Type` + `TextBoxAddWallArea` | (blank / 0) | leftover `SO Solid Brick` placeholder; cert wall is one timber-frame element |
| Walls · `…CheckBoxAditionalWallSheltered` | unchecked | unless an assessor sets a sheltered wall |
| Openings · surplus window grid rows (`GridViewExtendedWidows_DeleteButton_*`) | delete | window count from glazed-area band, not real rows |
| Space Heating · `DropDownListSecondaryHeatingPresent` + `TextBoxSecondaryHeatingCode` | **No** / (blank) | `secondary_heating_category` 1 = None (placeholder `RWM`) |
| Space Heating · `TabPanelMainHeating2_*` | (blank) | single main system |
| Water Heating · `CheckBoxHotWaterCylinder` + cylinder fields | unchecked / (blank) | combi instantaneous, no cylinder |
| Water Heating · Solar (`…CheckBoxSolaWaterHeating`), WWHRS, FGHRS | none | not lodged |
| Conservatory / PV / Wind / Hydro | none | not lodged |
## Engine reference figures (reconcile against Elmhurst's worksheet)
| Quantity | Engine value |
|---|---|
| **SAP score** | **77** (continuous 76.85) |
| Total fuel cost | £445.80/yr |
| Space-heating demand | 3,917.4 kWh/yr |
| Main heating fuel | 4,401.5 kWh/yr |
| Hot water | 2,271.0 kWh/yr |
| Pumps & fans | 483.3 kWh/yr |
| Lighting | 222.4 kWh/yr |
| CO₂ | 1,501.8 kg/yr |
| Heat transfer coefficient | 112.11 W/K |
**Heat-loss element breakdown (W/K):** walls 12.60 · floor 8.82 · roof 0 · party wall 0 ·
windows 20.68 · doors 2.59 · thermal bridging 12.75 · infiltration 54.68 → total HTC 112.11.
> **🔸 Assessor-only fields** (EPC can't supply — a human must set them):
> stories-in-block & corridor type (Flats), per-window geometry rows (Openings),
> boiler PCDB reference 17929 & control code 2110 via their search dialogs
> (Space Heating), MV unit selection (Ventilation), water-heating code dialog.

View file

@ -0,0 +1,438 @@
{
"uprn": 10093116528,
"roofs": [
{
"description": "Average thermal transmittance 0.11 W/m\u00b2K",
"energy_efficiency_rating": 5,
"environmental_efficiency_rating": 5
}
],
"walls": [
{
"description": "Average thermal transmittance 0.19 W/m\u00b2K",
"energy_efficiency_rating": 5,
"environmental_efficiency_rating": 5
}
],
"floors": [
{
"description": "Average thermal transmittance 0.11 W/m\u00b2K",
"energy_efficiency_rating": 5,
"environmental_efficiency_rating": 5
}
],
"status": "entered",
"tenure": "ND",
"windows": {
"description": "High performance glazing",
"energy_efficiency_rating": 5,
"environmental_efficiency_rating": 5
},
"lighting": {
"description": "Low energy lighting in all fixed outlets",
"energy_efficiency_rating": 5,
"environmental_efficiency_rating": 5
},
"postcode": "PO10 8BG",
"data_type": 2,
"hot_water": {
"description": "From main system, flue gas heat recovery",
"energy_efficiency_rating": 5,
"environmental_efficiency_rating": 5
},
"post_town": "EMSWORTH",
"built_form": 2,
"created_at": "2018-06-04 10:56:39",
"living_area": 28.81,
"orientation": 0,
"region_code": 16,
"report_type": 3,
"sap_heating": {
"thermal_store": 1,
"water_fuel_type": 1,
"water_heating_code": 901,
"main_heating_details": [
{
"has_fghrs": "true",
"main_fuel_type": 1,
"heat_emitter_type": 1,
"fghrs_index_number": 60031,
"emitter_temperature": 1,
"is_flue_fan_present": "true",
"main_heating_number": 1,
"main_heating_control": 2110,
"is_interlocked_system": "true",
"main_heating_category": 2,
"main_heating_fraction": 1,
"main_heating_flue_type": 2,
"central_heating_pump_age": 2,
"main_heating_data_source": 1,
"main_heating_index_number": 17644,
"has_separate_delayed_start": "true",
"load_or_weather_compensation": 0,
"is_central_heating_pump_in_heated_space": "true"
}
],
"has_hot_water_cylinder": "false",
"has_fixed_air_conditioning": "false",
"secondary_heating_category": 1
},
"sap_version": 9.92,
"schema_type": "SAP-Schema-17.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": "Air permeability 4.5 m\u00b3/h.m\u00b2 (as tested)",
"energy_efficiency_rating": 4,
"environmental_efficiency_rating": 4
},
"dwelling_type": "Semi-detached house",
"language_code": 1,
"property_type": 0,
"address_line_1": "4, Woodfield Park Road",
"assessment_date": "2018-06-01",
"assessment_type": "SAP",
"completion_date": "2018-06-04",
"inspection_date": "2018-06-01",
"sap_ventilation": {
"psv_count": 0,
"pressure_test": 1,
"air_permeability": 4.5,
"open_flues_count": 0,
"ventilation_type": 1,
"extract_fans_count": 3,
"open_fireplaces_count": 0,
"sheltered_sides_count": 1,
"flueless_gas_fires_count": 0
},
"design_water_use": 1,
"sap_data_version": 9.92,
"total_floor_area": 90,
"transaction_type": 6,
"conservatory_type": 1,
"registration_date": "2018-06-04",
"sap_energy_source": {
"electricity_tariff": 1,
"wind_turbines_count": 0,
"wind_turbine_terrain_type": 2,
"fixed_lighting_outlets_count": 10,
"low_energy_fixed_lighting_outlets_count": 10,
"low_energy_fixed_lighting_outlets_percentage": 100
},
"sap_opening_types": [
{
"name": 1,
"type": 4,
"u_value": 1.4,
"data_source": 2,
"frame_factor": 0.7,
"glazing_type": 4,
"solar_transmittance": 0.72
},
{
"name": 5,
"type": 1,
"u_value": 1.6,
"data_source": 2,
"glazing_type": 1
}
],
"secondary_heating": {
"description": "None",
"energy_efficiency_rating": 0,
"environmental_efficiency_rating": 0
},
"sap_building_parts": [
{
"sap_roofs": [
{
"name": "Roof 1",
"u_value": 0.113,
"roof_type": 2,
"description": "Roof 1",
"total_roof_area": 44.93
}
],
"sap_walls": [
{
"name": "Wall 1",
"u_value": 0.187,
"wall_type": 2,
"description": "External",
"total_wall_area": 67.29,
"is_curtain_walling": "false"
},
{
"name": "Wall 2",
"u_value": 0,
"wall_type": 4,
"description": "To other house",
"total_wall_area": 79.1
}
],
"identifier": "Main Dwelling",
"overshading": 2,
"sap_openings": [
{
"name": 1,
"type": 1,
"width": 0.9,
"height": 2.5,
"location": "Wall 1",
"orientation": 3
},
{
"name": 2,
"type": 1,
"width": 2.85,
"height": 2.5,
"location": "Wall 1",
"orientation": 3
},
{
"name": 3,
"type": 1,
"width": 0.8,
"height": 2.5,
"location": "Wall 1",
"orientation": 3
},
{
"name": 4,
"type": 1,
"width": 1.4,
"height": 2.5,
"location": "Wall 1",
"orientation": 3
},
{
"name": 5,
"type": 5,
"width": 1,
"height": 2.3,
"location": "Wall 1",
"orientation": 0
},
{
"name": 6,
"type": 1,
"width": 1,
"height": 2.45,
"location": "Wall 1",
"orientation": 7
},
{
"name": 7,
"type": 1,
"width": 1.45,
"height": 2.2,
"location": "Wall 1",
"orientation": 7
},
{
"name": 8,
"type": 1,
"width": 1.35,
"height": 2.45,
"location": "Wall 1",
"orientation": 7
}
],
"construction_year": 2017,
"sap_thermal_bridges": {
"thermal_bridges": [
{
"length": 10.75,
"psi_value": 0.3,
"psi_value_source": 2,
"thermal_bridge_type": "E2"
},
{
"length": 9.75,
"psi_value": 0.04,
"psi_value_source": 2,
"thermal_bridge_type": "E3"
},
{
"length": 38.8,
"psi_value": 0.05,
"psi_value_source": 2,
"thermal_bridge_type": "E4"
},
{
"length": 12.94,
"psi_value": 0.16,
"psi_value_source": 2,
"thermal_bridge_type": "E5"
},
{
"length": 12.94,
"psi_value": 0.14,
"psi_value_source": 4,
"thermal_bridge_type": "E7"
},
{
"length": 10,
"psi_value": 0.06,
"psi_value_source": 2,
"thermal_bridge_type": "E10"
},
{
"length": 2.1,
"psi_value": 0.24,
"psi_value_source": 2,
"thermal_bridge_type": "E12"
},
{
"length": 5.2,
"psi_value": 0.09,
"psi_value_source": 2,
"thermal_bridge_type": "E16"
},
{
"length": 5.2,
"psi_value": 0.06,
"psi_value_source": 2,
"thermal_bridge_type": "E18"
},
{
"length": 15.21,
"psi_value": 0.16,
"psi_value_source": 4,
"thermal_bridge_type": "P1"
},
{
"length": 15.21,
"psi_value": 0,
"psi_value_source": 4,
"thermal_bridge_type": "P3"
},
{
"length": 15.24,
"psi_value": 0.24,
"psi_value_source": 4,
"thermal_bridge_type": "P4"
}
],
"thermal_bridge_code": 5
},
"building_part_number": 1,
"sap_floor_dimensions": [
{
"storey": 0,
"u_value": 0.11,
"floor_type": 2,
"description": "Ground floor",
"storey_height": 2.6,
"heat_loss_area": 44.93,
"total_floor_area": 44.93
},
{
"storey": 1,
"u_value": 0,
"floor_type": 3,
"storey_height": 2.6,
"heat_loss_area": 0,
"total_floor_area": 44.93
}
],
"thermal_mass_parameter": 250
}
],
"heating_cost_current": {
"value": 202,
"currency": "GBP"
},
"co2_emissions_current": 1.2,
"energy_rating_average": 60,
"energy_rating_current": 84,
"lighting_cost_current": {
"value": 61,
"currency": "GBP"
},
"main_heating_controls": [
{
"description": "Time and temperature zone control",
"energy_efficiency_rating": 5,
"environmental_efficiency_rating": 5
}
],
"has_hot_water_cylinder": "false",
"heating_cost_potential": {
"value": 202,
"currency": "GBP"
},
"hot_water_cost_current": {
"value": 72,
"currency": "GBP"
},
"suggested_improvements": [
{
"sequence": 1,
"typical_saving": {
"value": 29,
"currency": "GBP"
},
"indicative_cost": "\u00a34,000 - \u00a36,000",
"improvement_type": "N",
"improvement_details": {
"improvement_number": 19
},
"improvement_category": 5,
"energy_performance_rating": 85,
"environmental_impact_rating": 88
},
{
"sequence": 2,
"typical_saving": {
"value": 327,
"currency": "GBP"
},
"indicative_cost": "\u00a35,000 - \u00a38,000",
"improvement_type": "U",
"improvement_details": {
"improvement_number": 34
},
"improvement_category": 5,
"energy_performance_rating": 95,
"environmental_impact_rating": 97
}
],
"co2_emissions_potential": -0.1,
"energy_rating_potential": 95,
"lighting_cost_potential": {
"value": 61,
"currency": "GBP"
},
"schema_version_original": "LIG-17.0",
"hot_water_cost_potential": {
"value": 43,
"currency": "GBP"
},
"is_in_smoke_control_area": "unknown",
"renewable_heat_incentive": {
"rhi_new_dwelling": {
"space_heating": 2310,
"water_heating": 1818
}
},
"seller_commission_report": "Y",
"energy_consumption_current": 75,
"has_fixed_air_conditioning": "false",
"multiple_glazed_percentage": 100,
"calculation_software_version": 6.2,
"energy_consumption_potential": -6,
"environmental_impact_current": 87,
"current_energy_efficiency_band": "B",
"environmental_impact_potential": 97,
"has_heated_separate_conservatory": "false",
"potential_energy_efficiency_band": "A",
"co2_emissions_current_per_floor_area": 13
}