Commit graph

7211 commits

Author SHA1 Message Date
Daniel Roth
a7ecb0eaec add local handler and orchestrator 2026-06-30 13:58:41 +00:00
Daniel Roth
78673e96f7 Mapper reads 'Individual Trickle Vent' label variant 🟩
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 13:44:38 +00:00
Daniel Roth
33061ba347 Mapper reads 'Individual Trickle Vent' label variant 🟥
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 13:43:48 +00:00
Daniel Roth
3461b54498 Mapper falls back to legacy trickle vent label for pre-existing API responses 🟩
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 13:34:57 +00:00
Daniel Roth
093563b0c9 Mapper falls back to legacy trickle vent label for pre-existing API responses 🟥
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 13:34:06 +00:00
Daniel Roth
7fcb64bd8c Door columns shift to Q/R/S/T after column P deletion 🟩
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 12:58:46 +00:00
Daniel Roth
372586bb29 Door columns shift to Q/R/S/T after column P deletion 🟥
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 12:58:00 +00:00
Daniel Roth
6cb9800608 Mapper reads new 'Total Trickle Vent Effective Area' label 🟩
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 12:57:26 +00:00
Daniel Roth
54f045f4c6 Mapper reads new 'Total Trickle Vent Effective Area' label 🟥
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 12:56:54 +00:00
Daniel Roth
52749d4931 delete redundant column from spreadsheet 2026-06-30 12:53:29 +00:00
Daniel Roth
550b2ae5e6 revert changes 2026-06-30 11:34:16 +00:00
Daniel Roth
1f0fffe8af Write total trickle vent area to column O; shift door columns to Q/R/S/T 🟩
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 09:59:37 +00:00
Daniel Roth
367fd3664b Write total trickle vent area to column O; shift door columns to Q/R/S/T 🟥
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 09:37:55 +00:00
Daniel Roth
fad7bd6e96
Merge pull request #1363 from Hestia-Homes/fix/hyde-portfolio-audit
fix(full-sap): seven mapper/overlay fixes from the portfolio-796 modelling audit
2026-06-30 10:26:17 +01:00
Khalim Conn-Kowlessar
2c851e9e5e Re-baseline pins for full-SAP PV + tariff mapper fixes 🟩
The PV-array (ea7f4f43) and electricity-tariff (6ec09892) mapper fixes shifted
the observed output of five frozen gates that weren't updated alongside:

- has_pv component-accuracy floor 0.9798 -> 0.9697: carrying full-SAP lodged PV
  now reads the true has_pv=True for full-SAP PV dwellings, so the leave-one-out
  scorer's actual changes (ground-truth-method shift, ADR-0037 pattern).
- uprn_10093116528 80->... pin 82 -> 83: tariff=1 (standard) was wrongly read as
  dual/Economy 7; translating to "single" re-prices the gas semi's electricity.
- uprn_10096028301 82 -> 84, uprn_10023444324 80 -> 82 (== lodged 82),
  uprn_10023444320 81 -> 83: now credit the lodged sap_energy_source.pv_arrays
  the schema previously dropped. Comments document the per-cert PV/Elmhurst
  relationship (incl. the mid-floor sibling landing +2 over its lodged integer).

Pre-existing, unrelated failures untouched: the missing
sap_16_0_full_no_floor_dims.json fixture and the RdSAP-21 floor-area test (both
reproduce on origin/main).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 09:18:39 +00:00
Daniel Roth
398016505d
Merge pull request #1362 from Hestia-Homes/audit/portfolio-796-scenario-1268
docs(audit): record stale-default-plan expectation + default-plan-only rule
2026-06-30 08:36:29 +01:00
Khalim Conn-Kowlessar
0b8765481d Engine now matches lodged 82 on a PV cert (was under-rating to 80) 🟩
Crediting the full-SAP lodged PV closes the 2-point under-rating on uprn
10023444324 — the engine now reproduces the accredited lodged value exactly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 22:01:33 +00:00
Khalim Conn-Kowlessar
ea7f4f4329 Carry full-SAP lodged PV arrays through to the domain 🟩
Full-SAP certs lodge measured PV under sap_energy_source.pv_arrays, but the
SAP-Schema-17.1 SapEnergySource modelled only wind, so from_dict dropped it at
parse and the mapper hardcoded no PV. A new SapPvArray schema field + the
_sap_17_1_pv_arrays mapper helper carry it to the domain photovoltaic_arrays the
Appendix-M generation credit reads — without it an all-electric dwelling the
array lifts to A/B is mis-modelled down a band or more.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 21:59:21 +00:00
Khalim Conn-Kowlessar
4393812638 Carry full-SAP lodged PV arrays through to the domain 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 21:51:09 +00:00
Khalim Conn-Kowlessar
e02e6a76e1 Preserve an existing more-off-peak cert meter under a heating overlay 🟩
A landlord heating override DESCRIBES the dwelling, so its assumed off-peak meter
(Dual/E7) is a coherent default — it must not downgrade a cert that already
lodges a more-off-peak meter (e.g. property 709874's 24-hour all-low tariff). The
overlay opts in via keep_existing_off_peak_meter; _fold_heating then keeps the
cert's meter when both it and the desired meter are off-peak. Heating MEASURES
build HeatingOverlay directly and leave the flag False, so they still re-meter
for real (Elmhurst re-lodges 18-hour -> Dual on a storage install) — the cascade
pins stay green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:32:31 +00:00
Khalim Conn-Kowlessar
e3c023e0f6 Preserve an existing more-off-peak cert meter under a heating overlay 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:00:41 +00:00
Khalim Conn-Kowlessar
6279924773 Stop a System-built landlord override being mis-read as a basement 🟩
System-built is RdSAP code 6, colliding with the gov-EPC code-6 basement
sentinel that main_wall_is_basement falls back to. The wall overlay now pins
wall_is_basement=False for system-built, mirroring the gov-API mapper's
_clear_basement_flag_when_system_built, so the override no longer adds a phantom
basement (which inflated both wall and ground-floor heat loss).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:37:11 +00:00
Khalim Conn-Kowlessar
da17ddce8f Stop a System-built landlord override being mis-read as a basement 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 19:30:25 +00:00
Khalim Conn-Kowlessar
6ec0989283 Translate full-SAP electricity tariff into the RdSAP meter type 🟩
Full-SAP energy_tariff (1=standard/2=7hr/3=10hr/4=24hr) and RdSAP meter_type
(1=dual/2=single/3=unknown/4=24hr) are different code spaces; the mapper passed
the code through untranslated, reading standard-tariff full-SAP certs as Economy 7
(over-rated) and Economy-7 certs as single (under-rated). Map onto the RdSAP word
aliases so the resolved Table 12a tariff is correct; absent/ND -> unknown.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 18:54:51 +00:00
Khalim Conn-Kowlessar
a764b5fa9c Translate full-SAP electricity tariff into the RdSAP meter type 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 18:45:27 +00:00
Khalim Conn-Kowlessar
4e96ea91a5 Assume a dual Economy-7 meter for all-electric room-heater dwellings 🟩
Electric room heaters (691) get a Dual meter from the overlay (not single-rate):
an all-electric room-heater dwelling realistically bills on Economy 7, and the
§12 dispatch then applies a high/low split rather than a single-rate over-penalty.
Overlay owns its assumed-meter policy via _ASSUMED_DUAL_METER_CODES (the §12
off-peak systems + room heaters), keeping OFF_PEAK_IMPLYING_HEATING_CODES pure.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 16:18:13 +00:00
Khalim Conn-Kowlessar
13f1981776 Assume a dual Economy-7 meter for all-electric room-heater dwellings 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 16:15:48 +00:00
Khalim Conn-Kowlessar
54acc0388b docs(audit): record stale-default-plan expectation + default-plan-only rule 🟪
Portfolio-796/scenario-1268 audit found the bulk of MEDIUM/HIGH anomalies
(already-meets-goal-with-works, zero-works-post-differs, plan-score-below-
baseline, and the non-fuel-switch slice of negative-bill-savings) trace to one
root cause: the persisted default plan is stale relative to the live model, so
it resolves on re-model rather than a code change. Confirmed via
run_modelling_e2e on three samples (stored vs live plans differ wholesale).

No new check added — the staleness is already surfaced by the existing checks
and addressed by the override-aware-rebaseline / persistence-fidelity work, so
a new check would only re-flag known divergence. Instead record the expectation
and the "audit the default plan only" rule in the skill Notes so the next
reviewer starts ahead. References kept to durable docs/adr (no PR numbers).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 16:08:17 +00:00
Khalim Conn-Kowlessar
4b2f406b6c Add Electric room heaters as a canonical landlord heating archetype 🟩
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 16:01:07 +00:00
Khalim Conn-Kowlessar
2b0b7eff91 Add Electric room heaters as a canonical landlord heating archetype 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 16:00:36 +00:00
Daniel Roth
085bd29af4
Merge pull request #1359 from Hestia-Homes/fix/heat-pump-flow-temp-efficiency
fix(sap): heat-pump PSR-extension + water-heating 100% floor (Appendix N)
2026-06-29 16:59:47 +01:00
Khalim Conn-Kowlessar
ada2bc078e Map landlord electric room heaters to the direct-acting room-heater SAP code 🟩
'Electric room heaters' archetype -> SAP Table 4a code 691 (panel/convector/
radiant), on a single-rate meter (691 is not off-peak-implying, unlike storage).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 15:59:25 +00:00
Khalim Conn-Kowlessar
ce59413f46 Map landlord electric room heaters to the direct-acting room-heater SAP code 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 15:58:34 +00:00
Daniel Roth
6c42065304
Merge pull request #1358 from Hestia-Homes/feature/batch-save-and-delete-epc
Batch saving and deleting of epc property data, bulk saving of plans
2026-06-29 16:46:19 +01:00
Khalim Conn-Kowlessar
8914496456 test(accuracy): ratchet after HP water-heating 100% floor 🟪
The Appendix N3.7 water-heating 100% floor drops corpus MAE 0.726 -> 0.721
and lifts within-0.5 74.1% -> 74.2% on the 1000-cert RdSAP-21.0.1 sample
(cert 100110101713 moves inside +-0.5). Tighten the MAE ceiling to 0.722 and
the within-0.5 floor to 0.742, and log the slice.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 15:40:53 +00:00
Daniel Roth
c202f15d8c fix broken unit tests 2026-06-29 15:40:22 +00:00
Khalim Conn-Kowlessar
dbaf3c49e2 fix(hp): floor heat-pump water-heating efficiency at 100% (App N3.7) 🟩
_heat_pump_apm_efficiencies applied the Table N8 in-use factor to the PCDB
water-heating efficiency but omitted the spec's "subject to a minimum
efficiency of 100%" clause (SAP 10.2 Appendix N3.7, PDF p.109). An oversized
heat pump whose PSR-extended water,3 x the 0.60 in-use factor fell below
100% therefore billed water heating at that sub-100% efficiency, over-
counting hot-water fuel.

Apply max(in_use x eta_water, 100%). Accredited Elmhurst worksheet for cert
100110101713 (golden fixture case 56, PCDB 100061): water (216) = 100.0000,
which we now match (was 77.13%). Combined with the space-heating PSR-
extension fix the cert lands 72.51 vs lodged 73 (|err| 18.32 -> 0.49).

Data-driven: only the single oversized-PSR cert moves (in-range heat pumps
keep their > 100% water COP, e.g. case 54 112.5%, case 55 179.6%). Corpus
(RdSAP-21.0.1 n=1000) MAE 0.726 -> 0.721, within-0.5 74.1% -> 74.2%.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 15:38:31 +00:00
Khalim Conn-Kowlessar
672e6679c8 test(hp): floor heat-pump water-heating efficiency at 100% (App N3.7) 🟥
SAP 10.2 Appendix N3.7 ("Thermal efficiency for water heating - heat pumps",
PDF p.109): "multiply the thermal efficiency for water heating by the in-use
factor in Table N8; subject to a minimum efficiency of 100%." Our
_heat_pump_apm_efficiencies applies the in-use factor but omits the floor.

Anchored to golden fixture case 56 (PCDB 100061, cert 100110101713): an
oversized HP (PSR 3.107) extends water,3 198.9% -> 128.55%, x 0.60 in-use =
77.13% < 100% -> the accredited Elmhurst worksheet (216) reads 100.0000, we
read 77.13%. In-range PSR keeps 0.60 x 198.9 = 119.34% (above the floor).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 15:33:04 +00:00
Khalim Conn-Kowlessar
235c2ca466 Merge remote-tracking branch 'origin/main' into fix/heat-pump-flow-temp-efficiency 2026-06-29 15:17:10 +00:00
Khalim Conn-Kowlessar
2d6479536c test(accuracy): ratchet SAP MAE 0.740 -> 0.726 after HP PSR-extension 🟪
The heat-pump PSR-extension fix (SAP 10.2 Appendix N2) drops corpus MAE from
0.740 to 0.726 on the 1000-cert RdSAP-21.0.1 sample; within-0.5 holds at
74.1%. Tighten the ceiling and log the slice.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 15:16:07 +00:00
Jun-te Kim
d732ec3fa3
Merge pull request #1357 from Hestia-Homes/chore/devcontainer-pyright
Add pyright + pandas-stubs to backend devcontainer
2026-06-29 16:14:39 +01:00
Khalim Conn-Kowlessar
51d8f65aac fix(pcdb): extend heat-pump efficiency toward 100% beyond table PSR range 🟩
interpolate_heat_pump_efficiency_at_psr clamped to the smallest/largest PSR
row when the dwelling's plant size ratio fell outside the record's range.
That is the SAP 10.2 Appendix N rule for *combined heat-pump-and-boiler*
packages, not for a plain air/ground/water source heat pump.

Per Appendix N2 (PDF p.101, footnotes 44/45) a source heat pump whose PSR
exceeds the record's largest value takes a reciprocal-linear interpolation
between the largest-PSR efficiency and 100% at twice that PSR (100% beyond),
and 100% when the PSR is below the record's smallest value. Both the space-
and water-heating PSR-dependent efficiencies extend this way.

Effect: an oversized heat pump in a small dwelling is no longer credited the
full top-of-table COP. Accredited Elmhurst worksheet for cert 100110101713
(golden fixture case 56, PCDB 100061, PSR 3.107 over largest 2.0): (206)
334.4% -> 139.66% = Elmhurst exact. Corpus (RdSAP-21.0.1, n=1000) MAE
0.7397 -> 0.7258, within-0.5 0.7410 held; only two certs move (both
oversized-PSR heat pumps), 100110101713 +18.32 -> -4.97.

Exhaust-air and combined heat-pump-and-boiler packages have different
boundary rules (straight-to-100% / clamp-to-edge) but are not distinguished
by the current PCDB parse; the air/ground/water rule is applied uniformly,
a documented limitation noted in the function docstring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 15:13:16 +00:00
Jun-te Kim
c2e6b88744 Add pyright + pandas-stubs to backend devcontainer for the strict type gate
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 15:10:40 +00:00
Daniel Roth
4764bc7c15 Batch plan saves reduce RDS CPU during bulk modelling runs 🟪
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 15:08:47 +00:00
Khalim Conn-Kowlessar
3d93c7b7d5 test(pcdb): PSR-extension toward 100% above largest / below smallest 🟥
SAP 10.2 Appendix N2 (PDF p.101, footnote 44/45): for an air/ground/water
source heat pump whose plant size ratio exceeds the record's largest PSR,
the efficiency is reciprocal-interpolated between the largest-PSR value and
100% at twice the largest PSR (100% beyond that); below the smallest PSR the
efficiency is 100%. Our interpolator instead clamps to the top/bottom row.

Anchored to the accredited Elmhurst worksheet for cert 100110101713 (golden
fixture case 56, PCDB 100061): PSR 3.10665 over the record's largest 2.0
gives eta_space,1 = 147.011 -> (206) = 0.95 x 147.011 = 139.660, vs the
clamped 352.0 -> 334.4% that over-rates the dwelling by +18 SAP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 15:08:15 +00:00
Daniel Roth
46ca714ef9 Batch plan saves reduce RDS CPU during bulk modelling runs 🟩
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 15:06:47 +00:00
Daniel Roth
9c6b477025 Batch plan saves reduce RDS CPU during bulk modelling runs 🟥
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 15:04:54 +00:00
Daniel Roth
9f0dd067f8 Merge branch 'main' into feature/batch-save-and-delete-epc 2026-06-29 14:38:57 +00:00
Daniel Roth
597510b996
Merge pull request #1353 from Hestia-Homes/feature/dont-resave-epc-if-refetch-false
Don't re-save EPC data which has been read from database rather than fetched. Also turn on database insights
2026-06-29 15:14:14 +01:00
Daniel Roth
0718533d3a turn on rds performance insights 2026-06-29 14:09:24 +00:00