mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
4 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
433f4a49ce |
Slice S0380.99: PCDB Table 329 (MV In-Use Factors) ETL + parser + lookup (PCDF Spec §A.20)
PCDF Spec Rev 6b §A.20 (May 2021) Format 430 — Mechanical Ventilation
In-Use Factors Table. Pcdb10.dat carries Format 432 (header
`$329,432,4,2021,11,25,2`), an extended-field version where Format
430 fields 1-4 (system_type + 3 SFP factors for the "no approved
scheme" variant) align at positions 0..3. The remainder of Format
432 carries MVHR adjustments + "with approved scheme" variants +
additional Format 432 columns, preserved verbatim in `raw` for
follow-up slices.
Per PCDF Spec §A.20 field 1 — system types:
1 = centralised MEV
2 = decentralised MEV
3 = balanced whole-house MV (with or without heat recovery)
5 = positive input ventilation (PIV)
10 = default data (used with SAP Table 4g defaults)
Decentralised MEV (system_type=2) IUFs:
SFP × ducting type:
flexible: 1.45 (field 2)
rigid: 1.30 (field 3)
no-duct: 1.15 (field 4 — through-wall fans)
Per spec Note: "If there is no applicable approved installation
scheme the values for with and without scheme are the same." Cert
000565 lodges "Approved Installation: No" → use the "no scheme"
IUFs.
Validation for cert 000565 against worksheet line (230a):
Σ(SFP_j × FR_j × IUF_j) for the 4 lodged fans:
in-room kitchen: 1×0.15×13×1.45 = 2.8275
in-room other wet: 1×0.15× 8×1.45 = 1.7400
through-wall kitchen: 2×0.11×13×1.15 = 3.2890
through-wall other wet: 3×0.14× 8×1.15 = 3.8640
Σ = 11.7205 W (matches worksheet "total watage = 11.7205")
Σ(FR_j) = 92.0 l/s (matches worksheet "total flow = 92.0000")
SFPav = 11.7205 / 92.0 = 0.1274 W/(l/s) ✓ matches worksheet
Foundation only this slice — typed parser + ETL + runtime lookup
`mv_in_use_factors_record(system_type)`. No cascade integration; no
behavioural change on any cert. Next slice S0380.100 wires the
SFPav formula.
5 Table 329 records ingested. Pyright net-zero per touched file.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
b3330821e7 |
Slice S0380.98: PCDB Table 322 (Decentralised MEV) ETL + parser + lookup (PCDF Spec §A.19)
PCDF Spec Rev 6b §A.19 (May 2021) Format 427 — Decentralised MEV Systems Table. Pcdb10.dat carries the per-fan-configuration block in Format 428 (header `$322,428,72,...`), which drops the spec's per- group "Fan speed setting" string. Each group is a 3-field triplet: (config_code, flow_l_per_s, sfp_w_per_l_per_s). Per the spec § field 14, the 6 fan configurations are: 1 = In-room fan, kitchen 2 = In-room fan, other wet room 3 = In-duct fan, kitchen 4 = In-duct fan, other wet room 5 = Through-wall fan, kitchen 6 = Through-wall fan, other wet room Some configurations may be blank per spec Note 1 — these are not valid SAP selections and are excluded from the SFPav summation downstream. This slice lands the foundation only — typed parser, ETL promotion to typed write, and a runtime lookup `decentralised_mev_record(pcdb_ id)`. No cascade integration yet → no behavioural change on any cert; full test suite + cert 000565 expected fails unchanged. Subsequent slices in the arc: - S0380.99: PCDB Table 329 (In-Use Factors) ETL + lookup - S0380.100: SAP 10.2 §2.6.4 SFPav cascade helper - S0380.101: HP SAP code 211-227 / 521-527 → main_heating_category=4 - S0380.102: wire MEV cascade into pumps_fans Cert 000565 lodges `MV PCDF Reference Number = 500755` (Titon Ultimate dMEV), resolving via this lookup to: config 1 (in-room kitchen): flow=13.0, SFP=0.15 W/(l/s) config 2 (in-room other wet): flow=8.0, SFP=0.15 config 3 (in-duct kitchen): not tested config 4 (in-duct other wet): not tested config 5 (thru-wall kitchen): flow=13.0, SFP=0.11 config 6 (thru-wall other wet): flow=8.0, SFP=0.14 48 Table 322 records ingested. Pyright net-zero per touched file. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
4879e8c3d7 |
Slice S0380.20: extract PCDB keep-hot fields + strict-raise for no-keep-hot combis
Surfaces the SAP 10.2 Appendix J Table 3a sub-row dispatch gap that
masked +0.2..+0.4 SAP residuals on 11 cohort-2 PCDB-listed combi
certs. Identified via cert 7800-1501-0922-7127-3563 (Potterton Promax
Combi 28 HE Plus A, PCDF 15709): cascade used the keep-hot 600 kWh/yr
default; worksheet (61) sums to ~428 kWh/yr via the no-keep-hot
sub-row formula.
Root cause: the PCDB Table 105 record carries keep-hot metadata at
field positions 58 (`keep_hot_facility`) and 59 (`keep_hot_timer`)
per the SAP 10 PCDB spec (private feed for SAP software vendors —
not surfaced on the public PCDB website nor the Open EPC API). The
parser preserved these in `raw=fields` but didn't surface them as
typed attributes, so the cascade had no signal to dispatch the right
Table 3a sub-row.
Two-part change:
1. `domain/sap10_calculator/tables/pcdb/parser.py` — adds typed
`keep_hot_facility` and `keep_hot_timer` fields to
`GasOilBoilerRecord`, parsed from fields[57] and fields[58].
Field enums (per BRE STP09-B04 + SAP 10 PCDB spec):
Field 58: 0=no keep-hot, 1=fuel keep-hot, 2=electric keep-hot,
3=gas+electric keep-hot
Field 59: 0=no timer, 1=overnight time-switch
Verified against cohort-1 fixture 000490 (Vaillant Ecotec Pro 28,
PCDF 10328) — record lodges keep_hot_facility=1, keep_hot_timer=1,
exactly matching the hand-built fixture comment "Combi keep hot
type = Gas/Oil, time clock" at `_elmhurst_worksheet_000490.py:
277-280`.
2. `domain/sap10_calculator/rdsap/cert_to_inputs.py` — adds
`UnresolvedPcdbCombiLoss` exception. `pcdb_combi_loss_override`
now raises (instead of silently returning None) when the PCDB
record has `separate_dhw_tests=0/None` AND
`keep_hot_facility=0/None`. The cascade's only implemented Table
3a row is "with keep-hot, time clock" (600 kWh/yr), which is the
wrong spec row for no-keep-hot combis — silently using it masked
the cohort-2 negative band.
The ETL was re-run to refresh `pcdb_table_105_gas_oil_boilers.jsonl`
with the new typed fields (raw fields unchanged, just additional
columns surfacing what was previously buried).
Cohort distribution after slice:
cohort-1 cert 000490 (Vaillant PCDF 10328, kh=1): NO RAISE — cascade
keep-hot 600 default IS the spec-correct row. Tests still GREEN.
cohort-2: 10 exact + 13 sub-±0.07 + 2 ±0.07..0.5 + 1 ±0.5..1 +
1 ±5+ + 11 RAISES.
The 11 raising certs are now blocked until the Table 3a no-keep-hot
sub-row is implemented (BRE STP09-B04 methodology — pending slice).
Previously these certs silently produced +0.2..+0.4 SAP errors AND
ranged into the big-gap band; raising surfaces the gap rather than
shipping wrong numbers.
Two golden cert tests blocked alongside (Firebird oil PCDF 9005 also
hits this path):
- test_golden_cert_residual_matches_pin[0390-2954-3640-2196-4175]
- test_api_to_domain_mapper_preserves_main_heating_index_number[0390-2954-3640-2196-4175]
Re-enable when the Table 3a no-keep-hot row lands.
Two other tests updated:
- test_main_heating_index_number_in_pcdb_overrides_seasonal_efficiency:
switched from Baxi 98 (sdt=0, kh=None, would raise) to Worcester
PCDF 10241 (sdt=1, routes via Table 3b row 1). Asserts 0.885 not
0.66.
- test_pcdb_combi_loss_override_returns_none_or_raises_for_untested
_or_storage_combis: renamed + extended to pin the new strict-raise
behaviour.
Pyright net-zero per file:
- domain/sap10_calculator/rdsap/cert_to_inputs.py: 35 (baseline 35)
- domain/sap10_calculator/tables/pcdb/parser.py: 0
- domain/sap10_calculator/tables/pcdb/__init__.py: 0
- domain/sap10_calculator/rdsap/tests/test_cert_to_inputs.py: 13 (baseline 13)
- domain/sap10_calculator/rdsap/tests/test_golden_fixtures.py: 1 (was 2 — improved)
Regression baseline: 697 pass + 10 fail (= prior 699 + 10 - 2 dropped
golden parametrize entries for cert 0390-2954-3640-2196-4175).
Spec refs:
- SAP 10 PCDB spec (private SAP software vendor feed) — keep-hot
facility / timer / electric-heater fields at positions 58 / 59 / 60.
- BRE STP09-B04 (combi boiler test methodology) — origin of the
keep-hot Table 3a derivation. URL: https://bregroup.com/documents/d
/bre-group/stp09-b04_combi_boiler_tests
- SAP 10.2 Appendix J Table 3a row-selection — to be implemented per
PCDB keep-hot dispatch in a follow-up slice.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
a7b08a4e8f |
refactor: move docs/sap-spec/ contents into domain/sap10_calculator/
Locality of reference — SAP-specific docs, specs, and runtime data
now live alongside the calculator that consumes them, mirroring the
prior packages→domain layout moves.
Move targets:
- Narrative MDs → domain/sap10_calculator/docs/
NEXT_AGENT_PROMPT.md, HANDOVER_NEXT.md, SAP_CALCULATOR.md
- Spec PDFs → domain/sap10_calculator/docs/specs/
RdSAP 10 Specification 10-06-2025.pdf
PCDF_Spec_Rev-06b_12_May_2021.pdf
sap-10-2-full-specification-2025-03-14.pdf
sap-10-3-full-specification-2026-01-13.pdf
- PCDB runtime data → domain/sap10_calculator/tables/pcdb/data/
pcdb10.dat (8.3MB) + 7× pcdb_table_*.jsonl (18MB total)
Path code rewrites (load-bearing):
- tables/pcdb/__init__.py: replaced parents[4]/'docs'/'sap-spec' with
Path(__file__).resolve().parent/'data' for Table 105 JSONL loading.
- tables/pcdb/postcode_weather.py: same rebase for the pcdb10.dat path
read by _postcode_climate_table().
- tables/pcdb/etl.py __main__: same rebase for the manual ETL invocation
(source + output_dir both now point inside the package).
- tests/test_pcdb_etl.py: _PCDB_DAT_PATH now derives from
parents[1]/'tables'/'pcdb'/'data' (was parents[3]/'docs'/'sap-spec').
Citation rewrites:
- 12 .py docstrings and 4 .md docs (ADRs + READMEs + narrative docs)
had `docs/sap-spec/<file>` strings rewritten to their new locations.
- Two cases where the catch-all sed misfired (an ADR-0009 line about a
PCDB extract; the pcdb __init__.py docstring about ETL output) were
hand-corrected to point at tables/pcdb/data/ rather than docs/specs/.
docs/sap-spec/ is now empty (will be removed in a follow-up sweep or
left as a vestigial empty dir for future repurposing). ADRs 0009 and
0010 remain at docs/adr/ — they're part of the chronological
cross-cutting decision log, not calculator-specific narrative.
Verified:
- Calculator's 1e-4 production gate
(test_api_001479_full_chain_sap_matches_worksheet_pdf_exactly) GREEN.
- Wider sweep (domain/sap10_calculator/ + domain/sap10_ml/): 1654
passed / 20 failed — exact pre-move baseline. All 20 failures
pre-existing (10 hand-built skeleton + 4 cohort chain + 6 cohort
diff).
- Pyright net-zero on the 4 touched runtime/test files (0 errors)
and unchanged on heat_transmission.py (13) / cert_to_inputs.py (35) /
mapper.py (33).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|