mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Per SAP 10.2 §4 line (64)m: `(64)m = max(0, (62)m + (63a)m + (63b)m
+ (63c)m + (63d)m)` where (63c)m is the solar HW credit lodged as a
negative quantity. The cascade hardcoded (63c)m = 0 since S0380.66
when the Appendix H orchestrator landed without integration, pending
the 1.81× over-count resolution (closed in S0380.74).
This slice plumbs the orchestrator into `water_heating_from_cert`
via a new `solar_water_heating_monthly_kwh_override` parameter, and
adds `_solar_hw_monthly_override` in cert_to_inputs.py that drives
the orchestrator from RdSAP 10 §10.11 Table 29 defaults +
cert-lodged collector geometry on Elmhurst Summary §16.0.
RdSAP 10 §10.11 Table 29 row "Solar panel" (p.58, verbatim):
"If solar panel present, the parameters for the calculation not
provided in the RdSAP data set are:
- panel aperture area 3 m²
- flat panel, η₀ = 0.80, a₁ = 4.0, a₂ = 0.01
- facing South, pitch 30°, modest overshading
- …
- pump for solar-heated water is electric (75 kWh/year)
- showers are both electric and non-electric"
Lodged collector orientation / pitch / overshading on the Summary
§16.0 ("Are details known? Yes" branch) override South / 30° /
Modest. Aperture, η₀, a₁, a₂, IAM stay at Table 29 defaults — the
deeper thermal parameter lodgement (P960 worksheet) isn't yet in
the Summary extractor surface.
For (H17)m to include storage + primary + combi losses, the cascade
runs a `demand_pass` call without solar (gets (62)m) before sizing
the solar credit. The final call then uses all overrides.
Files:
- datatypes/epc/surveys/elmhurst_site_notes.py: Renewables gains
`solar_hw_collector_orientation` / `_pitch_deg` / `_overshading`
optional fields.
- datatypes/epc/domain/epc_property_data.py: same three fields
added at the end of the dataclass.
- datatypes/epc/domain/mapper.py: from_elmhurst_site_notes
propagates the three new fields.
- backend/documents_parser/elmhurst_extractor.py: §16.0 section
parsing reads "Collector orientation" / "Collector elevation" /
"Overshading" rows; `_parse_solar_pitch_deg` strips the degree
glyph.
- domain/sap10_calculator/worksheet/water_heating.py: new
`solar_water_heating_monthly_kwh_override` param on
`water_heating_from_cert`; threaded into `output_from_water_
heater_monthly_kwh(solar_monthly_kwh=...)`.
- domain/sap10_calculator/rdsap/cert_to_inputs.py: Table 29
constants + `_solar_hw_monthly_override` helper +
`_orientation_from_summary_string` mapper. Added the demand_pass
intermediate call so (H17)m sees the full (62)m. Negates the
orchestrator output at the boundary (spec convention: heat
displaced from boiler is negative on line (63c)m).
Cert 000565 cascade pin shifts:
- hot_water_kwh_per_yr: +271.84 → −68.96 (4× closer)
- sap_score_continuous: +0.6334 → +0.7732 (drift downstream of HW)
- ecf: −0.0643 → −0.0784 (drift)
- total_fuel_cost: −56.08 → −68.36 (drift)
- co2: −19.77 → −22.66 (drift)
- sap_score (int): 29 EXACT (unchanged)
- space_heating / main_heating_fuel / lighting / pumps_fans:
unchanged
The remaining −69 kWh HW residual is the gap between Table 29
defaults (H12 = 75 L separate tank) and cert 000565's lodged H12 =
53 L + combined cylinder 160 L. Closing this requires extracting
solar storage volume + combined-cylinder routing from the cert (P960
worksheet block lodges these explicitly; Summary doesn't). That's
the follow-on slice.
Test baseline: 547 pass + 9 expected `test_sap_result_pin[000565-*]`
fails preserved. Cohort-2 + ASHP cohort + all golden fixtures
untouched (no certs other than 000565 lodge `solar_water_heating =
True`).
Pyright net-zero on touched files (68 errors at baseline = 68 errors
post-change).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| handler | ||
| tests | ||
| __init__.py | ||
| db_writer.py | ||
| elmhurst_extractor.py | ||
| extractor.py | ||
| local_runner.py | ||
| parser.py | ||
| pdf.py | ||