diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/elmhurst_inputs.md b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/elmhurst_inputs.md new file mode 100644 index 000000000..f21db927a --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/elmhurst_inputs.md @@ -0,0 +1,127 @@ +# Elmhurst RdSAP inputs — UPRN 10094112770 (cert 9556-3047-3304-5355-1200, SAP-Schema-18.0.0) + +**Lodged SAP:** 81 (B) **Our engine:** 67 (D) ← compare Elmhurst against this +**Property:** Apartment 4, Dovestone Gardens, Briercliffe Road, BURNLEY, BB10 1BB (Calico portfolio 824, property 748351) + +**Known divergence (the whole point of this cert):** the dwelling has **direct-electric +room heaters for space heat** + a **WATER-ONLY communal heat network for hot water** +(`water_heating_code 950`, `community_heating_use 2`; network = 90 % heat pump COP 3.24 ++ 10 % boiler). Our engine drops the community DHW system and prices hot water as **raw +direct electric immersion** — 2,675 kWh ≈ £660 vs **lodged DHW cost £147**. That ~£500 +DHW error is what drags lodged B/81 → effective D/67. Build the **Community Hot Water** +page below faithfully so Elmhurst prices DHW on the heat-pump network; that is the number +we are reconciling to. PR #1688 does not fix this case (its community mapping is gated on +a category-6 *main*; here the main is category-10 electric). + +--- + +## Property Description +| Elmhurst field | Value | Notes (SAP code / EES path) | +|---|---|---| +| Property type | Flat | `property_type` 2 | +| Built form | End-terrace | `built_form` 3 | +| Flat position / which floor | Ground floor | `dwelling_type` = Ground-floor flat | +| Storeys in dwelling | 1 | single-storey flat | +| Above another dwelling? | No (ground floor) | floor is exposed/over unheated | +| Below another dwelling? | **Yes** | roof element = "(other premises above)" → no roof heat loss | +| Age band | **M — 2023 onwards** | 2025 inspection, genuine new build (band M is correct here) | +| Region | North West | BB (Burnley) | +| Country | England | `country_code` ENG | + +## Dimensions +| Elmhurst field | Value | Notes | +|---|---|---| +| Total floor area | **58 m²** | `total_floor_area` 58; single building part "Main Dwelling" | +| Living area | 22.57 m² | `living_area` (→ living-area fraction 0.39; habitable rooms ≈ 3) | +| Room height | ≈ 2.4 m | not lodged in full-SAP payload; use standard new-build flat height | +| Exposed (external) wall area | **37.01 m² gross** | External Wall 1, `total_wall_area` 37.01, U 0.19 (net of ~14.7 m² openings) | +| Heat-loss perimeter | derive from 37.01 m² gross wall ÷ room height | full SAP lodges wall *area*, not perimeter | + +## Walls +| Elmhurst field | Value | Notes | +|---|---|---| +| Wall construction | As built / measured U | `walls` = "Average thermal transmittance 0.19 W/m²K" | +| Wall U-value | **0.19 W/m²K** | External Wall 1, `wall_type` 2 | +| Party wall | **Present — 2 party walls, U = 0** | `wall_type` 4, areas 21.02 + 15.98 m² (Elmhurst "Party wall" = adiabatic, no heat loss) | + +## Roofs +| Elmhurst field | Value | Notes | +|---|---|---| +| Roof | **None / other premises above** | `roofs` = "(other premises above)" → 0 heat loss (flat below another dwelling) | + +## Floors +| Elmhurst field | Value | Notes | +|---|---|---| +| Floor | As built / measured U | `floors` = "Average thermal transmittance 0.17 W/m²K" | +| Floor U-value | **0.17 W/m²K** | ground floor of the flat | + +## Openings — Windows +| Elmhurst field | Value | Notes | +|---|---|---| +| Glazing type | High performance / triple or advanced double | `windows` = "High performance glazing", glazing_type 6, 100 % multiple glazed | +| Window U-value | **1.4 W/m²K** | joined opening-type U | +| Glazed area | as measured | 4 openings totalling ≈ 14.7 m² (W1 0.91×2.24, W2 1.58×2.24, W3+W4 7.08×1.0, W5 0.91×2.24); orientations NE/NW | +| Doors | **none** | `door_count` 0 (flat entrance internal / no external door lodged) | + +## Ventilation & Lighting +| Elmhurst field | Value | Notes | +|---|---|---| +| Ventilation type | **MEV (mechanical extract)** | `ventilation_type` 8; PCDB index **500167**, duct type 2 (rigid), insulated | +| Air permeability | **3.2 m³/h·m² (as tested)** | pressure test = yes | +| Wet rooms | 2 | | +| Sheltered sides | 2 | | +| Lighting | **100 % low-energy** | 10 of 10 fixed outlets low-energy | + +## Space Heating — Main Heating 1 +| Elmhurst field | Value | Notes | +|---|---|---| +| Main heat source | **Room heaters, electric** | `main_heating` desc; SAP code **691**, category 10, fuel 39 (electricity) | +| Emitter | n/a (direct-acting electric) | emitter_temperature "NA" | +| Main heating fraction | 1.0 | single main | +| Controls | **Programmer + appliance thermostats** | `main_heating_controls`; control code 2603 | +| Secondary heating | **None** | `secondary_heating` = None | + +## Space Heating — Meters +| Elmhurst field | Value | Notes | +|---|---|---| +| Electricity tariff / meter | **Standard (single rate)** | `electricity_tariff` 1 — **NOT** Economy 7, so the off-peak over-rating bug does not apply here | + +## Water Heating — **Community Hot Water** (the reconciliation target) +| Elmhurst field | Value | Notes | +|---|---|---| +| Water heating type | **Community / communal heat network** | `water_heating_code` **950** = water-only heat network; `hot_water` desc "Community scheme" | +| Community use | **Water heating only** | `community_heating_use` 2 (space heat is NOT on the network) | +| Heat source 1 | **Heat pump**, **90 %** heat fraction, **efficiency 324 %** (COP 3.24) | `heat_source_type` 3, `fuel_type` 41, `heat_efficiency` 324, `heat_fraction` 0.9 | +| Heat source 2 | **Boiler**, **10 %** heat fraction, efficiency **100 %** | `heat_source_type` 2, `fuel_type` 41, `heat_fraction` 0.1 | +| Distribution loss / type | **Type 3** | `community_heating_distribution_type` 3 | +| Charging linked to use | **Yes** | `charging_linked_to_heat_use` true | +| Cylinder in dwelling | **No** | `is_community_heating_cylinder_in_dwelling` false — no in-dwelling store | +| (cross-check) lodged DHW cost | **£147/yr** | this is the figure the correct build should land near | + +## Anchors to check against Elmhurst output +| Quantity | Lodged (cert) | Our engine (buggy) | +|---|---|---| +| SAP | **81 B** | 67 D | +| Heating cost | £374 | ~£? (space-heat electric) | +| **Hot-water cost** | **£147** | **~£660 (raw electric — the bug)** | +| Lighting cost | £64 | — | +| RHI space / water demand | 1,186 / 1,909 kWh | space 1,039 / DHW 2,675 kWh | + +--- + +## Fields to clear in Elmhurst (do NOT map) +| Elmhurst page · field | Set to | Why absent | +|---|---|---| +| Property Description · 1st–4th Extension age band | (blank) | single building part "Main Dwelling", no extensions | +| Property Description · Room-in-Roof | (blank) | ground-floor flat, no room-in-roof | +| Dimensions · Room(s)-in-Roof area | (blank, not 0) | ditto | +| Dimensions · 1st–4th Ext. sub-tabs | 0 / blank | one building part | +| Roofs · roof area / U | none | "(other premises above)" — flat below another dwelling | +| Openings · Doors | none | `door_count` 0 | +| Openings · surplus window rows | delete beyond the 4 lodged | only 4 openings lodged | +| Space Heating · Main Heating 2 | none | single main | +| Space Heating · Secondary heating | none | `secondary_heating` None | +| **Water Heating · in-dwelling cylinder / immersion** | **none** | `has_hot_water_cylinder` false; DHW is the community network, no local store | +| Water Heating · Solar water heating / WWHRS / FGHRS | none | not lodged (`solar_water_heating` false; `instantaneous_wwhrs` is room-count metadata, not a device) | +| New Technologies · PV / Wind / Hydro | none | none lodged | + diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/elmhurst_summary.pdf new file mode 100644 index 000000000..88adefe4b Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/elmhurst_summary.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/elmhurst_worksheet.pdf new file mode 100644 index 000000000..06681ab1a Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/elmhurst_worksheet.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/epc.json new file mode 100644 index 000000000..9f7321e0c --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-18.0.0/uprn_10094112770/epc.json @@ -0,0 +1,370 @@ +{ + "uprn": 10094112770, + "roofs": [ + { + "description": "(other premises above)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "walls": [ + { + "description": "Average thermal transmittance 0.19 W/m\u00b2K", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "floors": [ + { + "description": "Average thermal transmittance 0.17 W/m\u00b2K", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "status": "entered", + "tenure": 1, + "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": "BB10 1BB", + "data_type": 2, + "hot_water": { + "description": "Community scheme", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 5 + }, + "post_town": "BURNLEY", + "built_form": 3, + "created_at": "2025-04-15 09:28:31", + "living_area": 22.57, + "orientation": 6, + "region_code": 19, + "report_type": 3, + "sap_heating": { + "water_heating_code": 950, + "main_heating_details": [ + { + "main_fuel_type": 39, + "main_heating_code": 691, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2603, + "main_heating_category": 10, + "main_heating_fraction": 1, + "main_heating_data_source": 3 + } + ], + "has_hot_water_cylinder": "false", + "has_fixed_air_conditioning": "false", + "secondary_heating_category": 1, + "sap_community_heating_systems": [ + { + "community_heating_use": 2, + "community_heat_sources": [ + { + "fuel_type": 41, + "heat_fraction": 0.9, + "heat_efficiency": 324, + "heat_source_type": 3 + }, + { + "fuel_type": 41, + "heat_fraction": 0.1, + "heat_efficiency": 100, + "heat_source_type": 2 + } + ], + "charging_linked_to_heat_use": "true", + "community_heating_distribution_type": 3, + "is_community_heating_cylinder_in_dwelling": "false" + } + ] + }, + "sap_version": 9.92, + "schema_type": "SAP-Schema-18.0.0", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Room heaters, electric", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 2 + } + ], + "air_tightness": { + "description": "Air permeability 3.2 m\u00b3/h.m\u00b2 (as tested)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "dwelling_type": "Ground-floor flat", + "language_code": 1, + "property_type": 2, + "address_line_1": "Apartment 4", + "address_line_2": "Dovestone Gardens", + "address_line_3": "Briercliffe Road", + "assessment_date": "2025-04-15", + "assessment_type": "SAP", + "completion_date": "2025-04-15", + "inspection_date": "2025-04-15", + "sap_ventilation": { + "psv_count": 0, + "pressure_test": 1, + "wet_rooms_count": 2, + "air_permeability": 3.2, + "open_flues_count": 0, + "ventilation_type": 8, + "extract_fans_count": 0, + "open_fireplaces_count": 0, + "sheltered_sides_count": 2, + "flueless_gas_fires_count": 0, + "mechanical_vent_duct_type": 2, + "mechanical_vent_duct_insulation": 2, + "mechanical_ventilation_data_source": 1, + "mechanical_vent_system_index_number": 500167, + "is_mechanical_vent_approved_installer_scheme": "false" + }, + "design_water_use": 1, + "sap_data_version": 9.92, + "sap_flat_details": { + "level": 1 + }, + "total_floor_area": 58, + "transaction_type": 6, + "conservatory_type": 1, + "registration_date": "2025-04-15", + "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": "Windows SE SW", + "type": 4, + "u_value": 1.4, + "data_source": 2, + "frame_factor": 0.69, + "glazing_type": 6, + "solar_transmittance": 0.66 + }, + { + "name": "Windows NE NW", + "type": 4, + "u_value": 1.4, + "data_source": 2, + "frame_factor": 0.69, + "glazing_type": 6, + "solar_transmittance": 0.66 + } + ], + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "lzc_energy_sources": [ + 13 + ], + "sap_building_parts": [ + { + "sap_walls": [ + { + "name": "External Wall 1", + "u_value": 0.19, + "wall_type": 2, + "description": "External Wall 1", + "total_wall_area": 37.01, + "is_curtain_walling": "false" + }, + { + "name": "Party Wall 0", + "u_value": 0, + "wall_type": 4, + "total_wall_area": 21.02 + }, + { + "name": "Party Wall 0", + "u_value": 0, + "wall_type": 4, + "total_wall_area": 15.98 + } + ], + "identifier": "Main Dwelling", + "overshading": 2, + "sap_openings": [ + { + "name": "W1", + "type": "Windows NE NW", + "width": 0.91, + "height": 2.24, + "location": "External Wall 1", + "orientation": 8 + }, + { + "name": "W2", + "type": "Windows NE NW", + "width": 1.58, + "height": 2.24, + "location": "External Wall 1", + "orientation": 8 + }, + { + "name": "W3+W4", + "type": "Windows NE NW", + "width": 7.08, + "height": 1, + "location": "External Wall 1", + "orientation": 2 + }, + { + "name": "W5", + "type": "Windows NE NW", + "width": 0.91, + "height": 2.24, + "location": "External Wall 1", + "orientation": 2 + } + ], + "construction_year": 2022, + "sap_thermal_bridges": { + "thermal_bridges": [ + { + "length": 6.56, + "psi_value": 0.3, + "psi_value_source": 2, + "thermal_bridge_type": "E2" + }, + { + "length": 6.56, + "psi_value": 0.04, + "psi_value_source": 2, + "thermal_bridge_type": "E3" + }, + { + "length": 22.4, + "psi_value": 0.05, + "psi_value_source": 2, + "thermal_bridge_type": "E4" + }, + { + "length": 15.42, + "psi_value": 0.114, + "psi_value_source": 3, + "thermal_bridge_type": "E5" + }, + { + "length": 15.42, + "psi_value": 0.07, + "psi_value_source": 2, + "thermal_bridge_type": "E7" + }, + { + "length": 2.4, + "psi_value": 0.09, + "psi_value_source": 2, + "thermal_bridge_type": "E16" + }, + { + "length": 4.8, + "psi_value": 0.06, + "psi_value_source": 2, + "thermal_bridge_type": "E18" + }, + { + "length": 15.42, + "psi_value": 0.16, + "psi_value_source": 4, + "thermal_bridge_type": "P1" + }, + { + "length": 15.42, + "psi_value": 0, + "psi_value_source": 4, + "thermal_bridge_type": "P3" + } + ], + "thermal_bridge_code": 5 + }, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "storey": 0, + "u_value": 0.17, + "floor_type": 2, + "description": "Heat Loss Floor 1", + "storey_height": 2.4, + "heat_loss_area": 58.11, + "total_floor_area": 58.11 + } + ], + "thermal_mass_parameter": 250 + } + ], + "heating_cost_current": { + "value": 374, + "currency": "GBP" + }, + "co2_emissions_current": 1.2, + "energy_rating_average": 60, + "energy_rating_current": 81, + "lighting_cost_current": { + "value": 64, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer and appliance thermostats", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 374, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 147, + "currency": "GBP" + }, + "co2_emissions_potential": 1.2, + "energy_rating_potential": 81, + "lighting_cost_potential": { + "value": 64, + "currency": "GBP" + }, + "schema_version_original": "18.0.0", + "hot_water_cost_potential": { + "value": 147, + "currency": "GBP" + }, + "is_in_smoke_control_area": "unknown", + "renewable_heat_incentive": { + "rhi_new_dwelling": { + "space_heating": 1186, + "water_heating": 1909 + } + }, + "seller_commission_report": "Y", + "energy_consumption_current": 126, + "has_fixed_air_conditioning": "false", + "multiple_glazed_percentage": 100, + "calculation_software_version": "4.14r19", + "energy_consumption_potential": 126, + "environmental_impact_current": 85, + "current_energy_efficiency_band": "B", + "environmental_impact_potential": 85, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 21 +} \ No newline at end of file diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index f5e6593b1..d4150afea 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -1392,6 +1392,39 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="8059-6020-9429-4133-0996", sap_score=72, ), + # UPRN 10094112770 → cert 9556-3047-3304-5355-1200. SAP-Schema-18.0.0 — a + # FULL-SAP cert (2025 new-build GROUND-FLOOR FLAT, Dovestone Gardens, + # Burnley, TFA 58 m²). Direct-electric room heaters for space heat + a + # WATER-ONLY communal heat network for DHW (water_heating_code 950, + # community_heating_use 2; network = 90% heat pump @ COP 3.24 + 10% boiler, + # fuel 41). Lodged 81 (B); engine now produces 80. + # + # This cert IS the water-only community-DHW fix. The gov-API mapper dropped + # `sap_community_heating_systems` for a non-community (category-10) main, so + # the calculator priced communal heat-pump DHW as a DIRECT-ELECTRIC immersion + # cylinder (2675 kWh @ 13.19p ≈ £353) and pinned SAP at 67 (D). Mapping the + # network's fuel onto the DHW cascade (SAP Table 32 code 41 = heat from + # electric heat pump @ 4.24 p/kWh, COP priced into the row) bills DHW at £113 + # and lifts SAP 67 → 80. + # + # Built in Elmhurst RdSAP10 on the lodged inputs (evidence saved: + # elmhurst_summary.pdf / elmhurst_worksheet.pdf): Elmhurst worksheet SAP 74 + # (DHW 1839.64 kWh @ 4.24p = £78, heat pump 300%, distribution loss 1.5). + # The +6 (80 vs 74) is the documented full-SAP→RdSAP methodology gap: the + # engine uses the cert's MEASURED U-values (wall 0.19, floor 0.17) + MVHR + # (PCDB 500167) → space heat 1039 kWh, where Elmhurst RdSAP uses age-band-M + # proxies + a residual build AP50 (4.88 vs the cert's 3.2) → 1676 kWh. A + # KNOWN residual pulls the OTHER way (~-2): the engine still adds an in- + # dwelling cylinder storage loss (2675 vs the worksheet's cylinder-free 1839 + # kWh) though the network cylinder is not in the dwelling — a follow-up DHW- + # energy refinement. PINNED TO THE OBSERVED 80 — mapping deliberately + # untuned; the Elmhurst delta is the full-SAP→RdSAP residual, NOT a bug. + RealCertExpectation( + schema="SAP-Schema-18.0.0", + sample="uprn_10094112770", + cert_num="9556-3047-3304-5355-1200", + sap_score=80, + ), )