diff --git a/.claude/skills/expand-sap-accuracy-corpus/SKILL.md b/.claude/skills/expand-sap-accuracy-corpus/SKILL.md index 954264e70..25769ad4e 100644 --- a/.claude/skills/expand-sap-accuracy-corpus/SKILL.md +++ b/.claude/skills/expand-sap-accuracy-corpus/SKILL.md @@ -169,6 +169,34 @@ Pattern: `with E.session() as (ctx,page): E.goto(...); E.set_text/set_select(... lines 17/18). This drove the first campaign mapper fix — see Banked findings. ## Banked findings (fold new ones in here as the corpus grows) +- **Register cost-triangulation (no Elmhurst needed):** the register lodges + `heating_cost_current` / `hot_water_cost_current` / `lighting_cost_current` + at RETAIL prices — absolute £ never match SAP Table-12 spec prices, but for + same-fuel end-uses the RATIOS localize a divergence without a worksheet. + Normalize by lighting: `(lodged_hw/lodged_light) / (our_hw/our_light)` ≈ 1 + means our water cascade agrees with the lodging software; »1 flags the + divergent end-use. CAVEAT: the register's "hot water cost" INCLUDES the + SAP (64a) electric-shower electricity — add `instant_shower` cost to our + hw bucket before comparing on any electric-shower cert, else every + shower-outlet-type-2 cert false-positives at ratio ~2 (corpus-1000 band + triage, 36 certs, mean ratio 2.0 → 1.04 after adding (64a)). +- **Lodging-software conventions diverge from Elmhurst on two known axes** + (mark such corpus certs ⚠, don't tune): (a) out-of-range-PSR database + heat pumps — SAP 10.2 N2 footnotes 44/45 mandate the reciprocal extension + toward 100% at 2× the record's largest PSR (Elmhurst does this, golden + case 56); at least one software bills 100% direct electric + standard + schedule instead (corpus 4510053280, lodged 51 vs engine/Elmhurst-method + 75). (b) a lodged 0 extract fans — Elmhurst renders 0 as "unknown" → + Table 5 age-band default (worksheet case 46); LIG-21.0 lodgements + (calculation_software_version 10.2.2.0) honour the 0 literally (corpus + quadruplet at Δ −2.56, fans account for 1.42). +- **"insulated (assumed)" roof ≠ observed retrofit:** RdSAP renders + "(assumed)" when insulation PRESENCE is an age-band assumption — Table 18 + age default governs, for BOTH the "ND" and "NI" thickness sentinels + (which are lodging-software noise). The §5.11.4 50 mm row (U 0.68) is + only for the bare "insulated" description (observed retrofit, depth + unknown). Fixed in u_roof (corpus 74.2% → 75.5%); unit-pinned in + test_rdsap_uvalues. - **MAPPER GAP — cylinder insulation thickness dropped (RdSAP-17.0+):** the mapper carries `cylinder_size` + `cylinder_insulation_type` but NOT `cylinder_insulation_thickness` → `EpcPropertyData.sap_heating.cylinder_ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100040550095/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100040550095/epc.json new file mode 100644 index 000000000..98b566cf4 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100040550095/epc.json @@ -0,0 +1,510 @@ +{ + "uprn": 100040550095, + "roofs": [ + { + "description": "Pitched, 175 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Granite or whin, as built, no insulation (assumed)", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + }, + { + "description": "Solid brick, as built, no insulation (assumed)", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "floors": [ + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "addendum": { + "stone_walls": "true" + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "TQ1 2BW", + "hot_water": { + "description": "Electric immersion, standard tariff", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 5 + }, + "post_town": "TORQUAY", + "built_form": 4, + "created_at": "2026-05-20 13:21:34", + "door_count": 2, + "region_code": 15, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 2, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 2 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 903, + "water_heating_fuel": 29, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 29, + "heat_emitter_type": 0, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2603, + "main_heating_category": 10, + "main_heating_fraction": 1, + "sap_main_heating_code": 691, + "main_heating_data_source": 2 + } + ], + "immersion_heating_type": 2, + "cylinder_insulation_type": 2, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 38 + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 0.91, + "window_height": 1.64, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 0.91, + "window_height": 1.64, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 0.62, + "window_height": 0.91, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.2, + "window_height": 0.88, + "draught_proofed": "true", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.02, + "window_height": 0.82, + "draught_proofed": "true", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 0.6, + "window_height": 1.14, + "draught_proofed": "true", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Room heaters, electric", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 5 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Mid-terrace house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "11 Meadfoot Lane", + "assessment_type": "RdSAP", + "completion_date": "2026-05-20", + "inspection_date": "2026-05-20", + "extensions_count": 1, + "measurement_type": 1, + "total_floor_area": 59, + "transaction_type": 8, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2026-05-20", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "extract_fans_count": 1, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 510, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 1, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.31, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 17.29, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 7.27, + "quantity": "metres" + }, + "floor_construction": 1, + "heat_loss_perimeter": { + "value": 4.72, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.35, + "quantity": "metres" + }, + "total_floor_area": { + "value": 17.29, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 7.27, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 4.72, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "A", + "party_wall_construction": 1, + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "175mm", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + }, + { + "identifier": "Extension 1", + "wall_dry_lined": "N", + "wall_thickness": 185, + "floor_heat_loss": 7, + "sap_room_in_roof": { + "floor_area": 12.24, + "room_in_roof_type_2": { + "gable_wall_type_1": 1, + "gable_wall_type_2": 3, + "gable_wall_height_1": 2.5, + "gable_wall_height_2": 2.5, + "gable_wall_length_1": 7.39, + "gable_wall_length_2": 7.39, + "common_wall_height_1": 1.5, + "common_wall_height_2": 1.5, + "common_wall_length_1": 1.4, + "common_wall_length_2": 1.4 + }, + "construction_age_band": "A" + }, + "roof_construction": 5, + "wall_construction": 3, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.27, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 12.24, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 7.39, + "quantity": "metres" + }, + "floor_construction": 1, + "heat_loss_perimeter": { + "value": 2.8, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "A", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 4, + "roof_insulation_thickness": "ND", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 1266, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 1.1, + "energy_rating_average": 60, + "energy_rating_current": 40, + "lighting_cost_current": { + "value": 43, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer and appliance thermostats", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 366, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 679, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 449, + "currency": "GBP" + }, + "indicative_cost": "\u00a37,500 - \u00a311,000", + "improvement_type": "Q", + "improvement_details": { + "improvement_number": 7 + }, + "improvement_category": 5, + "energy_performance_rating": 55, + "environmental_impact_rating": 88 + }, + { + "sequence": 2, + "typical_saving": { + "value": 57, + "currency": "GBP" + }, + "indicative_cost": "\u00a35,000 - \u00a310,000", + "improvement_type": "W2", + "improvement_details": { + "improvement_number": 58 + }, + "improvement_category": 5, + "energy_performance_rating": 56, + "environmental_impact_rating": 89 + }, + { + "sequence": 3, + "typical_saving": { + "value": 100, + "currency": "GBP" + }, + "indicative_cost": "\u00a320 - \u00a340", + "improvement_type": "C", + "improvement_details": { + "improvement_number": 2 + }, + "improvement_category": 5, + "energy_performance_rating": 59, + "environmental_impact_rating": 89 + }, + { + "sequence": 4, + "typical_saving": { + "value": 671, + "currency": "GBP" + }, + "indicative_cost": "\u00a33,500 - \u00a310,000", + "improvement_type": "T", + "improvement_details": { + "improvement_number": 29 + }, + "improvement_category": 5, + "energy_performance_rating": 76, + "environmental_impact_rating": 83 + }, + { + "sequence": 5, + "typical_saving": { + "value": 220, + "currency": "GBP" + }, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 81, + "environmental_impact_rating": 84 + } + ], + "co2_emissions_potential": 1.1, + "energy_rating_potential": 81, + "lighting_cost_potential": { + "value": 43, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "alternative_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 822, + "currency": "GBP" + }, + "improvement_type": "J2", + "improvement_details": { + "improvement_number": 54 + }, + "improvement_category": 6, + "energy_performance_rating": 79, + "environmental_impact_rating": 96 + }, + { + "sequence": 2, + "typical_saving": { + "value": 524, + "currency": "GBP" + }, + "improvement_type": "Z3", + "improvement_details": { + "improvement_number": 53 + }, + "improvement_category": 6, + "energy_performance_rating": 71, + "environmental_impact_rating": 74 + } + ], + "hot_water_cost_potential": { + "value": 301, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2452.35, + "space_heating_existing_dwelling": 4576.09 + }, + "draughtproofed_door_count": 2, + "energy_consumption_current": 189, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 102, + "environmental_impact_current": 84, + "current_energy_efficiency_band": "E", + "environmental_impact_potential": 84, + "led_fixed_lighting_bulbs_count": 7, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 18, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050355518/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050355518/epc.json new file mode 100644 index 000000000..1b70bbe6c --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050355518/epc.json @@ -0,0 +1,700 @@ +{ + "uprn": 100050355518, + "roofs": [ + { + "description": "Pitched, 200 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + { + "description": "Pitched, limited insulation", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "walls": [ + { + "description": "Cavity wall, as built, no insulation (assumed)", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "floors": [ + { + "description": "Suspended, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Partial double glazing", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + }, + "addendum": { + "addendum_numbers": [ + 15 + ], + "cavity_fill_recommended": "true" + }, + "lighting": { + "description": "Below average lighting efficiency", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "postcode": "BD23 1BG", + "hot_water": { + "description": "From main system, no cylinder thermostat", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "post_town": "SKIPTON", + "psv_count": 0, + "built_form": 2, + "created_at": "2026-05-18 08:00:25", + "door_count": 1, + "region_code": 7, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 2, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 2 + }, + { + "shower_wwhrs": 1, + "shower_outlet_type": 2 + } + ], + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "N", + "secondary_fuel_type": 5, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "N", + "heat_emitter_type": 1, + "main_heating_number": 1, + "main_heating_control": 2102, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 117, + "central_heating_pump_age": 0, + "main_heating_data_source": 2 + } + ], + "immersion_heating_type": "NA", + "secondary_heating_type": 631, + "cylinder_insulation_type": 2, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 80 + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 0.4, + "window_height": 1.18, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 5.03, + "window_height": 1.72, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.19, + "window_height": 1, + "draught_proofed": "false", + "window_location": 2, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.74, + "window_height": 2.05, + "draught_proofed": "false", + "window_location": 2, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 2, + "glazing_type": 3, + "window_width": 0.6, + "window_height": 0.9, + "draught_proofed": "false", + "window_location": 2, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 2, + "glazing_type": 3, + "window_width": 0.6, + "window_height": 0.9, + "draught_proofed": "false", + "window_location": 2, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 2.34, + "window_height": 1.18, + "draught_proofed": "false", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.79, + "window_height": 2.06, + "draught_proofed": "false", + "window_location": 2, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 5.03, + "window_height": 1.23, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 1.11, + "window_height": 1.17, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.19, + "window_height": 1, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.18, + "window_height": 1.15, + "draught_proofed": "false", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.1, + "window_height": 1, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.66, + "window_height": 1.17, + "draught_proofed": "false", + "window_location": 1, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.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": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Semi-detached house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "26 Regent Crescent", + "assessment_type": "RdSAP", + "completion_date": "2026-05-18", + "inspection_date": "2026-05-15", + "extensions_count": 2, + "measurement_type": 1, + "open_flues_count": 0, + "total_floor_area": 122, + "transaction_type": 15, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 5, + "other_flues_count": 0, + "registration_date": "2026-05-18", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_diverter": "false", + "pv_connection": 0, + "pv_battery_count": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false", + "is_hydro_output_connected_to_dwelling_meter": "false" + }, + "secondary_heating": { + "description": "Room heaters, anthracite", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 1, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 230, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.53, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 35.63, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 6.09, + "quantity": "metres" + }, + "floor_construction": 2, + "heat_loss_perimeter": { + "value": 7.95, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.38, + "quantity": "metres" + }, + "total_floor_area": { + "value": 35.63, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 6.09, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 13.37, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "C", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm", + "wall_insulation_thickness": "NI" + }, + { + "identifier": "Extension 1", + "wall_dry_lined": "N", + "wall_thickness": 320, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.29, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 15.62, + "quantity": "square metres" + }, + "party_wall_length": 0, + "floor_construction": 2, + "heat_loss_perimeter": { + "value": 7.95, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.24, + "quantity": "metres" + }, + "total_floor_area": { + "value": 15.62, + "quantity": "square metres" + }, + "party_wall_length": 0, + "heat_loss_perimeter": { + "value": 11.19, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "C", + "party_wall_construction": "NA", + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm", + "wall_insulation_thickness": "NI" + }, + { + "identifier": "Extension 2", + "wall_dry_lined": "N", + "wall_thickness": 320, + "floor_heat_loss": 7, + "roof_construction": 8, + "wall_construction": 4, + "building_part_number": 3, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.86, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 19.28, + "quantity": "square metres" + }, + "party_wall_length": 0, + "floor_construction": 2, + "heat_loss_perimeter": { + "value": 12.66, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "C", + "party_wall_construction": "NA", + "wall_thickness_measured": "Y", + "roof_insulation_location": 7, + "wall_insulation_thickness": "NI", + "sloping_ceiling_insulation_thickness": "AB" + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 5, + "heating_cost_current": { + "value": 3523, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 12, + "energy_rating_average": 60, + "energy_rating_current": 36, + "lighting_cost_current": { + "value": 84, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, no room thermostat", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "blocked_chimneys_count": 1, + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 1387, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 574, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 260, + "indicative_cost": "\u00a3900 - \u00a31,200", + "improvement_type": "A2", + "improvement_details": { + "improvement_number": 45 + }, + "improvement_category": 5, + "energy_performance_rating": 39, + "environmental_impact_rating": 30 + }, + { + "sequence": 2, + "typical_saving": 606, + "indicative_cost": "\u00a3900 - \u00a31,500", + "improvement_type": "B", + "improvement_details": { + "improvement_number": 6 + }, + "improvement_category": 5, + "energy_performance_rating": 47, + "environmental_impact_rating": 38 + }, + { + "sequence": 3, + "typical_saving": 251, + "indicative_cost": "\u00a35,000 - \u00a310,000", + "improvement_type": "W1", + "improvement_details": { + "improvement_number": 57 + }, + "improvement_category": 5, + "energy_performance_rating": 51, + "environmental_impact_rating": 42 + }, + { + "sequence": 4, + "typical_saving": 134, + "indicative_cost": "\u00a3150 - \u00a3250", + "improvement_type": "D", + "improvement_details": { + "improvement_number": 10 + }, + "improvement_category": 5, + "energy_performance_rating": 53, + "environmental_impact_rating": 44 + }, + { + "sequence": 5, + "typical_saving": 276, + "indicative_cost": "\u00a3220 - \u00a3250", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 12 + }, + "improvement_category": 5, + "energy_performance_rating": 57, + "environmental_impact_rating": 49 + }, + { + "sequence": 6, + "typical_saving": 629, + "indicative_cost": "\u00a32,200 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 5, + "energy_performance_rating": 67, + "environmental_impact_rating": 61 + }, + { + "sequence": 7, + "typical_saving": 197, + "indicative_cost": "\u00a34,500 - \u00a36,000", + "improvement_type": "O", + "improvement_details": { + "improvement_number": 8 + }, + "improvement_category": 5, + "energy_performance_rating": 70, + "environmental_impact_rating": 66 + }, + { + "sequence": 8, + "typical_saving": 233, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 74, + "environmental_impact_rating": 67 + } + ], + "co2_emissions_potential": 4.6, + "energy_rating_potential": 74, + "lighting_cost_potential": { + "value": 84, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0.1", + "alternative_improvements": [ + { + "sequence": 1, + "typical_saving": 172, + "improvement_type": "Q2", + "improvement_details": { + "improvement_number": 55 + }, + "improvement_category": 6, + "energy_performance_rating": 50, + "environmental_impact_rating": 40 + }, + { + "sequence": 2, + "typical_saving": 774, + "improvement_type": "J2", + "improvement_details": { + "improvement_number": 54 + }, + "improvement_category": 6, + "energy_performance_rating": 64, + "environmental_impact_rating": 82 + }, + { + "sequence": 3, + "typical_saving": 828, + "improvement_type": "Z3", + "improvement_details": { + "improvement_number": 53 + }, + "improvement_category": 6, + "energy_performance_rating": 69, + "environmental_impact_rating": 66 + } + ], + "flueless_gas_fires_count": 0, + "hot_water_cost_potential": { + "value": 358, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 3736.92, + "space_heating_existing_dwelling": 24523.93 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 466, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 52, + "calculation_software_version": "4.3.74", + "energy_consumption_potential": 170, + "environmental_impact_current": 27, + "current_energy_efficiency_band": "F", + "environmental_impact_potential": 67, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 98, + "low_energy_fixed_lighting_bulbs_count": 17, + "incandescent_fixed_lighting_bulbs_count": 4 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/elmhurst_summary.pdf new file mode 100644 index 000000000..28a0ee26d Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/elmhurst_summary.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/elmhurst_worksheet.pdf new file mode 100644 index 000000000..418feb6de Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/elmhurst_worksheet.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/epc.json new file mode 100644 index 000000000..100e4eb06 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100050881708/epc.json @@ -0,0 +1,426 @@ +{ + "uprn": 100050881708, + "roofs": [ + { + "description": "Pitched, 225 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Cavity wall, filled cavity", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "To unheated space, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Below average lighting efficiency", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "postcode": "S65 3RW", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "ROTHERHAM", + "built_form": 2, + "created_at": "2026-05-27 15:09:39", + "door_count": 2, + "region_code": 3, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "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, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 17741 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.7, + "window_height": 1.4, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.2, + "window_height": 1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": 0.6, + "window_height": 1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 0.6, + "window_height": 0.7, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 0.6, + "window_height": 1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.2, + "window_height": 1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.2, + "window_height": 1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.1, + "window_height": 0.8, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 2, + "window_width": 0.6, + "window_height": 0.7, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 2, + "window_width": 0.6, + "window_height": 1.1, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.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": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Semi-detached house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "9 Woodgrove Road", + "assessment_type": "RdSAP", + "completion_date": "2026-05-27", + "inspection_date": "2026-05-27", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 63, + "transaction_type": 14, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2026-05-27", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "extract_fans_count": 2, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "floor_heat_loss": 2, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.4, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 31.62, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 6.2, + "quantity": "metres" + }, + "floor_construction": 2, + "heat_loss_perimeter": { + "value": 16.4, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.41, + "quantity": "metres" + }, + "total_floor_area": { + "value": 31.62, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 6.2, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 16.4, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 2, + "construction_age_band": "B", + "party_wall_construction": 1, + "wall_thickness_measured": "N", + "roof_insulation_location": 2, + "roof_insulation_thickness": "225mm", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 777, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 2.3, + "energy_rating_average": 60, + "energy_rating_current": 70, + "lighting_cost_current": { + "value": 79, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 671, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 172, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 110, + "currency": "GBP" + }, + "indicative_cost": "\u00a35,000 - \u00a310,000", + "improvement_type": "W1", + "improvement_details": { + "improvement_number": 57 + }, + "improvement_category": 5, + "energy_performance_rating": 73, + "environmental_impact_rating": 75 + }, + { + "sequence": 2, + "typical_saving": { + "value": 30, + "currency": "GBP" + }, + "indicative_cost": "\u00a3120 - \u00a3140", + "improvement_type": "E", + "improvement_details": { + "improvement_number": 35 + }, + "improvement_category": 5, + "energy_performance_rating": 74, + "environmental_impact_rating": 75 + }, + { + "sequence": 3, + "typical_saving": { + "value": 184, + "currency": "GBP" + }, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 79, + "environmental_impact_rating": 77 + } + ], + "co2_emissions_potential": 1.9, + "energy_rating_potential": 79, + "lighting_cost_potential": { + "value": 45, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 172, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2070.91, + "space_heating_existing_dwelling": 7543.77 + }, + "draughtproofed_door_count": 2, + "energy_consumption_current": 205, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 161, + "environmental_impact_current": 71, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 77, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 37, + "low_energy_fixed_lighting_bulbs_count": 4, + "incandescent_fixed_lighting_bulbs_count": 4 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100051051866/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100051051866/epc.json new file mode 100644 index 000000000..4e226b29f --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100051051866/epc.json @@ -0,0 +1,351 @@ +{ + "uprn": 100051051866, + "roofs": [ + { + "description": "Pitched, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Cavity wall, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Suspended, limited insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "addendum": { + "addendum_numbers": [ + 15 + ] + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "S20 7NQ", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "SHEFFIELD", + "psv_count": 0, + "built_form": 1, + "created_at": "2026-05-18 17:37:45", + "door_count": 1, + "region_code": 11, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 2, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 4 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "Y", + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 1, + "main_heating_number": 1, + "main_heating_control": 2104, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 102, + "central_heating_pump_age": 0, + "main_heating_data_source": 2, + "main_heating_index_number": 18773 + } + ], + "immersion_heating_type": "NA", + "cylinder_insulation_type": 1, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 50 + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.6, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.2, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 7, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.6, + "quantity": "m" + }, + "window_height": { + "value": 1.6, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.6, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 0.5, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.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": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Detached bungalow", + "language_code": 1, + "pressure_test": 4, + "property_type": 1, + "address_line_1": "3 Pentland Gardens", + "address_line_2": "Waterthorpe", + "assessment_type": "RdSAP", + "completion_date": "2026-05-18", + "inspection_date": "2026-05-18", + "extensions_count": 0, + "measurement_type": 1, + "open_flues_count": 0, + "total_floor_area": 60, + "transaction_type": 1, + "conservatory_type": 2, + "heated_room_count": 4, + "other_flues_count": 0, + "registration_date": "2026-05-18", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 3, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 0, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 300, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.4, + "floor_insulation": 1, + "total_floor_area": 60, + "party_wall_length": 0, + "floor_construction": 2, + "heat_loss_perimeter": 32 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "I", + "party_wall_construction": "NA", + "wall_thickness_measured": "Y", + "roof_insulation_location": 4, + "roof_insulation_thickness": "NI" + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 4, + "heating_cost_current": { + "value": 701, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 2.3, + "energy_rating_average": 60, + "energy_rating_current": 70, + "lighting_cost_current": { + "value": 40, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer and room thermostat", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "blocked_chimneys_count": 0, + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 701, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 235, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "schema_version_current": "LIG-21.0", + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 238, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 82, + "environmental_impact_rating": 73 + } + ], + "co2_emissions_potential": 2.1, + "energy_rating_potential": 82, + "lighting_cost_potential": { + "value": 40, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0", + "hot_water_cost_potential": { + "value": 235, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2544.67, + "space_heating_existing_dwelling": 6292.1 + }, + "draughtproofed_door_count": 1, + "energy_consumption_current": 209, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "10.2.2.0", + "energy_consumption_potential": 185, + "environmental_impact_current": 70, + "cfl_fixed_lighting_bulbs_count": 0, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 73, + "led_fixed_lighting_bulbs_count": 8, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 38, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf new file mode 100644 index 000000000..4a604044a Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_summary.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_worksheet.pdf new file mode 100644 index 000000000..9bb10c008 Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/elmhurst_worksheet.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/epc.json new file mode 100644 index 000000000..43225f661 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_100061275133/epc.json @@ -0,0 +1,410 @@ +{ + "uprn": 100061275133, + "roofs": [ + { + "description": "Pitched, 300 mm loft insulation", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "walls": [ + { + "description": "Solid brick, with external insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Suspended, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 2, + "window": { + "description": "High performance glazing", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "ME7 2ES", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "GILLINGHAM", + "built_form": 2, + "created_at": "2026-05-20 08:39:48", + "door_count": 2, + "region_code": 14, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "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, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 18908 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "orientation": 8, + "window_type": 1, + "glazing_type": 13, + "window_width": 1.19, + "window_height": 1.13, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 8, + "window_type": 1, + "glazing_type": 13, + "window_width": 0.57, + "window_height": 0.55, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 8, + "window_type": 1, + "glazing_type": 13, + "window_width": 1.19, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 2, + "window_type": 1, + "glazing_type": 13, + "window_width": 1.05, + "window_height": 0.85, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 2, + "window_type": 1, + "glazing_type": 13, + "window_width": 0.57, + "window_height": 0.56, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 4, + "window_type": 1, + "glazing_type": 13, + "window_width": 2.11, + "window_height": 1.13, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 4, + "window_type": 1, + "glazing_type": 13, + "window_width": 1.8, + "window_height": 0.97, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 4, + "window_type": 1, + "glazing_type": 13, + "window_width": 1.8, + "window_height": 0.97, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 4, + "window_type": 1, + "glazing_type": 13, + "window_width": 1.2, + "window_height": 0.99, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 8, + "window_type": 1, + "glazing_type": 13, + "window_width": 1.8, + "window_height": 0.97, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 8, + "window_type": 1, + "glazing_type": 13, + "window_width": 1.19, + "window_height": 0.97, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 8, + "window_type": 1, + "glazing_type": 13, + "window_width": 1.18, + "window_height": 0.99, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.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": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Semi-detached house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "75 Toronto Road", + "assessment_type": "RdSAP", + "completion_date": "2026-05-20", + "inspection_date": "2026-05-19", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 78, + "transaction_type": 8, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2026-05-20", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 400, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.4, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 38.99, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 5.09, + "quantity": "metres" + }, + "floor_construction": 0, + "heat_loss_perimeter": { + "value": 17.92, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.4, + "quantity": "metres" + }, + "total_floor_area": { + "value": 38.99, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 5.09, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 17.92, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 1, + "construction_age_band": "B", + "party_wall_construction": 1, + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "300mm", + "wall_insulation_thickness": "100mm", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 608, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 1.9, + "energy_rating_average": 60, + "energy_rating_current": 76, + "lighting_cost_current": { + "value": 58, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 608, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 182, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 216, + "currency": "GBP" + }, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 81, + "environmental_impact_rating": 79 + } + ], + "co2_emissions_potential": 1.8, + "energy_rating_potential": 81, + "lighting_cost_potential": { + "value": 58, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 182, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2203.16, + "space_heating_existing_dwelling": 5517.85 + }, + "draughtproofed_door_count": 2, + "energy_consumption_current": 133, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 118, + "environmental_impact_current": 78, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 79, + "led_fixed_lighting_bulbs_count": 5, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 24, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10012334488/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10012334488/epc.json new file mode 100644 index 000000000..59f78d7aa --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10012334488/epc.json @@ -0,0 +1,337 @@ +{ + "uprn": 10012334488, + "roofs": [ + { + "description": "(another dwelling above)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "walls": [ + { + "description": "System built, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "(another dwelling below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "SL4 3BP", + "hot_water": { + "description": "From main system, no cylinder thermostat", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 4 + }, + "post_town": "WINDSOR", + "built_form": "NR", + "created_at": "2026-05-14 18:33:57", + "door_count": 1, + "region_code": 17, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 0, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 29, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 29, + "heat_emitter_type": 2, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2110, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 195, + "central_heating_pump_age": 0, + "main_heating_data_source": 2 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 2, + "glazing_type": 2, + "window_width": 0.85, + "window_height": 1.11, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and underfloor heating, electric", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 5 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Mid-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "Flat 12", + "address_line_2": "Alexandra Court 25a", + "address_line_3": "St. Leonards Road", + "assessment_type": "RdSAP", + "completion_date": "2026-05-14", + "inspection_date": "2026-05-14", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 2, + "top_storey": "N", + "storey_count": 4, + "flat_location": 3, + "heat_loss_corridor": 1 + }, + "total_floor_area": 62, + "transaction_type": 14, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 2, + "registration_date": "2026-05-14", + "sap_energy_source": { + "mains_gas": "N", + "meter_type": 1, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 1, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "extract_fans_count": 2, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 260, + "floor_heat_loss": 6, + "roof_construction": 3, + "wall_construction": 8, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.48, + "quantity": "metres" + }, + "total_floor_area": { + "value": 62, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 23.99, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 11.89, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "L", + "party_wall_construction": 1, + "wall_thickness_measured": "Y", + "roof_insulation_location": "ND", + "roof_insulation_thickness": "ND", + "wall_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 2, + "heating_cost_current": { + "value": 136, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 0.5, + "energy_rating_average": 60, + "energy_rating_current": 72, + "lighting_cost_current": { + "value": 51, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Time and temperature zone control", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 136, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 893, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 91, + "currency": "GBP" + }, + "indicative_cost": "\u00a3600 - \u00a31,500", + "improvement_type": "Y", + "improvement_details": { + "improvement_number": 49 + }, + "improvement_category": 5, + "energy_performance_rating": 74, + "environmental_impact_rating": 93 + } + ], + "co2_emissions_potential": 0.5, + "energy_rating_potential": 74, + "lighting_cost_potential": { + "value": 51, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 802, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2802.07, + "space_heating_existing_dwelling": 628.72 + }, + "draughtproofed_door_count": 1, + "energy_consumption_current": 92, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 85, + "environmental_impact_current": 93, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 93, + "led_fixed_lighting_bulbs_count": 23, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 9, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10070056075/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10070056075/epc.json new file mode 100644 index 000000000..cc408d73d --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10070056075/epc.json @@ -0,0 +1,491 @@ +{ + "uprn": 10070056075, + "roofs": [ + { + "description": "Pitched, insulated", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Cavity wall, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Suspended, insulated (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "addendum": { + "addendum_numbers": [ + 15 + ] + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "BD10 9UG", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BRADFORD", + "psv_count": 0, + "built_form": 1, + "created_at": "2026-05-15 10:22:34", + "door_count": 1, + "region_code": 11, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 4, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 4 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "Y", + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 1, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 19012 + } + ], + "immersion_heating_type": "NA", + "cylinder_insulation_type": 1, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 80 + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.2, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.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": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Detached house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "36 Longlands", + "address_line_2": "Idle", + "assessment_type": "RdSAP", + "completion_date": "2026-05-15", + "inspection_date": "2026-05-08", + "extensions_count": 0, + "measurement_type": 1, + "open_flues_count": 0, + "total_floor_area": 139, + "transaction_type": 5, + "conservatory_type": 1, + "heated_room_count": 8, + "other_flues_count": 0, + "registration_date": "2026-05-15", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 1, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 0, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 400, + "floor_heat_loss": 7, + "roof_construction": 8, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.3, + "floor_insulation": 1, + "total_floor_area": 69.6, + "party_wall_length": 0, + "floor_construction": 2, + "heat_loss_perimeter": 37.7 + }, + { + "floor": 1, + "room_height": 2.3, + "total_floor_area": 69.6, + "party_wall_length": 0, + "heat_loss_perimeter": 37.7 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "K", + "party_wall_construction": "NA", + "wall_thickness_measured": "N", + "roof_insulation_location": 7, + "wall_insulation_thickness": "NI", + "sloping_ceiling_insulation_thickness": "AB" + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 8, + "heating_cost_current": { + "value": 938, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 3.0, + "energy_rating_average": 60, + "energy_rating_current": 80, + "lighting_cost_current": { + "value": 89, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "blocked_chimneys_count": 0, + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 938, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 236, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "schema_version_current": "LIG-21.0", + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 308, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 87, + "environmental_impact_rating": 81 + } + ], + "co2_emissions_potential": 2.8, + "energy_rating_potential": 87, + "lighting_cost_potential": { + "value": 89, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0", + "hot_water_cost_potential": { + "value": 236, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2744.25, + "space_heating_existing_dwelling": 9473.16 + }, + "draughtproofed_door_count": 1, + "energy_consumption_current": 117, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "10.2.2.0", + "energy_consumption_potential": 106, + "environmental_impact_current": 79, + "cfl_fixed_lighting_bulbs_count": 0, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 81, + "led_fixed_lighting_bulbs_count": 18, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 21, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10091578598/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10091578598/epc.json new file mode 100644 index 000000000..04774b623 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10091578598/epc.json @@ -0,0 +1,316 @@ +{ + "uprn": 10091578598, + "roofs": [ + { + "description": "(another dwelling above)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "walls": [ + { + "description": "Cavity wall, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "(another dwelling below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 2, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Good lighting efficiency", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "RM1 3FB", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 5 + }, + "post_town": "ROMFORD", + "built_form": "NR", + "created_at": "2026-05-16 17:47:19", + "door_count": 1, + "region_code": 2, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 4, + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 29, + "cylinder_thermostat": "Y", + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 29, + "heat_emitter_type": 1, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 195, + "central_heating_pump_age": 0, + "main_heating_data_source": 2 + } + ], + "immersion_heating_type": "NA", + "cylinder_insulation_type": 1, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 50 + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 2, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.15, + "window_height": 1.65, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 2, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.15, + "window_height": 1.65, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 2, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.15, + "window_height": 1.65, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 2, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.15, + "window_height": 1.65, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Boiler and radiators, electric", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 5 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Mid-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "41 Verve Apartments", + "address_line_2": "5 Mercury Gardens", + "assessment_type": "RdSAP", + "completion_date": "2026-05-16", + "inspection_date": "2026-05-16", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 2, + "top_storey": "N", + "storey_count": 6, + "flat_location": 3, + "heat_loss_corridor": 2, + "unheated_corridor_length": 6 + }, + "total_floor_area": 60, + "transaction_type": 8, + "conservatory_type": 1, + "heated_room_count": 2, + "registration_date": "2026-05-16", + "sap_energy_source": { + "mains_gas": "N", + "meter_type": 4, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 300, + "floor_heat_loss": 6, + "roof_construction": 3, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.5, + "quantity": "metres" + }, + "total_floor_area": { + "value": 60, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 20, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 12, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "I", + "sap_alternative_wall_1": { + "wall_area": 15, + "sheltered_wall": "Y", + "wall_dry_lined": "N", + "wall_thickness": 300, + "wall_construction": 4, + "wall_insulation_type": 4, + "wall_thickness_measured": "Y", + "wall_insulation_thickness": "NI" + }, + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": "ND", + "roof_insulation_thickness": "ND", + "wall_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 2, + "heating_cost_current": { + "value": 202, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 0.6, + "energy_rating_average": 60, + "energy_rating_current": 71, + "lighting_cost_current": { + "value": 55, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 370, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 847, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 80, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 76, + "currency": "GBP" + }, + "indicative_cost": "\u00a3150 - \u00a3250", + "improvement_type": "D", + "improvement_details": { + "improvement_number": 10 + }, + "improvement_category": 5, + "energy_performance_rating": 79, + "environmental_impact_rating": 92 + } + ], + "co2_emissions_potential": 0.6, + "energy_rating_potential": 79, + "lighting_cost_potential": { + "value": 48, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 611, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2659.46, + "space_heating_existing_dwelling": 1061.64 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 102, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 102, + "environmental_impact_current": 92, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 92, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 10, + "low_energy_fixed_lighting_bulbs_count": 20, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10094975827/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10094975827/epc.json new file mode 100644 index 000000000..5b68ee3b0 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_10094975827/epc.json @@ -0,0 +1,366 @@ +{ + "uprn": 10094975827, + "roofs": [ + { + "description": "Pitched, insulated (assumed)", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "description": "Solid brick, as built, no insulation (assumed)", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "floors": [ + { + "description": "(other premises below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "B8 2NG", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BIRMINGHAM", + "psv_count": 0, + "built_form": 3, + "created_at": "2026-05-14 13:27:59", + "door_count": 1, + "region_code": 6, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "N", + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 1, + "main_heating_number": 1, + "main_heating_control": 2107, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 18559 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": { + "value": 1.01, + "quantity": "m" + }, + "window_height": { + "value": 1.61, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": { + "value": 1.66, + "quantity": "m" + }, + "window_height": { + "value": 1.46, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 3, + "window_type": 1, + "glazing_type": 3, + "window_width": { + "value": 1.09, + "quantity": "m" + }, + "window_height": { + "value": 1.29, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 3, + "window_type": 1, + "glazing_type": 3, + "window_width": { + "value": 1.09, + "quantity": "m" + }, + "window_height": { + "value": 1.55, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 3, + "window_type": 1, + "glazing_type": 3, + "window_width": { + "value": 1.79, + "quantity": "m" + }, + "window_height": { + "value": 1.92, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.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": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Top-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "Flat 2", + "address_line_2": "874 Washwood Heath Road", + "assessment_type": "RdSAP", + "completion_date": "2026-05-14", + "inspection_date": "2026-05-13", + "extensions_count": 0, + "measurement_type": 1, + "open_flues_count": 0, + "sap_flat_details": { + "level": 3, + "top_storey": "N", + "storey_count": 2, + "flat_location": 1, + "heat_loss_corridor": 0 + }, + "total_floor_area": 78, + "transaction_type": 8, + "conservatory_type": 1, + "heated_room_count": 3, + "other_flues_count": 0, + "registration_date": "2026-05-14", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 3, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 0, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 340, + "floor_heat_loss": 3, + "roof_construction": 4, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.44, + "total_floor_area": 77.87, + "party_wall_length": 11.57, + "heat_loss_perimeter": 25.03 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "B", + "party_wall_construction": 1, + "wall_thickness_measured": "Y", + "roof_insulation_location": 4, + "roof_insulation_thickness": "NI", + "wall_insulation_thickness": "NI" + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 952, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 3.2, + "energy_rating_average": 60, + "energy_rating_current": 66, + "lighting_cost_current": { + "value": 56, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, TRVs and bypass", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "blocked_chimneys_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 735, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 197, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "schema_version_current": "LIG-21.0", + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 171, + "indicative_cost": "\u00a37,500 - \u00a311,000", + "improvement_type": "Q", + "improvement_details": { + "improvement_number": 7 + }, + "improvement_category": 5, + "energy_performance_rating": 70, + "environmental_impact_rating": 70 + }, + { + "sequence": 2, + "typical_saving": 45, + "indicative_cost": "\u00a3220 - \u00a3250", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 14 + }, + "improvement_category": 5, + "energy_performance_rating": 72, + "environmental_impact_rating": 71 + } + ], + "co2_emissions_potential": 2.6, + "energy_rating_potential": 72, + "lighting_cost_potential": { + "value": 56, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0", + "hot_water_cost_potential": { + "value": 198, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2548.95, + "space_heating_existing_dwelling": 10093.12 + }, + "draughtproofed_door_count": 1, + "energy_consumption_current": 227, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "10.2.2.0", + "energy_consumption_potential": 181, + "environmental_impact_current": 64, + "cfl_fixed_lighting_bulbs_count": 0, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 71, + "led_fixed_lighting_bulbs_count": 8, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 41, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_103001004/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_103001004/epc.json new file mode 100644 index 000000000..8897cb84d --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_103001004/epc.json @@ -0,0 +1,321 @@ +{ + "uprn": 103001004, + "roofs": [ + { + "description": "Pitched, Unknown loft insulation", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "description": "Cavity wall, filled cavity", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 2, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "lighting": { + "description": "Good lighting efficiency", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "NE33 1TN", + "hot_water": { + "description": "Electric immersion, off-peak", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 4 + }, + "post_town": "SOUTH SHIELDS", + "built_form": "NR", + "created_at": "2026-04-16 10:25:37", + "door_count": 0, + "region_code": 1, + "report_type": 2, + "sap_heating": { + "number_baths": 0, + "cylinder_size": 3, + "shower_outlets": [ + { + "shower_outlet": { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + } + ], + "cylinder_heat_loss": 1.8, + "number_baths_wwhrs": 0, + "water_heating_code": 903, + "water_heating_fuel": 29, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 20, + "heat_emitter_type": 0, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2307, + "main_heating_category": 6, + "main_heating_fraction": 1, + "sap_main_heating_code": 301, + "main_heating_data_source": 2, + "community_heat_distribution_type": 6 + } + ], + "immersion_heating_type": 2, + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "glazing_gap": 12, + "orientation": 7, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.21, + "window_height": 1.44, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": 12, + "orientation": 7, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.77, + "window_height": 1.14, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Community scheme", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Ground-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "3 Julius Court", + "address_line_2": "Mile End Road", + "assessment_type": "RdSAP", + "completion_date": "2026-04-16", + "inspection_date": "2026-04-16", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 1, + "top_storey": "N", + "storey_count": 1, + "flat_location": 0, + "heat_loss_corridor": 1 + }, + "total_floor_area": 31, + "transaction_type": 8, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 2, + "registration_date": "2026-04-16", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 1, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "extract_fans_count": 2, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.37, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 30.55, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 16.75, + "quantity": "metres" + }, + "floor_construction": 1, + "heat_loss_perimeter": { + "value": 5.37, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 2, + "construction_age_band": "F", + "party_wall_construction": 0, + "wall_thickness_measured": "N", + "roof_insulation_location": 2, + "roof_insulation_thickness": "NI", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 2, + "heating_cost_current": { + "value": 251, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 1.2, + "energy_rating_average": 60, + "energy_rating_current": 50, + "lighting_cost_current": { + "value": 29, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Flat rate charging, TRVs", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 313, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 1054, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 35, + "currency": "GBP" + }, + "indicative_cost": "\u00a3900 - \u00a31,200", + "improvement_type": "A", + "improvement_details": { + "improvement_number": 5 + }, + "improvement_category": 5, + "energy_performance_rating": 52, + "environmental_impact_rating": 81 + }, + { + "sequence": 2, + "typical_saving": { + "value": 598, + "currency": "GBP" + }, + "indicative_cost": "\u00a320 - \u00a340", + "improvement_type": "C", + "improvement_details": { + "improvement_number": 1 + }, + "improvement_category": 5, + "energy_performance_rating": 68, + "environmental_impact_rating": 83 + }, + { + "sequence": 3, + "typical_saving": { + "value": 51, + "currency": "GBP" + }, + "indicative_cost": "\u00a3600 - \u00a31,500", + "improvement_type": "Y", + "improvement_details": { + "improvement_number": 49 + }, + "improvement_category": 5, + "energy_performance_rating": 70, + "environmental_impact_rating": 83 + } + ], + "co2_emissions_potential": 1.0, + "energy_rating_potential": 70, + "lighting_cost_potential": { + "value": 29, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 308, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 5719.21, + "space_heating_existing_dwelling": 1270.63 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 367, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0342", + "energy_consumption_potential": 214, + "environmental_impact_current": 78, + "current_energy_efficiency_band": "E", + "environmental_impact_potential": 83, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 41, + "low_energy_fixed_lighting_bulbs_count": 5, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004017091/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004017091/epc.json new file mode 100644 index 000000000..80a987a43 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004017091/epc.json @@ -0,0 +1,372 @@ +{ + "uprn": 200004017091, + "roofs": [ + { + "description": "Pitched, 100 mm loft insulation", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "description": "Timber frame, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "addendum": { + "addendum_numbers": [ + 15 + ] + }, + "lighting": { + "description": "Good lighting efficiency", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "BN14 9EL", + "hot_water": { + "description": "From main system, no cylinder thermostat", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "post_town": "WORTHING", + "built_form": 3, + "created_at": "2026-04-21 13:18:06", + "door_count": 2, + "region_code": 14, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 0, + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "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, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 17803 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.1, + "window_height": 1.2, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 1, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.1, + "window_height": 1.2, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.1, + "window_height": 1.2, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 0.8, + "window_height": 0.8, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "glazing_gap": "16+", + "orientation": 5, + "window_type": 1, + "glazing_type": 3, + "window_width": 1.5, + "window_height": 0.8, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.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": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "End-terrace house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "3 Radbone Close", + "assessment_type": "RdSAP", + "completion_date": "2026-04-21", + "inspection_date": "2026-04-20", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 65, + "transaction_type": 1, + "conservatory_type": 1, + "heated_room_count": 4, + "registration_date": "2026-04-21", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "extract_fans_count": 1, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 280, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 5, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.37, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 32.38, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 7.42, + "quantity": "metres" + }, + "floor_construction": 1, + "heat_loss_perimeter": { + "value": 16.15, + "quantity": "metres" + } + }, + { + "floor": 1, + "room_height": { + "value": 2.35, + "quantity": "metres" + }, + "total_floor_area": { + "value": 32.37, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 7.42, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 16.15, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "G", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "100mm", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 4, + "heating_cost_current": { + "value": 556, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 2.2, + "energy_rating_average": 60, + "energy_rating_current": 71, + "lighting_cost_current": { + "value": 51, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 516, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 333, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 71, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 44, + "currency": "GBP" + }, + "indicative_cost": "\u00a35,000 - \u00a310,000", + "improvement_type": "W2", + "improvement_details": { + "improvement_number": 58 + }, + "improvement_category": 5, + "energy_performance_rating": 73, + "environmental_impact_rating": 74 + }, + { + "sequence": 2, + "typical_saving": { + "value": 143, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,000 - \u00a37,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 5, + "energy_performance_rating": 76, + "environmental_impact_rating": 79 + }, + { + "sequence": 3, + "typical_saving": { + "value": 212, + "currency": "GBP" + }, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 81, + "environmental_impact_rating": 80 + } + ], + "co2_emissions_potential": 1.5, + "energy_rating_potential": 81, + "lighting_cost_potential": { + "value": 51, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 186, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 3562.39, + "space_heating_existing_dwelling": 4593.09 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 184, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0342", + "energy_consumption_potential": 118, + "environmental_impact_current": 72, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 80, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 33, + "low_energy_fixed_lighting_bulbs_count": 12, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ELMHURST_FINDINGS.md b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ELMHURST_FINDINGS.md new file mode 100644 index 000000000..165cbe29a --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ELMHURST_FINDINGS.md @@ -0,0 +1,70 @@ +# Elmhurst validation — UPRN 200004296092 (corpus, slice-5 wall fix) + +Built in accredited Elmhurst RdSAP10-Online on the lodged register inputs +(end-terrace house, solid brick + **external insulation, thickness "NI"**, +pitched 150 mm loft, solid ground floor, mains-gas combi, TFA 62). +Artefacts: `elmhurst_summary.pdf` (Input Summary), `elmhurst_worksheet.pdf` +(SAP Worksheets). + +## Headline +- **Lodged SAP 71**; **engine 71.74** (post slice-5 §5.4 100 mm fix, was 64.35); + **accredited Elmhurst current SAP 66** (band D), potential 75. +- Slice 5 is **directionally validated**: the externally-insulated wall must be + billed insulated, not at the uninsulated 1.40 the §5.8 gate produced. Both + Elmhurst (0.48) and the engine (0.29) are far below 1.40. + +## Fabric line-by-line (engine dive vs Elmhurst worksheet) +| Element | Engine | Elmhurst | Note | +|---|---|---|---| +| External wall | 21.1 W/K (U 0.29) | 30.7 W/K (U **0.48**, "SolidWallDensePlaster**200**") | see WALL below | +| Roof | 9.35 W/K (U 0.30) | 9.35 W/K (U 0.30) | **exact match** | +| Ground floor | 21.2 W/K | 22.7 W/K (U 0.73) | close | +| Party wall | **8.57 W/K** | **0.00 W/K** | see PARTY below | +| Windows | 7.96 W/K | ~same area (4.31 + 4×2.89 split) | ~ | + +The wall (engine −9.6) and party wall (engine +8.6) differences nearly cancel, +so the two HTCs are close; the residual SAP gap (71.7 vs 66) is dominated by the +heating system — this build used a GENERIC Post-98 condensing combi, whereas the +engine uses the lodged PCDB 16137 (Ideal Logic combi 30). Not a clean 1e-4 +comparison for that reason. + +## Leads (both partly confounded by an imperfect build — see caveats) +1. **WALL — base thickness on an unmeasured wall.** The cert lodges + `wall_thickness 360` but `wall_thickness_measured = N`. Elmhurst modelled a + **~200 mm** base wall ("SolidWallDensePlaster200") — but note my build did + NOT enter a wall thickness, so Elmhurst used its own default; had I keyed + 360 mm it might match the engine. The open question is genuine though: + RdSAP §5.3 uses the documentary/measured thickness, and when NOT measured + the engine perhaps should fall to the Table-3 default rather than trust the + unmeasured lodged 360 mm. WORTH A DEDICATED CHECK (build with the thickness + keyed both ways). +2. **PARTY WALL — NOT an engine gap.** Elmhurst rendered the party wall as + "Solid, U 0.00", but the engine's **0.25** is SPEC-CORRECT: RdSAP §5.10 + Table 15 row 4 ("unable to determine, house") = 0.25. The cert lodges + `party_wall_construction = 0` (unable to determine), so 0.25 is right; the + Elmhurst 0.00 reflects how my build's party-wall dropdown resolved (a + "Solid" masonry party wall, Table 15 row 1 = 0), not the cert's "unknown". + Build artifact, not a bug. + +## Build caveats (why the 71.7-vs-66 residual isn't cleanly attributable) +- Heating: built a GENERIC Post-98 condensing combi; the engine uses the lodged + PCDB 16137 (Ideal Logic combi 30) — different efficiency. +- Wall thickness: not keyed into Elmhurst (defaulted 200 mm) vs engine's 360 mm. +- Party wall: entered as a resolved type (0.00) vs the cert's "unable to + determine" (engine 0.25). +So this build's clean, confirmed results are: (a) the ROOF matches exactly +(U 0.30, 9.35 W/K), (b) slice 5's DIRECTION is validated (insulated wall, not +the uninsulated 1.40). The wall-thickness question (lead 1) is the one genuine +follow-up. + +## Slice-5 calibration note (banked) +The accredited "External insulation, **Unknown** thickness" selection in Elmhurst +produced U 0.48 (≈ a 50 mm equivalent on its 200 mm base), NOT the 0.29 the +§5.4-literal "assume 100 mm" gives on the engine's 360 mm base. The 100 mm fix +nevertheless matches the LODGED corpus better (MAE 0.658 → 0.647, within held) — +lodged assessors typically knew the real (~100 mm) thickness the register then +flattens to "NI". Per the campaign rule (engine = lodged is the goal; Elmhurst +arbitrates only when lodged can't be explained from register data), the 100 mm +fix STANDS; the lodged-vs-Elmhurst gap here is explained by the register's "NI" +discarding the assessor's thickness knowledge. But the base-thickness and +party-wall leads above are genuine and independent of the insulation default. diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_summary.pdf new file mode 100644 index 000000000..2caa62058 Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_summary.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_worksheet.pdf new file mode 100644 index 000000000..3ebe582a3 Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/elmhurst_worksheet.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/epc.json new file mode 100644 index 000000000..93fe00f70 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/epc.json @@ -0,0 +1,361 @@ +{ + "uprn": 200004296092, + "roofs": [ + { + "description": "Pitched, 150 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Solid brick, with external insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "LL16 3RL", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "DENBIGH", + "psv_count": 0, + "built_form": 3, + "created_at": "2026-05-14 14:33:05", + "door_count": 2, + "region_code": 7, + "report_type": 2, + "sap_heating": { + "number_baths": 0, + "cylinder_size": 1, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 2 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "emitter_temperature": 1, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 16137 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.07, + "quantity": "m" + }, + "window_height": { + "value": 1.34, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1.07, + "quantity": "m" + }, + "window_height": { + "value": 1.34, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 0.47, + "quantity": "m" + }, + "window_height": { + "value": 0.85, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 0.47, + "quantity": "m" + }, + "window_height": { + "value": 0.85, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 0.76, + "quantity": "m" + }, + "window_height": { + "value": 0.84, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "WLS", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "End-terrace house", + "language_code": 1, + "pressure_test": 4, + "property_type": 0, + "address_line_1": "54 Myddleton Avenue", + "assessment_type": "RdSAP", + "completion_date": "2026-05-14", + "inspection_date": "2026-05-14", + "extensions_count": 0, + "measurement_type": 1, + "open_flues_count": 0, + "total_floor_area": 62, + "transaction_type": 1, + "conservatory_type": 1, + "heated_room_count": 3, + "other_flues_count": 0, + "registration_date": "2026-05-14", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 0, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 360, + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.4, + "floor_insulation": 1, + "total_floor_area": 31.16, + "party_wall_length": 6.79, + "floor_construction": 1, + "heat_loss_perimeter": 15.97 + }, + { + "floor": 1, + "room_height": 2.4, + "total_floor_area": 31.16, + "party_wall_length": 6.79, + "heat_loss_perimeter": 15.97 + } + ], + "wall_insulation_type": 1, + "construction_age_band": "B", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 2, + "roof_insulation_thickness": "150mm", + "wall_insulation_thickness": "NI" + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 589, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 1.8, + "energy_rating_average": 60, + "energy_rating_current": 71, + "lighting_cost_current": { + "value": 50, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "blocked_chimneys_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 543, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 275, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "schema_version_current": "LIG-21.0", + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 47, + "indicative_cost": "\u00a35,000 - \u00a310,000", + "improvement_type": "W2", + "improvement_details": { + "improvement_number": 58 + }, + "improvement_category": 5, + "energy_performance_rating": 72, + "environmental_impact_rating": 79 + }, + { + "sequence": 2, + "typical_saving": 275, + "indicative_cost": "\u00a38,000 - \u00a310,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 5, + "energy_performance_rating": 84, + "environmental_impact_rating": 81 + } + ], + "co2_emissions_potential": 1.4, + "energy_rating_potential": 84, + "lighting_cost_potential": { + "value": 50, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0", + "hot_water_cost_potential": { + "value": 275, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 1768.31, + "space_heating_existing_dwelling": 5933.75 + }, + "draughtproofed_door_count": 2, + "energy_consumption_current": 169, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "10.2.2.0", + "energy_consumption_potential": 130, + "environmental_impact_current": 77, + "cfl_fixed_lighting_bulbs_count": 0, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 81, + "led_fixed_lighting_bulbs_count": 12, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 29, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/sum.txt b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/sum.txt new file mode 100644 index 000000000..25a3346a2 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/sum.txt @@ -0,0 +1,254 @@ + Summary Information +Surveyor: P960-0001 +Name: Richard Matthew Ratcliff Title: Mr. Tel Number: 07760 443 469 +Survey Reference: 001431 My Reference: Khalim-test +Current SAP rating: D 66 Potential SAP rating: C 75 Emissions (t/year): 1.927 tonnes +Current EI rating: C 72 Potential EI rating: C 76 Fuel Bill: £1026 +Property Details: +RdSAP version: RdSAP10 +Reference Number: P960-0001-001431 +My Reference: Khalim-test +Lodgement Required: No +Regs Region: England +EPC Language: English +UPRN: +Postcode: W6 9BF +Region: Thames Valley +House Name: 28 Distillery Wharf +House No: 28 +Street: Distillery Wharf +Locality: +Town: London +County: +Property Tenure: Owner-occupied +Transaction Type: Marketed sale +Inspection Date: 25/06/2025 +Process date: 02/07/2026 +Check for the existence of No +an EPC: +Does an EPC exist at the No +point of carrying out this +energy assessment: +Reason why another energy +assessment needs to be +undertaken: + + RdSAP Inputs + +Property Description: +1.0 Property type: H House + E End-Terrace +2.0 Number of Storeys: 2 + Habitable Rooms: 3 + Heated Habitable Rooms: 3 +3.0 Date Built: Main Property B 1900-1929 + + +4.0 Dimensions: +Dimension type: Internal +Main Property + Floor Room Heat Loss Party Wall + Area Height Wall Perimeter Length + [m2] [m] [m] [m] + + 1st Floor: 31.16 2.40 15.97 6.79 + Lowest Floor: 31.16 2.40 15.97 6.79 No + +5.0 Conservatory: +Is there a conservatory? No +7.0 Walls: + + + + + © Elmhurst Energy Systems Limited Registered Office Unit 16, St Johns Business Park, Lutterworth, Leicestershire LE17 4HB + Summary Information +Main Property + + Type SO Solid Brick + Insulation E External + Insulation Thickness Unknown + Conductivity Known No + Thermal Conductivity Lambda = 0.04 W/m*K + Wall Thickness Unknown No + Wall Thickness 260 mm + U-value Known No + Party Wall Type S Solid masonry / timber / system build +8.0 Roofs: +Main Property + + Type PA Pitched (slates/tiles), access to loft + Insulation J Joists + Insulation Thickness 150 mm + U-value Known No +8.1 Rooms in Roof: +9.0 Floors: +Main Property + + Location G Ground floor + Type S Solid + Insulation A As built + Default U-value 0.73 + U-value Known No +10.0 Doors: + Total Number of Doors 2 + Number of Insulated Doors 0 +11.0 Windows: + Frame Frame Glazing Building U g Draught Permanent +W H Area Glazing Type Location Orient. Data-Source + Type Factor Gap Part value value Proofed Shutters + Double with unknown +4.31 1.00 4.31 PVC 0.70 12 mm Main External wall North Manufacturer 2.80 0.76 Yes None + install date + Double with unknown +2.89 1.00 2.89 PVC 0.70 12 mm Main External wall West Manufacturer 2.80 0.76 Yes None + install date + Double with unknown +2.89 1.00 2.89 PVC 0.70 12 mm Main External wall North Manufacturer 2.80 0.76 Yes None + install date + Double with unknown +2.89 1.00 2.89 PVC 0.70 12 mm Main External wall East Manufacturer 2.80 0.76 Yes None + install date + + Draught Proofing 67 % +12.0 Ventilation & Cooling + No. of open chimneys 0 + No. of open flues 0 + No. of open chimneys/open flues attached to closed fire 0 + No. of flues attached to solid fuel boiler 0 + No. of open flues attached to other heater 0 + No. of blocked chimneys 0 + No. of intermittent extract fans 0 + No. of passive vents 0 + No. of flueless gas fires 0 + Fixed Space Cooling No + Draught Lobby Unable to determine + + + + + © Elmhurst Energy Systems Limited Registered Office Unit 16, St Johns Business Park, Lutterworth, Leicestershire LE17 4HB + Summary Information +12.1 Mechanical Ventilation + Mechanical Ventilation No +12.2 Air Pressure Test + Test Method Not available +13.0 Lighting + Total number of bulbs 6 + Number of LED and CFL Known Yes + Number of LED lights 0 + Number of CFL lights 0 + Total number of Low Energy 0 + Total number of incandescents 6 +14.0 Main Heating1 + PCDF boiler Reference 0 + Main Heating EES Code BGW + Main Heating SAP Code 104 + Heat Emitter Radiators + Heat pump age 2013 or later + Flue Type Balanced + Fan Assisted Flue Yes + Design flow temperature <= 35°C + PCDF Heating Controls 0 + Main Heating Controls EES CBE + Main Heating Controls Sap SAP code 2106, Programmer, room thermostat and TRVs + PCDF Compensator 0 + Percentage of Heat 100 % +14.1 Main Heating2 + PCDF boiler Reference 0 + Main Heating EES Code + Main Heating SAP Code 0 + Percentage of Heat 0% +14.1 Community Heating/Heat Network + Heating Type None +14.2 Meters +Electricity meter type Single +Main gas Yes +Electricity Smart Meter Present No +Gas Smart Meter Present No +15.0 Water Heating + Water Heating Code HWP + Water Heating SapCode 901 + Water Heating Fuel Type Mains gas +15.1 Hot Water Cylinder + Hot Water Cylinder Present No +15.2 Community Hot Water + PCDF boiler Reference 0 +16.0 Solar water heating + Solar Water Heating No +17.0 Waste Water Heat Recovery System + Is WWHRS present in the property? No / Unknown +1x.0 Baths and Showers + Total Number of Baths 2 + Number of Baths Connected 0 + +Description Type Connected + +1 Non-electric shower None + + + + + © Elmhurst Energy Systems Limited Registered Office Unit 16, St Johns Business Park, Lutterworth, Leicestershire LE17 4HB + Summary Information +18.0 Flue Gas Heat Recovery System + Present No +19.0 Photovoltaic Panel + Photovoltaic Panel None + Export capable meter No +20.0 Wind Turbine + Terrain Type Urban + Wind turbine present? No +22.0 Special Features +21.0 Small-Scale Hydro + Electricity generated [kWh/year] 0.00 + + + + + © Elmhurst Energy Systems Limited Registered Office Unit 16, St Johns Business Park, Lutterworth, Leicestershire LE17 4HB + Summary Information + + Recommendations + + Loft insulation (SAP increase too small) + Flat roof insulation (Not applicable) + Room-in-roof insulation (Not applicable) + Cavity wall insulation (Not applicable) + Solid wall insulation (SAP increase too small) + Floor insulation (solid floor) (Recommended) + Hot water cylinder insulation (Not applicable) + Draught proofing (SAP increase too small) + Low energy lighting (Recommended) + Cylinder thermostat (Not applicable) + Heating controls for wet central heating system (Already installed) + Upgrade boiler, same fuel (Already installed) + Change heating to condensing gas condensing boiler (fuel switch) (Not applicable) + Flue gas heat recovery in conjunction with new boiler (Not applicable) + Solar water heating (SAP increase too small) + Heat recovery system for mixer showers (SAP increase too small) + Double glazed windows (Already installed) + Insulated doors (SAP increase too small) + Solar photovoltaic panels (Recommended) + Wind turbine (Not applicable) + PV diverter (Not applicable) + PV battery (Not applicable) + Water heating controls (Not applicable) + + Alternative Recommendations + External wall insulation with cavity insulation (Not applicable) + Biomass boiler (alternative) (Not applicable) + Micro CHP (alternative) (Not applicable) + + Related Party Disclosure + +No related party + + Addenda +When considering the PV installation consider installing PV battery and a PV diverter for water heating + + + + + © Elmhurst Energy Systems Limited Registered Office Unit 16, St Johns Business Park, Lutterworth, Leicestershire LE17 4HB + \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ws.txt b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ws.txt new file mode 100644 index 000000000..20c66e415 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_200004296092/ws.txt @@ -0,0 +1,1311 @@ +---------------------------------------------------------------------------------------------------- + SAP 10.02 Input Data (House) 02/07/2026 +---------------------------------------------------------------------------------------------------- +Full RefNo 001431 +Inspection date 25/06/2025 00:00:00 +Regs Region England +SAP Region Thames Valley +Property address 28 Distillery Wharf, 28 Distillery Wharf London +Postcode W6 9BF +Dwelling Orientation North +Property Type House, End-Terrace +Storeys 2 +Property Age Band B +Sheltered Sides 1 +Sunlight Shade Average or unknown +Measurements Perimeter, Floor Area, Storey Height + 1st Storey: 15.97, 31.16, 2.40 + 2nd Storey: 15.97, 31.16, 2.65 +Living Area 18.7 m2, fraction: 30.0% +Thermal Mass Enter TMP value +Thermal MassValue 250.00 +External Walls Nett Area, Gross Area, Kappa, Element, Construction, Type, ShelterFactor, UValueFinal + External walls Main 63.97, 80.65, 190, SolidWallDensePlaster200, Solid, 0.0, 0.48, Gross +Party Walls Area, Kappa, Element, Construction, Type, ShelterFactor, UValueFinal + Party walls Main 34.29, 0, Other, Solid, 0, 0.00 +External Roofs Nett Area, Gross Area, Kappa, Construction, Element, UValueFinal + External roof Main 31.16, 31.16, 9, Plasterboard, insulated slope, 0.3 +Heat Loss Floors Area, Kappa, Construction, Element, Type, ShelterFactor, UValueFinal + Ground floor Main 31.16, 0.00, Other, Ground Floor - Solid, 0.00, 0.73 +Description Data Source, Type, Glazing, Glazing Gap, Argon Filled, Solar Trans, Frame Type, Frame Factor, U Value + Doors uninsulated 1 Manufacturer, Solid Door, , , , , , , + Windows 1 Manufacturer, Window, Double glazed, , , 0.76, , 0.7, +Openings Opening Type, Location, Orientation, Pitch, Width, Height, Count, Area + Doors uninsulated Solid Door, External walls Main, East, , 3.7, 1, 1, 3.70 + Windows 1(Main) Window, External walls Main, North, , 4.31, 1, 1, 4.31 + Windows 2(Main) Window, External walls Main, West, , 2.89, 1, 1, 2.89 + Windows 2(Main) Window, External walls Main, North, , 2.89, 1, 1, 2.89 + Windows 2(Main) Window, External walls Main, East, , 2.89, 1, 1, 2.89 +Conservatory None +Draught Proofing 67 +Draught Lobby No +Thermal Bridges + Bridging User Input + Y 0.15 + Description RDSAP conversion + List of Bridges Junction with, Bridge Type, Source Type, Imported, Length, Psi, Adjusted, Result, Reference + 0. External wall, E22 Basement floor, Table K1 - Default, No, 1.00, 0.220, 0.220, 0.22, TER +Pressure Test False +Pressure Test Method Blower Door +Designed AP50 15.00 +AsBuilt AP50 0.00 +Property Tested True +Mechanical Ventilation None +Open Chimneys 0 +Open Flues 0 +Chimneys/Flues Attached to Closed Fire0 +Flues Attached to Solid Fuel Boiler0 +Flues Attached to Other Heater0 +Blocked chimneys 0 +Intermittent Fans 0 +Passive Vents 0 +Flueless Gas Fires 0 +Cooling System None +Lightings Name, Power, Efficacy, Capacity, Count + incandescent lights 60, 11.2, 672, 6 +Percentage of LEL Fittings 0.00 +Electricity Tariff Standard +Main Heating 1 + Description + Percentage 100 + FuelType Mains gas + SAP Code 104 + Boiler Efficiency Type SAP Table + Controls by PCDF 0 + MHS Controls 2106 Programmer, room thermostat and TRVs + Boiler Interlock Yes + Compensator 0 + Delayed Start Stat No + Ctrl SAP Code 2106 + Flue Type Balanced + Fan Assisted Flue Yes + Pumped Pump in heated space + Heat Pump Age 2013 or later + Heat Emitter Radiators + Flow Temperature Enter value + Flow Temperature Value 35 + Combi boiler type Standard Combi + Combi keep hot type None +Main Heating 2 None +Smoke Control Area Unknown +Community Heating None +Secondary Heating + Description Electricity Electric Panel, convector or radiant heaters + SAP Code 691 + Efficiency 100 +Water Heating + Type MainHeating1 + WHS 901 From main heating system + Low Water Usage No + SAP Code 901 + Cold Water Source From mains + Total number of baths in property2 + Hot Water Cylinder None +Showers Description, Type, Flow rate, Rated power, Connected, Connected WWHRS + Shower 01 Vented hot water system, 7.00, , No, +Flue Gas Heat Recovery System None +Waste Water Heat Recovery none +PV Unit None +Terrain Type Urban +Wind Turbine None +Small Scale Hydro None +Special Features None +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +SAP 10 WORKSHEET FOR Existing dwelling (SAP) (Version 10.2, February 2022) +CALCULATION OF ENERGY RATING +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +1. Overall dwelling characteristics + ---------------------------------------------------------------------------------------------------- + Area Storey height Volume +Main dwelling (m2) (m) (m3) + Ground floor 31.1600 (1b) x 2.4000 (2b) = 74.7840 (1b) - (3b) + First floor 31.1600 (1c) x 2.6500 (2c) = 82.5740 (1c) - (3c) +Total floor area TFA = (1a)+(1b)+(1c)+(1d)+(1e)...(1n) 62.3200 (4) +Dwelling volume (3a)+(3b)+(3c)+(3d)+(3e)...(3n) = 157.3580 (5) +---------------------------------------------------------------------------------------------------- +2. Ventilation rate +---------------------------------------------------------------------------------------------------- + m3 per hour + +Number of open chimneys 0 * 80 = 0.0000 (6a) +Number of open flues 0 * 20 = 0.0000 (6b) +Number of chimneys / flues attached to closed fire 0 * 10 = 0.0000 (6c) +Number of flues attached to solid fuel boiler 0 * 20 = 0.0000 (6d) +Number of flues attached to other heater 0 * 35 = 0.0000 (6e) +Number of blocked chimneys 0 * 20 = 0.0000 (6f) +Number of intermittent extract fans 0 * 10 = 0.0000 (7a) +Number of passive vents 0 * 10 = 0.0000 (7b) +Number of flueless gas fires 0 * 40 = 0.0000 (7c) + Air changes per hour +Infiltration due to chimneys, flues and fans = (6a)+(6b)+(6c)+(6d)+(6e)+(6f)+(6g)+(7a)+(7b)+(7c) = 0.0000 / (5) = 0.0000 (8) + Number of storeys in the dwelling (ns) 2 (9) + Additional infiltration [(9) - 1] x 0.1 = 0.1000 (10) + Structural infiltration: 0.25 for steel or timber frame or 0.35 for masonry construction 0.3500 (11) + If suspended wooden floor, enter 0.2 (unsealed) or 0.1 (sealed), else enter 0 0.0000 (12) + If no draught lobby, enter 0.05, else enter 0 0.0500 (13) + Percentage of windows and doors draught stripped 67.0000 (14) + Window infiltration 0.25 - [0.2 * (14) / 100] = 0.1160 (15) +Pressure test No +Infiltration rate 0.6160 (18) +Number of sides sheltered 1 (19) +Shelter factor (20) = 1 - [0.075 x (19)] = 0.9250 (20) +Infiltration rate adjusted to include shelter factor (21) = (18) x (20) = 0.5698 (21) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Wind speed 5.1000 5.0000 4.9000 4.4000 4.3000 3.8000 3.8000 3.7000 4.0000 4.3000 4.5000 4.7000 (22) +Wind factor 1.2750 1.2500 1.2250 1.1000 1.0750 0.9500 0.9500 0.9250 1.0000 1.0750 1.1250 1.1750 (22a) +Adj infilt rate + 0.7265 0.7123 0.6980 0.6268 0.6125 0.5413 0.5413 0.5271 0.5698 0.6125 0.6410 0.6695 (22b) +Effective ac 0.7639 0.7537 0.7436 0.6964 0.6876 0.6465 0.6465 0.6389 0.6623 0.6876 0.7055 0.7241 (25) +---------------------------------------------------------------------------------------------------- +3. Heat losses and heat loss parameter +---------------------------------------------------------------------------------------------------- +Element Gross Openings NetArea U-value A x U K-value A x K +Main dwelling m2 m2 m2 W/m2K W/K kJ/m2K kJ/K + Doors uninsulated 1 3.7000 3.0000 11.1000 (26) + Windows 1 12.9800 2.5180 32.6835 (27) + Ground floor Main 31.1600 0.7300 22.7468 (28a) + External walls Main 80.6500 16.6800 63.9700 0.4800 30.7056 (29a) + External roof Main 31.1600 31.1600 0.3000 9.3480 (30) +Total net area of external elements Aum(A, m2) 142.9700 (31) +Fabric heat loss, W/K = Sum (A x U) (26)...(30) + (32) = 106.5839 (33) +Main dwelling + Party walls Main 34.2900 0.0000 0.0000 (32) +Thermal mass parameter (TMP = Cm / TFA) in kJ/m2K 250.0000 (35) +Thermal bridges (User defined value 0.150 * total exposed area) 21.4455 (36) +Point Thermal bridges (36a) = 0.0000 +Total fabric heat loss (33) + (36) + (36a) = 128.0294 (37) +Ventilation heat loss calculated monthly (38)m = 0.33 x (25)m x (5) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(38)m 39.6678 39.1356 38.6140 36.1641 35.7058 33.5720 33.5720 33.1768 34.3939 35.7058 36.6330 37.6025 (38) +Heat transfer coeff + 167.6971 167.1650 166.6434 164.1935 163.7351 161.6013 161.6013 161.2062 162.4232 163.7351 164.6624 165.6318 (39) +Average = Sum(39)m / 12 = 164.1913 + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +HLP 2.6909 2.6824 2.6740 2.6347 2.6273 2.5931 2.5931 2.5867 2.6063 2.6273 2.6422 2.6578 (40) +HLP (average) 2.6346 +Days in mont 31 28 31 30 31 30 31 31 30 31 30 31 +---------------------------------------------------------------------------------------------------- +4. Water heating energy requirements (kWh/year) +---------------------------------------------------------------------------------------------------- +Assumed occupancy 2.0464 (42) +Hot water usage for mixer showers + 51.2148 50.4451 49.3236 47.1777 45.5941 43.8281 42.8243 43.9374 45.1575 47.0536 49.2456 51.0186 (42a) +Hot water usage for baths + 26.6248 26.2294 25.6726 24.6459 23.8771 23.0246 22.5642 23.1171 23.7192 24.6313 25.6791 26.5348 (42b) +Hot water usage for other uses + 37.4603 36.0981 34.7359 33.3737 32.0116 30.6494 30.6494 32.0116 33.3737 34.7359 36.0981 37.4603 (42c) +Average daily hot water use (litres/day) 105.9586 (43) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Daily hot water use + 115.2999 112.7727 109.7321 105.1973 101.4828 97.5021 96.0379 99.0660 102.2504 106.4209 111.0229 115.0137 (44) +Energy conte 182.6069 160.5868 168.6541 144.0099 136.6153 119.8902 116.1495 122.6644 126.0850 144.4121 158.1725 180.0836 (45) +Energy content (annual) Total = Sum(45)m = 1759.9303 +Distribution loss (46)m = 0.15 x (45)m + 27.3910 24.0880 25.2981 21.6015 20.4923 17.9835 17.4224 18.3997 18.9127 21.6618 23.7259 27.0125 (46) +Water storage loss (or HIU loss): +Total storage loss + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (56) +If cylinder contains dedicated solar storage + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (57) +Primary loss 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (59) +Combi loss 50.9589 46.0274 50.9589 49.3151 50.9589 48.0832 48.9398 50.4830 49.3151 50.9589 49.3151 50.9589 (61) +Total heat required for water heating calculated for each month + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (62) +WWHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63a) +PV diverter 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63b) +Solar input 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63c) +FGHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63d) +Output from w/h + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) + Total per year (kWh/year) = Sum(64)m = 2356.2034 (64) +Electric shower(s) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (64a) + Total Energy used by instantaneous electric shower(s) (kWh/year) = Sum(64a)m = 0.0000 (64a) +Heat gains from water heating, kWh/month + 73.4565 64.9019 68.8172 60.2121 58.1643 51.8843 50.8547 53.4067 54.2520 60.7568 64.9211 72.6175 (65) +---------------------------------------------------------------------------------------------------- +5. Internal gains (see Table 5 and 5a) +---------------------------------------------------------------------------------------------------- +Metabolic gains (Table 5), Watts + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(66)m 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 (66) +Lighting gains (calculated in Appendix L, equation L9 or L9a), also see Table 5 + 71.1593 63.2031 51.4002 38.9133 29.0881 24.5574 26.5352 34.4914 46.2943 58.7812 68.6064 73.1371 (67) +Appliances gains (calculated in Appendix L, equation L13 or L13a), also see Table 5 + 266.8027 269.5713 262.5946 247.7419 228.9932 211.3720 199.5999 196.8313 203.8081 218.6607 237.4095 255.0307 (68) +Cooking gains (calculated in Appendix L, equation L15 or L15a), also see Table 5 + 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 (69) +Pumps, fans 3.0000 3.0000 3.0000 3.0000 3.0000 0.0000 0.0000 0.0000 0.0000 3.0000 3.0000 3.0000 (70) +Losses e.g. evaporation (negative values) (Table 5) + -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 (71) +Water heating gains (Table 5) + 98.7319 96.5803 92.4963 83.6279 78.1778 72.0615 68.3530 71.7832 75.3500 81.6623 90.1682 97.6042 (72) +Total internal gains + 529.9471 522.6078 499.7442 463.5362 429.5123 398.2441 384.7412 393.3590 415.7055 452.3574 489.4372 519.0251 (73) +---------------------------------------------------------------------------------------------------- +6. Solar gains +---------------------------------------------------------------------------------------------------- +[Jan] Area Solar flux g FF Access Gains + m2 Table 6a Specific data Specific data factor W + W/m2 or Table 6b or Table 6c Table 6d +---------------------------------------------------------------------------------------------------- +North 7.2000 10.6334 0.7600 0.7000 0.7700 28.2260 (74) +East 2.8900 19.6403 0.7600 0.7000 0.7700 20.9262 (76) +West 2.8900 19.6403 0.7600 0.7000 0.7700 20.9262 (80) +---------------------------------------------------------------------------------------------------- +Solar gains 70.0784 135.8134 226.4912 343.8726 439.3250 459.0195 433.0958 359.0167 267.0192 161.3582 87.0054 57.9479 (83) +Total gains 600.0254 658.4212 726.2353 807.4088 868.8373 857.2635 817.8371 752.3758 682.7247 613.7156 576.4425 576.9730 (84) +---------------------------------------------------------------------------------------------------- +7. Mean internal temperature (heating season) +---------------------------------------------------------------------------------------------------- +Temperature during heating periods in the living area from Table 9, Th1 (C) 21.0000 (85) +Utilisation factor for gains for living area, ni1,m (see Table 9a) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +tau 25.8071 25.8893 25.9703 26.3578 26.4316 26.7806 26.7806 26.8462 26.6451 26.4316 26.2827 26.1289 +alpha 2.7205 2.7260 2.7314 2.7572 2.7621 2.7854 2.7854 2.7897 2.7763 2.7621 2.7522 2.7419 +util living area + 0.9881 0.9836 0.9735 0.9487 0.8963 0.8005 0.6824 0.7308 0.8833 0.9610 0.9831 0.9894 (86) +MIT 18.0348 18.2517 18.6986 19.3471 19.9916 20.5260 20.7917 20.7386 20.2963 19.4913 18.6708 18.0152 (87) +Th 2 18.9125 18.9172 18.9219 18.9438 18.9479 18.9673 18.9673 18.9709 18.9598 18.9479 18.9396 18.9309 (88) +util rest of house + 0.9835 0.9772 0.9621 0.9235 0.8361 0.6608 0.4360 0.4985 0.7860 0.9365 0.9751 0.9853 (89) +MIT 2 16.4138 16.6314 17.0756 17.7205 18.3240 18.7776 18.9318 18.9172 18.6162 17.8743 17.0631 16.4054 (90) +Living area fraction fLA = Living area / (4) = 0.3001 (91) +MIT 16.9002 17.1176 17.5626 18.2086 18.8244 19.3022 19.4899 19.4637 19.1203 18.3595 17.5455 16.8884 (92) +Temperature adjustment 0.0000 +adjusted MIT 16.9002 17.1176 17.5626 18.2086 18.8244 19.3022 19.4899 19.4637 19.1203 18.3595 17.5455 16.8884 (93) +---------------------------------------------------------------------------------------------------- +8. Space heating requirement +---------------------------------------------------------------------------------------------------- + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Utilisation 0.9765 0.9686 0.9509 0.9107 0.8312 0.6900 0.5126 0.5690 0.7966 0.9259 0.9666 0.9789 (94) +Useful gains 585.9077 637.7302 690.5719 735.2903 722.1589 591.5356 419.2138 428.1056 543.8706 568.2557 557.2080 564.7854 (95) +Ext temp. 4.3000 4.9000 6.5000 8.9000 11.7000 14.6000 16.6000 16.4000 14.1000 10.6000 7.1000 4.2000 (96) +Heat loss rate W + 2113.0154 2042.3548 1843.5024 1528.4133 1166.5069 759.8827 467.0161 493.8903 815.4187 1270.5091 1719.9789 2101.6097 (97) +Space heating kWh + 1136.1681 943.9077 857.7803 571.0485 330.5949 0.0000 0.0000 0.0000 0.0000 522.4765 837.1951 1143.3973 (98a) +Space heating requirement - total per year (kWh/year) 6342.5685 +Solar heating kWh + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (98b) +Solar heating contribution - total per year (kWh/year) 0.0000 +Space heating kWh + 1136.1681 943.9077 857.7803 571.0485 330.5949 0.0000 0.0000 0.0000 0.0000 522.4765 837.1951 1143.3973 (98c) +Space heating requirement after solar contribution - total per year (kWh/year) 6342.5685 +Space heating per m2 (98c) / (4) = 101.7742 (99) +---------------------------------------------------------------------------------------------------- +9a. Energy requirements - Individual heating systems, including micro-CHP +---------------------------------------------------------------------------------------------------- +Fraction of space heat from secondary/supplementary system (Table 11) 0.1000 (201) +Fraction of space heat from main system(s) 0.9000 (202) +Efficiency of main space heating system 1 (in %) 84.0000 (206) +Efficiency of main space heating system 2 (in %) 0.0000 (207) +Efficiency of secondary/supplementary heating system, % 100.0000 (208) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Space heating requirement + 1136.1681 943.9077 857.7803 571.0485 330.5949 0.0000 0.0000 0.0000 0.0000 522.4765 837.1951 1143.3973 (98) +Space heating efficiency (main heating system 1) + 84.0000 84.0000 84.0000 84.0000 84.0000 0.0000 0.0000 0.0000 0.0000 84.0000 84.0000 84.0000 (210) +Space heating fuel (main heating system) + 1217.3230 1011.3297 919.0504 611.8377 354.2088 0.0000 0.0000 0.0000 0.0000 559.7963 896.9947 1225.0686 (211) +Space heating efficiency (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (212) +Space heating fuel (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (213) +Space heating fuel (secondary) + 113.6168 94.3908 85.7780 57.1049 33.0595 0.0000 0.0000 0.0000 0.0000 52.2477 83.7195 114.3397 (215) +Water heating +Water heating requirement + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) +Efficiency of water heater 75.0000 (216) +(217)m 82.1666 82.0733 81.8254 81.3322 80.2753 75.0000 75.0000 75.0000 75.0000 81.1419 81.8785 82.1916 (217) +Fuel for water heating, kWh/month + 284.2588 251.7436 268.3923 237.6978 233.6638 223.9646 220.1191 230.8632 233.8667 240.7769 253.4089 281.1024 (219) +Space cooling fuel requirement +(221)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (221) +Pumps and Fa 7.3041 6.5973 7.3041 7.0685 7.3041 7.0685 7.3041 7.3041 7.0685 7.3041 7.0685 7.3041 (231) +Lighting 62.2853 49.9676 44.9903 32.9618 25.4607 20.8016 23.2261 30.1901 39.2140 51.4509 58.1136 64.0164 (232) +Electricity generated by PVs (Appendix M) (negative quantity) +(233a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233a) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234a) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235a) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235c)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235c) +Electricity generated by PVs (Appendix M) (negative quantity) +(233b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233b) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234b) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235b) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235d)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235d) +Annual totals kWh/year +Space heating fuel - main system 1 6795.6091 (211) +Space heating fuel - main system 2 0.0000 (213) +Space heating fuel - secondary 634.2569 (215) +Efficiency of water heater 75.0000 +Water heating fuel used 2959.8582 (219) +Space cooling fuel 0.0000 (221) +Electricity for pumps and fans: + central heating pump 41.0000 (230c) + main heating flue fan 45.0000 (230e) +Total electricity for the above, kWh/year 86.0000 (231) +Electricity for lighting (calculated in Appendix L) 502.6784 (232) + Energy saving/generation technologies (Appendices M ,N and Q) +PV generation 0.0000 (233) +Wind generation 0.0000 (234) +Hydro-electric generation (Appendix N) 0.0000 (235a) +Electricity generated - Micro CHP (Appendix N) 0.0000 (235) +Appendix Q - special features +Energy saved or generated 0.0000 (236) +Energy used 0.0000 (237) +Total delivered energy for all uses 10978.4026 (238) +---------------------------------------------------------------------------------------------------- +10a. Fuel costs - using Table 12 prices +---------------------------------------------------------------------------------------------------- + Fuel Fuel price Fuel cost + kWh/year p/kWh £/year +Space heating - main system 1 6795.6091 3.4800 236.4872 (240) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 634.2569 13.1900 83.6585 (242) +Water heating (other fuel) 2959.8582 3.4800 103.0031 (247) +Energy for instantaneous electric shower(s) 0.0000 13.1900 0.0000 (247a) +Pumps, fans and electric keep-hot 86.0000 13.1900 11.3434 (249) +Energy for lighting 502.6784 13.1900 66.3033 (250) +Additional standing charges 120.0000 (251) +Total energy cost 620.7954 (255) +---------------------------------------------------------------------------------------------------- +11a. SAP rating - Individual heating systems +---------------------------------------------------------------------------------------------------- +Energy cost deflator (Table 12): 0.4200 (256) +Energy cost factor (ECF) [(255) x (256)] / [(4) + 45.0] = 2.4295 (257) +SAP value 66.1085 +SAP rating (Section 12) 66 (258) +SAP band D +---------------------------------------------------------------------------------------------------- +12a. Carbon dioxide emissions - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Emission factor Emissions + kWh/year kg CO2/kWh kg CO2/year +Space heating - main system 1 6795.6091 0.2100 1427.0779 (261) +Total CO2 associated with community systems 0.0000 (373) +Space heating - secondary 634.2569 0.1540 97.6607 (263) +Water heating (other fuel) 2959.8582 0.2100 621.5702 (264) +Space and water heating 2146.3088 (265) +Pumps, fans and electric keep-hot 86.0000 0.1387 11.9293 (267) +Energy for lighting 502.6784 0.1443 72.5520 (268) +Total CO2, kg/year 2230.7901 (272) +CO2 emissions per m2 35.8000 (273) +EI value 72.1463 +EI rating 72 (274) +EI band C +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +SAP 10 WORKSHEET FOR Existing dwelling (SAP) (Version 10.2, February 2022) +CALCULATION OF EPC COSTS, EMISSIONS AND PRIMARY ENERGY +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +1. Overall dwelling characteristics +---------------------------------------------------------------------------------------------------- + Area Storey height Volume +Main dwelling (m2) (m) (m3) + Ground floor 31.1600 (1b) x 2.4000 (2b) = 74.7840 (1b) - (3b) + First floor 31.1600 (1c) x 2.6500 (2c) = 82.5740 (1c) - (3c) +Total floor area TFA = (1a)+(1b)+(1c)+(1d)+(1e)...(1n) 62.3200 (4) +Dwelling volume (3a)+(3b)+(3c)+(3d)+(3e)...(3n) = 157.3580 (5) +---------------------------------------------------------------------------------------------------- +2. Ventilation rate +---------------------------------------------------------------------------------------------------- + m3 per hour + +Number of open chimneys 0 * 80 = 0.0000 (6a) +Number of open flues 0 * 20 = 0.0000 (6b) +Number of chimneys / flues attached to closed fire 0 * 10 = 0.0000 (6c) +Number of flues attached to solid fuel boiler 0 * 20 = 0.0000 (6d) +Number of flues attached to other heater 0 * 35 = 0.0000 (6e) +Number of blocked chimneys 0 * 20 = 0.0000 (6f) +Number of intermittent extract fans 0 * 10 = 0.0000 (7a) +Number of passive vents 0 * 10 = 0.0000 (7b) +Number of flueless gas fires 0 * 40 = 0.0000 (7c) + Air changes per hour +Infiltration due to chimneys, flues and fans = (6a)+(6b)+(6c)+(6d)+(6e)+(6f)+(6g)+(7a)+(7b)+(7c) = 0.0000 / (5) = 0.0000 (8) + Number of storeys in the dwelling (ns) 2 (9) + Additional infiltration [(9) - 1] x 0.1 = 0.1000 (10) + Structural infiltration: 0.25 for steel or timber frame or 0.35 for masonry construction 0.3500 (11) + If suspended wooden floor, enter 0.2 (unsealed) or 0.1 (sealed), else enter 0 0.0000 (12) + If no draught lobby, enter 0.05, else enter 0 0.0500 (13) + Percentage of windows and doors draught stripped 67.0000 (14) + Window infiltration 0.25 - [0.2 * (14) / 100] = 0.1160 (15) +Pressure test No +Infiltration rate 0.6160 (18) +Number of sides sheltered 1 (19) +Shelter factor (20) = 1 - [0.075 x (19)] = 0.9250 (20) +Infiltration rate adjusted to include shelter factor (21) = (18) x (20) = 0.5698 (21) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Wind speed 3.8000 3.7000 3.7000 3.5000 3.5000 3.1000 3.3000 3.0000 3.0000 3.1000 3.1000 3.5000 (22) +Wind factor 0.9500 0.9250 0.9250 0.8750 0.8750 0.7750 0.8250 0.7500 0.7500 0.7750 0.7750 0.8750 (22a) +Adj infilt rate + 0.5413 0.5271 0.5271 0.4986 0.4986 0.4416 0.4701 0.4274 0.4274 0.4416 0.4416 0.4986 (22b) +Effective ac 0.6465 0.6389 0.6389 0.6243 0.6243 0.5975 0.6105 0.5913 0.5913 0.5975 0.5975 0.6243 (25) +---------------------------------------------------------------------------------------------------- +3. Heat losses and heat loss parameter +---------------------------------------------------------------------------------------------------- +Element Gross Openings NetArea U-value A x U K-value A x K +Main dwelling m2 m2 m2 W/m2K W/K kJ/m2K kJ/K + Doors uninsulated 1 3.7000 3.0000 11.1000 (26) + Windows 1 12.9800 2.5180 32.6835 (27) + Ground floor Main 31.1600 0.7300 22.7468 (28a) + External walls Main 80.6500 16.6800 63.9700 0.4800 30.7056 (29a) + External roof Main 31.1600 31.1600 0.3000 9.3480 (30) +Total net area of external elements Aum(A, m2) 142.9700 (31) +Fabric heat loss, W/K = Sum (A x U) (26)...(30) + (32) = 106.5839 (33) +Main dwelling + Party walls Main 34.2900 0.0000 0.0000 (32) +Thermal mass parameter (TMP = Cm / TFA) in kJ/m2K 250.0000 (35) +Thermal bridges (User defined value 0.150 * total exposed area) 21.4455 (36) +Point Thermal bridges (36a) = 0.0000 +Total fabric heat loss (33) + (36) + (36a) = 128.0294 (37) +Ventilation heat loss calculated monthly (38)m = 0.33 x (25)m x (5) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(38)m 33.5720 33.1768 33.1768 32.4181 32.4181 31.0272 31.7016 30.7058 30.7058 31.0272 31.0272 32.4181 (38) +Heat transfer coeff + 161.6013 161.2062 161.2062 160.4475 160.4475 159.0566 159.7310 158.7352 158.7352 159.0566 159.0566 160.4475 (39) +Average = Sum(39)m / 12 = 159.9773 + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +HLP 2.5931 2.5867 2.5867 2.5746 2.5746 2.5523 2.5631 2.5471 2.5471 2.5523 2.5523 2.5746 (40) +HLP (average) 2.5670 +Days in mont 31 28 31 30 31 30 31 31 30 31 30 31 +---------------------------------------------------------------------------------------------------- +4. Water heating energy requirements (kWh/year) +---------------------------------------------------------------------------------------------------- +Assumed occupancy 2.0464 (42) +Hot water usage for mixer showers + 51.2148 50.4451 49.3236 47.1777 45.5941 43.8281 42.8243 43.9374 45.1575 47.0536 49.2456 51.0186 (42a) +Hot water usage for baths + 26.6248 26.2294 25.6726 24.6459 23.8771 23.0246 22.5642 23.1171 23.7192 24.6313 25.6791 26.5348 (42b) +Hot water usage for other uses + 37.4603 36.0981 34.7359 33.3737 32.0116 30.6494 30.6494 32.0116 33.3737 34.7359 36.0981 37.4603 (42c) +Average daily hot water use (litres/day) 105.9586 (43) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Daily hot water use + 115.2999 112.7727 109.7321 105.1973 101.4828 97.5021 96.0379 99.0660 102.2504 106.4209 111.0229 115.0137 (44) +Energy conte 182.6069 160.5868 168.6541 144.0099 136.6153 119.8902 116.1495 122.6644 126.0850 144.4121 158.1725 180.0836 (45) +Energy content (annual) Total = Sum(45)m = 1759.9303 +Distribution loss (46)m = 0.15 x (45)m + 27.3910 24.0880 25.2981 21.6015 20.4923 17.9835 17.4224 18.3997 18.9127 21.6618 23.7259 27.0125 (46) +Water storage loss (or HIU loss): +Total storage loss + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (56) +If cylinder contains dedicated solar storage + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (57) +Primary loss 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (59) +Combi loss 50.9589 46.0274 50.9589 49.3151 50.9589 48.0832 48.9398 50.4830 49.3151 50.9589 49.3151 50.9589 (61) +Total heat required for water heating calculated for each month + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (62) +WWHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63a) +PV diverter 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63b) +Solar input 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63c) +FGHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63d) +Output from w/h + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) + Total per year (kWh/year) = Sum(64)m = 2356.2034 (64) +Electric shower(s) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (64a) + Total Energy used by instantaneous electric shower(s) (kWh/year) = Sum(64a)m = 0.0000 (64a) +Heat gains from water heating, kWh/month + 73.4565 64.9019 68.8172 60.2121 58.1643 51.8843 50.8547 53.4067 54.2520 60.7568 64.9211 72.6175 (65) +---------------------------------------------------------------------------------------------------- +5. Internal gains (see Table 5 and 5a) +---------------------------------------------------------------------------------------------------- +Metabolic gains (Table 5), Watts + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(66)m 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 (66) +Lighting gains (calculated in Appendix L, equation L9 or L9a), also see Table 5 + 71.1593 63.2031 51.4002 38.9133 29.0881 24.5574 26.5352 34.4914 46.2943 58.7812 68.6064 73.1371 (67) +Appliances gains (calculated in Appendix L, equation L13 or L13a), also see Table 5 + 266.8027 269.5713 262.5946 247.7419 228.9932 211.3720 199.5999 196.8313 203.8081 218.6607 237.4095 255.0307 (68) +Cooking gains (calculated in Appendix L, equation L15 or L15a), also see Table 5 + 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 (69) +Pumps, fans 3.0000 3.0000 3.0000 3.0000 3.0000 0.0000 0.0000 0.0000 0.0000 3.0000 3.0000 3.0000 (70) +Losses e.g. evaporation (negative values) (Table 5) + -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 (71) +Water heating gains (Table 5) + 98.7319 96.5803 92.4963 83.6279 78.1778 72.0615 68.3530 71.7832 75.3500 81.6623 90.1682 97.6042 (72) +Total internal gains + 529.9471 522.6078 499.7442 463.5362 429.5123 398.2441 384.7412 393.3590 415.7055 452.3574 489.4372 519.0251 (73) +---------------------------------------------------------------------------------------------------- +6. Solar gains +---------------------------------------------------------------------------------------------------- +[Jan] Area Solar flux g FF Access Gains + m2 Table 6a Specific data Specific data factor W + W/m2 or Table 6b or Table 6c Table 6d +---------------------------------------------------------------------------------------------------- +North 7.2000 11.5683 0.7600 0.7000 0.7700 30.7077 (74) +East 2.8900 21.5704 0.7600 0.7000 0.7700 22.9826 (76) +West 2.8900 21.5704 0.7600 0.7000 0.7700 22.9826 (80) +---------------------------------------------------------------------------------------------------- +Solar gains 76.6730 133.8602 224.7811 352.4577 437.5532 487.5086 459.0611 390.9446 291.1241 173.9501 98.4071 64.8811 (83) +Total gains 606.6201 656.4679 724.5253 815.9939 867.0655 885.7527 843.8023 784.3036 706.8297 626.3075 587.8443 583.9062 (84) +---------------------------------------------------------------------------------------------------- +7. Mean internal temperature (heating season) +---------------------------------------------------------------------------------------------------- +Temperature during heating periods in the living area from Table 9, Th1 (C) 21.0000 (85) +Utilisation factor for gains for living area, ni1,m (see Table 9a) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +tau 26.7806 26.8462 26.8462 26.9732 26.9732 27.2090 27.0942 27.2641 27.2641 27.2090 27.2090 26.9732 +alpha 2.7854 2.7897 2.7897 2.7982 2.7982 2.8139 2.8063 2.8176 2.8176 2.8139 2.8139 2.7982 +util living area + 0.9851 0.9800 0.9656 0.9261 0.8356 0.6366 0.4258 0.4815 0.7985 0.9397 0.9769 0.9865 (86) +MIT 18.4242 18.6244 19.0967 19.7531 20.3898 20.8355 20.9671 20.9519 20.6203 19.8886 19.0627 18.4121 (87) +Th 2 18.9673 18.9709 18.9709 18.9778 18.9778 18.9906 18.9844 18.9935 18.9935 18.9906 18.9906 18.9778 (88) +util rest of house + 0.9789 0.9715 0.9493 0.8856 0.7279 0.3908 0.0727 0.1199 0.6192 0.8964 0.9650 0.9808 (89) +MIT 2 16.8338 17.0336 17.4974 18.1289 18.6833 18.9656 18.9843 18.9933 18.8769 18.2799 17.4816 16.8285 (90) +Living area fraction fLA = Living area / (4) = 0.3001 (91) +MIT 17.3110 17.5110 17.9773 18.6163 19.1954 19.5267 19.5793 19.5810 19.4000 18.7626 17.9560 17.3037 (92) +Temperature adjustment 0.0000 +adjusted MIT 17.3110 17.5110 17.9773 18.6163 19.1954 19.5267 19.5793 19.5810 19.4000 18.7626 17.9560 17.3037 (93) +---------------------------------------------------------------------------------------------------- +8. Space heating requirement +---------------------------------------------------------------------------------------------------- + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Utilisation 0.9710 0.9622 0.9376 0.8756 0.7429 0.4675 0.1840 0.2358 0.6665 0.8892 0.9554 0.9735 (94) +Useful gains 589.0545 631.6483 679.2849 714.4648 644.1081 414.0819 155.2945 184.9239 471.0774 556.9055 561.6531 568.4109 (95) +Ext temp. 5.6000 6.2000 8.0000 10.6000 13.7000 16.7000 18.6000 18.4000 15.7000 12.2000 8.5000 5.6000 (96) +Heat loss rate W + 1892.5112 1823.3964 1608.4000 1286.1922 881.7185 449.6045 156.4215 187.4638 587.3223 1043.8267 1504.0390 1877.8239 (97) +Space heating kWh + 969.7718 800.8547 691.2617 411.6437 176.7821 0.0000 0.0000 0.0000 0.0000 362.2694 678.5179 974.2033 (98a) +Space heating requirement - total per year (kWh/year) 5065.3045 +Solar heating kWh + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (98b) +Solar heating contribution - total per year (kWh/year) 0.0000 +Space heating kWh + 969.7718 800.8547 691.2617 411.6437 176.7821 0.0000 0.0000 0.0000 0.0000 362.2694 678.5179 974.2033 (98c) +Space heating requirement after solar contribution - total per year (kWh/year) 5065.3045 +Space heating per m2 (98c) / (4) = 81.2790 (99) +---------------------------------------------------------------------------------------------------- +9a. Energy requirements - Individual heating systems, including micro-CHP +---------------------------------------------------------------------------------------------------- +Fraction of space heat from secondary/supplementary system (Table 11) 0.1000 (201) + Fraction of space heat from main system(s) 0.9000 (202) +Efficiency of main space heating system 1 (in %) 84.0000 (206) +Efficiency of main space heating system 2 (in %) 0.0000 (207) +Efficiency of secondary/supplementary heating system, % 100.0000 (208) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Space heating requirement + 969.7718 800.8547 691.2617 411.6437 176.7821 0.0000 0.0000 0.0000 0.0000 362.2694 678.5179 974.2033 (98) +Space heating efficiency (main heating system 1) + 84.0000 84.0000 84.0000 84.0000 84.0000 0.0000 0.0000 0.0000 0.0000 84.0000 84.0000 84.0000 (210) +Space heating fuel (main heating system) + 1039.0412 858.0586 740.6375 441.0468 189.4094 0.0000 0.0000 0.0000 0.0000 388.1458 726.9834 1043.7892 (211) +Space heating efficiency (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (212) +Space heating fuel (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (213) +Space heating fuel (secondary) + 96.9772 80.0855 69.1262 41.1644 17.6782 0.0000 0.0000 0.0000 0.0000 36.2269 67.8518 97.4203 (215) +Water heating +Water heating requirement + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) +Efficiency of water heater 75.0000 (216) +(217)m 81.9246 81.8127 81.4500 80.6802 78.8786 75.0000 75.0000 75.0000 75.0000 80.3856 81.5192 81.9491 (217) +Fuel for water heating, kWh/month + 285.0986 252.5452 269.6294 239.6187 237.8011 223.9646 220.1191 230.8632 233.8667 243.0424 254.5261 281.9342 (219) +Space cooling fuel requirement +(221)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (221) +Pumps and Fa 7.3041 6.5973 7.3041 7.0685 7.3041 7.0685 7.3041 7.3041 7.0685 7.3041 7.0685 7.3041 (231) +Lighting 62.2853 49.9676 44.9903 32.9618 25.4607 20.8016 23.2261 30.1901 39.2140 51.4509 58.1136 64.0164 (232) +Electricity generated by PVs (Appendix M) (negative quantity) +(233a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233a) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234a) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235a) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235c)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235c) +Electricity generated by PVs (Appendix M) (negative quantity) +(233b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233b) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234b) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235b) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235d)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235d) +Annual totals kWh/year +Space heating fuel - main system 1 5427.1120 (211) +Space heating fuel - main system 2 0.0000 (213) +Space heating fuel - secondary 506.5305 (215) +Efficiency of water heater 75.0000 +Water heating fuel used 2973.0093 (219) +Space cooling fuel 0.0000 (221) +Electricity for pumps and fans: + central heating pump 41.0000 (230c) + main heating flue fan 45.0000 (230e) +Total electricity for the above, kWh/year 86.0000 (231) +Electricity for lighting (calculated in Appendix L) 502.6784 (232) +Energy saving/generation technologies (Appendices M ,N and Q) +PV generation 0.0000 (233) +Wind generation 0.0000 (234) +Hydro-electric generation (Appendix N) 0.0000 (235a) +Electricity generated - Micro CHP (Appendix N) 0.0000 (235) +Appendix Q - special features +Energy saved or generated 0.0000 (236) +Energy used 0.0000 (237) +Total delivered energy for all uses 9495.3302 (238) +---------------------------------------------------------------------------------------------------- +10a. Fuel costs - using BEDF prices (596) +---------------------------------------------------------------------------------------------------- + Fuel Fuel price Fuel cost + kWh/year p/kWh £/year +Space heating - main system 1 5427.1120 7.3200 397.2646 (240) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 506.5305 27.6700 140.1570 (242) +Water heating (other fuel) 2973.0093 7.3200 217.6243 (247) +Energy for instantaneous electric shower(s) 0.0000 27.6700 0.0000 (247a) +Pumps, fans and electric keep-hot 86.0000 27.6700 23.7962 (249) +Energy for lighting 502.6784 27.6700 139.0911 (250) +Additional standing charges 108.0000 (251) +Total energy cost 1025.9332 (255) +---------------------------------------------------------------------------------------------------- +12a. Carbon dioxide emissions - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Emission factor Emissions + kWh/year kg CO2/kWh kg CO2/year +Space heating - main system 1 5427.1120 0.2100 1139.6935 (261) +Total CO2 associated with community systems 0.0000 (373) +Space heating - secondary 506.5305 0.1549 78.4693 (263) +Water heating (other fuel) 2973.0093 0.2100 624.3320 (264) +Space and water heating 1842.4948 (265) +Pumps, fans and electric keep-hot 86.0000 0.1387 11.9293 (267) +Energy for lighting 502.6784 0.1443 72.5520 (268) +Total CO2, kg/year 1926.9760 (272) +---------------------------------------------------------------------------------------------------- +13a. Primary energy - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Primary energy factor Primary energy + kWh/year kg CO2/kWh kWh/year +Space heating - main system 1 5427.1120 1.1300 6132.6365 (275) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 506.5305 1.5736 797.0530 (277) +Water heating (other fuel) 2973.0093 1.1300 3359.5005 (278) +Space and water heating 10289.1901 (279) +Pumps, fans and electric keep-hot 86.0000 1.5128 130.1008 (281) +Energy for lighting 502.6784 1.5338 771.0249 (282) +Total Primary energy kWh/year 11190.3158 (286) +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +SAP 10 WORKSHEET FOR Existing dwelling (SAP) (Version 10.2, February 2022) +CALCULATION OF ENERGY RATING FOR IMPROVED DWELLING +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +1. Overall dwelling characteristics +---------------------------------------------------------------------------------------------------- + Area Storey height Volume +Main dwelling (m2) (m) (m3) + Ground floor 31.1600 (1b) x 2.4000 (2b) = 74.7840 (1b) - (3b) + First floor 31.1600 (1c) x 2.6500 (2c) = 82.5740 (1c) - (3c) +Total floor area TFA = (1a)+(1b)+(1c)+(1d)+(1e)...(1n) 62.3200 (4) + Dwelling volume (3a)+(3b)+(3c)+(3d)+(3e)...(3n) = 157.3580 (5) +---------------------------------------------------------------------------------------------------- +2. Ventilation rate +---------------------------------------------------------------------------------------------------- + m3 per hour + +Number of open chimneys 0 * 80 = 0.0000 (6a) +Number of open flues 0 * 20 = 0.0000 (6b) +Number of chimneys / flues attached to closed fire 0 * 10 = 0.0000 (6c) +Number of flues attached to solid fuel boiler 0 * 20 = 0.0000 (6d) +Number of flues attached to other heater 0 * 35 = 0.0000 (6e) +Number of blocked chimneys 0 * 20 = 0.0000 (6f) +Number of intermittent extract fans 0 * 10 = 0.0000 (7a) +Number of passive vents 0 * 10 = 0.0000 (7b) +Number of flueless gas fires 0 * 40 = 0.0000 (7c) + Air changes per hour +Infiltration due to chimneys, flues and fans = (6a)+(6b)+(6c)+(6d)+(6e)+(6f)+(6g)+(7a)+(7b)+(7c) = 0.0000 / (5) = 0.0000 (8) + Number of storeys in the dwelling (ns) 2 (9) + Additional infiltration [(9) - 1] x 0.1 = 0.1000 (10) + Structural infiltration: 0.25 for steel or timber frame or 0.35 for masonry construction 0.3500 (11) + If suspended wooden floor, enter 0.2 (unsealed) or 0.1 (sealed), else enter 0 0.0000 (12) + If no draught lobby, enter 0.05, else enter 0 0.0500 (13) + Percentage of windows and doors draught stripped 67.0000 (14) + Window infiltration 0.25 - [0.2 * (14) / 100] = 0.1160 (15) +Pressure test No +Infiltration rate 0.6160 (18) +Number of sides sheltered 1 (19) +Shelter factor (20) = 1 - [0.075 x (19)] = 0.9250 (20) +Infiltration rate adjusted to include shelter factor (21) = (18) x (20) = 0.5698 (21) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Wind speed 5.1000 5.0000 4.9000 4.4000 4.3000 3.8000 3.8000 3.7000 4.0000 4.3000 4.5000 4.7000 (22) +Wind factor 1.2750 1.2500 1.2250 1.1000 1.0750 0.9500 0.9500 0.9250 1.0000 1.0750 1.1250 1.1750 (22a) +Adj infilt rate + 0.7265 0.7123 0.6980 0.6268 0.6125 0.5413 0.5413 0.5271 0.5698 0.6125 0.6410 0.6695 (22b) +Effective ac 0.7639 0.7537 0.7436 0.6964 0.6876 0.6465 0.6465 0.6389 0.6623 0.6876 0.7055 0.7241 (25) +---------------------------------------------------------------------------------------------------- +3. Heat losses and heat loss parameter +---------------------------------------------------------------------------------------------------- +Element Gross Openings NetArea U-value A x U K-value A x K +Main dwelling m2 m2 m2 W/m2K W/K kJ/m2K kJ/K + Doors uninsulated 1 3.7000 3.0000 11.1000 (26) + Windows 1 12.9800 2.5180 32.6835 (27) + Ground floor Main 31.1600 0.2500 7.7900 (28a) + External walls Main 80.6500 16.6800 63.9700 0.4800 30.7056 (29a) + External roof Main 31.1600 31.1600 0.3000 9.3480 (30) +Total net area of external elements Aum(A, m2) 142.9700 (31) +Fabric heat loss, W/K = Sum (A x U) (26)...(30) + (32) = 91.6271 (33) +Main dwelling + Party walls Main 34.2900 0.0000 0.0000 (32) +Thermal mass parameter (TMP = Cm / TFA) in kJ/m2K 250.0000 (35) +Thermal bridges (User defined value 0.150 * total exposed area) 21.4455 (36) +Point Thermal bridges (36a) = 0.0000 +Total fabric heat loss (33) + (36) + (36a) = 113.0726 (37) +Ventilation heat loss calculated monthly (38)m = 0.33 x (25)m x (5) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(38)m 39.6678 39.1356 38.6140 36.1641 35.7058 33.5720 33.5720 33.1768 34.3939 35.7058 36.6330 37.6025 (38) +Heat transfer coeff + 152.7403 152.2082 151.6866 149.2367 148.7783 146.6445 146.6445 146.2494 147.4664 148.7783 149.7056 150.6750 (39) +Average = Sum(39)m / 12 = 149.2345 + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +HLP 2.4509 2.4424 2.4340 2.3947 2.3873 2.3531 2.3531 2.3467 2.3663 2.3873 2.4022 2.4178 (40) +HLP (average) 2.3946 +Days in mont 31 28 31 30 31 30 31 31 30 31 30 31 +---------------------------------------------------------------------------------------------------- +4. Water heating energy requirements (kWh/year) +---------------------------------------------------------------------------------------------------- +Assumed occupancy 2.0464 (42) +Hot water usage for mixer showers + 51.2148 50.4451 49.3236 47.1777 45.5941 43.8281 42.8243 43.9374 45.1575 47.0536 49.2456 51.0186 (42a) +Hot water usage for baths + 26.6248 26.2294 25.6726 24.6459 23.8771 23.0246 22.5642 23.1171 23.7192 24.6313 25.6791 26.5348 (42b) +Hot water usage for other uses + 37.4603 36.0981 34.7359 33.3737 32.0116 30.6494 30.6494 32.0116 33.3737 34.7359 36.0981 37.4603 (42c) +Average daily hot water use (litres/day) 105.9586 (43) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Daily hot water use + 115.2999 112.7727 109.7321 105.1973 101.4828 97.5021 96.0379 99.0660 102.2504 106.4209 111.0229 115.0137 (44) +Energy conte 182.6069 160.5868 168.6541 144.0099 136.6153 119.8902 116.1495 122.6644 126.0850 144.4121 158.1725 180.0836 (45) +Energy content (annual) Total = Sum(45)m = 1759.9303 +Distribution loss (46)m = 0.15 x (45)m + 27.3910 24.0880 25.2981 21.6015 20.4923 17.9835 17.4224 18.3997 18.9127 21.6618 23.7259 27.0125 (46) +Water storage loss (or HIU loss): +Total storage loss + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (56) +If cylinder contains dedicated solar storage + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (57) +Primary loss 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (59) +Combi loss 50.9589 46.0274 50.9589 49.3151 50.9589 48.0832 48.9398 50.4830 49.3151 50.9589 49.3151 50.9589 (61) +Total heat required for water heating calculated for each month + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (62) +WWHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63a) +PV diverter 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63b) +Solar input 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63c) +FGHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63d) +Output from w/h + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) + Total per year (kWh/year) = Sum(64)m = 2356.2034 (64) +Electric shower(s) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (64a) + Total Energy used by instantaneous electric shower(s) (kWh/year) = Sum(64a)m = 0.0000 (64a) +Heat gains from water heating, kWh/month + 73.4565 64.9019 68.8172 60.2121 58.1643 51.8843 50.8547 53.4067 54.2520 60.7568 64.9211 72.6175 (65) +---------------------------------------------------------------------------------------------------- +5. Internal gains (see Table 5 and 5a) +---------------------------------------------------------------------------------------------------- +Metabolic gains (Table 5), Watts + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(66)m 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 (66) +Lighting gains (calculated in Appendix L, equation L9 or L9a), also see Table 5 + 21.4748 19.0737 15.5118 11.7434 8.7783 7.4110 8.0079 10.4090 13.9709 17.7393 20.7043 22.0716 (67) +Appliances gains (calculated in Appendix L, equation L13 or L13a), also see Table 5 + 266.8027 269.5713 262.5946 247.7419 228.9932 211.3720 199.5999 196.8313 203.8081 218.6607 237.4095 255.0307 (68) +Cooking gains (calculated in Appendix L, equation L15 or L15a), also see Table 5 + 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 (69) +Pumps, fans 3.0000 3.0000 3.0000 3.0000 3.0000 0.0000 0.0000 0.0000 0.0000 3.0000 3.0000 3.0000 (70) +Losses e.g. evaporation (negative values) (Table 5) + -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 (71) +Water heating gains (Table 5) + 98.7319 96.5803 92.4963 83.6279 78.1778 72.0615 68.3530 71.7832 75.3500 81.6623 90.1682 97.6042 (72) + Total internal gains + 480.2625 478.4784 463.8557 436.3663 409.2025 381.0977 366.2140 369.2766 383.3821 411.3154 441.5351 467.9596 (73) +---------------------------------------------------------------------------------------------------- +6. Solar gains +---------------------------------------------------------------------------------------------------- +[Jan] Area Solar flux g FF Access Gains + m2 Table 6a Specific data Specific data factor W + W/m2 or Table 6b or Table 6c Table 6d +---------------------------------------------------------------------------------------------------- +North 7.2000 10.6334 0.7600 0.7000 0.7700 28.2260 (74) +East 2.8900 19.6403 0.7600 0.7000 0.7700 20.9262 (76) +West 2.8900 19.6403 0.7600 0.7000 0.7700 20.9262 (80) +---------------------------------------------------------------------------------------------------- +Solar gains 70.0784 135.8134 226.4912 343.8726 439.3250 459.0195 433.0958 359.0167 267.0192 161.3582 87.0054 57.9479 (83) +Total gains 550.3409 614.2918 690.3469 780.2390 848.5275 840.1171 799.3098 728.2933 650.4014 572.6737 528.5405 525.9076 (84) +---------------------------------------------------------------------------------------------------- +7. Mean internal temperature (heating season) +---------------------------------------------------------------------------------------------------- +Temperature during heating periods in the living area from Table 9, Th1 (C) 21.0000 (85) +Utilisation factor for gains for living area, ni1,m (see Table 9a) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +tau 28.3342 28.4333 28.5310 28.9994 29.0888 29.5120 29.5120 29.5918 29.3475 29.0888 28.9086 28.7226 +alpha 2.8889 2.8956 2.9021 2.9333 2.9393 2.9675 2.9675 2.9728 2.9565 2.9393 2.9272 2.9148 +util living area + 0.9906 0.9863 0.9760 0.9497 0.8924 0.7878 0.6632 0.7179 0.8842 0.9654 0.9864 0.9919 (86) +MIT 18.2110 18.4316 18.8731 19.5070 20.1207 20.6096 20.8376 20.7883 20.3770 19.6041 18.8156 18.1916 (87) +Th 2 19.0497 19.0547 19.0597 19.0832 19.0876 19.1083 19.1083 19.1122 19.1003 19.0876 19.0787 19.0694 (88) +util rest of house + 0.9871 0.9810 0.9658 0.9258 0.8333 0.6527 0.4342 0.4999 0.7921 0.9440 0.9801 0.9888 (89) +MIT 2 16.6722 16.8940 17.3333 17.9651 18.5373 18.9492 19.0790 19.0662 18.7874 18.0739 17.2925 16.6652 (90) +Living area fraction fLA = Living area / (4) = 0.3001 (91) +MIT 17.1340 17.3553 17.7953 18.4277 19.0124 19.4474 19.6067 19.5829 19.2644 18.5330 17.7495 17.1232 (92) +Temperature adjustment 0.0000 +adjusted MIT 17.1340 17.3553 17.7953 18.4277 19.0124 19.4474 19.6067 19.5829 19.2644 18.5330 17.7495 17.1232 (93) +---------------------------------------------------------------------------------------------------- +8. Space heating requirement +---------------------------------------------------------------------------------------------------- + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Utilisation 0.9815 0.9738 0.9560 0.9143 0.8302 0.6825 0.5049 0.5658 0.8028 0.9348 0.9733 0.9838 (94) +Useful gains 540.1819 598.2008 659.9997 713.3767 704.4687 573.3873 403.5552 412.0764 522.1727 535.3218 514.4052 517.4024 (95) +Ext temp. 4.3000 4.9000 6.5000 8.9000 11.7000 14.6000 16.6000 16.4000 14.1000 10.6000 7.1000 4.2000 (96) +Heat loss rate W + 1960.2641 1895.8060 1713.3509 1421.8886 1087.9269 710.8496 440.9131 465.4991 761.5729 1180.2651 1594.2946 1947.2023 (97) +Space heating kWh + 1056.5411 871.9907 783.6932 510.1286 285.2929 0.0000 0.0000 0.0000 0.0000 479.8378 777.5204 1063.7711 (98a) +Space heating requirement - total per year (kWh/year) 5828.7758 +Solar heating kWh + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (98b) +Solar heating contribution - total per year (kWh/year) 0.0000 +Space heating kWh + 1056.5411 871.9907 783.6932 510.1286 285.2929 0.0000 0.0000 0.0000 0.0000 479.8378 777.5204 1063.7711 (98c) +Space heating requirement after solar contribution - total per year (kWh/year) 5828.7758 +Space heating per m2 (98c) / (4) = 93.5298 (99) +---------------------------------------------------------------------------------------------------- +9a. Energy requirements - Individual heating systems, including micro-CHP +---------------------------------------------------------------------------------------------------- +Fraction of space heat from secondary/supplementary system (Table 11) 0.1000 (201) +Fraction of space heat from main system(s) 0.9000 (202) +Efficiency of main space heating system 1 (in %) 84.0000 (206) +Efficiency of main space heating system 2 (in %) 0.0000 (207) +Efficiency of secondary/supplementary heating system, % 100.0000 (208) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Space heating requirement + 1056.5411 871.9907 783.6932 510.1286 285.2929 0.0000 0.0000 0.0000 0.0000 479.8378 777.5204 1063.7711 (98) +Space heating efficiency (main heating system 1) + 84.0000 84.0000 84.0000 84.0000 84.0000 0.0000 0.0000 0.0000 0.0000 84.0000 84.0000 84.0000 (210) +Space heating fuel (main heating system) + 1132.0083 934.2758 839.6713 546.5663 305.6709 0.0000 0.0000 0.0000 0.0000 514.1119 833.0576 1139.7547 (211) +Space heating efficiency (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (212) +Space heating fuel (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (213) +Space heating fuel (secondary) + 105.6541 87.1991 78.3693 51.0129 28.5293 0.0000 0.0000 0.0000 0.0000 47.9838 77.7520 106.3771 (215) +Water heating +Water heating requirement + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) +Efficiency of water heater 75.0000 (216) +(217)m 82.0582 81.9505 81.6730 81.1157 79.9500 75.0000 75.0000 75.0000 75.0000 80.9734 81.7563 82.0850 (217) +Fuel for water heating, kWh/month + 284.6342 252.1206 268.8932 238.3322 234.6145 223.9646 220.1191 230.8632 233.8667 241.2782 253.7878 281.4673 (219) +Space cooling fuel requirement +(221)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (221) +Pumps and Fa 7.3041 6.5973 7.3041 7.0685 7.3041 7.0685 7.3041 7.3041 7.0685 7.3041 7.0685 7.3041 (231) +Lighting 18.7968 15.0795 13.5774 9.9474 7.6836 6.2776 7.0093 9.1109 11.8342 15.5271 17.5378 19.3192 (232) +Electricity generated by PVs (Appendix M) (negative quantity) +(233a)m -34.1798 -49.1906 -71.4871 -79.7104 -83.3882 -72.3889 -71.4835 -67.4980 -60.4123 -54.9397 -37.6017 -29.4537 (233a) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234a) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235a) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235c)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235c) +Electricity generated by PVs (Appendix M) (negative quantity) +(233b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233b) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234b) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235b) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235d)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235d) +Annual totals kWh/year +Space heating fuel - main system 1 6245.1169 (211) +Space heating fuel - main system 2 0.0000 (213) +Space heating fuel - secondary 582.8776 (215) +Efficiency of water heater 75.0000 +Water heating fuel used 2963.9416 (219) +Space cooling fuel 0.0000 (221) +Electricity for pumps and fans: + central heating pump 41.0000 (230c) + main heating flue fan 45.0000 (230e) +Total electricity for the above, kWh/year 86.0000 (231) +Electricity for lighting (calculated in Appendix L) 151.7006 (232) +Energy saving/generation technologies (Appendices M ,N and Q) +PV generation -711.7338 (233) +Wind generation 0.0000 (234) +Hydro-electric generation (Appendix N) 0.0000 (235a) +Electricity generated - Micro CHP (Appendix N) 0.0000 (235) +Appendix Q - special features + Energy saved or generated 0.0000 (236) +Energy used 0.0000 (237) +Total delivered energy for all uses 9317.9029 (238) +---------------------------------------------------------------------------------------------------- +10a. Fuel costs - using Table 12 prices +---------------------------------------------------------------------------------------------------- + Fuel Fuel price Fuel cost + kWh/year p/kWh £/year +Space heating - main system 1 6245.1169 3.4800 217.3301 (240) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 582.8776 13.1900 76.8816 (242) +Water heating (other fuel) 2963.9416 3.4800 103.1452 (247) +Energy for instantaneous electric shower(s) 0.0000 13.1900 0.0000 (247a) +Pumps, fans and electric keep-hot 86.0000 13.1900 11.3434 (249) +Energy for lighting 151.7006 13.1900 20.0093 (250) +Additional standing charges 120.0000 (251) +Energy saving/generation technologies +PV Unit electricity used in dwelling -711.7338 13.1900 -93.8777 +PV Unit electricity exported 0.0000 13.1900 0.0000 +Total -93.8777 (252) +Total energy cost 454.8318 (255) +---------------------------------------------------------------------------------------------------- +11a. SAP rating - Individual heating systems +---------------------------------------------------------------------------------------------------- +Energy cost deflator (Table 12): 0.4200 (256) +Energy cost factor (ECF) [(255) x (256)] / [(4) + 45.0] = 1.7800 (257) +SAP value 75.1690 +SAP rating (Section 12) 75 (258) +SAP band C +---------------------------------------------------------------------------------------------------- +12a. Carbon dioxide emissions - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Emission factor Emissions + kWh/year kg CO2/kWh kg CO2/year +Space heating - main system 1 6245.1169 0.2100 1311.4746 (261) +Total CO2 associated with community systems 0.0000 (373) +Space heating - secondary 582.8776 0.1541 89.8305 (263) +Water heating (other fuel) 2963.9416 0.2100 622.4277 (264) +Space and water heating 2023.7328 (265) +Pumps, fans and electric keep-hot 86.0000 0.1387 11.9293 (267) +Energy for lighting 151.7006 0.1443 21.8951 (268) +Energy saving/generation technologies +PV Unit electricity used in dwelling -711.7338 0.1353 -96.2872 +PV Unit electricity exported 0.0000 0.0000 0.0000 +Total -96.2872 (269) +Total CO2, kg/year 1961.2700 (272) +CO2 emissions per m2 31.4700 (273) +EI value 75.5115 +EI rating 76 (274) +EI band C +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +SAP 10 WORKSHEET FOR Existing dwelling (SAP) (Version 10.2, February 2022) +CALCULATION OF EPC COSTS, EMISSIONS AND PRIMARY ENERGY FOR IMPROVED DWELLING +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +---------------------------------------------------------------------------------------------------- +1. Overall dwelling characteristics +---------------------------------------------------------------------------------------------------- + Area Storey height Volume +Main dwelling (m2) (m) (m3) + Ground floor 31.1600 (1b) x 2.4000 (2b) = 74.7840 (1b) - (3b) + First floor 31.1600 (1c) x 2.6500 (2c) = 82.5740 (1c) - (3c) +Total floor area TFA = (1a)+(1b)+(1c)+(1d)+(1e)...(1n) 62.3200 (4) +Dwelling volume (3a)+(3b)+(3c)+(3d)+(3e)...(3n) = 157.3580 (5) +---------------------------------------------------------------------------------------------------- +2. Ventilation rate +---------------------------------------------------------------------------------------------------- + m3 per hour + +Number of open chimneys 0 * 80 = 0.0000 (6a) +Number of open flues 0 * 20 = 0.0000 (6b) +Number of chimneys / flues attached to closed fire 0 * 10 = 0.0000 (6c) +Number of flues attached to solid fuel boiler 0 * 20 = 0.0000 (6d) +Number of flues attached to other heater 0 * 35 = 0.0000 (6e) +Number of blocked chimneys 0 * 20 = 0.0000 (6f) +Number of intermittent extract fans 0 * 10 = 0.0000 (7a) +Number of passive vents 0 * 10 = 0.0000 (7b) +Number of flueless gas fires 0 * 40 = 0.0000 (7c) + Air changes per hour +Infiltration due to chimneys, flues and fans = (6a)+(6b)+(6c)+(6d)+(6e)+(6f)+(6g)+(7a)+(7b)+(7c) = 0.0000 / (5) = 0.0000 (8) + Number of storeys in the dwelling (ns) 2 (9) + Additional infiltration [(9) - 1] x 0.1 = 0.1000 (10) + Structural infiltration: 0.25 for steel or timber frame or 0.35 for masonry construction 0.3500 (11) + If suspended wooden floor, enter 0.2 (unsealed) or 0.1 (sealed), else enter 0 0.0000 (12) + If no draught lobby, enter 0.05, else enter 0 0.0500 (13) + Percentage of windows and doors draught stripped 67.0000 (14) + Window infiltration 0.25 - [0.2 * (14) / 100] = 0.1160 (15) +Pressure test No +Infiltration rate 0.6160 (18) +Number of sides sheltered 1 (19) +Shelter factor (20) = 1 - [0.075 x (19)] = 0.9250 (20) +Infiltration rate adjusted to include shelter factor (21) = (18) x (20) = 0.5698 (21) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Wind speed 3.8000 3.7000 3.7000 3.5000 3.5000 3.1000 3.3000 3.0000 3.0000 3.1000 3.1000 3.5000 (22) +Wind factor 0.9500 0.9250 0.9250 0.8750 0.8750 0.7750 0.8250 0.7500 0.7500 0.7750 0.7750 0.8750 (22a) +Adj infilt rate + 0.5413 0.5271 0.5271 0.4986 0.4986 0.4416 0.4701 0.4274 0.4274 0.4416 0.4416 0.4986 (22b) +Effective ac 0.6465 0.6389 0.6389 0.6243 0.6243 0.5975 0.6105 0.5913 0.5913 0.5975 0.5975 0.6243 (25) +---------------------------------------------------------------------------------------------------- +3. Heat losses and heat loss parameter +---------------------------------------------------------------------------------------------------- +Element Gross Openings NetArea U-value A x U K-value A x K +Main dwelling m2 m2 m2 W/m2K W/K kJ/m2K kJ/K + Doors uninsulated 1 3.7000 3.0000 11.1000 (26) + Windows 1 12.9800 2.5180 32.6835 (27) + Ground floor Main 31.1600 0.2500 7.7900 (28a) + External walls Main 80.6500 16.6800 63.9700 0.4800 30.7056 (29a) + External roof Main 31.1600 31.1600 0.3000 9.3480 (30) +Total net area of external elements Aum(A, m2) 142.9700 (31) +Fabric heat loss, W/K = Sum (A x U) (26)...(30) + (32) = 91.6271 (33) +Main dwelling + Party walls Main 34.2900 0.0000 0.0000 (32) +Thermal mass parameter (TMP = Cm / TFA) in kJ/m2K 250.0000 (35) +Thermal bridges (User defined value 0.150 * total exposed area) 21.4455 (36) +Point Thermal bridges (36a) = 0.0000 +Total fabric heat loss (33) + (36) + (36a) = 113.0726 (37) +Ventilation heat loss calculated monthly (38)m = 0.33 x (25)m x (5) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec + (38)m 33.5720 33.1768 33.1768 32.4181 32.4181 31.0272 31.7016 30.7058 30.7058 31.0272 31.0272 32.4181 (38) +Heat transfer coeff + 146.6445 146.2494 146.2494 145.4907 145.4907 144.0998 144.7742 143.7784 143.7784 144.0998 144.0998 145.4907 (39) +Average = Sum(39)m / 12 = 145.0205 + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +HLP 2.3531 2.3467 2.3467 2.3346 2.3346 2.3123 2.3231 2.3071 2.3071 2.3123 2.3123 2.3346 (40) +HLP (average) 2.3270 +Days in mont 31 28 31 30 31 30 31 31 30 31 30 31 +---------------------------------------------------------------------------------------------------- +4. Water heating energy requirements (kWh/year) +---------------------------------------------------------------------------------------------------- +Assumed occupancy 2.0464 (42) +Hot water usage for mixer showers + 51.2148 50.4451 49.3236 47.1777 45.5941 43.8281 42.8243 43.9374 45.1575 47.0536 49.2456 51.0186 (42a) +Hot water usage for baths + 26.6248 26.2294 25.6726 24.6459 23.8771 23.0246 22.5642 23.1171 23.7192 24.6313 25.6791 26.5348 (42b) +Hot water usage for other uses + 37.4603 36.0981 34.7359 33.3737 32.0116 30.6494 30.6494 32.0116 33.3737 34.7359 36.0981 37.4603 (42c) +Average daily hot water use (litres/day) 105.9586 (43) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Daily hot water use + 115.2999 112.7727 109.7321 105.1973 101.4828 97.5021 96.0379 99.0660 102.2504 106.4209 111.0229 115.0137 (44) +Energy conte 182.6069 160.5868 168.6541 144.0099 136.6153 119.8902 116.1495 122.6644 126.0850 144.4121 158.1725 180.0836 (45) +Energy content (annual) Total = Sum(45)m = 1759.9303 +Distribution loss (46)m = 0.15 x (45)m + 27.3910 24.0880 25.2981 21.6015 20.4923 17.9835 17.4224 18.3997 18.9127 21.6618 23.7259 27.0125 (46) +Water storage loss (or HIU loss): +Total storage loss + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (56) +If cylinder contains dedicated solar storage + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (57) +Primary loss 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (59) +Combi loss 50.9589 46.0274 50.9589 49.3151 50.9589 48.0832 48.9398 50.4830 49.3151 50.9589 49.3151 50.9589 (61) +Total heat required for water heating calculated for each month + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (62) +WWHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63a) +PV diverter 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63b) +Solar input 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63c) +FGHRS 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (63d) +Output from w/h + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) + Total per year (kWh/year) = Sum(64)m = 2356.2034 (64) +Electric shower(s) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (64a) + Total Energy used by instantaneous electric shower(s) (kWh/year) = Sum(64a)m = 0.0000 (64a) +Heat gains from water heating, kWh/month + 73.4565 64.9019 68.8172 60.2121 58.1643 51.8843 50.8547 53.4067 54.2520 60.7568 64.9211 72.6175 (65) +---------------------------------------------------------------------------------------------------- +5. Internal gains (see Table 5 and 5a) +---------------------------------------------------------------------------------------------------- +Metabolic gains (Table 5), Watts + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +(66)m 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 122.7847 (66) +Lighting gains (calculated in Appendix L, equation L9 or L9a), also see Table 5 + 21.4748 19.0737 15.5118 11.7434 8.7783 7.4110 8.0079 10.4090 13.9709 17.7393 20.7043 22.0716 (67) +Appliances gains (calculated in Appendix L, equation L13 or L13a), also see Table 5 + 266.8027 269.5713 262.5946 247.7419 228.9932 211.3720 199.5999 196.8313 203.8081 218.6607 237.4095 255.0307 (68) +Cooking gains (calculated in Appendix L, equation L15 or L15a), also see Table 5 + 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 49.3249 (69) +Pumps, fans 3.0000 3.0000 3.0000 3.0000 3.0000 0.0000 0.0000 0.0000 0.0000 3.0000 3.0000 3.0000 (70) +Losses e.g. evaporation (negative values) (Table 5) + -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 -81.8565 (71) +Water heating gains (Table 5) + 98.7319 96.5803 92.4963 83.6279 78.1778 72.0615 68.3530 71.7832 75.3500 81.6623 90.1682 97.6042 (72) +Total internal gains + 480.2625 478.4784 463.8557 436.3663 409.2025 381.0977 366.2140 369.2766 383.3821 411.3154 441.5351 467.9596 (73) +---------------------------------------------------------------------------------------------------- +6. Solar gains +---------------------------------------------------------------------------------------------------- +[Jan] Area Solar flux g FF Access Gains + m2 Table 6a Specific data Specific data factor W + W/m2 or Table 6b or Table 6c Table 6d +---------------------------------------------------------------------------------------------------- +North 7.2000 11.5683 0.7600 0.7000 0.7700 30.7077 (74) +East 2.8900 21.5704 0.7600 0.7000 0.7700 22.9826 (76) +West 2.8900 21.5704 0.7600 0.7000 0.7700 22.9826 (80) +---------------------------------------------------------------------------------------------------- +Solar gains 76.6730 133.8602 224.7811 352.4577 437.5532 487.5086 459.0611 390.9446 291.1241 173.9501 98.4071 64.8811 (83) +Total gains 556.9355 612.3386 688.6368 788.8241 846.7557 868.6063 825.2750 760.2212 674.5063 585.2655 539.9422 532.8408 (84) +---------------------------------------------------------------------------------------------------- +7. Mean internal temperature (heating season) +---------------------------------------------------------------------------------------------------- +Temperature during heating periods in the living area from Table 9, Th1 (C) 21.0000 (85) +Utilisation factor for gains for living area, ni1,m (see Table 9a) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +tau 29.5120 29.5918 29.5918 29.7461 29.7461 30.0332 29.8933 30.1003 30.1003 30.0332 30.0332 29.7461 +alpha 2.9675 2.9728 2.9728 2.9831 2.9831 3.0022 2.9929 3.0067 3.0067 3.0022 3.0022 2.9831 +util living area + 0.9881 0.9831 0.9683 0.9259 0.8265 0.6133 0.4021 0.4603 0.7942 0.9446 0.9810 0.9895 (86) +MIT 18.5901 18.7933 19.2566 19.8925 20.4875 20.8766 20.9779 20.9661 20.6784 19.9847 19.1949 18.5759 (87) +Th 2 19.1083 19.1122 19.1122 19.1196 19.1196 19.1333 19.1266 19.1365 19.1365 19.1333 19.1333 19.1196 (88) +util rest of house + 0.9832 0.9760 0.9536 0.8869 0.7217 0.3874 0.0923 0.1390 0.6247 0.9057 0.9713 0.9851 (89) +MIT 2 17.0860 17.2893 17.7444 18.3557 18.8686 19.1133 19.1266 19.1361 19.0331 18.4675 17.7026 17.0793 (90) +Living area fraction fLA = Living area / (4) = 0.3001 (91) +MIT 17.5373 17.7406 18.1982 18.8168 19.3543 19.6424 19.6821 19.6852 19.5268 18.9228 18.1504 17.5284 (92) +Temperature adjustment 0.0000 +adjusted MIT 17.5373 17.7406 18.1982 18.8168 19.3543 19.6424 19.6821 19.6852 19.5268 18.9228 18.1504 17.5284 (93) +---------------------------------------------------------------------------------------------------- +8. Space heating requirement +---------------------------------------------------------------------------------------------------- + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Utilisation 0.9770 0.9682 0.9433 0.8784 0.7380 0.4574 0.1888 0.2404 0.6697 0.8994 0.9634 0.9794 (94) +Useful gains 544.1060 592.8372 649.5622 692.8756 624.9256 397.2799 155.7782 182.7905 451.6915 526.4023 520.2010 521.8383 (95) +Ext temp. 5.6000 6.2000 8.0000 10.6000 13.7000 16.7000 18.6000 18.4000 15.7000 12.2000 8.5000 5.6000 (96) +Heat loss rate W + 1750.5467 1687.8026 1491.4798 1195.4735 822.6545 423.9972 156.6578 184.7872 550.2136 968.7502 1390.6200 1735.4681 (97) +Space heating kWh + 897.5919 735.8167 626.3867 361.8705 147.1103 0.0000 0.0000 0.0000 0.0000 329.1069 626.7017 902.9406 (98a) +Space heating requirement - total per year (kWh/year) 4627.5252 +Solar heating kWh + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (98b) +Solar heating contribution - total per year (kWh/year) 0.0000 +Space heating kWh + 897.5919 735.8167 626.3867 361.8705 147.1103 0.0000 0.0000 0.0000 0.0000 329.1069 626.7017 902.9406 (98c) +Space heating requirement after solar contribution - total per year (kWh/year) 4627.5252 +Space heating per m2 (98c) / (4) = 74.2543 (99) +---------------------------------------------------------------------------------------------------- +9a. Energy requirements - Individual heating systems, including micro-CHP + ---------------------------------------------------------------------------------------------------- +Fraction of space heat from secondary/supplementary system (Table 11) 0.1000 (201) +Fraction of space heat from main system(s) 0.9000 (202) +Efficiency of main space heating system 1 (in %) 84.0000 (206) +Efficiency of main space heating system 2 (in %) 0.0000 (207) +Efficiency of secondary/supplementary heating system, % 100.0000 (208) + Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec +Space heating requirement + 897.5919 735.8167 626.3867 361.8705 147.1103 0.0000 0.0000 0.0000 0.0000 329.1069 626.7017 902.9406 (98) +Space heating efficiency (main heating system 1) + 84.0000 84.0000 84.0000 84.0000 84.0000 0.0000 0.0000 0.0000 0.0000 84.0000 84.0000 84.0000 (210) +Space heating fuel (main heating system) + 961.7056 788.3750 671.1287 387.7184 157.6182 0.0000 0.0000 0.0000 0.0000 352.6145 671.4661 967.4363 (211) +Space heating efficiency (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (212) +Space heating fuel (main heating system 2) + 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (213) +Space heating fuel (secondary) + 89.7592 73.5817 62.6387 36.1870 14.7110 0.0000 0.0000 0.0000 0.0000 32.9107 62.6702 90.2941 (215) +Water heating +Water heating requirement + 233.5658 206.6142 219.6130 193.3250 187.5742 167.9734 165.0893 173.1474 175.4000 195.3711 207.4875 231.0425 (64) +Efficiency of water heater 75.0000 (216) +(217)m 81.7985 81.6695 81.2661 80.4060 78.4793 75.0000 75.0000 75.0000 75.0000 80.1761 81.3739 81.8263 (217) +Fuel for water heating, kWh/month + 285.5380 252.9883 270.2395 240.4361 239.0111 223.9646 220.1191 230.8632 233.8667 243.6773 254.9804 282.3572 (219) +Space cooling fuel requirement +(221)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (221) +Pumps and Fa 7.3041 6.5973 7.3041 7.0685 7.3041 7.0685 7.3041 7.3041 7.0685 7.3041 7.0685 7.3041 (231) +Lighting 18.7968 15.0795 13.5774 9.9474 7.6836 6.2776 7.0093 9.1109 11.8342 15.5271 17.5378 19.3192 (232) +Electricity generated by PVs (Appendix M) (negative quantity) +(233a)m -36.0565 -47.5984 -69.1347 -78.0275 -80.0163 -73.7910 -72.7946 -69.6016 -62.6000 -55.9069 -40.3706 -31.7267 (233a) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234a) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235a)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235a) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235c)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235c) +Electricity generated by PVs (Appendix M) (negative quantity) +(233b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (233b) +Electricity generated by wind turbines (Appendix M) (negative quantity) +(234b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (234b) +Electricity generated by hydro-electric generators (Appendix M) (negative quantity) +(235b)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235b) +Electricity used or net electricity generated by micro-CHP (Appendix N) (negative if net generation) +(235d)m 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 0.0000 (235d) +Annual totals kWh/year +Space heating fuel - main system 1 4958.0627 (211) +Space heating fuel - main system 2 0.0000 (213) +Space heating fuel - secondary 462.7525 (215) +Efficiency of water heater 75.0000 +Water heating fuel used 2978.0416 (219) +Space cooling fuel 0.0000 (221) +Electricity for pumps and fans: + central heating pump 41.0000 (230c) + main heating flue fan 45.0000 (230e) +Total electricity for the above, kWh/year 86.0000 (231) +Electricity for lighting (calculated in Appendix L) 151.7006 (232) +Energy saving/generation technologies (Appendices M ,N and Q) +PV generation -717.6247 (233) +Wind generation 0.0000 (234) +Hydro-electric generation (Appendix N) 0.0000 (235a) +Electricity generated - Micro CHP (Appendix N) 0.0000 (235) +Appendix Q - special features +Energy saved or generated 0.0000 (236) +Energy used 0.0000 (237) +Total delivered energy for all uses 7918.9327 (238) +---------------------------------------------------------------------------------------------------- +10a. Fuel costs - using BEDF prices (596) +---------------------------------------------------------------------------------------------------- + Fuel Fuel price Fuel cost + kWh/year p/kWh £/year +Space heating - main system 1 4958.0627 7.3200 362.9302 (240) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 462.7525 27.6700 128.0436 (242) +Water heating (other fuel) 2978.0416 7.3200 217.9926 (247) +Energy for instantaneous electric shower(s) 0.0000 27.6700 0.0000 (247a) +Pumps, fans and electric keep-hot 86.0000 27.6700 23.7962 (249) +Energy for lighting 151.7006 27.6700 41.9755 (250) +Additional standing charges 108.0000 (251) +Energy saving/generation technologies +PV Unit electricity used in dwelling -717.6247 27.6700 -198.5668 +PV Unit electricity exported 0.0000 5.8100 0.0000 +Total -198.5668 (252) +Total energy cost 684.1714 (255) +---------------------------------------------------------------------------------------------------- +12a. Carbon dioxide emissions - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Emission factor Emissions + kWh/year kg CO2/kWh kg CO2/year +Space heating - main system 1 4958.0627 0.2100 1041.1932 (261) +Total CO2 associated with community systems 0.0000 (373) +Space heating - secondary 462.7525 0.1551 71.7611 (263) +Water heating (other fuel) 2978.0416 0.2100 625.3887 (264) +Space and water heating 1738.3430 (265) +Pumps, fans and electric keep-hot 86.0000 0.1387 11.9293 (267) +Energy for lighting 151.7006 0.1443 21.8951 (268) +Energy saving/generation technologies +PV Unit electricity used in dwelling -717.6247 0.1352 -97.0291 +PV Unit electricity exported 0.0000 0.0000 0.0000 +Total -97.0291 (269) +Total CO2, kg/year 1675.1383 (272) +---------------------------------------------------------------------------------------------------- +13a. Primary energy - Individual heating systems including micro-CHP +---------------------------------------------------------------------------------------------------- + Energy Primary energy factor Primary energy + kWh/year kg CO2/kWh kWh/year +Space heating - main system 1 4958.0627 1.1300 5602.6109 (275) +Total CO2 associated with community systems 0.0000 (473) +Space heating - secondary 462.7525 1.5741 728.4382 (277) +Water heating (other fuel) 2978.0416 1.1300 3365.1870 (278) +Space and water heating 9696.2361 (279) +Pumps, fans and electric keep-hot 86.0000 1.5128 130.1008 (281) +Energy for lighting 151.7006 1.5338 232.6834 (282) +Energy saving/generation technologies +PV Unit electricity used in dwelling -717.6247 1.4997 -1076.2548 +PV Unit electricity exported 0.0000 0.0000 0.0000 +Total -1076.2548 (283) +Total Primary energy kWh/year 8982.7654 (286) + \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_summary.pdf new file mode 100644 index 000000000..bf5e1e382 Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_summary.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_worksheet.pdf new file mode 100644 index 000000000..c99553292 Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/elmhurst_worksheet.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/epc.json new file mode 100644 index 000000000..5ac1c41ad --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_217091901/epc.json @@ -0,0 +1,384 @@ +{ + "uprn": 217091901, + "roofs": [ + { + "description": "Flat, no insulation", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "walls": [ + { + "description": "Solid brick, as built, no insulation (assumed)", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "floors": [ + { + "description": "(another dwelling below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Single glazed", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + }, + "lighting": { + "description": "Good lighting efficiency", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "W11 1EP", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "LONDON", + "built_form": "NR", + "created_at": "2026-05-16 15:45:17", + "door_count": 0, + "region_code": 17, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "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": 2107, + "main_heating_category": 2, + "main_heating_fraction": 1, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 18658 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 5, + "window_width": 1.2, + "window_height": 1.8, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 5, + "window_width": 1.2, + "window_height": 1.8, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 9, + "window_type": 2, + "glazing_type": 5, + "window_width": 0.5, + "window_height": 0.5, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 9, + "window_type": 2, + "glazing_type": 5, + "window_width": 0.7, + "window_height": 0.5, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 1.2, + "window_height": 1.8, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 1, + "window_type": 1, + "glazing_type": 5, + "window_width": 1.1, + "window_height": 1.4, + "draught_proofed": "false", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.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": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Top-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "Second Floor Flat", + "address_line_2": "216 Westbourne Park Road", + "assessment_type": "RdSAP", + "completion_date": "2026-05-16", + "inspection_date": "2026-05-16", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 3, + "top_storey": "Y", + "storey_count": 3, + "flat_location": 2, + "heat_loss_corridor": 0 + }, + "total_floor_area": 63, + "transaction_type": 8, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 3, + "registration_date": "2026-05-16", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 280, + "floor_heat_loss": 6, + "roof_construction": 1, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.85, + "quantity": "metres" + }, + "total_floor_area": { + "value": 63.29, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 22.8, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 14, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "A", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 6, + "wall_insulation_thickness": "NI", + "flat_roof_insulation_thickness": "AB" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 967, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 2.8, + "energy_rating_average": 60, + "energy_rating_current": 62, + "lighting_cost_current": { + "value": 43, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, TRVs and bypass", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "blocked_chimneys_count": 1, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 330, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 167, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 411, + "currency": "GBP" + }, + "indicative_cost": "\u00a3900 - \u00a31,200", + "improvement_type": "A2", + "improvement_details": { + "improvement_number": 45 + }, + "improvement_category": 5, + "energy_performance_rating": 74, + "environmental_impact_rating": 76 + }, + { + "sequence": 2, + "typical_saving": { + "value": 129, + "currency": "GBP" + }, + "indicative_cost": "\u00a37,500 - \u00a311,000", + "improvement_type": "Q", + "improvement_details": { + "improvement_number": 7 + }, + "improvement_category": 5, + "energy_performance_rating": 78, + "environmental_impact_rating": 81 + }, + { + "sequence": 3, + "typical_saving": { + "value": 18, + "currency": "GBP" + }, + "indicative_cost": "\u00a3150 - \u00a3250", + "improvement_type": "D", + "improvement_details": { + "improvement_number": 10 + }, + "improvement_category": 5, + "energy_performance_rating": 79, + "environmental_impact_rating": 82 + }, + { + "sequence": 4, + "typical_saving": { + "value": 78, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,500 - \u00a36,000", + "improvement_type": "O", + "improvement_details": { + "improvement_number": 8 + }, + "improvement_category": 5, + "energy_performance_rating": 81, + "environmental_impact_rating": 85 + } + ], + "co2_emissions_potential": 1.0, + "energy_rating_potential": 81, + "lighting_cost_potential": { + "value": 45, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 167, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2022.69, + "space_heating_existing_dwelling": 9246.82 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 245, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 0, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 90, + "environmental_impact_current": 59, + "cfl_fixed_lighting_bulbs_count": 2, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 85, + "led_fixed_lighting_bulbs_count": 9, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "B", + "co2_emissions_current_per_floor_area": 45, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_4510053280/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_4510053280/epc.json new file mode 100644 index 000000000..5e14204ab --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_4510053280/epc.json @@ -0,0 +1,299 @@ +{ + "uprn": 4510053280, + "roofs": [ + { + "description": "(another dwelling above)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "walls": [ + { + "description": "Solid brick, as built, no insulation (assumed)", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + { + "description": "Solid brick, as built, partial insulation (assumed)", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "floors": [ + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 2, + "window": { + "description": "Full secondary glazing", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "lighting": { + "description": "Good lighting efficiency", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "NE1 4DG", + "hot_water": { + "description": "From main system, no cylinder thermostat", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 4 + }, + "post_town": "NEWCASTLE UPON TYNE", + "built_form": "NR", + "created_at": "2026-05-24 12:41:32", + "door_count": 0, + "region_code": 1, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 29, + "secondary_fuel_type": 29, + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 29, + "heat_emitter_type": 1, + "emitter_temperature": 0, + "main_heating_number": 1, + "main_heating_control": 2203, + "main_heating_category": 4, + "main_heating_fraction": 1, + "mcs_installed_heat_pump": "false", + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 100053 + } + ], + "immersion_heating_type": "NA", + "secondary_heating_type": 691, + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "orientation": 4, + "window_type": 1, + "glazing_type": 4, + "window_width": 1.3, + "window_height": 1.46, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "orientation": 4, + "window_type": 1, + "glazing_type": 4, + "window_width": 1.3, + "window_height": 1.46, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Energy Assessor", + "country_code": "ENG", + "main_heating": [ + { + "description": "Air source heat pump, radiators, electric", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 5 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Ground-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "64 Waterloo Street", + "assessment_type": "RdSAP", + "completion_date": "2026-05-24", + "inspection_date": "2026-05-22", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 1, + "top_storey": "N", + "storey_count": 3, + "flat_location": 0, + "heat_loss_corridor": 2, + "unheated_corridor_length": 3.5 + }, + "total_floor_area": 47, + "transaction_type": 8, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 2, + "registration_date": "2026-05-24", + "sap_energy_source": { + "mains_gas": "N", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 1, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "Room heaters, electric", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "lzc_energy_sources": [ + 9 + ], + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 520, + "floor_heat_loss": 7, + "roof_construction": 3, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.32, + "quantity": "metres" + }, + "floor_insulation": 1, + "total_floor_area": { + "value": 47, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 8, + "quantity": "metres" + }, + "floor_construction": 1, + "heat_loss_perimeter": { + "value": 14.15, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 4, + "construction_age_band": "B", + "sap_alternative_wall_1": { + "wall_area": 8.12, + "sheltered_wall": "Y", + "wall_dry_lined": "N", + "wall_thickness": 520, + "wall_construction": 3, + "wall_insulation_type": 4, + "wall_thickness_measured": "Y", + "wall_insulation_thickness": "NI" + }, + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": "ND", + "roof_insulation_thickness": "ND", + "wall_insulation_thickness": "NI", + "floor_insulation_thickness": "NI" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 2, + "heating_cost_current": { + "value": 278, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 0.8, + "energy_rating_average": 60, + "energy_rating_current": 51, + "lighting_cost_current": { + "value": 39, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Room thermostat only", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 272, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 1295, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 68, + "currency": "GBP" + }, + "indicative_cost": "\u00a3220 - \u00a3250", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 16 + }, + "improvement_category": 5, + "energy_performance_rating": 53, + "environmental_impact_rating": 88 + } + ], + "co2_emissions_potential": 0.8, + "energy_rating_potential": 53, + "lighting_cost_potential": { + "value": 39, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 1233, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 5072.68, + "space_heating_existing_dwelling": 2884.0 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 190, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 182, + "environmental_impact_current": 88, + "current_energy_efficiency_band": "E", + "environmental_impact_potential": 88, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "E", + "co2_emissions_current_per_floor_area": 18, + "low_energy_fixed_lighting_bulbs_count": 6, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/elmhurst_summary.pdf new file mode 100644 index 000000000..80c83175c Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/elmhurst_summary.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/elmhurst_worksheet.pdf new file mode 100644 index 000000000..5e94b7ac8 Binary files /dev/null and b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/elmhurst_worksheet.pdf differ diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/epc.json new file mode 100644 index 000000000..f268aac88 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_47084930/epc.json @@ -0,0 +1,324 @@ +{ + "uprn": 47084930, + "roofs": [ + { + "description": "Flat, insulated", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "description": "Cavity wall, with internal insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "(other premises below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 3, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "NE12 8AQ", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "NEWCASTLE UPON TYNE", + "built_form": "NR", + "created_at": "2026-05-06 10:59:38", + "door_count": 0, + "region_code": 1, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 901, + "water_heating_fuel": 26, + "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, + "central_heating_pump_age": 0, + "main_heating_data_source": 1, + "main_heating_index_number": 17815 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.23, + "window_height": 1.61, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.23, + "window_height": 1.61, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.23, + "window_height": 1.61, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.23, + "window_height": 1.61, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 3, + "window_type": 1, + "glazing_type": 2, + "window_width": 1.23, + "window_height": 1.61, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.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": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Top-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "83 Station Road", + "address_line_2": "Forest Hall", + "assessment_type": "RdSAP", + "completion_date": "2026-05-06", + "inspection_date": "2026-05-05", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 3, + "top_storey": "Y", + "storey_count": 2, + "flat_location": 1, + "heat_loss_corridor": 1 + }, + "total_floor_area": 64, + "transaction_type": 8, + "conservatory_type": 1, + "has_draught_lobby": "true", + "heated_room_count": 3, + "registration_date": "2026-05-06", + "sap_energy_source": { + "mains_gas": "Y", + "meter_type": 2, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "true", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "true" + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 380, + "floor_heat_loss": 3, + "roof_construction": 1, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": { + "value": 2.32, + "quantity": "metres" + }, + "total_floor_area": { + "value": 64.26, + "quantity": "square metres" + }, + "party_wall_length": { + "value": 18.15, + "quantity": "metres" + }, + "heat_loss_perimeter": { + "value": 18.15, + "quantity": "metres" + } + } + ], + "wall_insulation_type": 3, + "construction_age_band": "E", + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": 6, + "wall_insulation_thickness": "100mm", + "flat_roof_insulation_thickness": "75mm" + } + ], + "solar_water_heating": "N", + "habitable_room_count": 3, + "heating_cost_current": { + "value": 623, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 2.0, + "energy_rating_average": 60, + "energy_rating_current": 74, + "lighting_cost_current": { + "value": 42, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 553, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 207, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 69, + "currency": "GBP" + }, + "indicative_cost": "\u00a3900 - \u00a31,200", + "improvement_type": "A2", + "improvement_details": { + "improvement_number": 45 + }, + "improvement_category": 5, + "energy_performance_rating": 76, + "environmental_impact_rating": 78 + } + ], + "co2_emissions_potential": 1.8, + "energy_rating_potential": 76, + "lighting_cost_potential": { + "value": 42, + "currency": "GBP" + }, + "schema_version_original": "21.0.1", + "hot_water_cost_potential": { + "value": 208, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2384.75, + "space_heating_existing_dwelling": 5681.26 + }, + "draughtproofed_door_count": 0, + "energy_consumption_current": 170, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "5.02r0344", + "energy_consumption_potential": 154, + "environmental_impact_current": 76, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 78, + "led_fixed_lighting_bulbs_count": 9, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 31, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_74061136/epc.json b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_74061136/epc.json new file mode 100644 index 000000000..86bc6b0c2 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/RdSAP-Schema-21.0.1/uprn_74061136/epc.json @@ -0,0 +1,315 @@ +{ + "uprn": 74061136, + "roofs": [ + { + "description": "(another dwelling above)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "walls": [ + { + "description": "Solid brick, with internal insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + { + "description": "Timber frame, with additional insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "(other premises below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "tenure": 1, + "window": { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "lighting": { + "description": "Excellent lighting efficiency", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "S41 7TP", + "hot_water": { + "description": "Electric instantaneous at point of use", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 5 + }, + "post_town": "Chesterfield,", + "psv_count": 0, + "built_form": 4, + "created_at": "2026-05-20 13:45:13", + "door_count": 1, + "region_code": 6, + "report_type": 2, + "sap_heating": { + "number_baths": 1, + "cylinder_size": 1, + "shower_outlets": [ + { + "shower_wwhrs": 1, + "shower_outlet_type": 1 + } + ], + "number_baths_wwhrs": 0, + "water_heating_code": 909, + "water_heating_fuel": 29, + "cylinder_thermostat": "N", + "main_heating_details": [ + { + "has_fghrs": "N", + "main_fuel_type": 29, + "storage_heaters": [ + { + "index_number": 230002, + "number_of_heaters": 1, + "high_heat_retention": "true" + } + ], + "fan_flue_present": "Y", + "heat_emitter_type": 0, + "emitter_temperature": "NA", + "main_heating_number": 1, + "main_heating_control": 2404, + "main_heating_category": 7, + "main_heating_fraction": 50, + "sap_main_heating_code": 409, + "main_heating_data_source": 2 + } + ], + "immersion_heating_type": "NA", + "has_fixed_air_conditioning": "false" + }, + "sap_version": 10.2, + "sap_windows": [ + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.6, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + }, + { + "pvc_frame": "true", + "orientation": 5, + "window_type": 1, + "glazing_type": 2, + "window_width": { + "value": 1, + "quantity": "m" + }, + "window_height": { + "value": 1.6, + "quantity": "m" + }, + "draught_proofed": "true", + "window_location": 0, + "window_wall_type": 1, + "permanent_shutters_present": "N", + "permanent_shutters_insulated": "N" + } + ], + "schema_type": "RdSAP-Schema-21.0.1", + "uprn_source": "Address Matched", + "country_code": "ENG", + "main_heating": [ + { + "description": "Electric storage heaters", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 5 + } + ], + "air_tightness": { + "description": "(not tested)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "dwelling_type": "Mid-floor flat", + "language_code": 1, + "pressure_test": 4, + "property_type": 2, + "address_line_1": "Flat 3,", + "address_line_2": "14-20 Corporation Street,", + "assessment_type": "RdSAP", + "completion_date": "2026-05-20", + "inspection_date": "2026-05-20", + "extensions_count": 0, + "measurement_type": 1, + "open_flues_count": 0, + "sap_flat_details": { + "level": 2, + "top_storey": "N", + "storey_count": 3, + "flat_location": 1, + "heat_loss_corridor": 2, + "unheated_corridor_length": 6 + }, + "total_floor_area": 24, + "transaction_type": 1, + "conservatory_type": 2, + "heated_room_count": 1, + "other_flues_count": 0, + "registration_date": "2026-05-20", + "sap_energy_source": { + "mains_gas": "N", + "meter_type": 3, + "pv_connection": 0, + "photovoltaic_supply": { + "none_or_no_details": { + "percent_roof_area": 0 + } + }, + "wind_turbines_count": 0, + "gas_smart_meter_present": "false", + "is_dwelling_export_capable": "false", + "wind_turbines_terrain_type": 2, + "electricity_smart_meter_present": "false" + }, + "secondary_heating": { + "description": "Portable electric heaters (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "closed_flues_count": 0, + "extract_fans_count": 0, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "wall_dry_lined": "N", + "wall_thickness": 300, + "floor_heat_loss": 3, + "roof_construction": 3, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.4, + "total_floor_area": 24, + "party_wall_length": 8, + "heat_loss_perimeter": 12 + } + ], + "wall_insulation_type": 3, + "construction_age_band": "B", + "sap_alternative_wall_1": { + "wall_area": 14.4, + "sheltered_wall": "Y", + "wall_dry_lined": "N", + "wall_thickness": 150, + "wall_construction": 5, + "wall_insulation_type": 3, + "wall_thickness_measured": "Y", + "wall_insulation_thickness": "NI" + }, + "party_wall_construction": 0, + "wall_thickness_measured": "Y", + "roof_insulation_location": "ND", + "roof_insulation_thickness": "ND", + "wall_insulation_thickness": "measured", + "wall_insulation_thickness_measured": 25, + "wall_insulation_thermal_conductivity": 3 + } + ], + "boilers_flues_count": 0, + "open_chimneys_count": 0, + "solar_water_heating": "N", + "habitable_room_count": 1, + "heating_cost_current": { + "value": 348, + "currency": "GBP" + }, + "insulated_door_count": 0, + "co2_emissions_current": 0.4, + "energy_rating_average": 60, + "energy_rating_current": 73, + "lighting_cost_current": { + "value": 23, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Controls for high heat retention storage heaters", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "blocked_chimneys_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 348, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 344, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "percent_draughtproofed": 100, + "schema_version_current": "LIG-21.0", + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 66, + "indicative_cost": "\u00a3600 - \u00a31,500", + "improvement_type": "Y", + "improvement_details": { + "improvement_number": 49 + }, + "improvement_category": 5, + "energy_performance_rating": 76, + "environmental_impact_rating": 92 + } + ], + "co2_emissions_potential": 0.4, + "energy_rating_potential": 76, + "lighting_cost_potential": { + "value": 23, + "currency": "GBP" + }, + "schema_version_original": "LIG-21.0", + "hot_water_cost_potential": { + "value": 278, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 1079.39, + "space_heating_existing_dwelling": 2013.05 + }, + "draughtproofed_door_count": 1, + "energy_consumption_current": 200, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "10.2.2.0", + "energy_consumption_potential": 187, + "environmental_impact_current": 91, + "cfl_fixed_lighting_bulbs_count": 0, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 92, + "led_fixed_lighting_bulbs_count": 6, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 19, + "incandescent_fixed_lighting_bulbs_count": 0 +} \ No newline at end of file diff --git a/domain/sap10_calculator/rdsap/cert_to_inputs.py b/domain/sap10_calculator/rdsap/cert_to_inputs.py index 22d379c32..5d87f80cd 100644 --- a/domain/sap10_calculator/rdsap/cert_to_inputs.py +++ b/domain/sap10_calculator/rdsap/cert_to_inputs.py @@ -2888,6 +2888,15 @@ def _hot_water_fuel_cost_gbp_per_kwh( ) blended = high_frac * high_rate + (1.0 - high_frac) * low_rate return blended * _PENCE_TO_GBP + if water_heating_code in _INSTANTANEOUS_WATER_CODES: + # SAP 10.2 §12 (PDF line 2680): the Table-13 off-peak on-peak HW + # split is keyed on the CYLINDER size — it presumes stored water + # charged overnight. An instantaneous point-of-use heater (WHC + # 907/909, no cylinder) heats on demand and cannot shift to the + # off-peak window, so 100% bills at the HIGH rate (Table 12a WH + # high-rate fraction 1.0), not the off-peak low rate. + high_rate, _low = _tariff_high_low_rates_p_per_kwh(tariff) + return high_rate * _PENCE_TO_GBP return _off_peak_low_rate_gbp_per_kwh(tariff) if water_heating_fuel is not None: return prices.unit_price_p_per_kwh(water_heating_fuel) * _PENCE_TO_GBP @@ -2942,6 +2951,11 @@ def _hot_water_high_rate_fraction( single_immersion=effective_single, tariff=tariff, ) + if water_heating_code in _INSTANTANEOUS_WATER_CODES: + # Instantaneous point-of-use electric DHW (WHC 907/909) has no + # cylinder to charge overnight — it heats on demand, wholly at the + # high/day rate (see `_hot_water_fuel_cost_gbp_per_kwh`). + return 1.0 return 0.0 @@ -5307,6 +5321,35 @@ _AGE_BANDS_A_TO_E: Final[frozenset[str]] = frozenset({"A", "B", "C", "D", "E"}) _SUSPENDED_TIMBER_FLOOR_TYPE: Final[str] = "Suspended timber" _GROUND_FLOOR_TYPE: Final[str] = "Ground floor" _FLOOR_U_SEALED_THRESHOLD: Final[float] = 0.5 +# Table 19 footnote (1): age bands whose default floor_construction is +# suspended timber when the construction is unknown. Mirrors +# `_SUSPENDED_TIMBER_DEFAULT_BANDS` in rdsap_uvalues.py — duplicated +# locally rather than cross-imported (private symbol) per this module's +# existing convention (see `_main_floor_u_value`). +_TABLE_19_FOOTNOTE_1_SUSPENDED_TIMBER_BANDS: Final[frozenset[str]] = frozenset({"A", "B"}) + + +def _effective_floor_description( + epc: EpcPropertyData, main: SapBuildingPart, +) -> Optional[str]: + """Mirror `heat_transmission_section_from_cert`'s + `effective_floor_description` rule: the per-bp `floor_construction_type` + lodgement ("Suspended timber" / "Solid") takes precedence over the + global `epc.floors[].description` since it's the explicit per-part + Elmhurst Summary §3/§9 lodgement. Falls back to the joined global + description when the per-bp field is unlodged (the gov-API mapper + often leaves it `None`). Inlined (vs importing from + heat_transmission) to keep cert_to_inputs free of cross-module + private symbol imports. + """ + if main.floor_construction_type: + return main.floor_construction_type + descs = [ + d for d in + (getattr(f, "description", None) for f in (epc.floors or [])) + if d + ] + return " | ".join(descs) if descs else None def _main_floor_u_value(epc: EpcPropertyData) -> Optional[float]: @@ -5343,21 +5386,6 @@ def _main_floor_u_value(epc: EpcPropertyData) -> Optional[float]: int(raw_floor_ins) if isinstance(raw_floor_ins, (int, float)) else (0 if raw_floor_ins == "NI" else None) ) - # Mirror heat_transmission's `effective_floor_description`: the per-bp - # `floor_construction_type` takes precedence over a joined - # `epc.floors[].description` since the per-part lodgement is the - # explicit Elmhurst Summary §3/§9 surface. Inline the join (vs - # importing from heat_transmission) to keep cert_to_inputs free of - # cross-module private symbol imports. - if main.floor_construction_type: - effective_floor_description = main.floor_construction_type - else: - descs = [ - d for d in - (getattr(f, "description", None) for f in (epc.floors or [])) - if d - ] - effective_floor_description = " | ".join(descs) if descs else None return u_floor( country=Country.from_code(epc.country_code) if epc.country_code else None, age_band=main.construction_age_band, @@ -5366,10 +5394,49 @@ def _main_floor_u_value(epc: EpcPropertyData) -> Optional[float]: area_m2=ground_fd.total_floor_area_m2, perimeter_m=ground_fd.heat_loss_perimeter_m, wall_thickness_mm=main.wall_thickness_mm, - description=effective_floor_description, + description=_effective_floor_description(epc, main), ) +def _floor_construction_is_suspended_timber( + epc: EpcPropertyData, main: SapBuildingPart, +) -> bool: + """RdSAP 10 Table 19 footnote (1) construction resolution for the §5 + (12) floor-infiltration rule. Tri-state, mirroring `u_floor`'s + `_floor_is_suspended_from_description` / `_SUSPENDED_TIMBER_DEFAULT_ + BANDS` cascade (rdsap_uvalues.py) so the (12) infiltration rule and + the floor U-value calc agree on which floors are suspended timber: + + 1. An explicit construction lodgement (`_effective_floor_description` + — per-bp `floor_construction_type` else the joined + `epc.floors[].description`) decides: "Suspended, ..." is timber + UNLESS it's "Suspended, not timber" (suspended concrete etc. has + no floorboard-gap infiltration); "Solid, ..." is not suspended. + 2. No description signal AND no lodged `floor_construction` code at + all → Table 19 footnote (1): unknown construction defaults to + suspended timber only for age bands A/B. + """ + desc = _effective_floor_description(epc, main) + if desc is not None: + d = desc.strip().lower() + if d.startswith("suspended"): + return "not timber" not in d + if d.startswith("solid"): + return False + ground_fd = next( + (fd for fd in main.sap_floor_dimensions if fd.floor == 0), + main.sap_floor_dimensions[0] if main.sap_floor_dimensions else None, + ) + construction_known = ( + ground_fd is not None + and _int_or_none(ground_fd.floor_construction) is not None + ) + if construction_known: + return False + age = (main.construction_age_band or "").strip().upper() + return age in _TABLE_19_FOOTNOTE_1_SUSPENDED_TIMBER_BANDS + + def _has_suspended_timber_floor_per_spec( epc: EpcPropertyData, ) -> tuple[bool, bool]: @@ -5395,9 +5462,13 @@ def _has_suspended_timber_floor_per_spec( infiltration 0.2. The rule only applies when the Main bp's lowest floor is a - "Ground floor" with "Suspended timber" construction. All other - combinations fall through to `(False, False)` and the cascade - enters 0 for (12). + "Ground floor" with "Suspended timber" construction. Construction is + resolved the same tri-state way `u_floor` resolves it (RdSAP 10 + Table 19 footnote 1): the explicit per-bp `floor_construction_type` / + joined `epc.floors[].description` lodgement, else — when neither + lodges a construction signal — the footnote-1 age-band default + (suspended timber for bands A/B only). All other combinations fall + through to `(False, False)` and the cascade enters 0 for (12). """ if not epc.sap_building_parts: return False, False @@ -5407,7 +5478,7 @@ def _has_suspended_timber_floor_per_spec( return True, False if main.floor_type != _GROUND_FLOOR_TYPE: return False, False - if main.floor_construction_type != _SUSPENDED_TIMBER_FLOOR_TYPE: + if not _floor_construction_is_suspended_timber(epc, main): return False, False age = (main.construction_age_band or "").strip().upper() if age in _AGE_BANDS_F_TO_M: @@ -7090,6 +7161,18 @@ def _cylinder_storage_loss_override( # 550 kWh/yr). The Table-2b temperature factor still applies (49)→(50). declared_loss = _float_or_none(getattr(sh, "cylinder_heat_loss", None)) volume_l = _cylinder_volume_l_from_code(epc) + if volume_l is None and _int_or_none(sh.cylinder_size) == 0: + # gov-API cylinder_size=0 = "size not determined" for a present + # cylinder (has_hot_water_cylinder=true). RdSAP 10 §10.5 Table 28: + # "If the actual size is not determined, the size ... is taken as + # according to Table 28" → the "Normal" 110 L baseline, which STILL + # incurs a storage loss. Without this the code lookup returned None + # and the `if volume_l is None: return None` below dropped the loss, + # under-costing the DHW (7 corpus certs; e.g. 200004017091 +1.75 -> + # +0.39). Gated on the EXPLICIT 0 so a full-SAP cert whose RdSAP + # cylinder_size is simply unlodged (None, e.g. 10091568921) keeps its + # own cylinder handling rather than a forced 110 L RdSAP default. + volume_l = _CYLINDER_SIZE_NOT_DETERMINED_L if declared_loss is not None: storage_56m = cylinder_storage_loss_monthly_kwh( volume_l=volume_l or 0.0, @@ -7517,8 +7600,17 @@ def _fuel_cost( secondary_fuel = ( epc.sap_heating.secondary_fuel_type if epc.sap_heating else None ) + # Canonicalise the colliding gov-API secondary fuel enums (5 anthracite / + # 9 dual fuel / 33 coal — `_GOV_API_COLLISION_FUELS`) BEFORE the price + # lookup, exactly as the main-fuel boundary and the CO2/display + # `_secondary_fuel_cost_gbp_per_kwh` already do. Without this the raw + # same-value Table-32 lookup mis-priced e.g. anthracite (enum 5) at the + # bulk-LPG code-5 rate (12.19 vs 3.64 p/kWh) — a 3× over-cost that sank + # cert 100050355518 (lodged 36, engine 20.8). This inline cost path had + # diverged from the already-canonicalised display helper. secondary_high_rate_gbp_per_kwh = ( - table_32_unit_price_p_per_kwh(secondary_fuel) * _PENCE_TO_GBP + table_32_unit_price_p_per_kwh(canonical_fuel_code(secondary_fuel)) + * _PENCE_TO_GBP if secondary_fuel is not None else other_uses_gbp_per_kwh ) diff --git a/domain/sap10_calculator/worksheet/heat_transmission.py b/domain/sap10_calculator/worksheet/heat_transmission.py index 32ae5bf75..789483e6c 100644 --- a/domain/sap10_calculator/worksheet/heat_transmission.py +++ b/domain/sap10_calculator/worksheet/heat_transmission.py @@ -922,6 +922,22 @@ def heat_transmission_from_cert( raw_rafter_thickness = getattr(part, "rafter_insulation_thickness", None) if raw_rafter_thickness is not None: raw_roof_thickness = raw_rafter_thickness + elif "flat" in (part.roof_construction_type or "").lower(): + # RdSAP 10 §5.11 — a FLAT roof lodges its insulation thickness in + # the dedicated gov-API `flat_roof_insulation_thickness` field + # (e.g. "75mm"), NOT `roof_insulation_thickness` (which stays None + # for flat roofs). Prefer it so a measured flat-roof thickness + # bills at its Table-16 U instead of the uninsulated age-band flat + # default. Mirrors the rafter branch above. Cert 47084930: flat + # roof "75mm" -> U 0.5 (accredited Elmhurst worksheet, "insulated + # flat roof") vs the age-E default 1.5 (roof 96.4 -> 32.1 W/K). An + # "AB"/"NI" (as-built/unknown) value parses to None and keeps the + # age-band default, unchanged. + raw_flat_thickness = getattr( + part, "flat_roof_insulation_thickness", None + ) + if raw_flat_thickness is not None: + raw_roof_thickness = raw_flat_thickness roof_thickness = _parse_thickness_mm(raw_roof_thickness) floor_ins_thickness = _parse_thickness_mm(getattr(part, "floor_insulation_thickness", None)) diff --git a/domain/sap10_ml/rdsap_uvalues.py b/domain/sap10_ml/rdsap_uvalues.py index 6687491f0..be1ab2f62 100644 --- a/domain/sap10_ml/rdsap_uvalues.py +++ b/domain/sap10_ml/rdsap_uvalues.py @@ -157,6 +157,11 @@ _WALL_INSULATION_INTERNAL: Final[int] = 3 WALL_INSULATION_CAVITY_PLUS_EXTERNAL: Final[int] = 6 WALL_INSULATION_CAVITY_PLUS_INTERNAL: Final[int] = 7 +# RdSAP 10 §5.4 (PDF p.32): "assume 100 mm if thickness is unknown" — the +# default added-insulation thickness for an External / Internal wall +# insulation lodgement (type 1/3) with no measured thickness. +_WALL_ADDED_INSULATION_UNKNOWN_THICKNESS_MM: Final[int] = 100 + # RdSAP 10 §4-6 (page 73): default thermal conductivity of insulation when # no documentary evidence is available. Used to convert the lodged # `wall_insulation_thickness` (mm) into thermal resistance (m²K/W) via @@ -348,7 +353,13 @@ def _insulation_bucket(thickness_mm: Optional[int], insulation_present: bool) -> to the 50 mm bucket when `insulation_present=True`; when not present, the as-built (bucket 0) row applies regardless. """ - if insulation_present and (thickness_mm is None or thickness_mm == 0): + # Insulation known to be present must never fall to the uninsulated + # (bucket 0) row. RdSAP 10 Table 6 footnote routes present-but-unknown + # thickness to the 50 mm row; a KNOWN thin lodgement (5-24 mm, below the + # smallest tabulated 50 mm column) must not read as WORSE (higher U) than + # the unknown case — so it too rounds up to the 50 mm row rather than to + # bucket 0. Only genuinely absent insulation (present=False) maps to 0. + if insulation_present and (thickness_mm is None or thickness_mm < 25): return 50 if thickness_mm is None: return 0 @@ -589,6 +600,28 @@ def u_wall( ctry = country if country is not None else Country.ENG age_idx = _age_index(age_band) band = _AGE_BANDS[age_idx] + # RdSAP 10 §5.4 (PDF p.32): "the U-value with additional insulation is + # based on the thickness of insulation of mineral wool type (assume + # 100 mm if thickness is unknown)". A SOLID-BRICK or STONE wall lodging + # External or Internal insulation (wall_insulation_type 1/3) but no + # measured insulation thickness (gov-API "NI" → None) takes the 100 mm + # default so the §5.8 Table-14 R-value adjustment (brick/stone branches + # below) fires instead of billing the wall at its uninsulated + # §5.6/Table-6 U (over-counting fabric loss → under-rate; corpus cert + # 200004296092, solid brick 360 mm, walls 101.7 W/K → PE +59.6). Scoped + # to brick/stone because only those constructions have a §5.8 added- + # insulation R-value path here — cavity uses the separate + # `WALL_INSULATION_CAVITY_PLUS_*` composite, and timber/system-built + # carry no §5.8 branch, so a thickness default there would be inert or + # mis-routed. + if ( + construction + in (WALL_STONE_GRANITE, WALL_STONE_SANDSTONE, WALL_SOLID_BRICK) + and wall_insulation_type + in (_WALL_INSULATION_EXTERNAL, _WALL_INSULATION_INTERNAL) + and (insulation_thickness_mm is None or insulation_thickness_mm == 0) + ): + insulation_thickness_mm = _WALL_ADDED_INSULATION_UNKNOWN_THICKNESS_MM # RdSAP 10 Tables 6-10 stone rows + footnote (a) (PDF p.33-39), §5.6 # formula (PDF p.40), §5.8 + Table 14 (PDF p.41-42). A documentary wall # thickness (per §5.3) routes stone in age bands A-E off the §5.6 formula, @@ -998,13 +1031,30 @@ def u_roof( # (band J = 0.16), matching the cohort's "ND" (thickness None) # vaulted roofs which already reach col (1) by falling through. return _ROOF_BY_AGE.get(age_band.upper(), 0.4) + if ( + age_band is not None + and insulation_thickness_mm == 0 + and _described_as_insulated(description) + and description is not None + and "(assumed)" in description.lower() + ): + # RdSAP renders "insulated (assumed)" when insulation PRESENCE is + # itself assumed (age-band / as-built assumption), not an observed + # retrofit — so the §5.11.4 50 mm footnote (below) does not apply; + # the thickness "cannot be determined" and the Table 18 age-band + # default governs (§5.11.4 opening clause). Identical + # "Pitched, insulated (assumed)" corpus dwellings lodge thickness + # "ND" (None → Table 18 by fallthrough) or "NI" (0 → previously the + # 50 mm row) purely per lodging software; both take Table 18. + table_18 = _FLAT_ROOF_BY_AGE if is_flat_roof else roof_by_age + return table_18.get(age_band.upper(), 0.4) if insulation_thickness_mm == 0 and _described_as_insulated(description): # Spec §5.11.4 (page 44 footnote): "If retrofit insulation # present of unknown thickness use 50 mm". The cert encodes - # "thickness unknown but retrofit insulation present" as the - # "NI" sentinel which `_parse_thickness_mm` parses to 0. Without - # this override the Table 16 row-0 lookup below returns the - # uninsulated 2.30 W/m²K. + # "thickness unknown but OBSERVED retrofit insulation" as the + # "NI" sentinel (parsed to 0) + an unqualified "insulated" + # description (no "(assumed)"). Without this override the Table + # 16 row-0 lookup below returns the uninsulated 2.30 W/m²K. return 0.68 # Table 16 row 50, "Insulation at joists at ceiling level" if insulation_thickness_mm is not None: # nearest tabulated thickness <= supplied (Table 16 column (1) diff --git a/domain/sap10_ml/tests/test_rdsap_uvalues.py b/domain/sap10_ml/tests/test_rdsap_uvalues.py index 4fb51f422..95993be78 100644 --- a/domain/sap10_ml/tests/test_rdsap_uvalues.py +++ b/domain/sap10_ml/tests/test_rdsap_uvalues.py @@ -31,6 +31,7 @@ from domain.sap10_ml.rdsap_uvalues import ( WALL_STONE_SANDSTONE, WALL_SYSTEM_BUILT, WALL_TIMBER_FRAME, + _insulation_bucket, thermal_bridging_y, u_door, u_exposed_floor, @@ -114,6 +115,43 @@ def test_u_wall_solid_brick_with_ni_thickness_uses_50mm_row_per_table6_footnote( assert result == pytest.approx(0.55, abs=0.001) +def test_u_wall_solid_brick_present_insulation_thin_known_thickness_not_uninsulated() -> None: + # Arrange — a solid-brick wall lodging internal insulation (type 3) + # with a KNOWN thin thickness (10 mm) but no documentary wall + # thickness (so the §5.8 formula branch, which needs wall_thickness, + # cannot fire) falls to the Table-6 bucket. A known 10 mm value sits + # below the smallest tabulated 50 mm column, but insulation IS present + # — it must NOT read as WORSE (higher U) than the present-but-unknown + # case, which the footnote routes to the 50 mm row. Pre-fix, + # `_insulation_bucket(10, present=True)` returned 0 (uninsulated, + # U=1.7), under-crediting the wall (corpus cert 5117280: Δ −4.44). + + # Act + result = u_wall( + country=Country.ENG, + age_band="B", + construction=WALL_SOLID_BRICK, + insulation_thickness_mm=10, + insulation_present=True, + wall_insulation_type=3, + ) + + # Assert — present insulation → 50 mm row (U=0.55), never uninsulated 1.7. + assert result == pytest.approx(0.55, abs=0.001) + + +def test_insulation_bucket_present_thin_thickness_rounds_up_to_50_not_zero() -> None: + # Direct guard on the bucket: present insulation never maps to bucket 0. + assert _insulation_bucket(10, True) == 50 + assert _insulation_bucket(24, True) == 50 + assert _insulation_bucket(None, True) == 50 + assert _insulation_bucket(50, True) == 50 + assert _insulation_bucket(100, True) == 100 + # Genuinely absent insulation still routes thin/zero to bucket 0. + assert _insulation_bucket(10, False) == 0 + assert _insulation_bucket(None, False) == 0 + + def test_u_wall_cavity_as_built_insulated_assumed_routes_to_as_built_row() -> None: # Arrange — a cavity lodged "Cavity wall, as built, insulated (assumed)" # with wall_insulation_type=4 is in its AS-BUILT state, NOT a retrofit @@ -835,6 +873,34 @@ def test_u_wall_stone_granite_with_external_insulation_applies_5_8_table_14_r_va assert abs(result - 0.57) <= 1e-4 +def test_u_wall_solid_brick_external_insulation_unknown_thickness_assumes_100mm() -> None: + # Arrange — RdSAP 10 §5.4 (PDF p.32): "the U-value with additional + # insulation is based on the thickness of insulation of mineral wool + # type (assume 100 mm if thickness is unknown)". A solid brick / stone + # wall lodging External or Internal insulation (wall_insulation_type + # 1/3) but NO measured insulation thickness (gov-API "NI" → parsed to + # None) must take the 100 mm §5.4 default so the §5.8 Table-14 R-value + # fires — NOT fall through to the uninsulated §5.6 U. Corpus cert + # 200004296092 (age-B solid brick 360 mm, "with external insulation", + # thickness NI) was billed at the uninsulated 1.40 (walls 101.7 W/K, + # HLP 3.46) → PE +59.6, SAP −6.65. With 100 mm: U₀(§5.6, 360 mm brick) + # + R(100 mm, λ=0.04 → 2.5) → 0.29. + + # Act + result = u_wall( + country=Country.ENG, + age_band="B", + construction=WALL_SOLID_BRICK, + insulation_thickness_mm=None, # gov-API "NI" — thickness unknown + insulation_present=True, + wall_insulation_type=1, # External + wall_thickness_mm=360, + ) + + # Assert — 100 mm default applied, not the uninsulated 1.40. + assert abs(result - 0.29) <= 1e-4 + + def test_u_wall_stone_granite_age_g_with_wall_thickness_ignores_5_6_formula_per_age_a_to_e_gate() -> None: # Arrange — §5.6 (PDF p.40) heading explicitly scopes the formula # to "age bands A to E". For age F onwards Table 6 gives literal @@ -1059,16 +1125,41 @@ def test_u_roof_description_with_measured_transmittance_returns_parsed_value() - assert result == pytest.approx(0.11, abs=0.001) -def test_u_roof_ni_thickness_with_insulated_description_applies_50mm_per_section_5_11_4() -> None: - # Arrange — 346 corpus certs lodge roof_insulation_thickness="NI" - # (Not Indicated, parsed to 0 by _parse_thickness_mm). When the - # description also signals retrofit insulation ("Pitched, insulated - # (assumed)" / "Flat, insulated" / "Roof room(s), insulated - # (assumed)"), RdSAP 10 §5.11.4 (page 44) footnote applies: +def test_u_roof_ni_thickness_with_observed_insulated_description_applies_50mm_per_section_5_11_4() -> None: + # Arrange — a roof lodging thickness "NI" (parsed to 0) whose + # description signals OBSERVED insulation without the "(assumed)" + # qualifier ("Pitched, insulated" — RdSAP renders the bare form when + # the assessor saw the insulation but not its depth). RdSAP 10 + # §5.11.4 (page 44) footnote applies: # "If retrofit insulation present of unknown thickness use 50 mm". # That maps to Table 16 row "50 mm at joists at ceiling level" = 0.68 - # W/m²K — vs the current 2.30 we return when thickness=0 hits the - # Table 16 row-0 lookup. + # W/m²K — vs the 2.30 the Table 16 row-0 lookup would give. + + # Act + result = u_roof( + country=Country.ENG, + age_band="C", + insulation_thickness_mm=0, # parsed from "NI" + description="Pitched, insulated", + ) + + # Assert + assert result == pytest.approx(0.68, abs=0.01) + + +def test_u_roof_ni_thickness_with_assumed_insulated_description_uses_table18_default() -> None: + # Arrange — RdSAP renders "insulated (assumed)" when insulation + # presence is ASSUMED (age-band / as-built assumption), not an + # observed retrofit — so the §5.11.4 "retrofit insulation present of + # unknown thickness use 50 mm" footnote does NOT apply; the thickness + # "cannot be determined" and Table 18's age-band default governs + # (§5.11.4 opening clause). The corpus lodges the SAME description + # with thickness "ND" (102 certs → already Table 18 via the + # thickness-None fallthrough) or "NI" (27 certs → previously took the + # 50 mm row 0.68), purely per lodging software; both must land on the + # same Table 18 value (band C pitched → 0.40). The loc-4 NI cohort + # was systematically under-rated by ~1 SAP before this (e.g. corpus + # cert 10094975827 band B: Δ −1.87). # Act result = u_roof( @@ -1078,8 +1169,8 @@ def test_u_roof_ni_thickness_with_insulated_description_applies_50mm_per_section description="Pitched, insulated (assumed)", ) - # Assert - assert result == pytest.approx(0.68, abs=0.01) + # Assert — Table 18 column (1) band C. + assert result == pytest.approx(0.40, abs=0.01) def test_u_roof_ni_thickness_with_no_insulation_description_stays_at_2_30() -> None: @@ -1324,18 +1415,20 @@ def test_u_roof_vaulted_ni_unknown_band_j_uses_col1_age_band_not_50mm() -> None: assert abs(result - 0.16) <= 1e-4 -def test_u_roof_normal_pitched_ni_insulated_still_returns_50mm_per_5_11_4() -> None: +def test_u_roof_normal_pitched_ni_observed_insulated_still_returns_50mm_per_5_11_4() -> None: # Arrange — regression guard: the is_sloping_ceiling flag defaults - # False, so a NORMAL pitched roof (with loft) lodged NI + "insulated - # (assumed)" must STILL hit the §5.11.4 retrofit-50 mm row (U=0.68). - # Same inputs as the sloping test above minus is_sloping_ceiling. + # False, so a NORMAL pitched roof (with loft) lodged NI + an + # unqualified "insulated" description (observed retrofit, no + # "(assumed)") must STILL hit the §5.11.4 retrofit-50 mm row + # (U=0.68). The "(assumed)" form routes to Table 18 instead — see + # test_u_roof_ni_thickness_with_assumed_insulated_description_uses_table18_default. # Act result = u_roof( country=Country.ENG, age_band="J", insulation_thickness_mm=0, - description="Pitched, insulated (assumed)", + description="Pitched, insulated", ) # Assert diff --git a/scripts/corpus_1000/build_worklist.py b/scripts/corpus_1000/build_worklist.py new file mode 100644 index 000000000..55df6586d --- /dev/null +++ b/scripts/corpus_1000/build_worklist.py @@ -0,0 +1,243 @@ +"""Build the RdSAP-21.0.1 corpus campaign ledger (scripts/corpus_1000/worklist.md). + +Runs all 1000 corpus certs through the gauge's own path +(from_api_response -> Sap10Calculator.calculate, mirroring +tests/infrastructure/epc_client/test_sap_accuracy_corpus.py), ranks by +|engine - lodged| descending, attaches a short dwelling signature per cert, +and groups same-signature certs into named clusters. + +USAGE +----- + PYTHONPATH=/workspaces/model python scripts/corpus_1000/build_worklist.py + +Rewrites worklist.md in place, PRESERVING existing per-cert statuses +([x] / 🔧 / ⚠ / ⛔ and trailing `<-` notes) keyed by uprn, so it doubles as +the re-rank step after each fix lands. +""" +from __future__ import annotations + +import json +import re +from collections import defaultdict +from pathlib import Path +from typing import Any, Optional + +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +from domain.sap10_calculator.calculator import Sap10Calculator + +ROOT = Path(__file__).resolve().parents[2] +CORPUS = ROOT / "backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl" +WORKLIST = ROOT / "scripts/corpus_1000/worklist.md" + +# Table 12 fuel names (abbreviated) for the signature column. +_FUEL = { + 1: "gas", 2: "gas-bulk", 3: "biogas", 4: "biogas", 7: "bLPG", 9: "LPG", + 17: "LPG-sc", 10: "oil", 15: "bioliquid", 16: "B30K", 18: "rapeseed", + 58: "biodiesel", 51: "housecoal", 20: "coal-anth", 21: "smokeless", + 22: "anthracite", 23: "manuf-smokeless", 12: "wood-log", 13: "wood-pellet", + 75: "wood-pellet-bag", 71: "wood-chip", 48: "dual-mineral-wood", + 26: "gas", 25: "elec", 29: "elec", 30: "elec7hr", 31: "elec10hr", + 32: "elec18hr", 33: "elec24hr", 34: "elec-heatnet", 35: "elec", + 36: "elec", 37: "elec", 47: "heatnet", 6: "heatnet", +} + + +def _fuel_name(code: Optional[int]) -> str: + if code is None: + return "?" + return _FUEL.get(code, f"fuel{code}") + + +def _lead(desc: Optional[str], n: int = 3) -> str: + """First n comma/word tokens of a register description, lowercased.""" + if not desc: + return "?" + return " ".join(desc.lower().replace(",", " ").split()[:n]) + + +def signature(doc: dict[str, Any]) -> tuple[str, str]: + """(cluster_key, human signature) for one cert.""" + h = doc.get("sap_heating") or {} + mhd = (h.get("main_heating_details") or [{}]) + m0 = mhd[0] if mhd else {} + code = m0.get("sap_main_heating_code") + idx = m0.get("main_heating_index_number") + fuel = _fuel_name(m0.get("main_fuel_type")) + heat = f"h{code or ('pcdb' + str(idx) if idx else '?')}/{fuel}" + if len(mhd) > 1: + heat += "+2mains" + + walls = doc.get("walls") or [] + wall = _lead(walls[0].get("description") if walls else None, 2) + roofs = doc.get("roofs") or [] + roof = _lead(roofs[0].get("description") if roofs else None, 2) + + es = doc.get("sap_energy_source") or {} + sec = (doc.get("secondary_heating") or {}).get("description") or "None" + feats: list[str] = [] + pv = es.get("photovoltaic_supply") or {} + if es.get("pv_connection") not in (0, None) or not pv.get("none_or_no_details"): + feats.append("PV") + if (es.get("wind_turbines_count") or 0) > 0: + feats.append("wind") + if sec != "None": + feats.append("sec:" + _lead(sec, 2)) + if (doc.get("extensions_count") or 0) > 0: + feats.append(f"ext{doc.get('extensions_count')}") + if (doc.get("conservatory_type") or 1) != 1: + feats.append(f"consv{doc.get('conservatory_type')}") + for bp in doc.get("sap_building_parts") or []: + if bp.get("sap_room_in_roof") is not None: + feats.append("RR") + break + mv = doc.get("mechanical_ventilation") + if mv not in (0, None): + feats.append(f"mv{mv}") + if (h.get("water_heating_code") or 901) != 901: + feats.append(f"whw{h.get('water_heating_code')}") + + key = f"{heat} | {wall} | {roof}" + (" | " + ",".join(sorted(set(feats))) if feats else "") + sig = key + return key, sig + + +_LINE_RE = re.compile( + r"^- \[(?P[ x])\] |^- (?P🔧|⚠|⛔) " +) + + +def load_existing_statuses() -> dict[str, tuple[str, str]]: + """uprn -> (status token, trailing note) from the current worklist.""" + out: dict[str, tuple[str, str]] = {} + if not WORKLIST.exists(): + return out + for line in WORKLIST.read_text().splitlines(): + m = re.match(r"^- (?:\[(?P[ x])\]|(?P🔧|⚠|⛔)) `(?P\w+)`", line) + if not m: + continue + status = f"[{m.group('st')}]" if m.group("st") is not None else m.group("emoji") + note = "" + if "<-" in line: + note = "<-" + line.split("<-", 1)[1] + out[m.group("uprn")] = (status, note) + return out + + +def main() -> None: + docs = [json.loads(l) for l in CORPUS.read_text().splitlines() if l.strip()] + calc = Sap10Calculator() + rows: list[dict[str, Any]] = [] + skipped: list[tuple[str, str]] = [] + sap_abs: list[float] = [] + + for idx, doc in enumerate(docs, 1): + # Some corpus docs lodge no top-level uprn; fall back to the corpus + # line number so ledger statuses don't collide on "None". + uprn = str(doc.get("uprn") or f"line{idx}") + lodged = doc.get("energy_rating_current") + if lodged is None: + skipped.append((uprn, "no lodged SAP")) + continue + try: + epc = EpcPropertyDataMapper.from_api_response(doc) + result = calc.calculate(epc) + except Exception as e: + skipped.append((uprn, f"{type(e).__name__}: {str(e)[:70]}")) + continue + eng = result.sap_score_continuous + delta = eng - lodged + sap_abs.append(abs(delta)) + key, sig = signature(doc) + rows.append({ + "uprn": uprn, "lodged": lodged, "eng": eng, "delta": delta, + "key": key, "sig": sig, + }) + + n = len(sap_abs) + within = sum(1 for e in sap_abs if e < 0.5) / n + mae = sum(sap_abs) / n + + # Cluster: same signature key, only certs still outside 0.5. + clusters: dict[str, list[dict[str, Any]]] = defaultdict(list) + for r in rows: + if abs(r["delta"]) >= 0.5: + clusters[r["key"]].append(r) + ranked = sorted( + clusters.items(), + key=lambda kv: -sum(abs(r["delta"]) for r in kv[1]), + ) + + prev = load_existing_statuses() + + lines: list[str] = [] + lines.append("# RdSAP-21.0.1 corpus campaign ledger") + lines.append("") + lines.append( + f"**Gauge:** {n} computed / {len(skipped)} skipped · " + f"SAP within-0.5 = **{within:.1%}** · MAE = **{mae:.3f}** " + f"(floors in test_sap_accuracy_corpus.py)" + ) + lines.append("") + lines.append( + "Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · " + "⚠ xfail engine bug · ⛔ unbuildable. " + "Line: `uprn · lodged L / eng E / Δ · signature`. " + "Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` " + "(preserves statuses & `<-` notes)." + ) + lines.append("") + lines.append(f"## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — {sum(len(v) for v in clusters.values())} certs in {len(ranked)} clusters") + lines.append("") + + for i, (key, members) in enumerate(ranked, 1): + members.sort(key=lambda r: -abs(r["delta"])) + tot = sum(abs(r["delta"]) for r in members) + lines.append( + f"### C{i:03d} · Σ|Δ| {tot:.1f} · {len(members)} certs · `{key}`" + ) + for r in members: + st, note = prev.get(r["uprn"], ("[ ]", "")) + frag = ( + f"- {st} `{r['uprn']}` · L {r['lodged']} / E {r['eng']:.2f} / " + f"Δ {r['delta']:+.2f}" + ) + if note: + frag += f" {note}" + lines.append(frag) + lines.append("") + + if skipped: + lines.append(f"## Skipped ({len(skipped)})") + for uprn, why in skipped: + st, note = prev.get(uprn, ("⛔", "")) + lines.append(f"- {st} `{uprn}` · {why} {note}".rstrip()) + lines.append("") + + resolved = [r for r in rows if abs(r["delta"]) < 0.5] + lines.append(f"## Resolved ≤0.5 ({len(resolved)} certs — no action)") + lines.append("") + lines.append("
expand") + lines.append("") + for r in sorted(resolved, key=lambda r: -abs(r["delta"])): + st, note = prev.get(r["uprn"], ("[x]", "")) + if st == "[ ]": + st = "[x]" + lines.append( + f"- {st} `{r['uprn']}` · L {r['lodged']} / E {r['eng']:.2f} / " + f"Δ {r['delta']:+.2f} · `{r['key']}` {note}".rstrip() + ) + lines.append("") + lines.append("
") + lines.append("") + + WORKLIST.write_text("\n".join(lines)) + print(f"wrote {WORKLIST}") + print(f"gauge: {n} computed / {len(skipped)} skipped, within-0.5 {within:.1%}, MAE {mae:.3f}") + print(f"clusters: {len(ranked)}, worst 5:") + for key, members in ranked[:5]: + tot = sum(abs(r["delta"]) for r in members) + print(f" Σ{tot:7.1f} n={len(members):3d} {key}") + + +if __name__ == "__main__": + main() diff --git a/scripts/corpus_1000/demand_cohort.py b/scripts/corpus_1000/demand_cohort.py new file mode 100644 index 000000000..cffa01e9e --- /dev/null +++ b/scripts/corpus_1000/demand_cohort.py @@ -0,0 +1,58 @@ +"""Demand-driven divergence analyzer. Flags corpus certs where the SAP miss is +driven by FABRIC/DEMAND (PE & CO2 move with SAP), not cost — the fixable class. +Tags nbp (building parts) and room-in-roof so multi-part / RR bugs surface.""" +from __future__ import annotations +import json +from pathlib import Path +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +from domain.sap10_calculator.calculator import calculate_sap_from_inputs +from domain.sap10_calculator.rdsap.cert_to_inputs import ( + SAP_10_2_SPEC_PRICES, cert_to_demand_inputs, cert_to_inputs) + +CORPUS = Path("backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl") + +def has_rr(doc): + for bp in doc.get("sap_building_parts") or []: + r = bp.get("room_in_roof") or bp.get("rooms_in_roof") + if r: return True + for r in doc.get("roofs") or []: + if "room in roof" in (r.get("description") or "").lower(): return True + return False + +rows = [] +for line in CORPUS.read_text().splitlines(): + doc = json.loads(line) + L = doc.get("energy_rating_current"); peL = doc.get("energy_consumption_current") + co2L = doc.get("co2_emissions_current") + if L is None: continue + try: + epc = EpcPropertyDataMapper.from_api_response(doc) + r = calculate_sap_from_inputs(cert_to_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + d = calculate_sap_from_inputs(cert_to_demand_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + except Exception: + continue + dsap = r.sap_score_continuous - L + if abs(dsap) < 0.5: continue + peE = getattr(d, "primary_energy_kwh_per_m2", None) + dpe = (peE - peL) if (peE is not None and peL is not None) else None + co2E = d.co2_kg_per_yr/1000 if d.co2_kg_per_yr is not None else None + dco2 = (co2E - co2L) if (co2E is not None and co2L is not None) else None + nbp = len(doc.get("sap_building_parts") or []) + rr = has_rr(doc) + # demand-driven: PE moves same direction as SAP-miss inverse (PE up -> SAP down) + # i.e. dpe and dsap have OPPOSITE signs, and |dpe| is material + demand = (dpe is not None and abs(dpe) >= 4 and (dpe > 0) == (dsap < 0)) + rows.append((doc.get("uprn"), L, round(r.sap_score_continuous,1), round(dsap,2), + round(dpe,1) if dpe is not None else None, + round(dco2,3) if dco2 is not None else None, nbp, rr, demand)) + +demand_rows = [r for r in rows if r[8]] +demand_rows.sort(key=lambda x:-abs(x[3])) +print(f"diverging certs: {len(rows)} | demand-driven: {len(demand_rows)}") +mp = [r for r in demand_rows if r[6] > 1] +rr = [r for r in demand_rows if r[7]] +print(f" demand+multipart(nbp>1): {len(mp)} | demand+RR: {len(rr)}") +print(f"\n=== top demand-driven divergences ===") +print(f"{'uprn':13s} {'L':>3} {'E':>5} {'dSAP':>6} {'dPE':>6} {'dCO2':>6} {'nbp':>3} {'RR':>3}") +for r in demand_rows[:32]: + print(f"{str(r[0]):13s} {r[1]:3d} {r[2]:5.1f} {r[3]:+6.2f} {str(r[4]):>6} {str(r[5]):>6} {r[6]:3d} {'Y' if r[7] else '':>3}") diff --git a/scripts/corpus_1000/elec_cohort.py b/scripts/corpus_1000/elec_cohort.py new file mode 100644 index 000000000..ad5fb44b1 --- /dev/null +++ b/scripts/corpus_1000/elec_cohort.py @@ -0,0 +1,61 @@ +"""Electric-main cohort analysis: for every corpus cert whose main heating is +electric, dump heating SAP code / tariff (meter_type) / lodged vs engine SAP / +cost-vs-demand signature. Used to steer a spec-grounded Table-12a tariff fix +without regressing in-band certs.""" +from __future__ import annotations +import json +from pathlib import Path +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +from domain.sap10_calculator.calculator import calculate_sap_from_inputs +from domain.sap10_calculator.rdsap.cert_to_inputs import ( + SAP_10_2_SPEC_PRICES, cert_to_demand_inputs, cert_to_inputs, _is_electric_main, + _first_main_heating, +) + +CORPUS = Path("backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl") + +def hcode(doc): + sh = doc.get("sap_heating") or {} + ds = sh.get("main_heating_details") or [{}] + return ds[0].get("main_heating_category"), ds[0].get("main_fuel_type") + +rows = [] +for line in CORPUS.read_text().splitlines(): + doc = json.loads(line) + try: + epc = EpcPropertyDataMapper.from_api_response(doc) + except Exception: + continue + main = _first_main_heating(epc) + if not _is_electric_main(main): + continue + try: + r = calculate_sap_from_inputs(cert_to_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + d = calculate_sap_from_inputs(cert_to_demand_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + except Exception as e: + continue + L = doc.get("energy_rating_current"); pe_l = doc.get("energy_consumption_current") + if L is None: continue + dsap = r.sap_score_continuous - L + dpe = (d.pe_per_m2 - pe_l) if (pe_l is not None and hasattr(d,'pe_per_m2')) else None + cat, fuel = hcode(doc) + mt = (doc.get("sap_energy_source") or {}).get("meter_type") + sh = doc.get("sap_heating") or {} + code = (sh.get("main_heating_details") or [{}])[0].get("main_heating_code") \ + or (sh.get("main_heating_details") or [{}])[0].get("main_heating_index_number") + rows.append((doc.get("uprn"), code, cat, mt, sh.get("water_heating_code"), + L, round(r.sap_score_continuous,1), round(dsap,2))) + +rows.sort(key=lambda x:-abs(x[7])) +print(f"electric-main certs: {len(rows)}") +print(f"{'uprn':14s} {'hcode':>6} {'cat':>4} {'mtr':>4} {'whc':>5} {'L':>3} {'E':>6} {'dSAP':>6}") +for r in rows: + print(f"{str(r[0]):14s} {str(r[1]):>6} {str(r[2]):>4} {str(r[3]):>4} {str(r[4]):>5} {r[5]:3d} {r[6]:6.1f} {r[7]:+6.2f}") +# summary by (hcode, meter) +from collections import defaultdict +agg = defaultdict(lambda:[0,0.0,0,0]) +for r in rows: + k=(r[1], r[3]); a=agg[k]; a[0]+=1; a[1]+=r[7]; a[2]+=(abs(r[7])>0.5); a[3]+=(abs(r[7])<=0.5) +print("\n=== by (hcode, meter): n, meanΔ, #div>0.5, #inband ===") +for k,a in sorted(agg.items(), key=lambda x:-abs(x[1][1])): + print(f" code {str(k[0]):>6} meter {str(k[1]):>4}: n={a[0]:3d} meanΔ={a[1]/a[0]:+6.2f} div={a[2]:3d} inband={a[3]:3d}") diff --git a/scripts/corpus_1000/field_bias.py b/scripts/corpus_1000/field_bias.py new file mode 100644 index 000000000..8331780f7 --- /dev/null +++ b/scripts/corpus_1000/field_bias.py @@ -0,0 +1,46 @@ +"""Field-level systematic-bias scan: mean Δ(SAP) grouped by each mapped +attribute. A subgroup with large |meanΔ| AND enough n is a systematic mapping +error for that attribute (would cancel in the overall ~0 bias).""" +from __future__ import annotations +import json, statistics +from collections import defaultdict +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +from domain.sap10_calculator.calculator import calculate_sap_from_inputs +from domain.sap10_calculator.rdsap.cert_to_inputs import SAP_10_2_SPEC_PRICES, cert_to_inputs +CORPUS="backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl" +G=defaultdict(lambda: defaultdict(list)) +def gv(x): return x.get('value') if isinstance(x,dict) else x +for line in open(CORPUS): + d=json.loads(line); L=d.get('energy_rating_current') + if L is None: continue + try: + epc=EpcPropertyDataMapper.from_api_response(d) + r=calculate_sap_from_inputs(cert_to_inputs(epc,prices=SAP_10_2_SPEC_PRICES)) + except Exception: continue + dsap=r.sap_score_continuous-L + bp=(d.get('sap_building_parts') or [{}])[0] + sh=d.get('sap_heating') or {}; md=(sh.get('main_heating_details') or [{}])[0] + G['wall_con'][bp.get('wall_construction')].append(dsap) + G['wall_ins'][bp.get('wall_insulation_type')].append(dsap) + G['wall_con+ins'][(bp.get('wall_construction'),bp.get('wall_insulation_type'))].append(dsap) + G['roof_con'][bp.get('roof_construction')].append(dsap) + G['floor_hl'][bp.get('floor_heat_loss')].append(dsap) + G['age'][bp.get('construction_age_band')].append(dsap) + G['main_cat'][md.get('main_heating_category')].append(dsap) + G['whc'][sh.get('water_heating_code')].append(dsap) + G['meter'][(d.get('sap_energy_source') or {}).get('meter_type')].append(dsap) + G['country'][d.get('country_code')].append(dsap) + G['dwelling'][d.get('dwelling_type')].append(dsap) + G['nbp'][len(d.get('sap_building_parts') or [])].append(dsap) + G['glz'][tuple(sorted(set(w.get('glazing_type') for w in (d.get('sap_windows') or []))))[:1]].append(dsap) +print("=== subgroups with |meanΔ| >= 0.5 and n >= 8 (systematic-bias candidates) ===") +hits=[] +for field, groups in G.items(): + for key, vals in groups.items(): + if len(vals) >= 8: + m=statistics.mean(vals) + if abs(m) >= 0.5: + hits.append((abs(m), field, key, len(vals), m, statistics.median(vals))) +for am,field,key,n,m,med in sorted(hits, reverse=True): + print(f" {field:12s} = {str(key):20s} n={n:4d} meanΔ={m:+.2f} medianΔ={med:+.2f}") +if not hits: print(" (none — no systematic subgroup bias)") diff --git a/scripts/corpus_1000/mapper_audit.py b/scripts/corpus_1000/mapper_audit.py new file mode 100644 index 000000000..6d82c5f1d --- /dev/null +++ b/scripts/corpus_1000/mapper_audit.py @@ -0,0 +1,56 @@ +"""Mapper faithfulness audit: for identity pass-through fields (dims, counts, +thicknesses) compare the RAW cert value to what EpcPropertyDataMapper produced. +Any mismatch is a mapper bug silently feeding the SAP engine wrong inputs.""" +from __future__ import annotations +import json +from collections import defaultdict +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +CORPUS="backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl" +def gv(x): return x.get('value') if isinstance(x,dict) else x +def num(x): + x=gv(x) + if x is None: return None + s=str(x).lower().replace('mm','').replace('m2','').strip() + try: return float(s) + except: return s # keep strings like 'measured'/'NI' for equality +mism=defaultdict(list) +n=0 +for line in open(CORPUS): + d=json.loads(line) + try: epc=EpcPropertyDataMapper.from_api_response(d) + except Exception: continue + n+=1; u=d.get('uprn') + # top-level counts + checks=[('door_count', d.get('door_count'), epc.door_count), + ('habitable', d.get('habitable_room_count'), getattr(epc,'habitable_room_count',None)), + ('led', d.get('led_fixed_lighting_bulbs_count'), epc.led_fixed_lighting_bulbs_count), + ('cfl', d.get('cfl_fixed_lighting_bulbs_count'), epc.cfl_fixed_lighting_bulbs_count), + ('incand', d.get('incandescent_fixed_lighting_bulbs_count'), epc.incandescent_fixed_lighting_bulbs_count)] + for name,rv,ev in checks: + if rv is not None and ev is not None and num(rv)!=num(ev): + mism[name].append((u,rv,ev)) + # per-building-part fabric + rbps=d.get('sap_building_parts') or []; ebps=epc.sap_building_parts or [] + for i,rbp in enumerate(rbps): + if i>=len(ebps): + mism['DROPPED_building_part'].append((u,len(rbps),len(ebps))); break + ebp=ebps[i] + for name,rv,ev in [('wall_thick',rbp.get('wall_thickness'),getattr(ebp,'wall_thickness_mm',None)), + ('wall_ins_thick',rbp.get('wall_insulation_thickness'),getattr(ebp,'wall_insulation_thickness',None)), + ('roof_ins_thick',rbp.get('roof_insulation_thickness'),getattr(ebp,'roof_insulation_thickness',None)), + ('wall_con',rbp.get('wall_construction'),getattr(ebp,'wall_construction',None)), + ('wall_ins_type',rbp.get('wall_insulation_type'),getattr(ebp,'wall_insulation_type',None))]: + if rv is not None and ev is not None and num(rv)!=num(ev): + mism[name].append((u,rv,ev)) + # windows: count + total area + rw=d.get('sap_windows') or []; ew=epc.sap_windows or [] + if len(rw)!=len(ew): mism['window_count'].append((u,len(rw),len(ew))) + ra=sum((gv(w.get('window_width')) or 0)*(gv(w.get('window_height')) or 0) for w in rw) + ea=sum((float(w.window_width) if w.window_width else 0)*(float(w.window_height) if w.window_height else 0) for w in ew) + if abs(ra-ea)>0.02: mism['window_area'].append((u,round(ra,2),round(ea,2))) +print(f"audited {n} certs") +print("=== field mismatches (raw cert vs EpcPropertyData) ===") +for k,v in sorted(mism.items(), key=lambda x:-len(x[1])): + print(f"\n[{len(v):4d}] {k}") + for u,rv,ev in v[:5]: print(f" {u}: raw={rv} epc={ev}") +if not mism: print(" (no mismatches — mapper is identity-faithful on all checked fields)") diff --git a/scripts/corpus_1000/why_diverge.py b/scripts/corpus_1000/why_diverge.py new file mode 100644 index 000000000..cf2aef86b --- /dev/null +++ b/scripts/corpus_1000/why_diverge.py @@ -0,0 +1,76 @@ +"""Categorize every corpus cert outside +-0.5 SAP by the REASON it diverges, +combining the computed cost-vs-demand signature, the electric heating code / +meter, and the ledger's RR/multipart tokens.""" +from __future__ import annotations +import json, re +from pathlib import Path +from collections import defaultdict +from datatypes.epc.domain.mapper import EpcPropertyDataMapper +from domain.sap10_calculator.calculator import calculate_sap_from_inputs +from domain.sap10_calculator.rdsap.cert_to_inputs import ( + SAP_10_2_SPEC_PRICES, cert_to_demand_inputs, cert_to_inputs, _is_electric_main, + _first_main_heating) + +CORPUS = Path("backend/epc_api/json_samples/RdSAP-Schema-21.0.1/corpus.jsonl") +# ledger signatures (for RR / multipart tokens) +sig_of={}; cur="" +for l in Path("scripts/corpus_1000/worklist.md").read_text().splitlines(): + if l.startswith('### C'): + m=re.search(r'`([^`]*)`',l); cur=m.group(1) if m else "" + m=re.match(r'^- .*?`([^`]+)`',l) + if m: sig_of[m.group(1)]=cur + +def bucket(doc, dsap, dpe, dco2, code, mt, sig): + rr = 'RR' in (sig or '') + elec = code in range(191,600) if code else False + demand = dpe is not None and abs(dpe) >= 4 and (dpe>0)==(dsap<0) + cost = dpe is not None and abs(dpe) < 4 + # 1. electric storage-boiler / CPSU on off-peak (spec §12 Rule 2/1) + if code in (192,193,194,195,196) and dsap>0: + return "elec storage/CPSU boiler → §12 off-peak (spec-faithful; lodged over-billed)" + # 2. electric direct + storage heaters, tariff/cost + if elec and cost: + return "electric tariff/cost (meter-column & high-rate fraction; spec-faithful vs lodged)" + if elec and demand: + return "electric + fabric/demand mismatch" + if elec: + return "electric other" + # 3. RR + if rr: + return "room-in-roof surface geometry (spec-mandated, worksheet-validated; high variance)" + # 4. non-elec demand/fabric + if demand: + return "non-electric fabric/demand (per-cert: glazing area, lodged geometry, mixed walls)" + if cost: + return "non-electric cost (secondary fuel / cylinder / tariff)" + return "unclassified" + +cnt=defaultdict(list) +band=defaultdict(int) +for line in CORPUS.read_text().splitlines(): + doc=json.loads(line); L=doc.get('energy_rating_current') + if L is None: continue + try: + epc=EpcPropertyDataMapper.from_api_response(doc) + r=calculate_sap_from_inputs(cert_to_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + d=calculate_sap_from_inputs(cert_to_demand_inputs(epc, prices=SAP_10_2_SPEC_PRICES)) + except Exception: continue + dsap=r.sap_score_continuous-L + if abs(dsap)<0.5: continue + peL=doc.get('energy_consumption_current'); co2L=doc.get('co2_emissions_current') + dpe=(d.primary_energy_kwh_per_m2-peL) if peL is not None else None + dco2=(d.co2_kg_per_yr/1000-co2L) if co2L is not None else None + sh=doc.get('sap_heating') or {}; det=(sh.get('main_heating_details') or [{}])[0] + code=det.get('sap_main_heating_code'); mt=(doc.get('sap_energy_source') or {}).get('meter_type') + b=bucket(doc,dsap,dpe,dco2,code,mt,sig_of.get(str(doc.get('uprn')),'')) + cnt[b].append((doc.get('uprn'),L,round(r.sap_score_continuous,1),round(dsap,1))) + ad=abs(dsap); band['0.5-1' if ad<1 else '1-2' if ad<2 else '2-4' if ad<4 else '4+']+=1 + +total=sum(len(v) for v in cnt.values()) +print(f"TOTAL diverging (|Δ|≥0.5): {total}\n") +print("by |Δ| band:", dict(band), "\n") +print("=== by REASON (count, mean|Δ|, examples) ===") +for b,rows in sorted(cnt.items(), key=lambda x:-len(x[1])): + mabs=sum(abs(x[3]) for x in rows)/len(rows) + ex=", ".join(f"{x[0]}({x[3]:+.1f})" for x in sorted(rows,key=lambda x:-abs(x[3]))[:3]) + print(f"\n[{len(rows):3d}] mean|Δ|={mabs:.1f} {b}\n e.g. {ex}") diff --git a/scripts/corpus_1000/worklist.md b/scripts/corpus_1000/worklist.md new file mode 100644 index 000000000..66fc7797b --- /dev/null +++ b/scripts/corpus_1000/worklist.md @@ -0,0 +1,1446 @@ +# RdSAP-21.0.1 corpus campaign ledger + +**Gauge:** 1000 computed / 0 skipped · SAP within-0.5 = **77.8%** · MAE = **0.636** (floors in test_sap_accuracy_corpus.py) + +Statuses: `[ ]` todo · `[x]` resolved ≤0.5 · 🔧 fix landed · ⚠ xfail engine bug · ⛔ unbuildable. Line: `uprn · lodged L / eng E / Δ · signature`. Rebuild/re-rank: `PYTHONPATH=. python scripts/corpus_1000/build_worklist.py` (preserves statuses & `<-` notes). + +## Clusters (certs with |Δ| ≥ 0.5, ranked by summed |Δ|) — 222 certs in 216 clusters + +### C001 · Σ|Δ| 23.9 · 1 certs · `hpcdb100053/elec | solid brick | (another dwelling | sec:room heaters` +- ⚠ `4510053280` · L 51 / E 74.94 / Δ +23.94 <- lodged software billed out-of-range-PSR (2.031 > 2.0) PCDB 100053 as 100% direct electric; engine follows SAP10.2 N2 extension (305%), Elmhurst-validated on case 56. Pinned engine 75 in test_real_cert_sap_accuracy. + +### C002 · Σ|Δ| 19.7 · 1 certs · `h301/coal-anth | cavity wall | pitched unknown | whw903` +- [ ] `103001004` · L 50 / E 69.69 / Δ +19.69 <- needs Elmhurst arbitration: lodged hw £1054 vs ours £113 (single-immersion on-peak fraction + cylinder declared-loss 1.8 kWh/day vs Table-2-sized loss); register data can't decompose. Other 14 declared-loss certs match lodged; only sibling outlier is 100121325434 (C008). + +### C003 · Σ|Δ| 13.2 · 1 certs · `h195/elec | system built | (another dwelling` +- ⚠ `10012334488` · L 72 / E 85.20 / Δ +13.20 <- SPEC-FAITHFUL: SAP code 195 = electric water-storage boiler (Table 4a p.170); §12 Rule 2 bills space+water at 7-hr off-peak (5.5p). Pure cost gap (PE/CO2 match). Lodged over-billed a storage system at peak rate. Pinned engine 85 in test_real_cert_sap_accuracy. + +### C004 · Σ|Δ| 13.1 · 1 certs · `hpcdb10326/gas | solid brick | pitched 75 | ext1,sec:room heaters` +- ⛔ `12109191` · L 58 / E 71.10 / Δ +13.10 <- LODGED DATA ERROR: BP0 floor-1 area 365.67 m² (10× its 36.77 ground floor; TFA 407 for a 4-habitable mid-terrace) — a decimal misplacement. Engine faithfully computes the near-wall-less huge floor → low HTC/m² → over-rate. Garbage-in, not an engine bug. + +### C005 · Σ|Δ| 10.3 · 4 certs · `h691/elec | cavity wall | (another dwelling | whw909` +- ⚠ `line279` · L 81 / E 78.44 / Δ -2.56 <- same as 10093237426 +- ⚠ `line301` · L 81 / E 78.44 / Δ -2.56 <- same as 10093237426 +- ⚠ `line318` · L 81 / E 78.44 / Δ -2.56 <- same as 10093237426 +- ⚠ `10093237426` · L 81 / E 78.44 / Δ -2.56 <- LIG-21.0 software (calc 10.2.2.0) honours lodged 0 extract fans literally; Elmhurst-validated convention (case 46) treats 0 as unknown -> Table 5 default. Fans-as-0 experiment closes 1.42 of 2.56; residual -1.14 unexplained, same-software quadruplet. + +### C006 · Σ|Δ| 10.1 · 1 certs · `h691/elec | granite or | pitched 175 | RR,ext1,whw903` +- [ ] `100040550095` · L 40 / E 29.87 / Δ -10.13 <- needs Elmhurst arbitration: PE+39/CO2+0.20 both over -> demand/fabric over-count (granite+solid-brick mixed walls + simplified RR type-2), not a cost bug + +### C007 · Σ|Δ| 8.7 · 1 certs · `h125/fuel28 | cavity wall | pitched 250 | consv2,sec:room heaters` +- [ ] `100121325434` · L 48 / E 56.75 / Δ +8.75 + +### C008 · Σ|Δ| 8.1 · 1 certs · `hpcdb17958/gas | system built | pitched 300 | PV,ext1,mv1` +- [ ] `100022294004` · L 75 / E 83.13 / Δ +8.13 + +### C009 · Σ|Δ| 7.8 · 1 certs · `h195/elec | cavity wall | (another dwelling` +- ⚠ `10091578598` · L 71 / E 78.81 / Δ +7.81 <- SPEC-FAITHFUL: code 195 electric water-storage boiler → §12 Rule 2 7-hr off-peak. Pure cost gap (PE/CO2 match). Same as 10012334488; lodged over-billed storage at peak. Pinned engine 79. + +### C010 · Σ|Δ| 7.1 · 1 certs · `h408/elec | cavity wall | (another dwelling | whw941` +- [ ] `200000322700` · L 58 / E 65.05 / Δ +7.05 <- electric storage cat7 E7 over-rate; see 74061136 + +### C011 · Σ|Δ| 6.7 · 1 certs · `h691/elec | solid brick | pitched 100 | RR,ext1,whw909` +- [ ] `100032223878` · L 11 / E 17.67 / Δ +6.67 + +### C012 · Σ|Δ| 6.5 · 1 certs · `h191/elec | cavity wall | (another dwelling` +- [ ] `10002272664` · L 79 / E 72.47 / Δ -6.53 + +### C013 · Σ|Δ| 6.5 · 1 certs · `h408/elec | granite or | (another dwelling | sec:portable electric,whw903` +- [ ] `100121397382` · L 69 / E 75.49 / Δ +6.49 + +### C014 · Σ|Δ| 6.5 · 1 certs · `h691/elec | solid brick | (another dwelling | ext1,sec:room heaters,whw903` +- [ ] `100062100640` · L 54 / E 47.51 / Δ -6.49 + +### C015 · Σ|Δ| 6.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 225` +- [ ] `100050844968` · L 71 / E 65.02 / Δ -5.98 + +### C016 · Σ|Δ| 5.8 · 1 certs · `hpcdb17777/gas+2mains | cavity wall | pitched insulated | ext1,sec:room heaters,whw914` +- [ ] `line804` · L 52 / E 57.76 / Δ +5.76 + +### C017 · Σ|Δ| 5.8 · 1 certs · `h408/elec+2mains | sandstone as | (another dwelling | sec:room heaters,whw903` +- [ ] `80838` · L 41 / E 35.25 / Δ -5.75 + +### C018 · Σ|Δ| 4.6 · 1 certs · `hpcdb18560/gas | solid brick | pitched no | RR` +- [ ] `100051233481` · L 65 / E 69.64 / Δ +4.64 + +### C019 · Σ|Δ| 4.5 · 1 certs · `h691/elec | timber frame | pitched limited | RR,ext2,whw903` +- [ ] `100061646773` · L 68 / E 63.46 / Δ -4.54 + +### C020 · Σ|Δ| 4.5 · 1 certs · `hpcdb18786/fuel27 | solid brick | pitched 100 | RR,consv3` +- [ ] `100071010014` · L 55 / E 50.47 / Δ -4.53 + +### C021 · Σ|Δ| 4.5 · 1 certs · `h301/coal-anth | system built | (another dwelling | mv4` +- [ ] `10093342182` · L 82 / E 77.51 / Δ -4.49 + +### C022 · Σ|Δ| 4.4 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2` +- [ ] `217060420` · L 42 / E 37.58 / Δ -4.42 + +### C023 · Σ|Δ| 4.4 · 1 certs · `h402/elec | cavity wall | (another dwelling | sec:room heaters,whw903` +- [ ] `72399971` · L 69 / E 64.60 / Δ -4.40 + +### C024 · Σ|Δ| 4.4 · 1 certs · `hpcdb19258/fuel28 | granite or | pitched no | ext2,sec:room heaters` +- [ ] `10007016314` · L 57 / E 52.64 / Δ -4.36 + +### C025 · Σ|Δ| 4.1 · 1 certs · `h633/heatnet | sandstone with | pitched insulated | sec:room heaters,whw903` +- [ ] `100052159386` · L 56 / E 51.92 / Δ -4.08 + +### C026 · Σ|Δ| 4.0 · 1 certs · `h408/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` +- [ ] `100040767294` · L 43 / E 47.04 / Δ +4.04 + +### C027 · Σ|Δ| 3.6 · 1 certs · `hpcdb15445/gas | granite or | pitched no | RR,ext3,sec:room heaters` +- [ ] `10002188054` · L 68 / E 64.42 / Δ -3.58 + +### C028 · Σ|Δ| 3.5 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | PV,ext2,sec:room heaters` +- [ ] `39066537` · L 78 / E 81.49 / Δ +3.49 + +### C029 · Σ|Δ| 3.5 · 1 certs · `hpcdb8387/gas | cavity wall | pitched 150` +- [ ] `100100137438` · L 69 / E 72.48 / Δ +3.48 + +### C030 · Σ|Δ| 3.4 · 1 certs · `hpcdb17507/gas | cavity wall | pitched insulated | RR,sec:room heaters` +- [ ] `100080122910` · L 60 / E 63.45 / Δ +3.45 + +### C031 · Σ|Δ| 3.3 · 1 certs · `h691/elec | cavity wall | pitched 300 | mv5,sec:portable electric,whw903` +- [ ] `452010022` · L 42 / E 38.67 / Δ -3.33 + +### C032 · Σ|Δ| 3.3 · 1 certs · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` +- [ ] `200004818752` · L 34 / E 30.73 / Δ -3.27 + +### C033 · Σ|Δ| 3.2 · 1 certs · `hpcdb1770/fuel28 | solid brick | pitched no | ext3,sec:room heaters` +- [ ] `200004522639` · L 37 / E 33.77 / Δ -3.23 + +### C034 · Σ|Δ| 3.2 · 1 certs · `hpcdb18759/gas | sandstone as | pitched insulated | RR,ext1,sec:room heaters` +- [ ] `72351021` · L 64 / E 60.85 / Δ -3.15 + +### C035 · Σ|Δ| 3.1 · 1 certs · `h633/heatnet | timber frame | roof room(s) | RR,ext1,sec:room heaters,whw909` +- [ ] `22077224` · L 37 / E 33.90 / Δ -3.10 + +### C036 · Σ|Δ| 3.0 · 1 certs · `hpcdb18498/gas | solid brick | pitched 250 | RR,ext2` +- [ ] `10011740578` · L 70 / E 67.00 / Δ -3.00 + +### C037 · Σ|Δ| 2.9 · 1 certs · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +- [ ] `100110680822` · L 79 / E 76.07 / Δ -2.93 + +### C038 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | solid brick | pitched 250` +- [ ] `452032915` · L 75 / E 72.09 / Δ -2.91 + +### C039 · Σ|Δ| 2.9 · 1 certs · `h301/coal-anth | cavity wall | (another dwelling | whw909` +- [ ] `100071306639` · L 73 / E 70.14 / Δ -2.86 + +### C040 · Σ|Δ| 2.9 · 1 certs · `hpcdb18435/gas+2mains | cavity wall | pitched 100 | ext3,sec:room heaters,whw903` +- [ ] `100061346049` · L 55 / E 52.15 / Δ -2.85 + +### C041 · Σ|Δ| 2.7 · 1 certs · `hpcdb8443/fuel28 | cavity wall | pitched 100 | RR,ext2,sec:room heaters` +- [ ] `10013008238` · L 41 / E 38.26 / Δ -2.74 + +### C042 · Σ|Δ| 2.7 · 3 certs · `h691/elec | cavity wall | (another dwelling | whw903` +- [ ] `10033187652` · L 70 / E 71.21 / Δ +1.21 <- non-electric cost (secondary fuel/cylinder/tariff); spec-faithful vs lodged +- [ ] `200002730` · L 65 / E 64.13 / Δ -0.87 +- [ ] `10023328117` · L 78 / E 78.64 / Δ +0.64 + +### C043 · Σ|Δ| 2.7 · 1 certs · `h633/heatnet | cavity wall | pitched 200 | RR,sec:room heaters,whw903` +- [ ] `10004873253` · L 65 / E 62.29 / Δ -2.71 + +### C044 · Σ|Δ| 2.7 · 1 certs · `h691/elec | cavity wall | (another dwelling | mv1,whw903` +- [ ] `10090793715` · L 73 / E 75.71 / Δ +2.71 + +### C045 · Σ|Δ| 2.7 · 1 certs · `hpcdb17964/gas+2mains | cavity wall | pitched 100 | ext1,sec:room heaters` +- [ ] `100120745600` · L 65 / E 67.69 / Δ +2.69 + +### C046 · Σ|Δ| 2.7 · 1 certs · `hpcdb17757/gas | granite or | pitched no | RR,ext1` +- [ ] `100051178830` · L 63 / E 65.66 / Δ +2.66 + +### C047 · Σ|Δ| 2.6 · 1 certs · `hpcdb10321/gas | sandstone as | pitched 100 | ext2` +- [ ] `100120018282` · L 64 / E 61.36 / Δ -2.64 + +### C048 · Σ|Δ| 2.6 · 1 certs · `hpcdb17968/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +- [ ] `83035979` · L 65 / E 67.60 / Δ +2.60 + +### C049 · Σ|Δ| 2.5 · 1 certs · `h524/elec | solid brick | (another dwelling | consv2,sec:room heaters,whw909` +- [ ] `10014073761` · L 75 / E 72.52 / Δ -2.48 + +### C050 · Σ|Δ| 2.5 · 1 certs · `hpcdb10328/gas | solid brick | pitched insulated | RR` +- [ ] `100050964834` · L 60 / E 62.47 / Δ +2.47 + +### C051 · Σ|Δ| 2.4 · 1 certs · `h694/elec | cavity wall | (another dwelling | whw941` +- [ ] `100120752995` · L 71 / E 73.42 / Δ +2.42 + +### C052 · Σ|Δ| 2.4 · 1 certs · `h691/elec | solid brick | roof room(s) | RR,ext2,sec:room heaters,whw903` +- [ ] `100062174575` · L 46 / E 48.40 / Δ +2.40 + +### C053 · Σ|Δ| 2.3 · 1 certs · `hpcdb15753/gas | solid brick | pitched 150 | RR` +- [ ] `100000034023` · L 73 / E 70.71 / Δ -2.29 + +### C054 · Σ|Δ| 2.2 · 1 certs · `h506/gas | cavity wall | flat limited | sec:room heaters` +- [ ] `100020377671` · L 62 / E 64.23 / Δ +2.23 + +### C055 · Σ|Δ| 2.2 · 1 certs · `h104/gas | solid brick | pitched insulated | RR,ext1` +- [ ] `22027335` · L 76 / E 73.77 / Δ -2.23 + +### C056 · Σ|Δ| 2.1 · 1 certs · `hpcdb18833/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` +- [ ] `48056153` · L 65 / E 62.89 / Δ -2.11 + +### C057 · Σ|Δ| 2.0 · 1 certs · `hpcdb19008/gas | solid brick | pitched insulated | sec:room heaters` +- [ ] `100021924710` · L 63 / E 65.00 / Δ +2.00 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C058 · Σ|Δ| 1.9 · 1 certs · `hpcdb18774/gas | solid brick | pitched 100 | RR,ext1` +- [ ] `100031270375` · L 69 / E 70.93 / Δ +1.93 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C059 · Σ|Δ| 1.9 · 1 certs · `hpcdb106417/elec | cavity wall | pitched 250 | RR,ext2,sec:room heaters` +- [ ] `10001118522` · L 80 / E 78.07 / Δ -1.93 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C060 · Σ|Δ| 1.9 · 1 certs · `h192/elec | cavity wall | (another dwelling` +- [ ] `10010234711` · L 81 / E 79.08 / Δ -1.92 <- electric other (per-cert cost noise) + +### C061 · Σ|Δ| 1.9 · 1 certs · `hpcdb18250/gas | solid brick | pitched 100 | consv2,sec:room heaters` +- [ ] `100031768368` · L 61 / E 59.12 / Δ -1.88 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C062 · Σ|Δ| 1.8 · 1 certs · `h301/elec10hr | cavity wall | (another dwelling` +- [ ] `4510729926` · L 73 / E 71.15 / Δ -1.85 <- electric + fabric/demand mismatch (per-cert; not a coherent cluster) + +### C063 · Σ|Δ| 1.8 · 1 certs · `hpcdb17138/fuel28 | granite or | pitched 200 | ext1,sec:room heaters` +- [ ] `100091329112` · L 49 / E 50.82 / Δ +1.82 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C064 · Σ|Δ| 1.8 · 1 certs · `h691/elec | timber frame | pitched insulated | RR,ext1,sec:portable electric,whw908` +- [ ] `10011797347` · L 47 / E 48.77 / Δ +1.77 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C065 · Σ|Δ| 1.8 · 1 certs · `hpcdb17570/gas+2mains | solid brick | (another dwelling | RR,ext3,sec:room heaters` +- [ ] `100022668387` · L 68 / E 66.25 / Δ -1.75 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C066 · Σ|Δ| 1.7 · 1 certs · `hpcdb10354/gas+2mains | sandstone as | pitched 300 | ext1` +- [ ] `100100892216` · L 69 / E 67.28 / Δ -1.72 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C067 · Σ|Δ| 1.7 · 1 certs · `hpcdb8119/gas | cavity wall | pitched insulated | RR,ext1` +- [ ] `100060878876` · L 49 / E 50.71 / Δ +1.71 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C068 · Σ|Δ| 1.7 · 1 certs · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` +- [ ] `12126160` · L 69 / E 70.71 / Δ +1.71 <- electric + fabric/demand mismatch (per-cert; not a coherent cluster) + +### C069 · Σ|Δ| 1.7 · 1 certs · `h401/elec | solid brick | (another dwelling | sec:portable electric,whw950` +- [ ] `22032926` · L 61 / E 62.71 / Δ +1.71 <- electric + fabric/demand mismatch (per-cert; not a coherent cluster) + +### C070 · Σ|Δ| 1.7 · 1 certs · `hpcdb18560/gas | cavity wall | pitched insulated | RR,ext1` +- [ ] `100010942905` · L 72 / E 73.70 / Δ +1.70 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C071 · Σ|Δ| 1.6 · 1 certs · `hpcdb18119/gas | solid brick | pitched 100 | ext1` +- [ ] `100030307976` · L 71 / E 69.37 / Δ -1.63 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C072 · Σ|Δ| 1.6 · 1 certs · `hpcdb18909/gas | cavity wall | pitched 100 | whw903` +- [ ] `100061404488` · L 70 / E 68.38 / Δ -1.62 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C073 · Σ|Δ| 1.6 · 1 certs · `h402/elec | system built | (another dwelling | sec:room heaters,whw903` +- [ ] `21067296` · L 67 / E 68.60 / Δ +1.60 <- electric + fabric/demand mismatch (per-cert; not a coherent cluster) + +### C074 · Σ|Δ| 1.6 · 1 certs · `hpcdb10164/gas | solid brick | pitched insulated | sec:room heaters` +- [ ] `5870047440` · L 58 / E 59.58 / Δ +1.58 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C075 · Σ|Δ| 1.6 · 1 certs · `hpcdb8051/gas | cavity wall | (same dwelling | ext2` +- [ ] `100070450818` · L 65 / E 63.43 / Δ -1.57 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C076 · Σ|Δ| 1.6 · 1 certs · `hpcdb17741/gas | cavity wall | pitched 225` +- [ ] `100050881708` · L 70 / E 71.55 / Δ +1.55 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C077 · Σ|Δ| 1.5 · 1 certs · `h301/elec | system built | (another dwelling | whw950` +- [ ] `10010254955` · L 79 / E 77.46 / Δ -1.54 <- electric other (per-cert cost noise) + +### C078 · Σ|Δ| 1.5 · 1 certs · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1,mv2,sec:room heaters` +- [ ] `3455011834` · L 69 / E 67.48 / Δ -1.52 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C079 · Σ|Δ| 1.5 · 1 certs · `hpcdb15502/gas | granite or | pitched 150 | RR,ext1,sec:room heaters` +- [ ] `100100274789` · L 60 / E 61.51 / Δ +1.51 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C080 · Σ|Δ| 1.5 · 1 certs · `hpcdb16453/gas | cavity wall | pitched 300 | consv2,ext1` +- [ ] `100050852755` · L 65 / E 66.49 / Δ +1.49 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C081 · Σ|Δ| 1.5 · 1 certs · `hpcdb17679/gas | solid brick | pitched 125 | ext1` +- [ ] `100021326422` · L 70 / E 68.51 / Δ -1.49 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C082 · Σ|Δ| 1.5 · 1 certs · `hpcdb15029/gas | solid brick | pitched insulated | RR,ext1` +- [ ] `100050988345` · L 61 / E 59.51 / Δ -1.49 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C083 · Σ|Δ| 1.5 · 1 certs · `hpcdb17998/gas | solid brick | pitched insulated | RR,consv2` +- [ ] `100030285758` · L 54 / E 55.48 / Δ +1.48 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C084 · Σ|Δ| 1.4 · 1 certs · `hpcdb17978/gas | solid brick | flat no | RR,ext1` +- [ ] `line80` · L 72 / E 70.56 / Δ -1.44 + +### C085 · Σ|Δ| 1.4 · 1 certs · `hpcdb10356/gas | solid brick | pitched 150 | RR,ext1,sec:room heaters` +- [ ] `100080518673` · L 57 / E 58.42 / Δ +1.42 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C086 · Σ|Δ| 1.4 · 1 certs · `hpcdb18561/gas | solid brick | pitched 250 | ext2` +- [ ] `235025284` · L 69 / E 67.59 / Δ -1.41 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C087 · Σ|Δ| 1.4 · 1 certs · `hpcdb18767/gas | sandstone as | (another dwelling` +- [ ] `250063088` · L 73 / E 71.60 / Δ -1.40 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C088 · Σ|Δ| 1.4 · 1 certs · `hpcdb16210/gas | cavity wall | pitched 300 | sec:room heaters` +- [ ] `100110097281` · L 64 / E 65.37 / Δ +1.37 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C089 · Σ|Δ| 1.4 · 1 certs · `h691/elec | solid brick | (another dwelling | whw903` +- [ ] `10091630692` · L 58 / E 56.63 / Δ -1.37 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C090 · Σ|Δ| 1.3 · 1 certs · `hpcdb19227/fuel28 | solid brick | pitched 100 | RR,ext3,sec:room heaters` +- [ ] `100012368622` · L 39 / E 40.32 / Δ +1.32 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C091 · Σ|Δ| 1.3 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +- [ ] `90077194` · L 65 / E 63.69 / Δ -1.31 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C092 · Σ|Δ| 1.3 · 1 certs · `hpcdb19083/gas | cavity wall | pitched 75 | RR,consv2` +- [ ] `100031461986` · L 70 / E 71.29 / Δ +1.29 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C093 · Σ|Δ| 1.3 · 1 certs · `h691/elec | granite or | pitched insulated | PV,ext3,whw903` +- [ ] `30095054` · L 46 / E 44.74 / Δ -1.26 <- non-electric cost (secondary fuel/cylinder/tariff); spec-faithful vs lodged + +### C094 · Σ|Δ| 1.3 · 1 certs · `hpcdb18335/gas | cavity wall | pitched 100 | RR,ext1,sec:room heaters` +- [ ] `100100055589` · L 58 / E 59.26 / Δ +1.26 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C095 · Σ|Δ| 1.2 · 1 certs · `h409/elec | solid brick | (another dwelling | consv2,sec:portable electric,whw909` +- [ ] `74061136` · L 73 / E 71.75 / Δ -1.25 <- electric storage cat7 E7: over-rate = off-peak rate/fraction too generous; needs Elmhurst tariff arbitration + +### C096 · Σ|Δ| 1.2 · 1 certs · `hpcdb15101/gas | cavity wall | pitched 270 | consv3,sec:room heaters` +- [ ] `100091435353` · L 65 / E 66.23 / Δ +1.23 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C097 · Σ|Δ| 1.2 · 2 certs · `h301/coal-anth | system built | (another dwelling` +- [ ] `10091070164` · L 69 / E 69.60 / Δ +0.60 +- [ ] `10090927185` · L 79 / E 79.60 / Δ +0.60 + +### C098 · Σ|Δ| 1.2 · 1 certs · `hpcdb19110/gas | cavity wall | pitched no | ext3` +- [ ] `100100614412` · L 53 / E 51.81 / Δ -1.19 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C099 · Σ|Δ| 1.2 · 1 certs · `hpcdb18658/gas | solid brick | flat no` +- [ ] `217091901` · L 62 / E 60.82 / Δ -1.18 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C100 · Σ|Δ| 1.2 · 1 certs · `hpcdb17115/gas | sandstone as | (another dwelling | ext2,sec:room heaters` +- [x] `line768` · L 57 / E 55.84 / Δ -1.16 + +### C101 · Σ|Δ| 1.2 · 1 certs · `h102/gas | solid brick | (same dwelling | ext1,sec:portable electric` +- [ ] `217061895` · L 61 / E 59.84 / Δ -1.16 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C102 · Σ|Δ| 1.1 · 1 certs · `hpcdb15708/gas | cavity wall | pitched insulated | RR,sec:room heaters` +- [ ] `10002349227` · L 76 / E 77.14 / Δ +1.14 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C103 · Σ|Δ| 1.1 · 1 certs · `hpcdb15451/gas | timber frame | pitched insulated | RR,ext1,sec:room heaters` +- [ ] `200001634005` · L 66 / E 67.11 / Δ +1.11 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C104 · Σ|Δ| 1.1 · 1 certs · `hpcdb16407/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [ ] `100071059081` · L 63 / E 64.09 / Δ +1.09 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C105 · Σ|Δ| 1.1 · 1 certs · `hpcdb17973/gas | solid brick | (another dwelling` +- [ ] `5117280` · L 76 / E 77.08 / Δ +1.08 <- 🔧 thin-internal-insulation bucket-0 fix: present insulation + known <25mm thickness was mapped to uninsulated (U 1.7); now routes to 50mm row like unknown-thickness. Δ-4.44 -> +1.08. + +### C106 · Σ|Δ| 1.1 · 1 certs · `hpcdb19007/gas+2mains | cavity wall | pitched 350 | ext2,mv5,sec:room heaters,whw914` +- [ ] `100011820199` · L 55 / E 56.06 / Δ +1.06 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C107 · Σ|Δ| 1.1 · 1 certs · `h691/elec | system built | (another dwelling | whw903` +- [ ] `90214753` · L 83 / E 81.95 / Δ -1.05 <- non-electric cost (secondary fuel/cylinder/tariff); spec-faithful vs lodged + +### C108 · Σ|Δ| 1.0 · 1 certs · `h102/gas | cavity wall | pitched insulated | consv2` +- [ ] `100051051866` · L 70 / E 71.04 / Δ +1.04 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C109 · Σ|Δ| 1.0 · 1 certs · `hpcdb18737/gas | cavity wall | pitched insulated | PV,sec:room heaters` +- [ ] `10013836852` · L 100 / E 98.97 / Δ -1.03 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C110 · Σ|Δ| 1.0 · 1 certs · `hpcdb17985/gas | solid brick | (another dwelling` +- [ ] `line899` · L 73 / E 71.97 / Δ -1.03 + +### C111 · Σ|Δ| 1.0 · 1 certs · `hpcdb18524/gas+2mains | cavity wall | pitched 400+ | ext4` +- [ ] `40037847` · L 81 / E 79.98 / Δ -1.02 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C112 · Σ|Δ| 1.0 · 1 certs · `hpcdb19012/gas | cavity wall | pitched insulated` +- [ ] `10070056075` · L 80 / E 78.99 / Δ -1.01 <- non-electric fabric/demand: per-cert lodged-geometry noise (field_bias scan clean, no coherent subgroup) + +### C113 · Σ|Δ| 1.0 · 1 certs · `hpcdb16843/gas+2mains | cavity wall | pitched insulated | PV,RR,ext2` +- [ ] `200131078` · L 86 / E 85.00 / Δ -1.00 <- room-in-roof surface geometry (spec-mandated, worksheet-validated; see PRs #1440/#1441) + +### C114 · Σ|Δ| 1.0 · 1 certs · `hpcdb17489/gas | cavity wall | pitched 270 | PV,consv2,ext1,sec:room heaters` +- [ ] `10000245212` · L 101 / E 100.00 / Δ -1.00 <- non-electric cost (secondary fuel/cylinder/tariff); spec-faithful vs lodged + +### C115 · Σ|Δ| 1.0 · 1 certs · `h191/elec | solid brick | (another dwelling | ext2,whw909` +- [ ] `15129162` · L 62 / E 61.00 / Δ -1.00 + +### C116 · Σ|Δ| 1.0 · 1 certs · `h301/coal-anth | cavity wall | pitched 270` +- [ ] `23032873` · L 73 / E 72.00 / Δ -1.00 + +### C117 · Σ|Δ| 1.0 · 1 certs · `hpcdb16930/gas | cavity wall | pitched unknown | RR,ext1,sec:room heaters` +- [ ] `45019020` · L 62 / E 61.01 / Δ -0.99 + +### C118 · Σ|Δ| 1.0 · 1 certs · `hpcdb17939/gas | solid brick | (another dwelling` +- [ ] `42065028` · L 59 / E 58.02 / Δ -0.98 + +### C119 · Σ|Δ| 1.0 · 1 certs · `hpcdb10071/gas | cavity wall | pitched 150 | RR` +- [ ] `10032928147` · L 77 / E 76.04 / Δ -0.96 + +### C120 · Σ|Δ| 1.0 · 1 certs · `hpcdb17045/gas | cavity wall | pitched 300` +- [ ] `10010678937` · L 78 / E 77.04 / Δ -0.96 + +### C121 · Σ|Δ| 1.0 · 1 certs · `hpcdb15247/gas | cavity wall | pitched insulated | RR` +- [ ] `100011010151` · L 62 / E 62.96 / Δ +0.96 + +### C122 · Σ|Δ| 1.0 · 1 certs · `hpcdb16406/gas | solid brick | pitched insulated | RR,consv2,ext2,sec:room heaters` +- [ ] `100050477371` · L 65 / E 64.04 / Δ -0.96 + +### C123 · Σ|Δ| 0.9 · 1 certs · `hpcdb17529/fuel28 | cavity wall | pitched insulated | RR,ext2,sec:room heaters` +- [ ] `10002945522` · L 61 / E 61.94 / Δ +0.94 + +### C124 · Σ|Δ| 0.9 · 1 certs · `h691/elec+2mains | cob as | pitched 300 | whw903` +- [ ] `10032957680` · L 45 / E 45.94 / Δ +0.94 + +### C125 · Σ|Δ| 0.9 · 1 certs · `hpcdb18204/gas | solid brick | pitched 400+ | PV,ext2` +- [ ] `2465057465` · L 81 / E 81.93 / Δ +0.93 + +### C126 · Σ|Δ| 0.9 · 1 certs · `hpcdb19019/gas | solid brick | pitched 100 | ext3,sec:room heaters` +- [ ] `100090616327` · L 63 / E 63.93 / Δ +0.93 + +### C127 · Σ|Δ| 0.9 · 1 certs · `hpcdb17612/gas | cavity wall | pitched 270 | ext1` +- [ ] `100012753833` · L 74 / E 73.07 / Δ -0.93 + +### C128 · Σ|Δ| 0.9 · 1 certs · `hpcdb19006/gas | solid brick | pitched 75 | ext1,sec:room heaters` +- [ ] `100031269525` · L 53 / E 53.91 / Δ +0.91 + +### C129 · Σ|Δ| 0.9 · 1 certs · `hpcdb17964/gas | cavity wall | pitched insulated | consv3` +- [ ] `200003725358` · L 75 / E 74.09 / Δ -0.91 + +### C130 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | solid brick | pitched insulated | RR,ext3` +- [ ] `100050986162` · L 62 / E 61.10 / Δ -0.90 + +### C131 · Σ|Δ| 0.9 · 1 certs · `hpcdb17985/gas | cavity wall | (another dwelling | mv2` +- [ ] `5300000141` · L 78 / E 77.10 / Δ -0.90 + +### C132 · Σ|Δ| 0.9 · 1 certs · `hpcdb18616/gas | cavity wall | pitched 250 | sec:room heaters` +- [ ] `100050618404` · L 73 / E 73.89 / Δ +0.89 + +### C133 · Σ|Δ| 0.9 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 250 | PV,ext1` +- [ ] `100090476016` · L 81 / E 81.89 / Δ +0.89 + +### C134 · Σ|Δ| 0.9 · 1 certs · `h691/elec | timber frame | pitched 200 | RR,ext3,whw903` +- [ ] `10012119141` · L 45 / E 45.89 / Δ +0.89 + +### C135 · Σ|Δ| 0.9 · 1 certs · `h524/elec | cavity wall | pitched 300 | PV` +- [ ] `100040938206` · L 75 / E 75.89 / Δ +0.89 + +### C136 · Σ|Δ| 0.9 · 1 certs · `hpcdb18234/gas | cavity wall | pitched insulated | RR,consv2` +- [ ] `38188474` · L 76 / E 76.87 / Δ +0.87 + +### C137 · Σ|Δ| 0.9 · 1 certs · `hpcdb16777/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +- [ ] `100061194957` · L 69 / E 69.87 / Δ +0.87 + +### C138 · Σ|Δ| 0.9 · 1 certs · `hpcdb18559/gas+2mains | solid brick | pitched 200 | whw914` +- [ ] `100021236527` · L 72 / E 71.13 / Δ -0.87 + +### C139 · Σ|Δ| 0.9 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 270 | consv2` +- [ ] `100040193752` · L 71 / E 71.86 / Δ +0.86 + +### C140 · Σ|Δ| 0.9 · 1 certs · `hpcdb10327/gas | cavity wall | (another dwelling` +- [ ] `100060701552` · L 74 / E 74.86 / Δ +0.86 + +### C141 · Σ|Δ| 0.9 · 1 certs · `h691/elec | system built | flat insulated | whw903` +- [ ] `10070396146` · L 61 / E 60.14 / Δ -0.86 + +### C142 · Σ|Δ| 0.8 · 1 certs · `hpcdb8587/gas | cavity wall | (another dwelling` +- [ ] `100030528930` · L 74 / E 73.16 / Δ -0.84 + +### C143 · Σ|Δ| 0.8 · 1 certs · `hpcdb18212/gas | solid brick | (another dwelling` +- [ ] `100020982570` · L 72 / E 71.17 / Δ -0.83 + +### C144 · Σ|Δ| 0.8 · 1 certs · `hpcdb16888/gas | cavity wall | pitched 350 | consv2` +- [ ] `394024487` · L 75 / E 74.17 / Δ -0.83 + +### C145 · Σ|Δ| 0.8 · 1 certs · `hpcdb17503/gas | solid brick | pitched insulated | RR,ext1,mv4` +- [ ] `217070698` · L 78 / E 78.83 / Δ +0.83 + +### C146 · Σ|Δ| 0.8 · 1 certs · `hpcdb15709/gas | cavity wall | (another dwelling | ext1` +- [ ] `77022508` · L 69 / E 68.18 / Δ -0.82 + +### C147 · Σ|Δ| 0.8 · 1 certs · `hpcdb18496/gas | cavity wall | pitched 250 | RR,consv4` +- [ ] `100040259104` · L 68 / E 68.82 / Δ +0.82 + +### C148 · Σ|Δ| 0.8 · 1 certs · `hpcdb18559/gas | solid brick | pitched 270 | ext1` +- [ ] `100031399026` · L 70 / E 70.81 / Δ +0.81 + +### C149 · Σ|Δ| 0.8 · 1 certs · `hpcdb16374/gas | cavity wall | pitched unknown` +- [ ] `10009645698` · L 67 / E 67.81 / Δ +0.81 + +### C150 · Σ|Δ| 0.8 · 1 certs · `hpcdb16395/gas | timber frame | thatched with | ext1,sec:room heaters` +- [ ] `100080818887` · L 56 / E 55.19 / Δ -0.81 + +### C151 · Σ|Δ| 0.8 · 1 certs · `hpcdb16835/gas | solid brick | pitched insulated | RR,ext1` +- [ ] `100012374381` · L 69 / E 69.80 / Δ +0.80 + +### C152 · Σ|Δ| 0.8 · 1 certs · `hpcdb17560/gas | cavity wall | pitched 250 | ext2` +- [ ] `100012350270` · L 78 / E 77.20 / Δ -0.80 + +### C153 · Σ|Δ| 0.8 · 1 certs · `hpcdb15166/gas+2mains | sandstone as | pitched no | PV,ext4,sec:room heaters,whw914` +- [ ] `100051109723` · L 60 / E 60.78 / Δ +0.78 + +### C154 · Σ|Δ| 0.8 · 1 certs · `hpcdb18911/gas | cavity wall | pitched 50 | consv4` +- [ ] `100061616915` · L 63 / E 62.22 / Δ -0.78 + +### C155 · Σ|Δ| 0.8 · 1 certs · `h691/elec | cavity wall | pitched 200 | whw903` +- [ ] `line71` · L 74 / E 74.77 / Δ +0.77 + +### C156 · Σ|Δ| 0.8 · 1 certs · `hpcdb17986/gas | cavity wall | (another dwelling` +- [ ] `100011603934` · L 72 / E 71.23 / Δ -0.77 + +### C157 · Σ|Δ| 0.8 · 1 certs · `hpcdb10244/gas | cavity wall | pitched 100` +- [ ] `24030987` · L 73 / E 73.76 / Δ +0.76 + +### C158 · Σ|Δ| 0.8 · 1 certs · `h193/elec | solid brick | (another dwelling | whw909` +- [ ] `100032043038` · L 74 / E 73.24 / Δ -0.76 + +### C159 · Σ|Δ| 0.8 · 1 certs · `hpcdb17513/gas | cavity wall | pitched unknown` +- [ ] `100010866608` · L 71 / E 70.24 / Δ -0.76 + +### C160 · Σ|Δ| 0.7 · 1 certs · `hpcdb17965/gas | cavity wall | pitched insulated | RR,ext1,sec:room heaters` +- [ ] `100090399615` · L 67 / E 67.75 / Δ +0.75 + +### C161 · Σ|Δ| 0.7 · 1 certs · `hpcdb16137/gas | solid brick | pitched 150` +- [ ] `200004296092` · L 71 / E 71.74 / Δ +0.74 + +### C162 · Σ|Δ| 0.7 · 1 certs · `hpcdb17576/gas | cavity wall | pitched insulated | RR,consv2` +- [ ] `10012341135` · L 79 / E 79.73 / Δ +0.73 + +### C163 · Σ|Δ| 0.7 · 1 certs · `h409/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +- [ ] `100091005853` · L 70 / E 69.27 / Δ -0.73 + +### C164 · Σ|Δ| 0.7 · 1 certs · `hpcdb18908/gas | cavity wall | pitched 175` +- [ ] `100021533514` · L 71 / E 71.73 / Δ +0.73 + +### C165 · Σ|Δ| 0.7 · 1 certs · `h301/coal-anth | solid brick | (another dwelling` +- [ ] `5062075` · L 69 / E 69.72 / Δ +0.72 + +### C166 · Σ|Δ| 0.7 · 1 certs · `hpcdb18112/gas | cavity wall | pitched 100 | RR,ext1` +- [ ] `100040813308` · L 62 / E 62.72 / Δ +0.72 + +### C167 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched unknown | ext2` +- [ ] `38105600` · L 68 / E 67.28 / Δ -0.72 + +### C168 · Σ|Δ| 0.7 · 1 certs · `h104/gas | solid brick | pitched 200` +- [ ] `line255` · L 72 / E 71.29 / Δ -0.71 + +### C169 · Σ|Δ| 0.7 · 1 certs · `h304/elec | cavity wall | (another dwelling | whw950` +- [ ] `5300047580` · L 69 / E 68.30 / Δ -0.70 + +### C170 · Σ|Δ| 0.7 · 1 certs · `h104/gas | cavity wall | pitched 250 | ext1` +- [ ] `100110433403` · L 69 / E 68.32 / Δ -0.68 + +### C171 · Σ|Δ| 0.7 · 1 certs · `hpcdb16835/gas | cavity wall | pitched insulated` +- [ ] `10093416558` · L 79 / E 78.32 / Δ -0.68 + +### C172 · Σ|Δ| 0.7 · 1 certs · `hpcdb18251/gas | solid brick | pitched 100` +- [ ] `100050958217` · L 68 / E 68.68 / Δ +0.68 + +### C173 · Σ|Δ| 0.7 · 1 certs · `hpcdb18224/gas | solid brick | pitched 225 | ext1` +- [ ] `100022667797` · L 68 / E 67.32 / Δ -0.68 + +### C174 · Σ|Δ| 0.7 · 1 certs · `hpcdb10243/gas | cavity wall | pitched insulated | RR,sec:room heaters` +- [ ] `100030528925` · L 78 / E 78.65 / Δ +0.65 + +### C175 · Σ|Δ| 0.6 · 1 certs · `hpcdb17657/gas | cavity wall | (another dwelling` +- [ ] `100110300037` · L 74 / E 73.35 / Δ -0.65 + +### C176 · Σ|Δ| 0.6 · 1 certs · `hpcdb2044/gas | solid brick | (another dwelling | ext1` +- [ ] `217092450` · L 52 / E 52.64 / Δ +0.64 + +### C177 · Σ|Δ| 0.6 · 1 certs · `hpcdb15101/gas | solid brick | pitched 300` +- [ ] `100061164545` · L 72 / E 71.36 / Δ -0.64 + +### C178 · Σ|Δ| 0.6 · 1 certs · `hpcdb10328/gas | cavity wall | pitched unknown` +- [ ] `100051075936` · L 71 / E 70.36 / Δ -0.64 + +### C179 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | cavity wall | roof room(s) | RR,sec:room heaters` +- [ ] `100011565830` · L 72 / E 72.64 / Δ +0.64 + +### C180 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | sandstone with | pitched 100 | RR,sec:room heaters` +- [ ] `61010956` · L 75 / E 74.37 / Δ -0.63 + +### C181 · Σ|Δ| 0.6 · 1 certs · `hpcdb17115/gas+2mains | cavity wall | pitched insulated | RR,ext4,sec:room heaters` +- [ ] `100110752514` · L 67 / E 67.62 / Δ +0.62 + +### C182 · Σ|Δ| 0.6 · 1 certs · `h404/elec | cavity wall | pitched 175 | sec:room heaters,whw909` +- [ ] `100070295212` · L 75 / E 74.38 / Δ -0.62 + +### C183 · Σ|Δ| 0.6 · 1 certs · `hpcdb18766/gas+2mains | sandstone as | pitched 100 | RR` +- [ ] `100012534027` · L 65 / E 64.38 / Δ -0.62 + +### C184 · Σ|Δ| 0.6 · 1 certs · `hpcdb9058/fuel28 | solid brick | pitched 100 | RR,ext2,sec:room heaters` +- [x] `10009812472` · L 40 / E 39.40 / Δ -0.60 + +### C185 · Σ|Δ| 0.6 · 1 certs · `hpcdb18218/gas | solid brick | (another dwelling` +- [ ] `34080035` · L 77 / E 76.41 / Δ -0.59 + +### C186 · Σ|Δ| 0.6 · 1 certs · `hpcdb16137/gas | cavity wall | pitched 150 | RR,ext1` +- [ ] `21032732` · L 69 / E 69.59 / Δ +0.59 + +### C187 · Σ|Δ| 0.6 · 1 certs · `h101/gas | cavity wall | pitched 100 | RR,ext1` +- [ ] `100060562056` · L 66 / E 65.41 / Δ -0.59 + +### C188 · Σ|Δ| 0.6 · 1 certs · `hpcdb17514/fuel27 | cavity wall | pitched 400+ | PV,ext2` +- [ ] `100091086558` · L 79 / E 79.58 / Δ +0.58 + +### C189 · Σ|Δ| 0.6 · 1 certs · `hpcdb18908/gas | solid brick | (another dwelling` +- [ ] `line599` · L 74 / E 73.42 / Δ -0.58 + +### C190 · Σ|Δ| 0.6 · 1 certs · `hpcdb17973/gas | cavity wall | pitched insulated` +- [ ] `100020407741` · L 72 / E 71.42 / Δ -0.58 + +### C191 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | cavity wall | pitched 200 | consv2,ext1,sec:room heaters` +- [ ] `100050839457` · L 70 / E 70.57 / Δ +0.57 + +### C192 · Σ|Δ| 0.6 · 1 certs · `hpcdb19007/gas | solid brick | pitched insulated | RR,sec:room heaters` +- [ ] `42105250` · L 59 / E 59.57 / Δ +0.57 + +### C193 · Σ|Δ| 0.6 · 1 certs · `hpcdb1917/gas | timber frame | pitched insulated` +- [ ] `77200509` · L 69 / E 69.57 / Δ +0.57 + +### C194 · Σ|Δ| 0.6 · 1 certs · `hpcdb10356/gas | cavity wall | pitched insulated | ext2` +- [ ] `200040534` · L 65 / E 65.56 / Δ +0.56 + +### C195 · Σ|Δ| 0.6 · 1 certs · `hpcdb17507/gas | solid brick | pitched 150 | ext1,mv2` +- [ ] `200049463` · L 69 / E 69.56 / Δ +0.56 + +### C196 · Σ|Δ| 0.6 · 1 certs · `h126/fuel28+2mains | cavity wall | pitched 300 | RR,consv2,ext3,sec:room heaters` +- [ ] `100062527568` · L 61 / E 61.56 / Δ +0.56 + +### C197 · Σ|Δ| 0.6 · 1 certs · `hpcdb15700/gas | cavity wall | pitched limited | RR,ext1` +- [ ] `100100268900` · L 69 / E 69.56 / Δ +0.56 + +### C198 · Σ|Δ| 0.6 · 1 certs · `hpcdb17004/fuel27+2mains | sandstone as | pitched no | ext3,sec:room heaters` +- [x] `200003110548` · L 29 / E 28.45 / Δ -0.55 + +### C199 · Σ|Δ| 0.5 · 1 certs · `hpcdb9464/gas | cavity wall | pitched 150 | ext1` +- [ ] `90036914` · L 60 / E 60.55 / Δ +0.55 + +### C200 · Σ|Δ| 0.5 · 1 certs · `h409/elec | cavity wall | pitched 250 | mv5,sec:room heaters,whw903` +- [ ] `10004742671` · L 70 / E 69.46 / Δ -0.54 + +### C201 · Σ|Δ| 0.5 · 1 certs · `hpcdb18251/gas | cavity wall | roof room(s) | RR` +- [ ] `100010657450` · L 75 / E 75.54 / Δ +0.54 + +### C202 · Σ|Δ| 0.5 · 1 certs · `hpcdb17507/gas | cavity wall | pitched 150 | ext1` +- [ ] `100061834344` · L 71 / E 70.46 / Δ -0.54 + +### C203 · Σ|Δ| 0.5 · 1 certs · `h113/gas | cavity wall | pitched 200` +- [ ] `4510097194` · L 70 / E 70.53 / Δ +0.53 + +### C204 · Σ|Δ| 0.5 · 1 certs · `hpcdb18907/gas | cavity wall | pitched 125 | ext1` +- [ ] `100010913220` · L 72 / E 72.53 / Δ +0.53 + +### C205 · Σ|Δ| 0.5 · 1 certs · `hpcdb18908/gas | solid brick | pitched 300` +- [ ] `207032630` · L 74 / E 73.47 / Δ -0.53 + +### C206 · Σ|Δ| 0.5 · 1 certs · `hpcdb18242/gas | sandstone as | pitched 150 | ext2,sec:room heaters` +- [ ] `43074051` · L 63 / E 62.48 / Δ -0.52 + +### C207 · Σ|Δ| 0.5 · 1 certs · `h104/gas | cavity wall | pitched 300` +- [ ] `100010723814` · L 69 / E 69.52 / Δ +0.52 + +### C208 · Σ|Δ| 0.5 · 1 certs · `hpcdb16137/gas | cavity wall | (another dwelling` +- [ ] `100020955792` · L 77 / E 77.52 / Δ +0.52 + +### C209 · Σ|Δ| 0.5 · 1 certs · `hpcdb19079/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +- [ ] `77172223` · L 65 / E 65.52 / Δ +0.52 + +### C210 · Σ|Δ| 0.5 · 1 certs · `hpcdb10242/gas | granite or | pitched insulated | RR,sec:room heaters` +- [ ] `100051245439` · L 62 / E 61.48 / Δ -0.52 + +### C211 · Σ|Δ| 0.5 · 1 certs · `hpcdb10328/gas | cavity wall | (another dwelling` +- [ ] `100012553958` · L 67 / E 66.48 / Δ -0.52 + +### C212 · Σ|Δ| 0.5 · 1 certs · `hpcdb10033/gas | cavity wall | pitched 200 | ext2,sec:room heaters` +- [ ] `100110108632` · L 63 / E 63.51 / Δ +0.51 + +### C213 · Σ|Δ| 0.5 · 1 certs · `h109/gas | cavity wall | pitched 270 | consv2,ext1,sec:room heaters` +- [ ] `100091102581` · L 65 / E 65.51 / Δ +0.51 + +### C214 · Σ|Δ| 0.5 · 1 certs · `hpcdb19008/gas | cavity wall | pitched 150 | ext1,sec:room heaters` +- [ ] `10002326688` · L 69 / E 68.50 / Δ -0.50 + +### C215 · Σ|Δ| 0.5 · 1 certs · `h129/fuel28 | granite or | pitched 200 | ext2,sec:room heaters` +- [ ] `10023132869` · L 46 / E 45.50 / Δ -0.50 + +### C216 · Σ|Δ| 0.5 · 1 certs · `hpcdb9007/fuel28 | sandstone as | pitched insulated | RR,ext4,sec:room heaters` +- [ ] `10091707271` · L 41 / E 41.50 / Δ +0.50 + +## Resolved ≤0.5 (778 certs — no action) + +
expand + +- [x] `100090733462` · L 67 / E 67.50 / Δ +0.50 · `hpcdb17974/gas | solid brick | pitched insulated | ext1` +- [x] `100050567367` · L 64 / E 64.50 / Δ +0.50 · `hpcdb19020/gas | solid brick | pitched insulated | RR,sec:room heaters` +- [x] `10034815294` · L 78 / E 77.51 / Δ -0.49 · `hpcdb18559/gas | timber frame | pitched 125` +- [x] `100110206000` · L 57 / E 56.51 / Δ -0.49 · `h111/gas | cavity wall | pitched 175 | ext1,sec:room heaters` +- [x] `100090478973` · L 86 / E 86.49 / Δ +0.49 · `hpcdb18907/gas | cavity wall | pitched 150 | PV` +- [x] `217039192` · L 70 / E 69.51 / Δ -0.49 · `hpcdb17975/gas | solid brick | (another dwelling | mv4` +- [x] `100050839462` · L 69 / E 68.51 / Δ -0.49 · `hpcdb19007/gas | cavity wall | pitched 150 | ext1` +- [x] `100021753513` · L 77 / E 76.51 / Δ -0.49 · `hpcdb17511/gas | cavity wall | pitched insulated` +- [x] `100010402433` · L 70 / E 70.49 / Δ +0.49 · `hpcdb15705/gas | cavity wall | pitched insulated | PV,RR` +- [x] `100031059396` · L 75 / E 74.51 / Δ -0.49 · `hpcdb17982/gas | cavity wall | (another dwelling` +- [x] `100040387235` · L 72 / E 71.51 / Δ -0.49 · `hpcdb18907/gas | sandstone as | pitched insulated | ext1,sec:room heaters` +- [x] `100121020262` · L 63 / E 63.49 / Δ +0.49 · `hpcdb18432/gas | cavity wall | pitched insulated | sec:room heaters` +- [x] `100060596060` · L 68 / E 68.49 / Δ +0.49 · `hpcdb4048/gas | cavity wall | pitched 150 | ext1` +- [x] `100110101713` · L 73 / E 72.51 / Δ -0.49 · `hpcdb100061/elec | cavity wall | (another dwelling | PV` +- [x] `100052163521` · L 73 / E 72.51 / Δ -0.49 · `h104/gas | cavity wall | pitched 300` +- [x] `202030317` · L 74 / E 74.49 / Δ +0.49 · `hpcdb18820/gas | solid brick | (another dwelling` +- [x] `10022829122` · L 82 / E 82.49 / Δ +0.49 · `hpcdb104568/elec | cavity wall | (another dwelling` +- [x] `10034812814` · L 65 / E 65.49 / Δ +0.49 · `hpcdb17978/gas | solid brick | pitched 200 | ext1,sec:room heaters` +- [x] `72103702` · L 70 / E 70.48 / Δ +0.48 · `hpcdb18759/gas | sandstone as | pitched insulated | sec:room heaters` +- [x] `100091572782` · L 74 / E 74.48 / Δ +0.48 · `hpcdb19168/gas | cavity wall | pitched 100 | ext1` +- [x] `28012066` · L 71 / E 71.48 / Δ +0.48 · `hpcdb16212/gas | cavity wall | pitched 400+` +- [x] `74057326` · L 73 / E 72.52 / Δ -0.48 · `h691/elec | solid brick | pitched 270 | whw909` +- [x] `34087745` · L 68 / E 67.52 / Δ -0.48 · `hpcdb10243/gas | solid brick | (another dwelling | ext1` +- [x] `33042105` · L 54 / E 54.48 / Δ +0.48 · `h691/elec | cavity wall | pitched 100 | whw903` +- [x] `100040286465` · L 65 / E 64.52 / Δ -0.48 · `hpcdb16210/gas | cavity wall | pitched 175 | ext2,sec:room heaters` +- [x] `10034663764` · L 74 / E 74.48 / Δ +0.48 · `h104/gas | cavity wall | pitched 350 | ext1` +- [x] `100060858571` · L 67 / E 66.52 / Δ -0.48 · `h104/gas | cavity wall | pitched 100` +- [x] `100090444184` · L 69 / E 68.52 / Δ -0.48 · `hpcdb15032/gas | solid brick | pitched 270 | RR,ext1` +- [x] `100110139702` · L 69 / E 68.52 / Δ -0.48 · `hpcdb18684/gas | cavity wall | pitched 200 | consv2,sec:room heaters` +- [x] `100070365977` · L 78 / E 77.52 / Δ -0.48 · `hpcdb19001/gas | solid brick | pitched 400+ | PV` +- [x] `100080323739` · L 67 / E 67.48 / Δ +0.48 · `hpcdb10327/gas | cavity wall | pitched 150` +- [x] `100100840201` · L 60 / E 60.48 / Δ +0.48 · `hpcdb10244/gas | granite or | pitched 100 | ext1` +- [x] `100071135609` · L 68 / E 68.48 / Δ +0.48 · `hpcdb18229/gas | solid brick | pitched 200 | ext2` +- [x] `100121043224` · L 77 / E 77.48 / Δ +0.48 · `hpcdb1758/gas | cavity wall | pitched 300` +- [x] `30025401` · L 70 / E 69.52 / Δ -0.48 · `hpcdb18433/gas | cavity wall | pitched 270 | ext2` +- [x] `100021037247` · L 71 / E 70.52 / Δ -0.48 · `hpcdb10112/gas | solid brick | (another dwelling` +- [x] `10013778285` · L 80 / E 79.52 / Δ -0.48 · `hpcdb16138/gas | cavity wall | (another dwelling` +- [x] `100010348502` · L 76 / E 75.52 / Δ -0.48 · `hpcdb16839/gas | cavity wall | pitched 175` +- [x] `100040227808` · L 58 / E 58.48 / Δ +0.48 · `hpcdb15502/gas | solid brick | pitched 270 | sec:room heaters` +- [x] `100050355518` · L 36 / E 35.53 / Δ -0.47 · `h117/gas | cavity wall | pitched 200 | ext2,sec:room heaters` +- [x] `100051118081` · L 73 / E 73.47 / Δ +0.47 · `hpcdb18907/gas | cavity wall | pitched 300 | PV` +- [x] `100110190943` · L 67 / E 66.53 / Δ -0.47 · `hpcdb16777/gas | cavity wall | pitched 200` +- [x] `545523` · L 59 / E 59.47 / Δ +0.47 · `hpcdb16840/gas | cavity wall | pitched 100` +- [x] `100091241575` · L 70 / E 69.53 / Δ -0.47 · `hpcdb18908/gas | cavity wall | (another dwelling | mv2` +- [x] `100091265662` · L 63 / E 63.47 / Δ +0.47 · `h104/gas | cavity wall | pitched no` +- [x] `32066846` · L 59 / E 59.47 / Δ +0.47 · `hpcdb17507/gas | solid brick | pitched insulated | ext2,sec:room heaters` +- [x] `100030896498` · L 51 / E 51.47 / Δ +0.47 · `hpcdb10244/gas | solid brick | pitched no | ext1,sec:room heaters` +- [x] `100120636023` · L 72 / E 71.53 / Δ -0.47 · `hpcdb19009/gas | cavity wall | pitched 200` +- [x] `2465112185` · L 73 / E 73.47 / Δ +0.47 · `hpcdb18511/gas | cavity wall | pitched 270` +- [x] `200000569282` · L 69 / E 69.47 / Δ +0.47 · `hpcdb19076/gas | cavity wall | (another dwelling` +- [x] `10008075105` · L 77 / E 76.53 / Δ -0.47 · `hpcdb16810/gas | cavity wall | pitched 270` +- [x] `100010677806` · L 70 / E 70.47 / Δ +0.47 · `hpcdb10354/gas | cavity wall | pitched 150 | RR,ext1,sec:room heaters` +- [x] `100100607883` · L 67 / E 67.46 / Δ +0.46 · `hpcdb17679/gas | cavity wall | pitched 250` +- [x] `40032301` · L 72 / E 72.46 / Δ +0.46 · `hpcdb18234/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `21035507` · L 72 / E 71.54 / Δ -0.46 · `hpcdb16137/gas | cavity wall | (another dwelling` +- [x] `100071073344` · L 73 / E 73.46 / Δ +0.46 · `hpcdb10244/gas | cavity wall | (another dwelling | sec:room heaters` +- [x] `100091287350` · L 67 / E 67.46 / Δ +0.46 · `hpcdb17507/gas | solid brick | pitched insulated` +- [x] `10023324935` · L 72 / E 72.46 / Δ +0.46 · `h104/gas | cavity wall | pitched insulated` +- [x] `1775072187` · L 70 / E 69.54 / Δ -0.46 · `hpcdb15273/gas | timber frame | flat limited` +- [x] `5870069932` · L 73 / E 72.54 / Δ -0.46 · `hpcdb17483/gas | cavity wall | pitched insulated | PV` +- [x] `10033057673` · L 77 / E 76.54 / Δ -0.46 · `hpcdb18204/gas | cavity wall | pitched 250` +- [x] `42027366` · L 73 / E 72.54 / Δ -0.46 · `hpcdb10446/gas | cavity wall | pitched 150 | PV,sec:room heaters` +- [x] `100031607789` · L 75 / E 75.46 / Δ +0.46 · `hpcdb10457/gas | system built | pitched 250 | ext1` +- [x] `100061423798` · L 75 / E 74.54 / Δ -0.46 · `hpcdb18820/gas | cavity wall | pitched 100` +- [x] `100110090714` · L 71 / E 71.46 / Δ +0.46 · `hpcdb8587/gas | cavity wall | pitched 175` +- [x] `1775121297` · L 79 / E 78.55 / Δ -0.45 · `hpcdb16400/gas | cavity wall | pitched 300 | PV` +- [x] `100070304824` · L 76 / E 76.45 / Δ +0.45 · `hpcdb18119/gas | cavity wall | pitched insulated` +- [x] `41229335` · L 76 / E 75.55 / Δ -0.45 · `hpcdb16839/gas | cavity wall | pitched 200` +- [x] `200000571972` · L 64 / E 63.55 / Δ -0.45 · `hpcdb17986/gas | solid brick | pitched 250 | ext1` +- [x] `600039` · L 71 / E 70.55 / Δ -0.45 · `h104/gas | cavity wall | pitched 200` +- [x] `100050635265` · L 68 / E 67.55 / Δ -0.45 · `hpcdb17956/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `100040685184` · L 59 / E 59.45 / Δ +0.45 · `hpcdb18432/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `100070537862` · L 97 / E 96.55 / Δ -0.45 · `hpcdb10244/gas | cavity wall | pitched 400+ | PV,sec:room heaters` +- [x] `100100607333` · L 65 / E 64.55 / Δ -0.45 · `hpcdb15752/gas | granite or | pitched 175 | ext1` +- [x] `100090385996` · L 90 / E 90.45 / Δ +0.45 · `h409/elec | solid brick | pitched 270 | PV,mv2,sec:room heaters,whw903` +- [x] `200051823` · L 83 / E 82.55 / Δ -0.45 · `hpcdb17505/gas | cavity wall | (another dwelling` +- [x] `100040647307` · L 67 / E 66.55 / Δ -0.45 · `hpcdb10326/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `10091709997` · L 80 / E 79.55 / Δ -0.45 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `422000130066` · L 77 / E 77.45 / Δ +0.45 · `hpcdb18225/gas | cavity wall | pitched 200` +- [x] `200004196713` · L 69 / E 68.55 / Δ -0.45 · `hpcdb19083/gas | cavity wall | pitched 200 | ext1` +- [x] `100020988934` · L 70 / E 69.55 / Δ -0.45 · `hpcdb17974/gas | solid brick | pitched 100` +- [x] `10013448474` · L 80 / E 79.55 / Δ -0.45 · `h408/elec | cavity wall | (another dwelling | whw903` +- [x] `100010542167` · L 65 / E 65.45 / Δ +0.45 · `hpcdb15445/gas | cavity wall | pitched 100 | consv3` +- [x] `100050721946` · L 73 / E 72.56 / Δ -0.44 · `hpcdb15024/gas | cavity wall | (another dwelling | ext1` +- [x] `10002589494` · L 70 / E 70.44 / Δ +0.44 · `hpcdb8642/gas | cavity wall | pitched 200` +- [x] `100010460076` · L 67 / E 66.56 / Δ -0.44 · `hpcdb17515/gas | cavity wall | pitched 100` +- [x] `100051178837` · L 63 / E 63.44 / Δ +0.44 · `h104/gas | sandstone as | pitched no | RR` +- [x] `63017340` · L 74 / E 73.56 / Δ -0.44 · `hpcdb17956/gas | solid brick | pitched insulated` +- [x] `50101945` · L 75 / E 74.56 / Δ -0.44 · `hpcdb10243/gas | timber frame | (another dwelling | ext1` +- [x] `10032778242` · L 65 / E 65.44 / Δ +0.44 · `hpcdb9209/gas | sandstone as | pitched 100` +- [x] `40002036` · L 64 / E 63.56 / Δ -0.44 · `hpcdb17904/gas | cavity wall | pitched no` +- [x] `100090412407` · L 71 / E 70.56 / Δ -0.44 · `hpcdb18908/gas | cavity wall | pitched 200` +- [x] `10070623452` · L 84 / E 84.44 / Δ +0.44 · `hpcdb18616/gas | cavity wall | (another dwelling` +- [x] `100000059044` · L 73 / E 72.56 / Δ -0.44 · `hpcdb17983/gas | cavity wall | (another dwelling` +- [x] `10012437206` · L 67 / E 67.44 / Δ +0.44 · `hpcdb16136/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `100070391608` · L 65 / E 64.56 / Δ -0.44 · `hpcdb18283/gas | solid brick | pitched 225 | ext2` +- [x] `100050849874` · L 70 / E 70.44 / Δ +0.44 · `hpcdb19007/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +- [x] `10094494653` · L 76 / E 75.57 / Δ -0.43 · `hpcdb18559/gas | solid brick | (another dwelling` +- [x] `10070088126` · L 74 / E 73.57 / Δ -0.43 · `hpcdb16210/gas | cavity wall | pitched 270 | consv3` +- [x] `39036600` · L 72 / E 72.43 / Δ +0.43 · `hpcdb18225/gas | cavity wall | pitched 400 | mv2` +- [x] `100021219619` · L 69 / E 68.57 / Δ -0.43 · `hpcdb18559/gas | solid brick | pitched 100` +- [x] `100100579892` · L 71 / E 71.43 / Δ +0.43 · `hpcdb10244/gas | cavity wall | pitched 400+` +- [x] `5128014` · L 67 / E 66.57 / Δ -0.43 · `hpcdb18250/gas | solid brick | pitched insulated` +- [x] `200000795879` · L 58 / E 57.57 / Δ -0.43 · `h402/elec | cavity wall | pitched 150 | ext1,sec:room heaters,whw903` +- [x] `39096576` · L 82 / E 81.57 / Δ -0.43 · `hpcdb17617/gas | timber frame | pitched 400+` +- [x] `1775045933` · L 69 / E 69.43 / Δ +0.43 · `hpcdb8180/gas | cavity wall | pitched 150` +- [x] `83105081` · L 67 / E 67.43 / Δ +0.43 · `hpcdb18119/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `21072782` · L 66 / E 65.57 / Δ -0.43 · `hpcdb18045/gas | cavity wall | pitched 175 | sec:room heaters` +- [x] `100031468327` · L 69 / E 69.43 / Δ +0.43 · `hpcdb19083/gas | cavity wall | pitched 300 | consv2` +- [x] `100100253270` · L 71 / E 71.43 / Δ +0.43 · `hpcdb18496/gas | cavity wall | pitched 250 | ext1` +- [x] `100071116347` · L 62 / E 62.43 / Δ +0.43 · `h104/gas | solid brick | pitched 150` +- [x] `422000030203` · L 75 / E 75.42 / Δ +0.42 · `hpcdb10328/gas | cavity wall | pitched 225` +- [x] `100010399776` · L 63 / E 63.42 / Δ +0.42 · `hpcdb10462/gas | cavity wall | pitched 270 | RR,ext1,sec:room heaters` +- [x] `100080945063` · L 70 / E 70.42 / Δ +0.42 · `hpcdb10326/gas | cavity wall | (another dwelling | ext1` +- [x] `10034692050` · L 82 / E 81.58 / Δ -0.42 · `hpcdb18250/gas | sandstone as | pitched 350 | PV,ext2,sec:room heaters` +- [x] `100100284086` · L 69 / E 69.42 / Δ +0.42 · `hpcdb17983/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `100031674118` · L 66 / E 66.42 / Δ +0.42 · `hpcdb17986/gas | cavity wall | pitched 125 | consv2,sec:room heaters` +- [x] `10023449405` · L 59 / E 58.58 / Δ -0.42 · `hpcdb18219/gas | granite or | pitched insulated | consv3,ext1,sec:room heaters` +- [x] `47237825` · L 79 / E 79.42 / Δ +0.42 · `hpcdb15707/gas | cavity wall | (another dwelling` +- [x] `100010265441` · L 69 / E 69.42 / Δ +0.42 · `hpcdb16839/gas | cavity wall | pitched 200` +- [x] `666329` · L 69 / E 69.42 / Δ +0.42 · `hpcdb10599/fuel28 | sandstone as | pitched insulated | ext2,sec:room heaters` +- [x] `100010197780` · L 65 / E 65.42 / Δ +0.42 · `hpcdb1839/gas | cavity wall | pitched 75 | sec:room heaters` +- [x] `100100991435` · L 74 / E 74.42 / Δ +0.42 · `hpcdb18907/gas | cavity wall | (another dwelling` +- [x] `100070537860` · L 91 / E 91.42 / Δ +0.42 · `hpcdb18225/gas | cavity wall | pitched 400+ | PV,sec:room heaters` +- [x] `100051145841` · L 70 / E 70.42 / Δ +0.42 · `hpcdb18559/gas | cavity wall | pitched 150` +- [x] `100030488548` · L 62 / E 62.42 / Δ +0.42 · `hpcdb1848/gas | solid brick | pitched insulated | ext1,sec:room heaters` +- [x] `100030538980` · L 68 / E 68.42 / Δ +0.42 · `hpcdb19109/gas | solid brick | pitched insulated | ext1` +- [x] `4510015395` · L 70 / E 69.58 / Δ -0.42 · `hpcdb19007/gas | cavity wall | pitched 200` +- [x] `100021798076` · L 56 / E 55.58 / Δ -0.42 · `hpcdb17505/gas | cavity wall | pitched 12 | ext1,sec:room heaters` +- [x] `200002597778` · L 73 / E 72.58 / Δ -0.42 · `hpcdb15282/gas | cavity wall | pitched 200` +- [x] `200004402879` · L 74 / E 73.58 / Δ -0.42 · `hpcdb17983/gas | cavity wall | pitched 200` +- [x] `10091186955` · L 82 / E 82.42 / Δ +0.42 · `hpcdb17505/gas | cavity wall | (another dwelling` +- [x] `100000054651` · L 70 / E 70.42 / Δ +0.42 · `hpcdb17983/gas | cavity wall | pitched 125` +- [x] `100030769969` · L 58 / E 57.59 / Δ -0.41 · `h130/fuel28 | cavity wall | pitched 250` +- [x] `10070086972` · L 18 / E 17.59 / Δ -0.41 · `hpcdb710/fuel28+2mains | sandstone as | pitched insulated | RR,ext4,sec:room heaters` +- [x] `100050397944` · L 65 / E 64.59 / Δ -0.41 · `hpcdb17681/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `63105357` · L 74 / E 74.41 / Δ +0.41 · `hpcdb17507/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100090989765` · L 70 / E 70.41 / Δ +0.41 · `hpcdb16408/gas | timber frame | pitched 300 | consv3,ext1,sec:room heaters` +- [x] `30523770` · L 72 / E 71.60 / Δ -0.40 · `hpcdb8191/fuel28 | granite or | pitched 200 | sec:room heaters` +- [x] `200004700463` · L 65 / E 65.40 / Δ +0.40 · `hpcdb18559/gas | sandstone as | pitched 75` +- [x] `100020675575` · L 60 / E 60.40 / Δ +0.40 · `h102/gas | cavity wall | pitched 12` +- [x] `100110694244` · L 72 / E 72.40 / Δ +0.40 · `hpcdb18512/gas | granite or | pitched 200 | sec:room heaters` +- [x] `10003910753` · L 64 / E 63.60 / Δ -0.40 · `h409/elec | granite or | pitched 300 | sec:room heaters,whw903` +- [x] `100040881207` · L 73 / E 73.40 / Δ +0.40 · `hpcdb16839/gas | solid brick | pitched 100 | ext1` +- [x] `100070601575` · L 68 / E 68.40 / Δ +0.40 · `hpcdb18560/gas | solid brick | pitched 250` +- [x] `100061125812` · L 75 / E 74.60 / Δ -0.40 · `hpcdb17983/gas | solid brick | pitched 50 | PV,ext2,sec:room heaters` +- [x] `100010596378` · L 67 / E 67.40 / Δ +0.40 · `hpcdb16839/gas | cavity wall | pitched 350 | RR,consv3,ext1,sec:room heaters` +- [x] `100051185130` · L 67 / E 66.60 / Δ -0.40 · `hpcdb18156/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `38198539` · L 80 / E 80.40 / Δ +0.40 · `hpcdb18229/gas | cavity wall | (another dwelling` +- [x] `10008501568` · L 76 / E 76.40 / Δ +0.40 · `hpcdb16909/gas | cavity wall | (another dwelling` +- [x] `10090849417` · L 73 / E 72.60 / Δ -0.40 · `hpcdb17000/fuel27 | cavity wall | (another dwelling` +- [x] `100110494926` · L 66 / E 66.40 / Δ +0.40 · `h104/gas | cavity wall | pitched 250` +- [x] `100050553337` · L 70 / E 69.60 / Δ -0.40 · `hpcdb16839/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100071356612` · L 69 / E 68.61 / Δ -0.39 · `h301/coal-anth | solid brick | (another dwelling` +- [x] `74041417` · L 79 / E 79.39 / Δ +0.39 · `hpcdb17507/gas | cavity wall | pitched 300 | PV` +- [x] `100110452552` · L 67 / E 67.39 / Δ +0.39 · `hpcdb15068/gas | cavity wall | pitched 175 | mv2,sec:room heaters` +- [x] `100022607800` · L 73 / E 72.61 / Δ -0.39 · `hpcdb18119/gas | solid brick | pitched 270` +- [x] `200004017091` · L 71 / E 71.39 / Δ +0.39 · `hpcdb17803/gas | timber frame | pitched 100` +- [x] `100022277442` · L 58 / E 58.39 / Δ +0.39 · `h409/elec | cavity wall | pitched insulated | whw903` +- [x] `250029611` · L 73 / E 72.61 / Δ -0.39 · `hpcdb17553/gas | cavity wall | pitched 250 | consv2,ext1` +- [x] `100022887979` · L 72 / E 72.39 / Δ +0.39 · `hpcdb18861/gas | solid brick | (another dwelling` +- [x] `44006508` · L 78 / E 78.39 / Δ +0.39 · `hpcdb17683/gas | cavity wall | pitched 150` +- [x] `38081666` · L 69 / E 68.61 / Δ -0.39 · `hpcdb17919/gas | solid brick | pitched 400+ | sec:room heaters` +- [x] `10090034244` · L 80 / E 80.39 / Δ +0.39 · `h691/elec | system built | (another dwelling | whw903` +- [x] `100010692849` · L 74 / E 73.61 / Δ -0.39 · `hpcdb16455/gas | cavity wall | pitched 300 | consv4,ext2,sec:room heaters` +- [x] `100090148760` · L 67 / E 67.39 / Δ +0.39 · `hpcdb15032/gas | cavity wall | pitched 100 | consv2` +- [x] `72304070` · L 76 / E 75.61 / Δ -0.39 · `hpcdb18225/gas | cavity wall | pitched 200` +- [x] `100070668967` · L 76 / E 76.39 / Δ +0.39 · `hpcdb17816/gas | cavity wall | pitched 200 | consv2` +- [x] `100040892555` · L 71 / E 71.39 / Δ +0.39 · `hpcdb16840/gas | cavity wall | pitched insulated` +- [x] `100061274293` · L 71 / E 71.39 / Δ +0.39 · `hpcdb17553/gas | cavity wall | pitched 300 | ext1` +- [x] `11064046` · L 65 / E 64.61 / Δ -0.39 · `h104/gas | solid brick | pitched insulated | ext2` +- [x] `77069148` · L 71 / E 71.39 / Δ +0.39 · `hpcdb17507/gas | cavity wall | pitched 200` +- [x] `148002976` · L 72 / E 71.61 / Δ -0.39 · `hpcdb16840/gas | cavity wall | pitched insulated | ext1` +- [x] `10096536318` · L 66 / E 65.62 / Δ -0.38 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100030585620` · L 59 / E 59.38 / Δ +0.38 · `h102/gas | cavity wall | pitched insulated | ext4,sec:room heaters` +- [x] `10008325030` · L 82 / E 81.62 / Δ -0.38 · `h301/coal-anth | system built | (another dwelling` +- [x] `100050869353` · L 75 / E 74.62 / Δ -0.38 · `hpcdb10547/gas | solid brick | pitched 300` +- [x] `45034352` · L 70 / E 70.38 / Δ +0.38 · `hpcdb18684/gas | cavity wall | pitched 250 | ext1` +- [x] `72274934` · L 66 / E 66.38 / Δ +0.38 · `hpcdb17985/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `100030893211` · L 70 / E 69.62 / Δ -0.38 · `hpcdb17546/gas | cavity wall | pitched 200 | ext1` +- [x] `21018821` · L 67 / E 67.38 / Δ +0.38 · `hpcdb19014/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `100080145093` · L 69 / E 69.38 / Δ +0.38 · `hpcdb18907/gas | cavity wall | pitched 225 | ext1` +- [x] `100021434831` · L 74 / E 74.38 / Δ +0.38 · `h102/gas | cavity wall | pitched insulated | RR,ext1` +- [x] `100090160202` · L 78 / E 77.62 / Δ -0.38 · `hpcdb18120/gas | cavity wall | pitched 300 | PV` +- [x] `100000001899` · L 70 / E 70.38 / Δ +0.38 · `hpcdb17507/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `63015070` · L 69 / E 69.38 / Δ +0.38 · `hpcdb19082/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `100032207872` · L 71 / E 71.38 / Δ +0.38 · `hpcdb17505/gas | cavity wall | (another dwelling` +- [x] `90089745` · L 62 / E 61.62 / Δ -0.38 · `hpcdb10243/gas | solid brick | pitched 150` +- [x] `100090379526` · L 67 / E 66.62 / Δ -0.38 · `hpcdb17992/gas | cavity wall | pitched 150 | ext2` +- [x] `100031755813` · L 73 / E 73.37 / Δ +0.37 · `hpcdb15706/gas | cavity wall | pitched 150` +- [x] `100040668971` · L 14 / E 13.63 / Δ -0.37 · `h631/LPG | cavity wall | pitched 250 | consv2,sec:portable electric,whw908` +- [x] `10013258835` · L 78 / E 77.63 / Δ -0.37 · `hpcdb16138/gas | timber frame | pitched 270 | ext1` +- [x] `10008774426` · L 77 / E 77.37 / Δ +0.37 · `h402/elec | cavity wall | pitched 250 | sec:room heaters,whw903` +- [x] `100090183995` · L 70 / E 70.37 / Δ +0.37 · `hpcdb15018/gas | cavity wall | pitched insulated` +- [x] `100100904720` · L 82 / E 81.63 / Δ -0.37 · `hpcdb19023/gas+2mains | cavity wall | flat insulated | RR,ext1,sec:room heaters` +- [x] `100050111553` · L 39 / E 39.37 / Δ +0.37 · `h191/elec | cavity wall | pitched 200 | whw903` +- [x] `100052105637` · L 59 / E 58.63 / Δ -0.37 · `hpcdb17741/gas | solid brick | pitched 200 | ext1,sec:room heaters` +- [x] `1775071220` · L 74 / E 73.63 / Δ -0.37 · `hpcdb10326/gas | cavity wall | (another dwelling` +- [x] `10000452538` · L 77 / E 76.63 / Δ -0.37 · `h104/gas | timber frame | pitched insulated` +- [x] `100120650297` · L 77 / E 76.63 / Δ -0.37 · `hpcdb17507/gas | cavity wall | (another dwelling` +- [x] `1775087250` · L 75 / E 74.63 / Δ -0.37 · `hpcdb18861/gas | cavity wall | pitched 250 | ext1` +- [x] `100061253556` · L 60 / E 59.63 / Δ -0.37 · `hpcdb18907/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `6083595` · L 76 / E 76.37 / Δ +0.37 · `hpcdb17685/gas | cavity wall | pitched insulated` +- [x] `200033141` · L 76 / E 75.64 / Δ -0.36 · `hpcdb16738/gas | cavity wall | flat insulated` +- [x] `100030357741` · L 72 / E 72.36 / Δ +0.36 · `hpcdb18560/gas | cavity wall | pitched 300 | consv2,ext1` +- [x] `100080707176` · L 72 / E 71.64 / Δ -0.36 · `hpcdb10243/gas | cavity wall | pitched 100` +- [x] `100062132377` · L 81 / E 80.64 / Δ -0.36 · `h214/elec | cavity wall | (another dwelling` +- [x] `100062132384` · L 81 / E 80.64 / Δ -0.36 · `h214/elec | cavity wall | (another dwelling` +- [x] `100031679582` · L 66 / E 66.36 / Δ +0.36 · `hpcdb10243/gas | cavity wall | pitched insulated` +- [x] `100031300973` · L 70 / E 70.36 / Δ +0.36 · `hpcdb10328/gas | cavity wall | pitched insulated` +- [x] `100090373553` · L 50 / E 49.64 / Δ -0.36 · `h102/gas | cavity wall | pitched insulated | ext1` +- [x] `100110122381` · L 70 / E 70.36 / Δ +0.36 · `hpcdb18119/gas | solid brick | pitched 300 | ext1` +- [x] `100110084287` · L 69 / E 68.64 / Δ -0.36 · `hpcdb17513/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `10010610915` · L 69 / E 69.36 / Δ +0.36 · `hpcdb18559/gas | cavity wall | pitched 75 | consv2,sec:room heaters` +- [x] `100050858546` · L 58 / E 58.36 / Δ +0.36 · `hpcdb19030/gas | cavity wall | pitched 150 | sec:room heaters` +- [x] `100061152006` · L 66 / E 66.36 / Δ +0.36 · `hpcdb17503/gas | cavity wall | pitched 270 | ext1,sec:room heaters` +- [x] `100070649980` · L 69 / E 68.64 / Δ -0.36 · `hpcdb17505/gas | solid brick | pitched 200` +- [x] `100121236760` · L 58 / E 58.36 / Δ +0.36 · `hpcdb18044/gas | sandstone as | pitched insulated | RR,ext3,sec:room heaters` +- [x] `64024859` · L 54 / E 53.64 / Δ -0.36 · `hpcdb8358/gas | cavity wall | pitched 125 | consv3,ext1,sec:room heaters` +- [x] `100031166296` · L 58 / E 57.64 / Δ -0.36 · `hpcdb15100/gas | cavity wall | pitched unknown | sec:room heaters` +- [x] `100110061827` · L 71 / E 70.64 / Δ -0.36 · `hpcdb16688/gas | cavity wall | pitched 150 | ext2` +- [x] `100110394521` · L 73 / E 72.64 / Δ -0.36 · `hpcdb10328/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `10023253242` · L 72 / E 72.36 / Δ +0.36 · `h104/gas | cavity wall | pitched insulated` +- [x] `90090727` · L 67 / E 66.64 / Δ -0.36 · `h104/gas | cavity wall | pitched 200 | ext1` +- [x] `21055668` · L 61 / E 61.36 / Δ +0.36 · `hpcdb17546/gas | cavity wall | pitched no` +- [x] `100110496019` · L 76 / E 75.65 / Δ -0.35 · `hpcdb18560/gas | cavity wall | pitched 200` +- [x] `422000037738` · L 72 / E 72.35 / Δ +0.35 · `hpcdb17975/gas | cavity wall | pitched 400+` +- [x] `77102428` · L 78 / E 77.65 / Δ -0.35 · `hpcdb17558/gas | cavity wall | pitched 300 | ext1` +- [x] `100071034423` · L 72 / E 71.65 / Δ -0.35 · `hpcdb18908/gas | cavity wall | pitched 100` +- [x] `100071026195` · L 71 / E 71.35 / Δ +0.35 · `hpcdb18907/gas | solid brick | pitched insulated | ext1` +- [x] `200003757985` · L 72 / E 71.65 / Δ -0.35 · `h301/coal-anth | cavity wall | (another dwelling | PV` +- [x] `100051029525` · L 67 / E 67.35 / Δ +0.35 · `hpcdb17986/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `100051332624` · L 66 / E 65.65 / Δ -0.35 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `10094297916` · L 80 / E 80.35 / Δ +0.35 · `hpcdb17929/gas | timber frame | pitched unknown` +- [x] `2465002794` · L 64 / E 64.35 / Δ +0.35 · `h104/gas | solid brick | pitched insulated` +- [x] `28018668` · L 58 / E 58.35 / Δ +0.35 · `hpcdb17115/gas | solid brick | pitched 250 | ext1,sec:room heaters` +- [x] `100020275185` · L 67 / E 67.35 / Δ +0.35 · `hpcdb17975/gas | solid brick | pitched 100` +- [x] `100000320896` · L 71 / E 70.65 / Δ -0.35 · `hpcdb18559/gas | cavity wall | (another dwelling | ext1,sec:room heaters` +- [x] `4510706229` · L 71 / E 71.35 / Δ +0.35 · `h402/elec | solid brick | (another dwelling | sec:room heaters,whw903` +- [x] `10023179506` · L 77 / E 76.65 / Δ -0.35 · `hpcdb16400/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `32039356` · L 72 / E 72.34 / Δ +0.34 · `hpcdb17983/gas | cavity wall | pitched 200` +- [x] `100071281443` · L 72 / E 71.66 / Δ -0.34 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100050971905` · L 46 / E 46.34 / Δ +0.34 · `hpcdb19059/fuel27 | cavity wall | flat limited` +- [x] `50120779` · L 76 / E 75.66 / Δ -0.34 · `hpcdb16848/gas | solid brick | (another dwelling` +- [x] `23018106` · L 66 / E 66.34 / Δ +0.34 · `hpcdb18250/gas | cavity wall | pitched 150 | sec:room heaters` +- [x] `100110515241` · L 64 / E 63.66 / Δ -0.34 · `hpcdb18559/gas | solid brick | pitched insulated | ext1,sec:room heaters` +- [x] `100010779964` · L 72 / E 72.34 / Δ +0.34 · `hpcdb17683/gas | sandstone as | pitched 75` +- [x] `64106486` · L 72 / E 71.66 / Δ -0.34 · `hpcdb17926/fuel27 | timber frame | pitched 270 | ext1` +- [x] `100060109253` · L 62 / E 62.34 / Δ +0.34 · `hpcdb18435/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +- [x] `47084930` · L 74 / E 74.34 / Δ +0.34 · `hpcdb17815/gas | cavity wall | flat insulated` +- [x] `200002819281` · L 72 / E 71.66 / Δ -0.34 · `h104/gas | solid brick | pitched insulated | RR,ext1` +- [x] `100051237659` · L 65 / E 64.67 / Δ -0.33 · `hpcdb18560/gas | sandstone as | pitched insulated | sec:room heaters` +- [x] `12027355` · L 70 / E 70.33 / Δ +0.33 · `hpcdb1838/gas | solid brick | pitched insulated | ext1` +- [x] `100120926050` · L 71 / E 70.67 / Δ -0.33 · `hpcdb18514/gas | cavity wall | pitched 175 | ext2` +- [x] `100012548450` · L 74 / E 74.33 / Δ +0.33 · `hpcdb10338/gas | cavity wall | (another dwelling` +- [x] `100061275133` · L 76 / E 76.33 / Δ +0.33 · `hpcdb18908/gas | solid brick | pitched 300` +- [x] `10012184174` · L 75 / E 74.67 / Δ -0.33 · `hpcdb19006/gas | solid brick | pitched insulated` +- [x] `100031680815` · L 61 / E 60.67 / Δ -0.33 · `h402/elec | cavity wall | pitched 150 | sec:room heaters,whw903` +- [x] `100070057052` · L 66 / E 65.67 / Δ -0.33 · `hpcdb10200/gas | cavity wall | pitched 250 | ext1` +- [x] `100060240863` · L 75 / E 75.33 / Δ +0.33 · `hpcdb15032/gas | solid brick | pitched 150` +- [x] `10008295210` · L 75 / E 74.67 / Δ -0.33 · `hpcdb18224/gas | system built | (another dwelling | ext1` +- [x] `83171858` · L 74 / E 73.67 / Δ -0.33 · `hpcdb18119/gas | system built | pitched 250` +- [x] `72304132` · L 67 / E 67.33 / Δ +0.33 · `hpcdb17986/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `12160542` · L 81 / E 81.32 / Δ +0.32 · `hpcdb18737/gas | cavity wall | (another dwelling` +- [x] `100062035546` · L 75 / E 74.68 / Δ -0.32 · `h104/gas | cavity wall | pitched 100` +- [x] `100071033825` · L 63 / E 63.32 / Δ +0.32 · `hpcdb17505/gas | cavity wall | pitched 225 | sec:room heaters` +- [x] `100040027178` · L 65 / E 64.68 / Δ -0.32 · `hpcdb19262/fuel28 | system built | pitched 270 | sec:room heaters` +- [x] `10091482156` · L 74 / E 74.32 / Δ +0.32 · `h104/gas | cavity wall | flat insulated` +- [x] `5182876` · L 80 / E 79.68 / Δ -0.32 · `hpcdb16841/gas | cavity wall | (another dwelling` +- [x] `100031703043` · L 63 / E 62.68 / Δ -0.32 · `hpcdb17284/gas | cavity wall | pitched 100 | ext1` +- [x] `200001480500` · L 75 / E 74.68 / Δ -0.32 · `h409/elec | cavity wall | pitched 100 | whw903` +- [x] `21037089` · L 68 / E 68.32 / Δ +0.32 · `hpcdb19007/gas | cavity wall | pitched insulated | ext1,mv5,sec:room heaters` +- [x] `100031318648` · L 79 / E 78.68 / Δ -0.32 · `hpcdb18907/gas | timber frame | pitched 400+ | PV,sec:room heaters` +- [x] `21089432` · L 64 / E 63.68 / Δ -0.32 · `hpcdb18045/gas | cavity wall | pitched no | ext1` +- [x] `93099` · L 63 / E 63.32 / Δ +0.32 · `hpcdb18250/gas | solid brick | pitched 200 | ext2` +- [x] `100120765933` · L 57 / E 57.32 / Δ +0.32 · `hpcdb15921/fuel28 | cavity wall | pitched 200 | sec:room heaters` +- [x] `100051053673` · L 66 / E 66.32 / Δ +0.32 · `hpcdb17660/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `200002919291` · L 59 / E 59.32 / Δ +0.32 · `h691/elec | system built | (another dwelling | whw903` +- [x] `21082835` · L 78 / E 77.69 / Δ -0.31 · `hpcdb16137/gas | system built | pitched 270` +- [x] `100070126788` · L 58 / E 57.69 / Δ -0.31 · `hpcdb18090/gas | system built | pitched 75 | sec:room heaters` +- [x] `100010997844` · L 71 / E 71.31 / Δ +0.31 · `hpcdb18651/gas | cavity wall | pitched insulated` +- [x] `100051275257` · L 61 / E 61.31 / Δ +0.31 · `hpcdb19007/gas | sandstone as | pitched insulated | RR,ext1` +- [x] `72207515` · L 71 / E 70.69 / Δ -0.31 · `hpcdb17973/gas | cavity wall | (another dwelling | sec:room heaters` +- [x] `100070312027` · L 72 / E 71.69 / Δ -0.31 · `hpcdb18908/gas | solid brick | pitched 270 | ext2,sec:room heaters` +- [x] `100071105301` · L 72 / E 72.31 / Δ +0.31 · `hpcdb10312/gas | solid brick | pitched 150` +- [x] `10008275334` · L 76 / E 76.31 / Δ +0.31 · `h691/elec | system built | (another dwelling | whw903` +- [x] `100110174472` · L 74 / E 74.31 / Δ +0.31 · `hpcdb8368/gas | solid brick | pitched 175 | ext2,mv5` +- [x] `100071450760` · L 55 / E 54.69 / Δ -0.31 · `h691/elec | cavity wall | (another dwelling | whw903` +- [x] `207096040` · L 69 / E 69.31 / Δ +0.31 · `hpcdb18219/gas | solid brick | pitched insulated | ext1` +- [x] `200004695006` · L 69 / E 69.31 / Δ +0.31 · `hpcdb10243/gas | sandstone as | pitched insulated` +- [x] `100100800577` · L 64 / E 64.31 / Δ +0.31 · `h301/coal-anth | system built | pitched 200 | whw903` +- [x] `100110234047` · L 71 / E 70.70 / Δ -0.30 · `hpcdb16136/gas | cavity wall | pitched 300` +- [x] `10007966883` · L 64 / E 64.30 / Δ +0.30 · `hpcdb17785/gas | solid brick | pitched 100 | ext1` +- [x] `100091292858` · L 59 / E 59.30 / Δ +0.30 · `h691/elec | solid brick | (another dwelling | whw903` +- [x] `100120820445` · L 72 / E 71.70 / Δ -0.30 · `hpcdb10267/gas | solid brick | pitched insulated | RR,ext2,sec:room heaters` +- [x] `100010719461` · L 56 / E 56.30 / Δ +0.30 · `hpcdb16930/gas | cavity wall | pitched no` +- [x] `100070487183` · L 66 / E 66.30 / Δ +0.30 · `h691/elec | timber frame | pitched 150 | whw909` +- [x] `116895` · L 73 / E 72.70 / Δ -0.30 · `hpcdb18119/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `10008031947` · L 79 / E 78.70 / Δ -0.30 · `hpcdb16406/gas+2mains | cavity wall | pitched 250 | ext2` +- [x] `100050834171` · L 73 / E 72.70 / Δ -0.30 · `hpcdb10547/gas | cavity wall | pitched 100` +- [x] `10010159639` · L 65 / E 65.30 / Δ +0.30 · `hpcdb18759/gas | sandstone with | pitched 150 | ext1,mv5,sec:room heaters` +- [x] `100110455808` · L 67 / E 66.70 / Δ -0.30 · `hpcdb10242/gas | cavity wall | pitched no` +- [x] `100070968292` · L 72 / E 71.70 / Δ -0.30 · `h104/gas | cavity wall | pitched insulated` +- [x] `100011754031` · L 69 / E 69.30 / Δ +0.30 · `hpcdb16839/gas | cavity wall | pitched 150 | ext1` +- [x] `61008954` · L 67 / E 67.30 / Δ +0.30 · `hpcdb18559/gas | sandstone as | pitched insulated` +- [x] `100061379950` · L 32 / E 31.70 / Δ -0.30 · `h104/fuel27+2mains | solid brick | pitched unknown | ext1,sec:room heaters,whw907` +- [x] `100050549118` · L 69 / E 68.70 / Δ -0.30 · `hpcdb15282/gas | cavity wall | pitched 100 | RR` +- [x] `100021754159` · L 57 / E 57.30 / Δ +0.30 · `hpcdb17503/gas | solid brick | pitched 100 | consv2,ext1,sec:room heaters` +- [x] `200000323155` · L 74 / E 74.30 / Δ +0.30 · `hpcdb17974/gas | timber frame | pitched 100 | consv2,ext1` +- [x] `422000091523` · L 71 / E 70.70 / Δ -0.30 · `hpcdb18767/gas | solid brick | pitched 50` +- [x] `100031351512` · L 65 / E 65.30 / Δ +0.30 · `hpcdb10265/gas | solid brick | pitched insulated | RR,ext1,sec:room heaters` +- [x] `100040531566` · L 70 / E 69.71 / Δ -0.29 · `hpcdb15706/gas | cavity wall | pitched 75` +- [x] `100120850835` · L 59 / E 59.29 / Δ +0.29 · `hpcdb108793/elec | solid brick | pitched insulated | ext2` +- [x] `100010159140` · L 77 / E 77.29 / Δ +0.29 · `hpcdb17688/gas | cavity wall | pitched 300 | PV,ext1,sec:room heaters` +- [x] `77110396` · L 76 / E 75.71 / Δ -0.29 · `hpcdb18737/gas | cavity wall | pitched 200` +- [x] `100080908496` · L 81 / E 80.71 / Δ -0.29 · `hpcdb19006/gas | cavity wall | (another dwelling` +- [x] `100031831649` · L 67 / E 67.29 / Δ +0.29 · `hpcdb17663/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +- [x] `100052098782` · L 70 / E 69.71 / Δ -0.29 · `hpcdb15706/gas | cavity wall | pitched 150` +- [x] `10014035608` · L 79 / E 78.71 / Δ -0.29 · `h301/elec10hr | system built | (another dwelling` +- [x] `100022206341` · L 66 / E 66.29 / Δ +0.29 · `hpcdb15100/gas | solid brick | pitched insulated | RR,ext1` +- [x] `10091185672` · L 84 / E 84.29 / Δ +0.29 · `hpcdb16400/gas | cavity wall | (another dwelling` +- [x] `32049938` · L 63 / E 62.71 / Δ -0.29 · `hpcdb17983/gas | solid brick | pitched 350 | sec:room heaters` +- [x] `100110433442` · L 70 / E 69.71 / Δ -0.29 · `hpcdb16839/gas | cavity wall | pitched 400+ | ext1` +- [x] `100070532674` · L 76 / E 76.29 / Δ +0.29 · `hpcdb17983/gas | cavity wall | pitched insulated` +- [x] `100032230128` · L 55 / E 54.71 / Δ -0.29 · `hpcdb1245/gas | solid brick | pitched insulated | ext1` +- [x] `10024298029` · L 72 / E 72.29 / Δ +0.29 · `hpcdb17503/gas | solid brick | pitched 270 | ext1,sec:room heaters` +- [x] `5079850` · L 39 / E 39.29 / Δ +0.29 · `h301/coal-anth | system built | (another dwelling | ext1,whw903` +- [x] `10001235167` · L 74 / E 73.71 / Δ -0.29 · `hpcdb17645/gas | solid brick | pitched 225` +- [x] `100080531660` · L 64 / E 63.71 / Δ -0.29 · `hpcdb16408/gas | cavity wall | pitched 50 | ext1` +- [x] `100110515199` · L 91 / E 91.28 / Δ +0.28 · `hpcdb17741/gas | cavity wall | pitched 400+ | PV` +- [x] `61016813` · L 72 / E 72.28 / Δ +0.28 · `hpcdb17590/gas | sandstone as | pitched insulated` +- [x] `200001186113` · L 82 / E 82.28 / Δ +0.28 · `h409/elec | cavity wall | pitched 270 | PV,mv2,sec:room heaters,whw903` +- [x] `3040022036` · L 69 / E 69.28 / Δ +0.28 · `hpcdb17986/gas | cavity wall | (another dwelling` +- [x] `100070536189` · L 75 / E 75.28 / Δ +0.28 · `hpcdb10244/gas | cavity wall | pitched insulated | PV` +- [x] `90204248` · L 41 / E 40.72 / Δ -0.28 · `h691/elec | cavity wall | pitched 100 | whw909` +- [x] `28054454` · L 74 / E 73.72 / Δ -0.28 · `hpcdb102431/elec | cavity wall | pitched 200` +- [x] `303001211` · L 72 / E 72.28 / Δ +0.28 · `h301/coal-anth | cavity wall | pitched 250` +- [x] `202215644` · L 80 / E 79.72 / Δ -0.28 · `hpcdb17560/gas | cavity wall | (another dwelling | ext1` +- [x] `202207892` · L 77 / E 77.28 / Δ +0.28 · `h301/coal-anth | system built | (another dwelling` +- [x] `100120836206` · L 73 / E 73.28 / Δ +0.28 · `hpcdb17762/gas | cavity wall | pitched 100` +- [x] `100010450242` · L 70 / E 70.28 / Δ +0.28 · `h104/gas | sandstone as | pitched 270 | ext1` +- [x] `100031416239` · L 70 / E 70.27 / Δ +0.27 · `h104/gas | cavity wall | pitched 125` +- [x] `100061093506` · L 73 / E 72.73 / Δ -0.27 · `hpcdb18276/gas | cavity wall | pitched 125 | ext1` +- [x] `100000488045` · L 76 / E 75.73 / Δ -0.27 · `hpcdb15709/gas | cavity wall | pitched 250` +- [x] `100000025104` · L 76 / E 75.73 / Δ -0.27 · `hpcdb19007/gas | system built | (another dwelling` +- [x] `10093494727` · L 69 / E 68.73 / Δ -0.27 · `h691/elec | cavity wall | pitched insulated | whw903` +- [x] `1775073252` · L 76 / E 76.27 / Δ +0.27 · `h104/gas | cavity wall | (another dwelling` +- [x] `1775121299` · L 81 / E 81.27 / Δ +0.27 · `hpcdb17044/gas | cavity wall | pitched 300 | PV` +- [x] `100110136322` · L 66 / E 66.27 / Δ +0.27 · `hpcdb16882/gas | cavity wall | pitched insulated | RR,ext1` +- [x] `100022243530` · L 61 / E 61.27 / Δ +0.27 · `hpcdb17959/gas | solid brick | pitched 250 | sec:room heaters` +- [x] `83159458` · L 77 / E 76.73 / Δ -0.27 · `hpcdb17683/gas | system built | pitched 250 | sec:room heaters` +- [x] `100031193650` · L 70 / E 69.73 / Δ -0.27 · `hpcdb15100/gas | cavity wall | pitched insulated | consv2,sec:room heaters` +- [x] `100110435186` · L 75 / E 74.73 / Δ -0.27 · `hpcdb15709/gas | cavity wall | pitched 300 | PV,ext1,mv2,sec:room heaters` +- [x] `38327244` · L 81 / E 80.73 / Δ -0.27 · `hpcdb17507/gas | timber frame | pitched 300 | ext1` +- [x] `100031388370` · L 71 / E 71.27 / Δ +0.27 · `hpcdb16931/gas | solid brick | pitched 300 | ext2` +- [x] `45115812` · L 75 / E 74.73 / Δ -0.27 · `h304/elec | system built | (another dwelling` +- [x] `207084872` · L 60 / E 59.74 / Δ -0.26 · `h114/gas | solid brick | pitched 75 | ext1` +- [x] `100060061070` · L 70 / E 69.74 / Δ -0.26 · `hpcdb17986/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `100021026327` · L 72 / E 71.74 / Δ -0.26 · `hpcdb15502/gas | solid brick | (another dwelling` +- [x] `50016716` · L 62 / E 62.26 / Δ +0.26 · `hpcdb18431/gas | cavity wall | pitched 100` +- [x] `100040724662` · L 73 / E 73.26 / Δ +0.26 · `hpcdb18229/gas | cavity wall | pitched insulated | ext1` +- [x] `72155875` · L 68 / E 67.74 / Δ -0.26 · `hpcdb17038/gas | cavity wall | pitched 150 | ext1,sec:room heaters` +- [x] `5870012976` · L 62 / E 62.26 / Δ +0.26 · `hpcdb17501/gas | solid brick | pitched 200` +- [x] `100010049310` · L 70 / E 70.26 / Δ +0.26 · `hpcdb15706/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +- [x] `100070642087` · L 68 / E 68.26 / Δ +0.26 · `hpcdb18560/gas | cavity wall | pitched 100 | ext1` +- [x] `100050429574` · L 70 / E 70.26 / Δ +0.26 · `hpcdb19110/gas | solid brick | pitched 250 | sec:room heaters` +- [x] `10012816887` · L 65 / E 65.26 / Δ +0.26 · `h402/elec | cavity wall | pitched 50 | sec:portable electric,whw903` +- [x] `100051080419` · L 69 / E 68.74 / Δ -0.26 · `hpcdb10328/gas | cavity wall | pitched 200` +- [x] `68144811` · L 80 / E 79.74 / Δ -0.26 · `hpcdb8867/gas | cavity wall | (another dwelling` +- [x] `100050424781` · L 69 / E 69.26 / Δ +0.26 · `hpcdb17507/gas | cavity wall | pitched 175 | mv5` +- [x] `50011586` · L 69 / E 68.74 / Δ -0.26 · `hpcdb10328/gas | cavity wall | pitched 225 | consv2` +- [x] `100010680786` · L 73 / E 73.26 / Δ +0.26 · `hpcdb18907/gas | granite or | pitched 400+ | ext1` +- [x] `422000127372` · L 79 / E 78.75 / Δ -0.25 · `hpcdb17741/gas | cavity wall | pitched 400+` +- [x] `200000339841` · L 72 / E 72.25 / Δ +0.25 · `hpcdb18736/gas | cavity wall | (another dwelling` +- [x] `72380835` · L 82 / E 82.25 / Δ +0.25 · `hpcdb17507/gas | cavity wall | pitched 200 | PV,sec:room heaters` +- [x] `38193503` · L 65 / E 65.25 / Δ +0.25 · `hpcdb18907/gas | cavity wall | pitched 100 | ext2,sec:room heaters` +- [x] `100070155960` · L 53 / E 53.25 / Δ +0.25 · `hpcdb10462/gas | cavity wall | pitched 150 | ext2` +- [x] `83147775` · L 71 / E 71.25 / Δ +0.25 · `hpcdb16839/gas | cavity wall | pitched insulated` +- [x] `72303880` · L 63 / E 62.75 / Δ -0.25 · `hpcdb17507/gas | cavity wall | pitched 150 | sec:room heaters` +- [x] `100022711136` · L 72 / E 71.75 / Δ -0.25 · `hpcdb16495/gas | cavity wall | (another dwelling` +- [x] `100090536443` · L 86 / E 86.25 / Δ +0.25 · `hpcdb17974/gas | cavity wall | pitched 175 | PV,ext1` +- [x] `83147745` · L 75 / E 75.25 / Δ +0.25 · `hpcdb16839/gas | cavity wall | (another dwelling | sec:room heaters` +- [x] `200002598542` · L 61 / E 61.25 / Δ +0.25 · `h402/elec | cavity wall | pitched 175 | ext1,sec:room heaters,whw903` +- [x] `100010572385` · L 62 / E 62.25 / Δ +0.25 · `hpcdb18817/gas | cavity wall | pitched 250 | ext2,sec:room heaters` +- [x] `100120874299` · L 72 / E 71.75 / Δ -0.25 · `hpcdb107234/elec | cavity wall | pitched 200 | mv2` +- [x] `100030332130` · L 51 / E 50.76 / Δ -0.24 · `h402/elec | cavity wall | pitched 100 | ext1,sec:room heaters,whw903` +- [x] `100060721835` · L 68 / E 67.76 / Δ -0.24 · `hpcdb16841/gas | system built | pitched 250` +- [x] `100011764055` · L 72 / E 71.76 / Δ -0.24 · `hpcdb15823/gas | cavity wall | pitched 200 | ext4,sec:room heaters` +- [x] `5067734` · L 67 / E 67.24 / Δ +0.24 · `hpcdb17726/gas | solid brick | (another dwelling` +- [x] `100021942272` · L 69 / E 69.24 / Δ +0.24 · `hpcdb17501/gas | solid brick | pitched insulated | RR` +- [x] `100050587694` · L 70 / E 70.24 / Δ +0.24 · `hpcdb18516/gas | cavity wall | pitched 270` +- [x] `100062195466` · L 73 / E 72.76 / Δ -0.24 · `h104/gas | cavity wall | (another dwelling` +- [x] `100100880740` · L 69 / E 69.24 / Δ +0.24 · `hpcdb17733/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `10090015178` · L 77 / E 76.76 / Δ -0.24 · `hpcdb16138/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `200001745207` · L 59 / E 59.24 / Δ +0.24 · `hpcdb1761/fuel28 | cavity wall | pitched 250 | ext1` +- [x] `250021965` · L 71 / E 71.24 / Δ +0.24 · `hpcdb10244/gas | cavity wall | pitched 200 | RR` +- [x] `100051346364` · L 63 / E 62.77 / Δ -0.23 · `hpcdb17983/gas | sandstone as | pitched no | sec:room heaters` +- [x] `100110203348` · L 66 / E 65.77 / Δ -0.23 · `hpcdb18559/gas | solid brick | pitched insulated | ext2` +- [x] `90164142` · L 80 / E 79.77 / Δ -0.23 · `h402/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +- [x] `5870055814` · L 72 / E 72.23 / Δ +0.23 · `hpcdb15100/gas | cavity wall | pitched 125 | ext1` +- [x] `100040118353` · L 74 / E 73.77 / Δ -0.23 · `h402/elec | cavity wall | (another dwelling | ext1,sec:portable electric,whw903` +- [x] `100011419346` · L 69 / E 68.77 / Δ -0.23 · `hpcdb16839/gas | cavity wall | pitched insulated` +- [x] `10091678339` · L 95 / E 94.77 / Δ -0.23 · `hpcdb110399/elec | cavity wall | pitched insulated | PV,RR` +- [x] `100031779857` · L 64 / E 64.23 / Δ +0.23 · `hpcdb16210/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +- [x] `100010470853` · L 67 / E 66.77 / Δ -0.23 · `hpcdb17505/gas | sandstone as | pitched 300 | ext1` +- [x] `10002147299` · L 71 / E 71.23 / Δ +0.23 · `hpcdb16810/gas | cavity wall | pitched 200 | consv2` +- [x] `200003864157` · L 73 / E 72.77 / Δ -0.23 · `hpcdb17039/gas | cavity wall | pitched 100 | ext1` +- [x] `6040073` · L 72 / E 71.77 / Δ -0.23 · `h301/coal-anth | solid brick | (another dwelling` +- [x] `100062014047` · L 76 / E 75.77 / Δ -0.23 · `hpcdb10547/gas | cavity wall | pitched 200` +- [x] `14003893` · L 69 / E 69.22 / Δ +0.22 · `hpcdb16931/gas | cavity wall | pitched 150` +- [x] `6721183` · L 82 / E 81.78 / Δ -0.22 · `h301/coal-anth | system built | (another dwelling` +- [x] `100040914059` · L 72 / E 72.22 / Δ +0.22 · `hpcdb10244/gas | solid brick | pitched 400+` +- [x] `10034523788` · L 69 / E 69.22 / Δ +0.22 · `hpcdb10459/gas+2mains | cavity wall | pitched 250 | RR,ext4,sec:room heaters,whw914` +- [x] `41223299` · L 76 / E 76.22 / Δ +0.22 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100091119847` · L 79 / E 78.78 / Δ -0.22 · `hpcdb17105/fuel28 | cavity wall | pitched 300 | PV` +- [x] `100020453894` · L 63 / E 63.22 / Δ +0.22 · `hpcdb10321/gas | solid brick | pitched 200` +- [x] `100080166105` · L 57 / E 56.78 / Δ -0.22 · `hpcdb17507/gas | solid brick | pitched insulated | consv2,mv2` +- [x] `10013855655` · L 78 / E 78.22 / Δ +0.22 · `hpcdb10071/gas | cavity wall | pitched insulated | RR` +- [x] `100010842519` · L 69 / E 68.78 / Δ -0.22 · `hpcdb17507/gas | cavity wall | pitched insulated | RR` +- [x] `100061696040` · L 72 / E 71.78 / Δ -0.22 · `hpcdb19015/gas | cavity wall | pitched 300 | PV,ext1` +- [x] `100071098291` · L 59 / E 59.22 / Δ +0.22 · `hpcdb9571/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `10012437388` · L 62 / E 62.22 / Δ +0.22 · `hpcdb19014/gas | cavity wall | pitched no` +- [x] `100080154263` · L 70 / E 69.78 / Δ -0.22 · `hpcdb10444/gas | cavity wall | pitched 125` +- [x] `100030564080` · L 67 / E 66.79 / Δ -0.21 · `hpcdb15282/gas | solid brick | pitched 200 | ext1` +- [x] `100023491276` · L 74 / E 74.21 / Δ +0.21 · `hpcdb19051/gas | solid brick | (another dwelling` +- [x] `100071320610` · L 75 / E 74.79 / Δ -0.21 · `h104/gas | system built | (another dwelling` +- [x] `10090835500` · L 83 / E 82.79 / Δ -0.21 · `hpcdb16321/gas | cavity wall | pitched 270 | PV` +- [x] `10090383598` · L 76 / E 76.21 / Δ +0.21 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100050841010` · L 69 / E 69.21 / Δ +0.21 · `hpcdb10546/gas | cavity wall | pitched 100 | ext1` +- [x] `10090481366` · L 77 / E 76.79 / Δ -0.21 · `h691/elec | cavity wall | (another dwelling | whw909` +- [x] `100070308464` · L 65 / E 65.21 / Δ +0.21 · `h104/gas | cavity wall | pitched 250 | PV` +- [x] `100012547948` · L 75 / E 74.79 / Δ -0.21 · `hpcdb17931/gas | cavity wall | pitched 100` +- [x] `100061316828` · L 69 / E 69.21 / Δ +0.21 · `hpcdb18403/gas | cavity wall | pitched 250 | mv2` +- [x] `83067520` · L 65 / E 64.79 / Δ -0.21 · `hpcdb18119/gas | cavity wall | pitched 200` +- [x] `100120954950` · L 66 / E 65.79 / Δ -0.21 · `hpcdb10243/gas | cavity wall | pitched 250` +- [x] `68100715` · L 39 / E 39.20 / Δ +0.20 · `h691/elec | cavity wall | (another dwelling | whw903` +- [x] `10090641681` · L 82 / E 82.20 / Δ +0.20 · `hpcdb17045/gas | cavity wall | (another dwelling` +- [x] `100070189144` · L 49 / E 49.20 / Δ +0.20 · `h402/elec | cavity wall | pitched 150 | consv2,sec:portable electric,whw903` +- [x] `6007002` · L 76 / E 76.20 / Δ +0.20 · `hpcdb17702/gas | system built | (another dwelling` +- [x] `100040926648` · L 70 / E 69.80 / Δ -0.20 · `hpcdb10244/gas | cavity wall | pitched 250 | ext1` +- [x] `100100299483` · L 67 / E 66.80 / Δ -0.20 · `hpcdb17507/gas | granite or | pitched 50 | ext3` +- [x] `100010391723` · L 66 / E 66.20 / Δ +0.20 · `hpcdb18760/gas | solid brick | pitched 100 | RR,ext2,sec:room heaters` +- [x] `100110431858` · L 84 / E 83.80 / Δ -0.20 · `hpcdb18119/gas | cavity wall | pitched 400+ | PV` +- [x] `30102683` · L 78 / E 77.80 / Δ -0.20 · `hpcdb9969/gas | cavity wall | roof room(s) | RR,consv2` +- [x] `200000800903` · L 75 / E 74.80 / Δ -0.20 · `hpcdb2040/gas | timber frame | pitched 150 | ext2` +- [x] `100060370575` · L 70 / E 69.80 / Δ -0.20 · `hpcdb17760/gas | cavity wall | (another dwelling` +- [x] `10022972987` · L 11 / E 11.20 / Δ +0.20 · `h691/elec | sandstone as | pitched 200 | ext1,sec:room heaters,whw921` +- [x] `10023219663` · L 78 / E 77.80 / Δ -0.20 · `h301/coal-anth | system built | (another dwelling` +- [x] `100020603440` · L 74 / E 73.80 / Δ -0.20 · `h104/gas | cavity wall | pitched insulated` +- [x] `45040195` · L 75 / E 75.19 / Δ +0.19 · `hpcdb18250/gas | cavity wall | pitched 100` +- [x] `653958` · L 79 / E 78.81 / Δ -0.19 · `hpcdb10071/gas | cavity wall | pitched 250` +- [x] `10096575045` · L 44 / E 44.19 / Δ +0.19 · `h691/elec | cavity wall | (another dwelling | whw909` +- [x] `217058896` · L 68 / E 67.81 / Δ -0.19 · `h301/coal-anth | solid brick | (another dwelling` +- [x] `100050823534` · L 73 / E 73.19 / Δ +0.19 · `hpcdb18204/gas | cavity wall | pitched 75 | consv2,ext1` +- [x] `100061736655` · L 74 / E 73.81 / Δ -0.19 · `hpcdb18911/gas | cavity wall | pitched 400+ | PV,ext1,mv2` +- [x] `100040006258` · L 74 / E 74.19 / Δ +0.19 · `hpcdb15834/gas | granite or | pitched 300` +- [x] `100070051157` · L 72 / E 72.19 / Δ +0.19 · `hpcdb17998/gas | solid brick | pitched 75` +- [x] `100050722945` · L 67 / E 66.81 / Δ -0.19 · `hpcdb19158/gas | cavity wall | pitched insulated | ext2,sec:room heaters` +- [x] `100110491552` · L 70 / E 70.19 / Δ +0.19 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100061721679` · L 71 / E 71.19 / Δ +0.19 · `hpcdb10462/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `565298` · L 68 / E 67.82 / Δ -0.18 · `hpcdb15049/gas | cavity wall | pitched insulated` +- [x] `100090243980` · L 68 / E 68.18 / Δ +0.18 · `hpcdb10327/gas | cavity wall | pitched 100 | ext1` +- [x] `100100328304` · L 62 / E 61.82 / Δ -0.18 · `hpcdb18768/gas | cavity wall | pitched 270 | ext1` +- [x] `10001131873` · L 79 / E 78.82 / Δ -0.18 · `h402/elec | granite or | (another dwelling | sec:portable electric,whw903` +- [x] `63123708` · L 64 / E 63.82 / Δ -0.18 · `hpcdb16977/gas | cavity wall | pitched 300 | ext2,sec:room heaters` +- [x] `90100875` · L 57 / E 56.82 / Δ -0.18 · `hpcdb17507/gas | solid brick | pitched insulated | ext2,sec:room heaters` +- [x] `128012524` · L 56 / E 56.18 / Δ +0.18 · `hpcdb10265/gas | cavity wall | pitched insulated | ext1,sec:room heaters` +- [x] `100010830948` · L 69 / E 68.82 / Δ -0.18 · `hpcdb18559/gas | cavity wall | pitched 150 | consv3` +- [x] `21060468` · L 67 / E 67.18 / Δ +0.18 · `hpcdb10112/gas | system built | pitched 270 | mv2` +- [x] `200004250345` · L 72 / E 72.18 / Δ +0.18 · `hpcdb4035/gas | cavity wall | pitched unknown | ext1,sec:room heaters` +- [x] `11038944` · L 68 / E 67.83 / Δ -0.17 · `h104/gas | cavity wall | pitched insulated` +- [x] `100090656436` · L 72 / E 72.17 / Δ +0.17 · `h104/gas | cavity wall | pitched unknown | ext2` +- [x] `100121044742` · L 72 / E 72.17 / Δ +0.17 · `hpcdb17505/gas | cavity wall | pitched 100 | ext1` +- [x] `100031540900` · L 68 / E 68.17 / Δ +0.17 · `hpcdb17501/gas | cavity wall | pitched 250` +- [x] `50010028` · L 87 / E 87.17 / Δ +0.17 · `hpcdb16987/gas | cavity wall | pitched 250 | PV,ext2` +- [x] `100061741005` · L 74 / E 73.83 / Δ -0.17 · `hpcdb16210/gas | cavity wall | pitched 200 | RR,ext1` +- [x] `100110589642` · L 72 / E 72.17 / Δ +0.17 · `hpcdb16137/gas | cavity wall | pitched 200` +- [x] `100041131293` · L 76 / E 76.17 / Δ +0.17 · `hpcdb15502/gas | cavity wall | (another dwelling` +- [x] `21072798` · L 72 / E 71.83 / Δ -0.17 · `hpcdb19007/gas | cavity wall | (another dwelling` +- [x] `10094975827` · L 66 / E 65.83 / Δ -0.17 · `hpcdb18559/gas | solid brick | pitched insulated` +- [x] `10009830624` · L 78 / E 77.83 / Δ -0.17 · `hpcdb15706/gas | cavity wall | pitched 300` +- [x] `39023204` · L 68 / E 68.17 / Δ +0.17 · `hpcdb18155/gas | solid brick | pitched insulated | ext2` +- [x] `100060428487` · L 71 / E 71.17 / Δ +0.17 · `hpcdb18496/gas | cavity wall | pitched 100 | consv2,ext1` +- [x] `100121053407` · L 73 / E 72.83 / Δ -0.17 · `hpcdb16919/gas | cavity wall | pitched 300 | consv3` +- [x] `202229245` · L 67 / E 66.83 / Δ -0.17 · `hpcdb18224/gas | solid brick | pitched unknown | ext1` +- [x] `10000208277` · L 75 / E 75.17 / Δ +0.17 · `hpcdb16135/gas | cavity wall | pitched 225 | consv2` +- [x] `10094257000` · L 55 / E 55.16 / Δ +0.16 · `h691/elec | timber frame | pitched insulated | ext1,sec:room heaters,whw909` +- [x] `100040411293` · L 64 / E 64.16 / Δ +0.16 · `hpcdb16986/gas | cavity wall | pitched 150` +- [x] `200003712915` · L 73 / E 72.84 / Δ -0.16 · `hpcdb16396/gas | cavity wall | pitched 400+ | mv2` +- [x] `4510002139` · L 73 / E 72.84 / Δ -0.16 · `hpcdb18204/gas | solid brick | pitched insulated | RR,ext2` +- [x] `200000920341` · L 69 / E 69.16 / Δ +0.16 · `h104/gas | cavity wall | pitched 270` +- [x] `100021038893` · L 92 / E 91.84 / Δ -0.16 · `hpcdb18907/gas | cavity wall | pitched 300 | PV` +- [x] `100020435702` · L 64 / E 64.16 / Δ +0.16 · `hpcdb10328/gas | cavity wall | pitched insulated` +- [x] `200004517412` · L 74 / E 73.84 / Δ -0.16 · `hpcdb18560/gas | cavity wall | pitched 400+ | sec:room heaters` +- [x] `100020443300` · L 69 / E 68.84 / Δ -0.16 · `hpcdb17507/gas | cavity wall | pitched 100 | ext1` +- [x] `200000387611` · L 71 / E 71.16 / Δ +0.16 · `hpcdb15019/gas | cavity wall | pitched 100 | consv3,sec:room heaters` +- [x] `5870031233` · L 75 / E 74.84 / Δ -0.16 · `h401/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +- [x] `100120733015` · L 65 / E 65.16 / Δ +0.16 · `hpcdb16093/gas | solid brick | pitched 125 | ext1,sec:room heaters` +- [x] `100120629168` · L 70 / E 70.16 / Δ +0.16 · `hpcdb9897/gas | cavity wall | pitched 100 | consv2,ext2` +- [x] `100100713371` · L 65 / E 65.16 / Δ +0.16 · `hpcdb17507/gas | cavity wall | pitched 125 | consv4` +- [x] `10033058144` · L 65 / E 65.16 / Δ +0.16 · `hpcdb18560/gas | cavity wall | pitched 200 | ext1` +- [x] `200002626191` · L 63 / E 63.16 / Δ +0.16 · `hpcdb17505/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `148007532` · L 61 / E 60.84 / Δ -0.16 · `hpcdb1396/gas | solid brick | pitched insulated | RR,consv2,ext1` +- [x] `100010043608` · L 56 / E 56.16 / Δ +0.16 · `h401/elec | cavity wall | pitched 200 | PV,RR,consv2,ext1,sec:room heaters,whw903` +- [x] `100022232588` · L 56 / E 56.16 / Δ +0.16 · `h102/gas | solid brick | pitched 25 | ext1` +- [x] `100110450961` · L 69 / E 68.84 / Δ -0.16 · `h104/gas | sandstone as | pitched 250 | ext1` +- [x] `11071248` · L 78 / E 77.84 / Δ -0.16 · `h402/elec | solid brick | (another dwelling | sec:portable electric,whw903` +- [x] `10014540481` · L 81 / E 81.15 / Δ +0.15 · `hpcdb16400/gas | timber frame | roof room(s) | RR` +- [x] `100061860491` · L 69 / E 68.85 / Δ -0.15 · `hpcdb18824/gas | cavity wall | pitched 250 | consv3` +- [x] `100121065133` · L 81 / E 80.85 / Δ -0.15 · `hpcdb17511/gas | cavity wall | (another dwelling` +- [x] `231757` · L 73 / E 73.15 / Δ +0.15 · `hpcdb17505/gas | sandstone as | pitched 75 | ext1` +- [x] `200001694377` · L 45 / E 44.85 / Δ -0.15 · `hpcdb18429/fuel28 | granite or | pitched 250 | ext3,sec:room heaters` +- [x] `100062331529` · L 81 / E 81.15 / Δ +0.15 · `hpcdb18908/gas | cavity wall | (another dwelling` +- [x] `10033267429` · L 57 / E 56.85 / Δ -0.15 · `h691/elec | system built | (another dwelling | whw903` +- [x] `100090372586` · L 71 / E 71.15 / Δ +0.15 · `h102/gas | cavity wall | pitched 300 | PV,consv3` +- [x] `100060587363` · L 62 / E 62.15 / Δ +0.15 · `hpcdb10462/gas | solid brick | pitched 250 | consv2,ext2,sec:room heaters` +- [x] `207037318` · L 59 / E 58.85 / Δ -0.15 · `h699/fuel0 | cavity wall | (another dwelling | sec:portable electric,whw903` +- [x] `100051048523` · L 67 / E 67.15 / Δ +0.15 · `hpcdb17507/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `551000` · L 72 / E 72.15 / Δ +0.15 · `h104/gas | cavity wall | pitched 150` +- [x] `202137997` · L 69 / E 68.85 / Δ -0.15 · `hpcdb10443/gas | cavity wall | (another dwelling` +- [x] `10090368756` · L 80 / E 79.85 / Δ -0.15 · `hpcdb17033/gas | cavity wall | pitched insulated | RR,ext3,sec:room heaters` +- [x] `100120881623` · L 53 / E 53.15 / Δ +0.15 · `h158/heatnet+2mains | solid brick | pitched insulated | ext4,sec:room heaters,whw903` +- [x] `5870106813` · L 78 / E 78.15 / Δ +0.15 · `hpcdb17505/gas | solid brick | pitched 300` +- [x] `100000056169` · L 62 / E 61.85 / Δ -0.15 · `hpcdb18559/gas | cavity wall | pitched 150 | consv2,ext1` +- [x] `21029519` · L 67 / E 66.85 / Δ -0.15 · `hpcdb17983/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100110469288` · L 67 / E 67.15 / Δ +0.15 · `hpcdb18155/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `10022949096` · L 74 / E 73.85 / Δ -0.15 · `hpcdb17507/gas | cavity wall | pitched 200` +- [x] `100000341714` · L 64 / E 64.15 / Δ +0.15 · `hpcdb15709/gas | system built | pitched 270` +- [x] `100021046998` · L 69 / E 69.15 / Δ +0.15 · `hpcdb10327/gas | solid brick | pitched 100 | ext1` +- [x] `100080902546` · L 79 / E 78.85 / Δ -0.15 · `hpcdb17696/gas | solid brick | pitched insulated | RR,ext1` +- [x] `100021286876` · L 66 / E 66.15 / Δ +0.15 · `hpcdb17503/gas | solid brick | pitched insulated` +- [x] `100070056707` · L 72 / E 72.14 / Δ +0.14 · `hpcdb17505/gas | system built | (another dwelling` +- [x] `72513535` · L 70 / E 70.14 / Δ +0.14 · `h691/elec | system built | (another dwelling | whw903` +- [x] `100080166923` · L 68 / E 67.86 / Δ -0.14 · `hpcdb18826/gas | cavity wall | pitched 75 | consv3,ext1` +- [x] `100023483089` · L 77 / E 76.86 / Δ -0.14 · `h409/elec | system built | (another dwelling | sec:portable electric,whw903` +- [x] `10096537371` · L 37 / E 37.14 / Δ +0.14 · `h691/elec | solid brick | pitched 200 | ext1,whw909` +- [x] `100011476438` · L 57 / E 56.86 / Δ -0.14 · `h402/elec | cavity wall | pitched 125 | sec:room heaters,whw903` +- [x] `100090106879` · L 70 / E 69.86 / Δ -0.14 · `hpcdb16836/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `10003800267` · L 72 / E 71.86 / Δ -0.14 · `h301/coal-anth | cavity wall | (another dwelling` +- [x] `100060412840` · L 66 / E 66.14 / Δ +0.14 · `h102/gas | cavity wall | pitched 50 | ext1` +- [x] `2465082925` · L 66 / E 66.14 / Δ +0.14 · `hpcdb16848/gas | cavity wall | pitched 250` +- [x] `100030001912` · L 69 / E 68.86 / Δ -0.14 · `hpcdb19080/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100010757788` · L 68 / E 68.14 / Δ +0.14 · `hpcdb18119/gas | cavity wall | pitched 100 | sec:portable electric` +- [x] `200001601290` · L 61 / E 60.86 / Δ -0.14 · `hpcdb16394/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100100085877` · L 72 / E 72.14 / Δ +0.14 · `hpcdb10122/gas | cavity wall | pitched 270 | ext2,sec:room heaters` +- [x] `10002473454` · L 74 / E 73.86 / Δ -0.14 · `hpcdb19006/gas | cavity wall | pitched 300` +- [x] `100121097651` · L 72 / E 72.14 / Δ +0.14 · `hpcdb18433/gas | cavity wall | pitched 350 | sec:room heaters` +- [x] `100040638671` · L 80 / E 80.14 / Δ +0.14 · `hpcdb10356/gas | cavity wall | pitched 200 | PV,ext4,sec:room heaters` +- [x] `10002096859` · L 79 / E 79.14 / Δ +0.14 · `hpcdb16835/gas | cavity wall | pitched 300 | ext2` +- [x] `100071033049` · L 62 / E 61.86 / Δ -0.14 · `hpcdb18908/gas | cavity wall | pitched 150 | sec:room heaters` +- [x] `100022619802` · L 79 / E 79.13 / Δ +0.13 · `hpcdb16375/gas | cavity wall | flat insulated` +- [x] `100081154129` · L 65 / E 64.87 / Δ -0.13 · `h408/elec | cavity wall | pitched 100 | consv2,whw903` +- [x] `10009274535` · L 31 / E 30.87 / Δ -0.13 · `h126/fuel28 | sandstone as | pitched 50 | consv4,ext2,sec:room heaters` +- [x] `1710040599` · L 70 / E 70.13 / Δ +0.13 · `h102/gas | cavity wall | pitched 100 | RR,sec:room heaters` +- [x] `100050824478` · L 72 / E 71.87 / Δ -0.13 · `hpcdb17615/gas | cavity wall | pitched 200 | ext1` +- [x] `100060005933` · L 71 / E 70.87 / Δ -0.13 · `h102/gas | cavity wall | pitched 175` +- [x] `100080706341` · L 62 / E 61.87 / Δ -0.13 · `hpcdb18045/gas | system built | pitched 75` +- [x] `200003644880` · L 59 / E 58.87 / Δ -0.13 · `hpcdb15290/gas | solid brick | pitched insulated | ext2,sec:room heaters` +- [x] `46083795` · L 78 / E 78.13 / Δ +0.13 · `hpcdb16930/gas | cavity wall | (another dwelling` +- [x] `10090342779` · L 81 / E 80.87 / Δ -0.13 · `hpcdb10327/gas | timber frame | pitched 300` +- [x] `77068182` · L 68 / E 68.13 / Δ +0.13 · `hpcdb10242/gas | cavity wall | pitched 75 | ext2` +- [x] `11077408` · L 67 / E 67.13 / Δ +0.13 · `hpcdb10356/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `100100869589` · L 62 / E 62.13 / Δ +0.13 · `hpcdb17983/gas | cavity wall | pitched 270 | mv5,sec:room heaters` +- [x] `77018431` · L 65 / E 64.87 / Δ -0.13 · `hpcdb17987/gas | cavity wall | pitched insulated | ext1` +- [x] `63064761` · L 72 / E 72.13 / Δ +0.13 · `hpcdb18907/gas | cavity wall | (another dwelling` +- [x] `100011790131` · L 60 / E 60.13 / Δ +0.13 · `hpcdb15709/gas | solid brick | pitched 270 | ext1,sec:room heaters` +- [x] `100011756441` · L 73 / E 73.13 / Δ +0.13 · `hpcdb18511/gas | cavity wall | pitched 75` +- [x] `202028377` · L 66 / E 66.13 / Δ +0.13 · `hpcdb17548/gas | solid brick | pitched 75` +- [x] `100090533643` · L 85 / E 85.13 / Δ +0.13 · `hpcdb17507/gas | cavity wall | pitched insulated | PV,ext1` +- [x] `100090335261` · L 70 / E 70.13 / Δ +0.13 · `hpcdb17974/gas | cavity wall | (another dwelling` +- [x] `100050048691` · L 58 / E 57.87 / Δ -0.13 · `hpcdb18991/fuel28 | solid brick | pitched 250 | sec:room heaters` +- [x] `100061898123` · L 70 / E 70.13 / Δ +0.13 · `hpcdb17511/gas | solid brick | pitched 100` +- [x] `38149813` · L 74 / E 73.87 / Δ -0.13 · `h104/gas | solid brick | pitched 350 | ext1` +- [x] `10014619006` · L 77 / E 77.13 / Δ +0.13 · `hpcdb17045/gas | cavity wall | pitched 350 | mv2` +- [x] `100091201592` · L 71 / E 70.87 / Δ -0.13 · `hpcdb10464/gas | cavity wall | pitched 150` +- [x] `100040888018` · L 75 / E 75.12 / Δ +0.12 · `hpcdb10265/gas | cavity wall | pitched 250` +- [x] `100030350883` · L 72 / E 72.12 / Δ +0.12 · `hpcdb17660/gas | solid brick | pitched 300 | ext1` +- [x] `12151106` · L 71 / E 70.88 / Δ -0.12 · `hpcdb17929/gas | solid brick | (another dwelling | ext1` +- [x] `22151573` · L 69 / E 68.88 / Δ -0.12 · `hpcdb17991/gas | solid brick | (another dwelling | ext1,sec:room heaters` +- [x] `10008151417` · L 75 / E 75.12 / Δ +0.12 · `hpcdb18619/gas | cavity wall | pitched 225 | ext1,sec:room heaters` +- [x] `100031658267` · L 67 / E 66.88 / Δ -0.12 · `hpcdb19019/gas | cavity wall | pitched 300` +- [x] `100010155093` · L 72 / E 71.88 / Δ -0.12 · `hpcdb15884/gas | cavity wall | pitched 200` +- [x] `10023692117` · L 71 / E 70.88 / Δ -0.12 · `hpcdb9228/gas | system built | flat insulated | ext3,mv3` +- [x] `36046440` · L 78 / E 77.88 / Δ -0.12 · `hpcdb16327/gas | cavity wall | pitched 250` +- [x] `10012226756` · L 79 / E 79.12 / Δ +0.12 · `hpcdb16682/gas | cavity wall | pitched 250` +- [x] `77068828` · L 69 / E 69.12 / Δ +0.12 · `hpcdb10265/gas | cavity wall | pitched 200 | ext1,sec:room heaters` +- [x] `100031461590` · L 62 / E 62.12 / Δ +0.12 · `hpcdb2038/gas | cavity wall | pitched 100 | sec:room heaters` +- [x] `261969` · L 75 / E 75.12 / Δ +0.12 · `hpcdb17683/gas | solid brick | (another dwelling | ext1` +- [x] `100090986049` · L 65 / E 65.12 / Δ +0.12 · `hpcdb18830/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `10003926370` · L 62 / E 62.12 / Δ +0.12 · `hpcdb860/fuel28 | cavity wall | pitched 100 | PV,consv2,sec:room heaters` +- [x] `37015003` · L 69 / E 69.11 / Δ +0.11 · `hpcdb18218/gas | cavity wall | pitched unknown | ext1` +- [x] `4510733560` · L 77 / E 76.89 / Δ -0.11 · `h113/gas | cavity wall | (another dwelling` +- [x] `303001209` · L 70 / E 69.89 / Δ -0.11 · `h301/coal-anth | cavity wall | pitched 225` +- [x] `217041293` · L 83 / E 83.11 / Δ +0.11 · `h404/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +- [x] `100030534734` · L 5 / E 4.89 / Δ -0.11 · `h631/LPG | sandstone as | pitched insulated | RR,ext1,sec:portable electric,whw903` +- [x] `10008651218` · L 78 / E 78.11 / Δ +0.11 · `hpcdb10243/gas | cavity wall | pitched 250` +- [x] `100091151352` · L 72 / E 71.89 / Δ -0.11 · `hpcdb10122/gas | solid brick | pitched 270 | ext1` +- [x] `452029430` · L 72 / E 71.89 / Δ -0.11 · `hpcdb10241/gas | cavity wall | pitched 100` +- [x] `100050435392` · L 69 / E 68.89 / Δ -0.11 · `hpcdb18047/gas | cavity wall | pitched 200 | ext1` +- [x] `100060864327` · L 75 / E 75.11 / Δ +0.11 · `hpcdb19006/gas | cavity wall | (another dwelling` +- [x] `100011385976` · L 71 / E 71.11 / Δ +0.11 · `hpcdb16839/gas | cavity wall | pitched 300` +- [x] `10090929166` · L 64 / E 63.89 / Δ -0.11 · `h691/elec | cavity wall | pitched insulated | whw909` +- [x] `100062012` · L 72 / E 72.11 / Δ +0.11 · `hpcdb17117/gas | solid brick | (another dwelling` +- [x] `100030293609` · L 60 / E 59.89 / Δ -0.11 · `hpcdb10328/gas | cavity wall | pitched 200 | sec:room heaters` +- [x] `200164795` · L 82 / E 81.89 / Δ -0.11 · `hpcdb16400/gas | cavity wall | pitched insulated | PV,RR,ext1` +- [x] `100022628872` · L 74 / E 74.11 / Δ +0.11 · `hpcdb18908/gas | cavity wall | (another dwelling` +- [x] `10014460343` · L 79 / E 78.89 / Δ -0.11 · `hpcdb15754/gas | cavity wall | pitched 250` +- [x] `10001142950` · L 69 / E 69.11 / Δ +0.11 · `h301/coal-anth | sandstone as | (another dwelling` +- [x] `10014526109` · L 59 / E 59.11 / Δ +0.11 · `h126/fuel28 | solid brick | flat insulated | consv2,ext1,sec:room heaters` +- [x] `38137278` · L 69 / E 69.11 / Δ +0.11 · `hpcdb18907/gas | cavity wall | pitched 400+ | ext2,mv2,sec:room heaters` +- [x] `100040565259` · L 66 / E 66.11 / Δ +0.11 · `hpcdb18221/gas | cavity wall | pitched 300 | ext1` +- [x] `100110437510` · L 87 / E 87.11 / Δ +0.11 · `hpcdb15709/gas | cavity wall | pitched 270 | PV,ext1,mv2,sec:room heaters` +- [x] `100051116259` · L 70 / E 70.11 / Δ +0.11 · `hpcdb15520/gas | cavity wall | pitched insulated | consv4,ext1,sec:room heaters` +- [x] `100031466637` · L 52 / E 51.89 / Δ -0.11 · `h409/elec | solid brick | pitched no | ext3,sec:room heaters,whw903` +- [x] `10070089948` · L 64 / E 64.11 / Δ +0.11 · `hpcdb19094/gas | sandstone as | pitched 270 | ext2,sec:room heaters` +- [x] `100090866399` · L 79 / E 78.89 / Δ -0.11 · `hpcdb18435/gas | cavity wall | pitched 200 | PV,ext2,sec:room heaters` +- [x] `100060052603` · L 58 / E 57.89 / Δ -0.11 · `hpcdb17553/gas | cavity wall | pitched 100 | consv2,sec:room heaters` +- [x] `100010170141` · L 61 / E 60.89 / Δ -0.11 · `hpcdb4045/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `100031245724` · L 69 / E 68.90 / Δ -0.10 · `hpcdb17660/gas | cavity wall | pitched 200` +- [x] `24029210` · L 75 / E 75.10 / Δ +0.10 · `hpcdb15704/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `217079598` · L 77 / E 77.10 / Δ +0.10 · `hpcdb18821/gas | system built | (another dwelling` +- [x] `10008290975` · L 79 / E 79.10 / Δ +0.10 · `hpcdb17973/gas | cavity wall | (another dwelling` +- [x] `100040140820` · L 61 / E 61.10 / Δ +0.10 · `hpcdb1768/fuel28 | cavity wall | pitched 225 | ext1` +- [x] `100090121779` · L 73 / E 73.10 / Δ +0.10 · `hpcdb18089/gas | cavity wall | pitched 125` +- [x] `42180235` · L 77 / E 77.10 / Δ +0.10 · `hpcdb18559/gas | cavity wall | (another dwelling` +- [x] `100061414159` · L 65 / E 65.10 / Δ +0.10 · `hpcdb17313/gas | solid brick | pitched 100 | RR,consv4,ext4` +- [x] `207156543` · L 69 / E 69.10 / Δ +0.10 · `hpcdb18773/gas | solid brick | pitched insulated` +- [x] `10071154302` · L 78 / E 77.90 / Δ -0.10 · `h301/coal-anth | system built | (another dwelling` +- [x] `10004779730` · L 67 / E 67.10 / Δ +0.10 · `hpcdb16398/gas | cavity wall | pitched 300 | ext1,sec:room heaters` +- [x] `10001005083` · L 65 / E 65.10 / Δ +0.10 · `hpcdb16840/gas | solid brick | (another dwelling` +- [x] `100040960726` · L 89 / E 88.90 / Δ -0.10 · `hpcdb16212/gas | cavity wall | pitched 250 | PV,consv3,ext4,sec:room heaters` +- [x] `100100694586` · L 69 / E 68.90 / Δ -0.10 · `hpcdb10315/gas | solid brick | pitched 75 | ext1` +- [x] `100061607458` · L 69 / E 68.90 / Δ -0.10 · `hpcdb18909/gas | cavity wall | pitched 100` +- [x] `10023410348` · L 68 / E 68.10 / Δ +0.10 · `h301/coal-anth | cavity wall | flat limited` +- [x] `207104025` · L 78 / E 78.10 / Δ +0.10 · `h104/gas | solid brick | pitched unknown` +- [x] `1775077083` · L 72 / E 72.10 / Δ +0.10 · `hpcdb17974/gas | cavity wall | pitched insulated | ext1` +- [x] `100120918121` · L 83 / E 83.10 / Δ +0.10 · `hpcdb18618/gas | cavity wall | pitched 200 | PV,ext1` +- [x] `200000766345` · L 70 / E 70.10 / Δ +0.10 · `hpcdb18827/gas | sandstone as | pitched 270 | ext1,sec:room heaters` +- [x] `100050413774` · L 63 / E 63.10 / Δ +0.10 · `h104/gas | sandstone as | pitched insulated | ext1` +- [x] `100021531772` · L 68 / E 68.10 / Δ +0.10 · `hpcdb18560/gas | solid brick | pitched 100 | ext1` +- [x] `100020596099` · L 50 / E 49.90 / Δ -0.10 · `hpcdb17550/gas | solid brick | pitched insulated | sec:room heaters` +- [x] `38191704` · L 73 / E 73.10 / Δ +0.10 · `hpcdb18107/gas | cavity wall | pitched 125 | consv3` +- [x] `10014478958` · L 77 / E 76.91 / Δ -0.09 · `hpcdb16137/gas | timber frame | pitched 250` +- [x] `100051276007` · L 63 / E 63.09 / Δ +0.09 · `hpcdb16212/gas | cavity wall | pitched 225 | sec:room heaters` +- [x] `100021503967` · L 68 / E 67.91 / Δ -0.09 · `hpcdb18509/gas | solid brick | pitched 100 | ext1` +- [x] `100080331733` · L 72 / E 71.91 / Δ -0.09 · `hpcdb17816/gas | cavity wall | pitched 100 | ext1` +- [x] `100100480670` · L 67 / E 67.09 / Δ +0.09 · `h104/gas | sandstone as | pitched 300` +- [x] `23014695` · L 78 / E 77.91 / Δ -0.09 · `hpcdb18560/gas | system built | pitched 250` +- [x] `10003971523` · L 78 / E 78.09 / Δ +0.09 · `hpcdb17683/gas | cavity wall | flat insulated` +- [x] `523424` · L 23 / E 22.91 / Δ -0.09 · `h104/biogas | sandstone as | pitched insulated | ext1,sec:portable electric` +- [x] `10023385904` · L 77 / E 76.91 / Δ -0.09 · `hpcdb15239/gas | cavity wall | pitched 300 | consv2` +- [x] `100070621229` · L 72 / E 71.91 / Δ -0.09 · `hpcdb15709/gas | solid brick | pitched unknown` +- [x] `5870046999` · L 73 / E 73.09 / Δ +0.09 · `hpcdb17973/gas | cavity wall | (another dwelling` +- [x] `100010384681` · L 75 / E 74.91 / Δ -0.09 · `hpcdb19080/gas | cavity wall | pitched 400+ | PV,ext1,sec:room heaters` +- [x] `100022536385` · L 71 / E 70.92 / Δ -0.08 · `hpcdb17505/gas | solid brick | pitched 300` +- [x] `100031433810` · L 70 / E 70.08 / Δ +0.08 · `hpcdb19094/gas | cavity wall | (another dwelling | ext1,sec:room heaters` +- [x] `1710029098` · L 69 / E 69.08 / Δ +0.08 · `hpcdb17958/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `100040884417` · L 70 / E 70.08 / Δ +0.08 · `hpcdb10328/gas | cavity wall | (another dwelling` +- [x] `100080706339` · L 65 / E 65.08 / Δ +0.08 · `hpcdb16396/gas | system built | pitched 250` +- [x] `10090018805` · L 77 / E 76.92 / Δ -0.08 · `hpcdb15017/gas | cavity wall | pitched 250` +- [x] `100034336` · L 60 / E 60.08 / Δ +0.08 · `hpcdb17815/gas | solid brick | pitched 100` +- [x] `line979` · L 71 / E 71.08 / Δ +0.08 · `hpcdb15710/gas | cavity wall | pitched insulated` +- [x] `100070431508` · L 64 / E 63.92 / Δ -0.08 · `hpcdb18119/gas | solid brick | pitched insulated | sec:room heaters` +- [x] `100110515214` · L 73 / E 72.92 / Δ -0.08 · `hpcdb17741/gas | cavity wall | pitched 400+ | mv2` +- [x] `100100415869` · L 67 / E 67.08 / Δ +0.08 · `h104/gas | cavity wall | pitched 270` +- [x] `1775078613` · L 72 / E 71.92 / Δ -0.08 · `h104/gas | cavity wall | pitched 150` +- [x] `100091367939` · L 62 / E 62.08 / Δ +0.08 · `h102/gas | cavity wall | pitched 150 | ext2,sec:room heaters` +- [x] `100110175491` · L 74 / E 74.08 / Δ +0.08 · `h102/gas | cavity wall | pitched 150 | ext1` +- [x] `10011830488` · L 75 / E 75.08 / Δ +0.08 · `h102/gas | cavity wall | pitched insulated | consv2` +- [x] `line621` · L 78 / E 78.07 / Δ +0.07 · `hpcdb17679/gas | solid brick | pitched insulated` +- [x] `11063823` · L 66 / E 66.07 / Δ +0.07 · `hpcdb17507/gas | cavity wall | pitched unknown` +- [x] `21093278` · L 73 / E 72.93 / Δ -0.07 · `hpcdb16573/gas | cavity wall | pitched 100` +- [x] `100051035527` · L 74 / E 73.93 / Δ -0.07 · `hpcdb16842/gas | cavity wall | pitched 300 | sec:room heaters` +- [x] `100010835776` · L 69 / E 68.93 / Δ -0.07 · `hpcdb17942/gas | cavity wall | pitched 270 | sec:room heaters` +- [x] `10090019843` · L 76 / E 75.93 / Δ -0.07 · `hpcdb17615/gas | cavity wall | pitched 100` +- [x] `10013351333` · L 70 / E 69.93 / Δ -0.07 · `hpcdb18759/gas | cavity wall | pitched insulated | consv4` +- [x] `100080359994` · L 72 / E 72.07 / Δ +0.07 · `hpcdb15462/gas | cavity wall | pitched insulated | ext1` +- [x] `100080794353` · L 73 / E 73.07 / Δ +0.07 · `hpcdb19027/gas | cavity wall | pitched 200 | ext1` +- [x] `1710007756` · L 76 / E 76.07 / Δ +0.07 · `h104/gas | cavity wall | pitched 250 | RR,ext1,sec:room heaters` +- [x] `100080985468` · L 71 / E 71.07 / Δ +0.07 · `hpcdb17505/gas | cavity wall | pitched 125` +- [x] `32067719` · L 67 / E 66.93 / Δ -0.07 · `h104/gas | cavity wall | pitched 150 | consv2,ext1` +- [x] `100011465293` · L 47 / E 46.93 / Δ -0.07 · `h115/gas | cavity wall | pitched insulated | ext1` +- [x] `line77` · L 76 / E 76.07 / Δ +0.07 · `h401/elec | cavity wall | (another dwelling | sec:portable electric,whw903` +- [x] `100061690837` · L 75 / E 75.07 / Δ +0.07 · `hpcdb18862/gas | cavity wall | pitched 50` +- [x] `100010434688` · L 72 / E 72.07 / Δ +0.07 · `hpcdb17956/gas | sandstone as | pitched insulated` +- [x] `6077577` · L 83 / E 82.93 / Δ -0.07 · `hpcdb16840/gas | cavity wall | (another dwelling` +- [x] `48102004` · L 71 / E 70.94 / Δ -0.06 · `hpcdb17501/gas | solid brick | pitched insulated` +- [x] `10032999260` · L 76 / E 76.06 / Δ +0.06 · `hpcdb18619/gas | cavity wall | pitched 150` +- [x] `100061778601` · L 68 / E 67.94 / Δ -0.06 · `hpcdb18861/gas | cavity wall | pitched 200 | ext2,mv5` +- [x] `10034910386` · L 74 / E 74.06 / Δ +0.06 · `h113/gas | solid brick | (another dwelling` +- [x] `5039119` · L 70 / E 70.06 / Δ +0.06 · `h409/elec | system built | (another dwelling | sec:portable electric,whw903` +- [x] `50034918` · L 77 / E 77.06 / Δ +0.06 · `hpcdb16777/gas | cavity wall | pitched 200` +- [x] `100061621130` · L 25 / E 24.94 / Δ -0.06 · `h102/fuel27 | timber frame | pitched 100 | RR,ext2,sec:room heaters` +- [x] `100121228675` · L 60 / E 60.06 / Δ +0.06 · `h301/coal-anth | sandstone as | (another dwelling` +- [x] `100051248025` · L 57 / E 56.94 / Δ -0.06 · `hpcdb19038/gas | cavity wall | pitched insulated | sec:room heaters` +- [x] `100040663826` · L 67 / E 66.95 / Δ -0.05 · `hpcdb17001/gas | cavity wall | pitched 200` +- [x] `100110441268` · L 75 / E 75.05 / Δ +0.05 · `hpcdb10444/gas | solid brick | pitched 200` +- [x] `310012948` · L 74 / E 74.05 / Δ +0.05 · `hpcdb16454/gas | cavity wall | pitched 200` +- [x] `100010129331` · L 70 / E 69.95 / Δ -0.05 · `hpcdb17843/gas | solid brick | pitched insulated | ext2` +- [x] `10090880711` · L 75 / E 74.95 / Δ -0.05 · `hpcdb16138/gas | cavity wall | pitched 200 | consv4` +- [x] `100070333776` · L 74 / E 73.95 / Δ -0.05 · `hpcdb19082/gas | cavity wall | (another dwelling` +- [x] `100040882044` · L 73 / E 72.95 / Δ -0.05 · `hpcdb16839/gas | system built | pitched 200` +- [x] `207102835` · L 64 / E 64.05 / Δ +0.05 · `hpcdb18908/gas | solid brick | pitched 125 | ext2` +- [x] `83122910` · L 60 / E 59.95 / Δ -0.05 · `hpcdb17985/gas | sandstone as | pitched 100 | sec:room heaters` +- [x] `100050869764` · L 71 / E 70.95 / Δ -0.05 · `hpcdb10315/gas | cavity wall | pitched 150` +- [x] `64107249` · L 66 / E 66.05 / Δ +0.05 · `hpcdb15706/gas | cavity wall | (another dwelling | consv2,ext1,sec:room heaters` +- [x] `10012785474` · L 75 / E 74.96 / Δ -0.04 · `hpcdb10243/gas | solid brick | (another dwelling` +- [x] `100062342550` · L 62 / E 61.96 / Δ -0.04 · `h301/elec10hr | cavity wall | pitched 350` +- [x] `10008919006` · L 51 / E 51.04 / Δ +0.04 · `hpcdb17055/gas | granite or | pitched no | ext1` +- [x] `83166253` · L 72 / E 72.04 / Δ +0.04 · `hpcdb18119/gas | cavity wall | pitched 150` +- [x] `100121099490` · L 75 / E 74.96 / Δ -0.04 · `hpcdb19016/gas | cavity wall | pitched 250` +- [x] `100031412745` · L 62 / E 61.96 / Δ -0.04 · `hpcdb18251/gas | solid brick | pitched 200 | ext2` +- [x] `3040036578` · L 64 / E 64.04 / Δ +0.04 · `hpcdb17553/gas | solid brick | pitched 250 | ext2` +- [x] `100031665275` · L 63 / E 63.04 / Δ +0.04 · `hpcdb17932/gas | solid brick | pitched 50 | ext4,sec:room heaters` +- [x] `1775039958` · L 71 / E 70.96 / Δ -0.04 · `hpcdb16841/gas | cavity wall | pitched 200` +- [x] `100100694867` · L 62 / E 62.04 / Δ +0.04 · `h119/gas | cavity wall | pitched insulated` +- [x] `100031723834` · L 54 / E 53.96 / Δ -0.04 · `hpcdb18560/gas | cavity wall | pitched 100 | consv2,ext1,sec:room heaters` +- [x] `10008662860` · L 69 / E 69.04 / Δ +0.04 · `hpcdb17505/gas | solid brick | pitched 100` +- [x] `100061845289` · L 68 / E 67.96 / Δ -0.04 · `h409/elec | cavity wall | pitched 350 | sec:portable electric,whw903` +- [x] `14046362` · L 77 / E 77.04 / Δ +0.04 · `h104/gas | cavity wall | (another dwelling` +- [x] `100036648` · L 60 / E 60.04 / Δ +0.04 · `h104/gas | solid brick | pitched 100 | ext1` +- [x] `5072574` · L 66 / E 65.96 / Δ -0.04 · `hpcdb16840/gas | cavity wall | flat no` +- [x] `15041433` · L 70 / E 69.96 / Δ -0.04 · `hpcdb17507/gas | cavity wall | pitched 300` +- [x] `10096767959` · L 73 / E 73.04 / Δ +0.04 · `h421/elec | cavity wall | pitched 300 | sec:portable electric,whw903` +- [x] `100100357016` · L 75 / E 74.96 / Δ -0.04 · `hpcdb17507/gas | cavity wall | pitched 250` +- [x] `100060926936` · L 44 / E 44.04 / Δ +0.04 · `hpcdb1135/gas | cavity wall | pitched unknown` +- [x] `100031375565` · L 70 / E 69.97 / Δ -0.03 · `hpcdb18907/gas | cavity wall | pitched 300` +- [x] `100050859732` · L 57 / E 57.03 / Δ +0.03 · `h104/gas | solid brick | pitched insulated | ext3` +- [x] `100010663631` · L 67 / E 67.03 / Δ +0.03 · `hpcdb17974/gas | cavity wall | pitched 100 | RR,consv4` +- [x] `100040268694` · L 58 / E 57.97 / Δ -0.03 · `h127/fuel28 | granite or | pitched insulated | RR,ext1,sec:room heaters` +- [x] `100011594820` · L 70 / E 69.97 / Δ -0.03 · `hpcdb16136/gas | cavity wall | pitched insulated` +- [x] `100031288765` · L 62 / E 61.97 / Δ -0.03 · `hpcdb18203/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +- [x] `10013290770` · L 54 / E 53.97 / Δ -0.03 · `h691/elec | cavity wall | (another dwelling | whw903` +- [x] `100080918720` · L 69 / E 68.97 / Δ -0.03 · `h104/gas | cavity wall | pitched 250` +- [x] `4510035778` · L 71 / E 71.03 / Δ +0.03 · `hpcdb15705/gas | cavity wall | pitched 250` +- [x] `100071152554` · L 72 / E 71.97 / Δ -0.03 · `hpcdb18559/gas | solid brick | pitched 100 | ext1,sec:room heaters` +- [x] `100110568321` · L 72 / E 71.97 / Δ -0.03 · `hpcdb15030/gas | cavity wall | pitched 270 | ext1` +- [x] `100021283678` · L 70 / E 69.97 / Δ -0.03 · `h102/gas | solid brick | pitched insulated | RR,ext1` +- [x] `100031023432` · L 65 / E 65.03 / Δ +0.03 · `hpcdb10200/gas | cavity wall | pitched 50 | ext1` +- [x] `100080699036` · L 67 / E 67.03 / Δ +0.03 · `hpcdb19014/gas | system built | pitched 300` +- [x] `43049701` · L 70 / E 69.97 / Δ -0.03 · `hpcdb19110/gas | cavity wall | pitched 350` +- [x] `100030742978` · L 14 / E 14.03 / Δ +0.03 · `h699/fuel0 | solid brick | pitched 300 | consv2,ext2,sec:portable electric,whw903` +- [x] `24113231` · L 74 / E 73.98 / Δ -0.02 · `hpcdb8787/gas | cavity wall | pitched 250` +- [x] `100120472369` · L 69 / E 68.98 / Δ -0.02 · `hpcdb16453/gas | cavity wall | pitched 75` +- [x] `100020394076` · L 71 / E 70.98 / Δ -0.02 · `hpcdb17115/gas | cavity wall | pitched 150` +- [x] `100061141934` · L 72 / E 71.98 / Δ -0.02 · `hpcdb18433/gas | cavity wall | pitched 100 | consv2` +- [x] `83159875` · L 74 / E 74.02 / Δ +0.02 · `hpcdb10328/gas | cavity wall | pitched 250 | PV,sec:room heaters` +- [x] `15042002` · L 62 / E 61.98 / Δ -0.02 · `hpcdb10327/gas | cavity wall | pitched 125 | ext1,sec:room heaters` +- [x] `1775087633` · L 72 / E 72.02 / Δ +0.02 · `h104/gas | cavity wall | (another dwelling` +- [x] `362182` · L 77 / E 77.02 / Δ +0.02 · `hpcdb17501/gas | sandstone with | pitched 200 | ext1` +- [x] `100050737075` · L 69 / E 69.02 / Δ +0.02 · `hpcdb16841/gas | cavity wall | pitched 250 | sec:room heaters` +- [x] `10093200879` · L 71 / E 70.98 / Δ -0.02 · `hpcdb16401/gas | cavity wall | pitched insulated | mv2` +- [x] `10003500583` · L 70 / E 69.98 / Δ -0.02 · `hpcdb18042/gas | cavity wall | pitched 250 | consv3,ext1,sec:room heaters` +- [x] `100051199928` · L 67 / E 66.98 / Δ -0.02 · `hpcdb19094/gas | cavity wall | pitched 300` +- [x] `100031526911` · L 71 / E 71.02 / Δ +0.02 · `hpcdb15502/gas | solid brick | pitched 250 | consv3,ext1,sec:room heaters` +- [x] `100060516940` · L 68 / E 67.98 / Δ -0.02 · `hpcdb9587/gas | cavity wall | pitched 200` +- [x] `100050345781` · L 66 / E 65.99 / Δ -0.01 · `hpcdb17985/gas | cavity wall | pitched 200 | ext2` +- [x] `100031601615` · L 73 / E 73.01 / Δ +0.01 · `hpcdb19080/gas | cavity wall | pitched insulated | RR,ext1` +- [x] `100032122827` · L 65 / E 64.99 / Δ -0.01 · `hpcdb18432/gas | cavity wall | pitched 250 | ext1,sec:room heaters` +- [x] `15068830` · L 74 / E 73.99 / Δ -0.01 · `hpcdb18768/gas | cavity wall | pitched 50 | sec:room heaters` +- [x] `32015803` · L 75 / E 75.01 / Δ +0.01 · `hpcdb18155/gas | cavity wall | (another dwelling` +- [x] `43002062` · L 72 / E 72.01 / Δ +0.01 · `hpcdb15707/gas | sandstone as | pitched 200` +- [x] `40057815` · L 78 / E 77.99 / Δ -0.01 · `hpcdb18225/gas | timber frame | pitched 175 | ext1` +- [x] `28052680` · L 76 / E 75.99 / Δ -0.01 · `hpcdb19080/gas | cavity wall | pitched 400+` +- [x] `77163938` · L 69 / E 68.99 / Δ -0.01 · `hpcdb17683/gas | solid brick | pitched insulated | ext1` +- [x] `100110766495` · L 79 / E 79.01 / Δ +0.01 · `hpcdb16839/gas | cavity wall | (another dwelling` +- [x] `100040446690` · L 72 / E 71.99 / Δ -0.01 · `h104/gas | system built | pitched 400+ | ext1,sec:room heaters` +- [x] `100090834242` · L 53 / E 52.99 / Δ -0.01 · `hpcdb16842/gas | cavity wall | pitched no | ext1,sec:room heaters` +- [x] `10033241196` · L 78 / E 78.01 / Δ +0.01 · `h691/elec | solid brick | pitched 100 | whw909` +- [x] `100061583852` · L 71 / E 71.01 / Δ +0.01 · `hpcdb17507/gas | cavity wall | pitched 300` +- [x] `10009446250` · L 43 / E 42.99 / Δ -0.01 · `h402/elec | cavity wall | pitched 250 | sec:portable electric,whw903` +- [x] `line996` · L 75 / E 74.99 / Δ -0.01 · `h104/gas | cavity wall | flat insulated` +- [x] `10014235074` · L 76 / E 75.99 / Δ -0.01 · `hpcdb18516/gas | cavity wall | pitched 200 | ext1` +- [x] `83182597` · L 71 / E 71.00 / Δ +0.00 · `hpcdb18225/gas | cavity wall | (another dwelling` +- [x] `100100122657` · L 61 / E 61.00 / Δ -0.00 · `hpcdb1514/gas | cavity wall | pitched 100 | ext1,sec:room heaters` +- [x] `10007364829` · L 74 / E 74.00 / Δ +0.00 · `hpcdb18432/gas | cavity wall | pitched 200` +- [x] `4510136787` · L 76 / E 76.00 / Δ +0.00 · `h409/elec | solid brick | (another dwelling | whw903` +- [x] `422000111926` · L 1 / E 1.00 / Δ +0.00 · `h699/fuel0 | solid brick | pitched no | sec:portable electric,whw999` + +
diff --git a/scripts/hyde/build_100021924710.py b/scripts/hyde/build_100021924710.py new file mode 100644 index 000000000..ec06d8427 --- /dev/null +++ b/scripts/hyde/build_100021924710.py @@ -0,0 +1,231 @@ +"""Elmhurst build for UPRN 100021924710 (RdSAP-21.0.1, MID-TERRACE HOUSE, band B, +SOLID BRICK 250 mm uninsulated, pitched insulated (assumed) loft, floor to +UNHEATED space, mains-gas COMBI (PCDB 19008) + gas room-heater SECONDARY, DUAL +meter, 11 DG windows ~18.32 m², TFA 116. Lodged SAP 63; engine 65.0 (Δ +2.0). + +Per-cert Elmhurst validation. Uses set_single_window (deletes the shared +assessment's carried-over window rows) + reset_transient_state at the end so the +assessment is left neutral. Run: + DISPLAY=:99 python scripts/hyde/build_100021924710.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +PWALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelPartyWallMain_WebUserControlPartyWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_100021924710") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + E.set_select(page, "DropDownListPropertyType1", "H House") + _pick(page, "DropDownListPropertyType2", "mid-terrace") or \ + _pick(page, "DropDownListPropertyType2", "mid terrace") + E.set_text(page, "TextBoxStoreys", "2") + E.set_text(page, "TextBoxHabitableRooms", "5") + E.set_text(page, "TextBoxHeatedHabitableRooms", "5") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1900-1929")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.set_select(page, "DropDownListRoomInRoofMain", "") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "59.20") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.74") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "16.0") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "21.1") + E.set_text(page, f"{DIM}TextBoxFloorArea1stFloor", "57.10") + E.set_text(page, f"{DIM}TextBoxRoomHeight1stFloor", "2.74") + E.set_text(page, f"{DIM}TextBoxWallPerimeter1stFloor", "15.7") + E.set_text(page, f"{DIM}TextBoxPartyWallLength1stFloor", "21.7") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + _pick(page, f"{WALL}DropDownListType", "solid brick") + page.wait_for_timeout(500) + print("insulation ->", _pick(page, f"{WALL}DropDownListInsulation", "as built")) + print("party ->", _pick(page, f"{PWALL}DropDownListPartyWallType", "determine") + or _pick(page, f"{PWALL}DropDownListPartyWallType", "masonry")) + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + _pick(page, f"{ROOF}DropDownListType", "access to loft") or \ + _pick(page, f"{ROOF}DropDownListType", "loft") + _pick(page, f"{ROOF}DropDownListInsulationAt", "joists") + _pick(page, f"{ROOF}DropDownListThickness", "unknown") or \ + _pick(page, f"{ROOF}DropDownListThickness", "assumed") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + _pick(page, f"{FLOOR}DropDownListLocation", "unheated") + page.wait_for_timeout(400) + _pick(page, f"{FLOOR}DropDownListType", "solid") + ins = page.locator(f"#{E.FP}{FLOOR}DropDownListInsulation") + if ins.count(): + E.set_select(page, f"{FLOOR}DropDownListInsulation", "A As built") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + page.wait_for_timeout(500) + E.set_single_window(page, 18.32, "North", + _glazing(page) if False else "Double post or during 2022") + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "1") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + return "Double with unknown install date" + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "1") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "8") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + # dual meter (cert meter_type 1) + E.click_tab(page, "TabContainer_TabPanelMeters") + try: + E.set_select(page, "TabContainer_TabPanelMeters_RadioButtonListElectricityType", "Dual") + except Exception: + pass + E.save_close(page) + + +def secondary(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(600) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "Yes") + page.wait_for_timeout(900) + E.set_heating_dialog(page, "ButtonSecondaryHeatingCode", + "^Gas", "Mains gas", "Room Heater") + tb = page.locator(f"#{E.FP}TextBoxSecondaryHeatingCode") + print("secondary code:", tb.input_value() if tb.count() else "?") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + E.goto(page, "Recommendations", "WebFormRecommendations.aspx") + page.wait_for_timeout(1500) + with page.expect_navigation(wait_until="networkidle", timeout=40000): + page.click("#ContentBody_buttonActionSummary_Link", timeout=15000) + page.wait_for_timeout(2000) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60000) as dl: + page.click(f"#{btn}", timeout=15000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +def cleanup(page): + """Leave the shared assessment neutral for the next build.""" + E.reset_transient_state(page) + print("reset transient state (RR/secondary/meter)") + + +_ORDER = ["property_description", "dimensions", "walls", "roofs", "floors", + "openings", "ventilation", "space_heating", "secondary", + "water_heating", "download", "cleanup"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_100021924710.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/hyde/build_100050881708.py b/scripts/hyde/build_100050881708.py new file mode 100644 index 000000000..e61ddbd8d --- /dev/null +++ b/scripts/hyde/build_100050881708.py @@ -0,0 +1,223 @@ +"""Elmhurst build for UPRN 100050881708 (RdSAP-21.0.1, MID-TERRACE HOUSE, band B, +SOLID BRICK 250 mm uninsulated, pitched insulated (assumed) loft, floor to +UNHEATED space, mains-gas COMBI (PCDB 19008) + gas room-heater SECONDARY, DUAL +meter, 11 DG windows ~18.32 m², TFA 116. Lodged SAP 63; engine 65.0 (Δ +2.0). + +Per-cert Elmhurst validation. Uses set_single_window (deletes the shared +assessment's carried-over window rows) + reset_transient_state at the end so the +assessment is left neutral. Run: + DISPLAY=:99 python scripts/hyde/build_100050881708.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +PWALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelPartyWallMain_WebUserControlPartyWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_100050881708") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + E.set_select(page, "DropDownListPropertyType1", "H House") + _pick(page, "DropDownListPropertyType2", "semi") + E.set_text(page, "TextBoxStoreys", "2") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1900-1929")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.set_select(page, "DropDownListRoomInRoofMain", "") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "31.62") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "16.4") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "6.2") + E.set_text(page, f"{DIM}TextBoxFloorArea1stFloor", "31.62") + E.set_text(page, f"{DIM}TextBoxRoomHeight1stFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeter1stFloor", "16.4") + E.set_text(page, f"{DIM}TextBoxPartyWallLength1stFloor", "6.2") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + _pick(page, f"{WALL}DropDownListType", "cavity") + page.wait_for_timeout(500) + print("insulation ->", _pick(page, f"{WALL}DropDownListInsulation", "filled")) + print("party ->", _pick(page, f"{PWALL}DropDownListPartyWallType", "determine") + or _pick(page, f"{PWALL}DropDownListPartyWallType", "masonry")) + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + _pick(page, f"{ROOF}DropDownListType", "access to loft") or \ + _pick(page, f"{ROOF}DropDownListType", "loft") + _pick(page, f"{ROOF}DropDownListInsulationAt", "joists") + _pick(page, f"{ROOF}DropDownListThickness", "225") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + _pick(page, f"{FLOOR}DropDownListLocation", "unheated") + page.wait_for_timeout(400) + _pick(page, f"{FLOOR}DropDownListType", "solid") + ins = page.locator(f"#{E.FP}{FLOOR}DropDownListInsulation") + if ins.count(): + E.set_select(page, f"{FLOOR}DropDownListInsulation", "A As built") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + page.wait_for_timeout(500) + E.set_single_window(page, 9.56, "North", + _glazing(page) if False else "Double post or during 2022") + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "2") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + return "Double with unknown install date" + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "2") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "8") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "No") + E.save_close(page) + + +def secondary(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(600) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "Yes") + page.wait_for_timeout(900) + E.set_heating_dialog(page, "ButtonSecondaryHeatingCode", + "^Gas", "Mains gas", "Room Heater") + tb = page.locator(f"#{E.FP}TextBoxSecondaryHeatingCode") + print("secondary code:", tb.input_value() if tb.count() else "?") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + E.goto(page, "Recommendations", "WebFormRecommendations.aspx") + page.wait_for_timeout(1500) + with page.expect_navigation(wait_until="networkidle", timeout=40000): + page.click("#ContentBody_buttonActionSummary_Link", timeout=15000) + page.wait_for_timeout(2000) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60000) as dl: + page.click(f"#{btn}", timeout=15000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +def cleanup(page): + """Leave the shared assessment neutral for the next build.""" + E.reset_transient_state(page) + print("reset transient state (RR/secondary/meter)") + + +_ORDER = ["property_description", "dimensions", "walls", "roofs", "floors", + "openings", "ventilation", "space_heating", "water_heating", "download", "cleanup"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_100050881708.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/hyde/build_100061275133.py b/scripts/hyde/build_100061275133.py new file mode 100644 index 000000000..106488c79 --- /dev/null +++ b/scripts/hyde/build_100061275133.py @@ -0,0 +1,230 @@ +"""Elmhurst build for UPRN 100061275133 (RdSAP-21.0.1, SEMI-DETACHED HOUSE, band B, +SOLID BRICK 400 mm with EXTERNAL insulation, pitched 300 mm loft, ground floor +SUSPENDED, no insulation (assumed) — no per-bp floor_construction_type lodged, +mains-gas COMBI (PCDB 18908, Worcester Greenstar 4000 88.70%), no secondary +heating, single meter, 12 DG windows ~15.32 m², TFA 78. Lodged SAP 76; engine +76 (76.33, exact match after the §5 (12) floor-infiltration fix). + +Per-cert Elmhurst validation. Uses set_single_window (deletes the shared +assessment's carried-over window rows) + reset_transient_state at the end so the +assessment is left neutral. Run: + DISPLAY=:99 python scripts/hyde/build_100061275133.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +PWALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelPartyWallMain_WebUserControlPartyWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_100061275133") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + E.set_select(page, "DropDownListPropertyType1", "H House") + _pick(page, "DropDownListPropertyType2", "semi") + E.set_text(page, "TextBoxStoreys", "2") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1900-1929")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.set_select(page, "DropDownListRoomInRoofMain", "") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "38.99") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "17.92") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "5.09") + E.set_text(page, f"{DIM}TextBoxFloorArea1stFloor", "38.99") + E.set_text(page, f"{DIM}TextBoxRoomHeight1stFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeter1stFloor", "17.92") + E.set_text(page, f"{DIM}TextBoxPartyWallLength1stFloor", "5.09") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + _pick(page, f"{WALL}DropDownListType", "solid brick") + page.wait_for_timeout(500) + print("insulation ->", _pick(page, f"{WALL}DropDownListInsulation", "external")) + print("party ->", _pick(page, f"{PWALL}DropDownListPartyWallType", "determine") + or _pick(page, f"{PWALL}DropDownListPartyWallType", "masonry")) + # wall thickness (cert lodges 400 mm; Elmhurst else defaults 260) + for suf in (f"{WALL}TextBoxThickness", f"{WALL}TextBoxWallThickness"): + if page.locator(f"#{E.FP}{suf}").count(): + E.set_text(page, suf, "400"); print("wall thickness set 400 via", suf); break + else: + print("thickness field not found; wall fields:", [i for i in page.evaluate("()=>Array.from(document.querySelectorAll('[id*=Wall]')).map(e=>e.id)")][:20]) + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + _pick(page, f"{ROOF}DropDownListType", "access to loft") or \ + _pick(page, f"{ROOF}DropDownListType", "loft") + _pick(page, f"{ROOF}DropDownListInsulationAt", "joists") + _pick(page, f"{ROOF}DropDownListThickness", "300") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + _pick(page, f"{FLOOR}DropDownListLocation", "ground floor") + page.wait_for_timeout(400) + _pick(page, f"{FLOOR}DropDownListType", "suspended") + ins = page.locator(f"#{E.FP}{FLOOR}DropDownListInsulation") + if ins.count(): + E.set_select(page, f"{FLOOR}DropDownListInsulation", "A As built") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + page.wait_for_timeout(500) + E.set_single_window(page, 15.32, "North", _glazing(page)) + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "2") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "2") # cert: percent_draughtproofed=100 + E.save_close(page) + + +def _glazing(page): + # glazed_type 13 -> double glazed, 2022 or later (U 1.4) + return "Double post or during 2022" + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + # Cert lodges no extract-fan count; RdSAP 10 Table 5 age-band default for + # band B (A-E) is 0, and our engine's ventilation_from_cert computes 0 — + # was wrongly entered as 1 here, inflating Elmhurst's (8)/(21) ACH vs ours. + E.set_text(page, f"{VP}TextBoxIntermittentFans", "0") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "5") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "5") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + # PCDB exact-boiler entry (elmhurst_lib.set_pcdb_boiler): the cert's + # main_heating_index_number 18908 resolves to Worcester Greenstar 4000 + # GR4700iW 25 C NG, 88.70% winter efficiency — matching the SAP engine's + # PCDB lookup exactly, vs the generic "Combi condens" SAP-Table code + # (84%) the old dialog-driven entry carried a keep-hot artifact from. + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + E.clear_main_heating_code(page) + desc = E.set_pcdb_boiler(page, 18908) + print("PCDB boiler ->", desc) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "No") + E.save_close(page) + + +def _unused_secondary(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(600) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "Yes") + page.wait_for_timeout(900) + E.set_heating_dialog(page, "ButtonSecondaryHeatingCode", + "^Gas", "Mains gas", "Room Heater") + tb = page.locator(f"#{E.FP}TextBoxSecondaryHeatingCode") + print("secondary code:", tb.input_value() if tb.count() else "?") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + E.goto(page, "Recommendations", "WebFormRecommendations.aspx") + page.wait_for_timeout(1500) + with page.expect_navigation(wait_until="networkidle", timeout=40000): + page.click("#ContentBody_buttonActionSummary_Link", timeout=15000) + page.wait_for_timeout(2000) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60000) as dl: + page.click(f"#{btn}", timeout=15000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +def cleanup(page): + """Leave the shared assessment neutral for the next build.""" + E.reset_transient_state(page) + print("reset transient state (RR/secondary/meter)") + + +_ORDER = ["property_description", "dimensions", "walls", "roofs", "floors", + "openings", "ventilation", "space_heating", + "water_heating", "download", "cleanup"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_100061275133.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/hyde/build_200004296092.py b/scripts/hyde/build_200004296092.py new file mode 100644 index 000000000..926b6809c --- /dev/null +++ b/scripts/hyde/build_200004296092.py @@ -0,0 +1,297 @@ +"""Elmhurst build for UPRN 200004296092 (RdSAP-Schema-21.0.1, END-TERRACE HOUSE, +2-storey, band B, SOLID BRICK 360 mm WITH EXTERNAL INSULATION (thickness lodged +"NI" = unknown), pitched 150 mm loft, solid uninsulated ground floor, mains-gas +COMBI (PCDB 16137 Ideal Logic combi 30 ~ generic Post-98 condensing combi), +control 2106 (CBE), double glazed ~4.31 m², 2 doors, TFA ~62, party wall 6.79 m. +Engine 71.74 = lodged 71 AFTER the §5.4 "assume 100 mm if unknown" wall fix +(slice 5); this build validates that against the accredited Elmhurst worksheet. + +The KEY page is `walls`: it prints Elmhurst's insulation dropdown so we can see +how the accredited tool handles External insulation of unknown thickness. Run: + DISPLAY=:99 python scripts/hyde/build_200004296092.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +PWALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelPartyWallMain_WebUserControlPartyWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +WP = "TabContainer_TabPanelWindowsPanel_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" + +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_200004296092") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def _options(page, suffix): + return page.evaluate( + """(id)=>{const s=document.getElementById(id);if(!s)return []; + return Array.from(s.options).map(o=>o.text);}""", f"{E.FP}{suffix}") + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + E.set_select(page, "DropDownListPropertyType1", "H House") + print("built_form ->", _pick(page, "DropDownListPropertyType2", "end-terrace") + or _pick(page, "DropDownListPropertyType2", "end terrace")) + E.set_text(page, "TextBoxStoreys", "2") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1900-1929") + or _pick(page, "DropDownListDateBuiltMain", "1900")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.set_select(page, "DropDownListRoomInRoofMain", "") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "31.16") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "15.97") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "6.79") + E.set_text(page, f"{DIM}TextBoxFloorArea1stFloor", "31.16") + E.set_text(page, f"{DIM}TextBoxRoomHeight1stFloor", "2.40") + E.set_text(page, f"{DIM}TextBoxWallPerimeter1stFloor", "15.97") + E.set_text(page, f"{DIM}TextBoxPartyWallLength1stFloor", "6.79") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + print("WALL TYPE options:", _options(page, f"{WALL}DropDownListType")) + _pick(page, f"{WALL}DropDownListType", "solid brick") \ + or _pick(page, f"{WALL}DropDownListType", "brick") + page.wait_for_timeout(600) + print("INSULATION options:", _options(page, f"{WALL}DropDownListInsulation")) + ins = (_pick(page, f"{WALL}DropDownListInsulation", "external") + or _pick(page, f"{WALL}DropDownListInsulation", "ext")) + print("insulation ->", ins) + page.wait_for_timeout(600) + # If a thickness dropdown appears for external insulation, show it (this is + # the slice-5 question: what does Elmhurst do with UNKNOWN thickness?). + for suf in (f"{WALL}DropDownListInsulationThickness", + f"{WALL}DropDownListExternalInsulationThickness"): + if page.locator(f"#{E.FP}{suf}").count(): + print("INSULATION THICKNESS options:", _options(page, suf), + "current:", page.locator(f"#{E.FP}{suf}").input_value()) + print("party wall ->", + _pick(page, f"{PWALL}DropDownListPartyWallType", "determine") + or _pick(page, f"{PWALL}DropDownListPartyWallType", "masonry")) + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + _pick(page, f"{ROOF}DropDownListType", "access to loft") \ + or _pick(page, f"{ROOF}DropDownListType", "loft") + _pick(page, f"{ROOF}DropDownListInsulationAt", "joists") + E.set_select(page, f"{ROOF}DropDownListThickness", "150 mm") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + E.set_select(page, f"{FLOOR}DropDownListLocation", "G Ground floor") + _pick(page, f"{FLOOR}DropDownListType", "solid") + E.set_select(page, f"{FLOOR}DropDownListInsulation", "A As built") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + _add_window(page, 4.31, "North", _glazing(page)) + _delete_zero_rows(page) + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "2") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + for needle in ("unknown install date", "before 2002", "pre 2002"): + for opt in _options(page, f"{WP}DropDownListExtGlazing"): + low = opt.lower() + if needle in low and "triple" not in low and "single" not in low and "known data" not in low: + return opt + return "Double post or during 2022" + + +def _add_window(page, area, orientation, glazing): + print("glazing ->", glazing) + E.set_select(page, f"{WP}DropDownListExtGlazing", glazing) + page.wait_for_timeout(400) + ft = page.locator(f"#{E.FP}{WP}DropDownListExtFrameType") + if ft.count(): + ft.select_option("PVC") + gg = page.locator(f"#{E.FP}{WP}DropDownListExtGlazingGap") + if gg.count(): + gg.select_option("12 mm") + wid = f"{E.FP}{WP}TextBoxExtWidth" + page.evaluate( + """(a)=>{const e=document.getElementById(a[0]);if(e){e.value=a[1]; + e.dispatchEvent(new Event('input',{bubbles:true})); + e.dispatchEvent(new Event('change',{bubbles:true})); + e.dispatchEvent(new Event('blur',{bubbles:true}));}}""", [wid, str(area)]) + page.locator(f"#{E.FP}{WP}TextBoxExtHeight").fill("1.00") + page.locator(f"#{E.FP}{WP}DropDownListExtOrientation").select_option(orientation) + page.locator(f"#{E.FP}{WP}DropDownListExtBuildingPartId").select_option("Main") + page.locator(f"#{E.FP}{WP}DropDownListExtLocation").select_option("External wall") + page.wait_for_timeout(300) + before = E.window_row_count(page) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}{WP}ButtonAddWindow") + for _ in range(25): + page.wait_for_timeout(200) + if E.window_row_count(page) > before: + break + + +def _grid_rows(page): + return page.evaluate( + """()=>{const t=document.querySelector("[id*=GridViewExtendedWidows]"); + if(!t)return[];return Array.from(t.querySelectorAll('tr')).slice(1) + .map(r=>Array.from(r.querySelectorAll('td')).map(c=>c.innerText.trim()));}""") + + +def _delete_zero_rows(page): + g = 0 + while g < 6 and E.window_row_count(page) > 1: + g += 1 + rows = _grid_rows(page) + bad = next((i for i, c in enumerate(rows) if len(c) > 1 and c[1] in ("0.00", "0", "0.0")), None) + if bad is None: + break + _delete_row(page, bad) + page.wait_for_timeout(400) + + +def _delete_row(page, idx): + before = E.window_row_count(page) + btn = page.evaluate( + """(i)=>{const b=document.querySelectorAll("[id*='GridViewExtendedWidows_DeleteButton_']");return b[i]?b[i].id:null;}""", idx) + if not btn: + return + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", btn) + page.wait_for_selector(f"#{E.FP}DeleteWindowDialog_LinkButtonYes", state="visible", timeout=5000) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}DeleteWindowDialog_LinkButtonYes") + for _ in range(20): + page.wait_for_timeout(200) + if E.window_row_count(page) < before: + break + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "0") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "6") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + # Generic Post-1998 condensing combi (~89% SAP 4b, ≈ PCDB 16137 Ideal Logic + # combi 30). combi vs regular is set on the water page (from primary + no + # cylinder). Control 2106 = CBE (programmer, room thermostat and TRVs). + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "No") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + print("navigating via Recommendations ...") + with page.expect_navigation(wait_until="networkidle", timeout=60_000): + page.click("#ContentBody_buttonActionRecommendations_Link", timeout=15_000) + page.wait_for_timeout(1500) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60_000) as dl: + page.click(f"#{btn}", timeout=15_000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +_ORDER = ["property_description", "dimensions", "walls", "roofs", "floors", + "openings", "ventilation", "space_heating", "water_heating", "download"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_200004296092.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/hyde/build_217091901.py b/scripts/hyde/build_217091901.py new file mode 100644 index 000000000..f487d973c --- /dev/null +++ b/scripts/hyde/build_217091901.py @@ -0,0 +1,287 @@ +"""Elmhurst build for UPRN 217091901 (RdSAP-21.0.1, TOP-FLOOR FLAT, band A, +SOLID BRICK 280 mm UNINSULATED, FLAT ROOF no insulation (As Built), floor over +ANOTHER DWELLING below (zero loss), mains-gas COMBI (PCDB 18658), 6 DG windows +~8.62 m², no doors, TFA 63. Lodged SAP 62; engine 60.82 (Δ −1.18, PE +8.7). + +Per-cert worksheet validation. The roof dominates loss (145.6 W/K at flat-default +U 2.30); this build confirms the accredited uninsulated flat-roof + solid-brick +wall U against the engine. Run: + DISPLAY=:99 python scripts/hyde/build_217091901.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +WP = "TabContainer_TabPanelWindowsPanel_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_217091901") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def _options(page, suffix): + return page.evaluate( + """(id)=>{const s=document.getElementById(id);if(!s)return []; + return Array.from(s.options).map(o=>o.text);}""", f"{E.FP}{suffix}") + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + _pick(page, "DropDownListPropertyType1", "flat") or \ + E.set_select(page, "DropDownListPropertyType1", "F Flat") + E.set_text(page, "TextBoxStoreys", "1") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "before 1900")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.save_close(page) + + +def flats(page): + E.goto(page, "Flats", "WebFormFlats.aspx") + print("flat positions:", _options(page, "" if False else "DropDownListPositionOfFlat")) + _pick(page, "DropDownListPositionOfFlat", "top") or \ + E.set_select(page, "DropDownListPositionOfFlat", "Top Floor") + E.set_text(page, "TextBoxFloor", "3") + E.set_select(page, "RadioButtonListFlatCoridor", "None") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "63.29") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.85") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "14.0") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "22.8") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + _pick(page, f"{WALL}DropDownListType", "solid brick") + page.wait_for_timeout(500) + print("insulation opts:", _options(page, f"{WALL}DropDownListInsulation")) + _pick(page, f"{WALL}DropDownListInsulation", "as built") or \ + _pick(page, f"{WALL}DropDownListInsulation", "none") + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + print("ROOF TYPE opts:", _options(page, f"{ROOF}DropDownListType")) + _pick(page, f"{ROOF}DropDownListType", "flat") + page.wait_for_timeout(600) + _pick(page, f"{ROOF}DropDownListInsulationAt", "flat roof insulation") + page.wait_for_timeout(600) + # discover the thickness/additional field that appears for flat-roof insulation + for suf in (f"{ROOF}DropDownListThickness", f"{ROOF}DropDownListInsulation", + f"{ROOF}DropDownListAdditionalInsulation"): + if page.locator(f"#{E.FP}{suf}").count(): + print(f" {suf.split('_')[-1]} opts:", _options(page, suf)) + _pick(page, suf, "as built") or _pick(page, suf, "unknown") or \ + _pick(page, suf, "none") or _pick(page, suf, "nil") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + print("FLOOR LOCATION opts:", _options(page, f"{FLOOR}DropDownListLocation")) + # "(other premises below)" = above a partially-heated space + _pick(page, f"{FLOOR}DropDownListLocation", "another dwelling below") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + E.set_single_window(page, 8.62, "North", _glazing(page)) + _delete_zero_rows(page) + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "0") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + # Cert glazed_type=5 → SINGLE glazing (epc_codes.csv, RdSAP-Schema-21). + for opt in _options(page, f"{WP}DropDownListExtGlazing"): + if "single" in opt.lower(): + return opt + return "Single glazed" + + +def _add_window(page, area, orientation, glazing): + print("glazing ->", glazing) + E.set_select(page, f"{WP}DropDownListExtGlazing", glazing) + page.wait_for_timeout(400) + ft = page.locator(f"#{E.FP}{WP}DropDownListExtFrameType") + if ft.count(): + ft.select_option("PVC") + gg = page.locator(f"#{E.FP}{WP}DropDownListExtGlazingGap") + if gg.count(): + gg.select_option("12 mm") + wid = f"{E.FP}{WP}TextBoxExtWidth" + page.evaluate( + """(a)=>{const e=document.getElementById(a[0]);if(e){e.value=a[1]; + e.dispatchEvent(new Event('input',{bubbles:true})); + e.dispatchEvent(new Event('change',{bubbles:true})); + e.dispatchEvent(new Event('blur',{bubbles:true}));}}""", [wid, str(area)]) + page.locator(f"#{E.FP}{WP}TextBoxExtHeight").fill("1.00") + page.locator(f"#{E.FP}{WP}DropDownListExtOrientation").select_option(orientation) + page.locator(f"#{E.FP}{WP}DropDownListExtBuildingPartId").select_option("Main") + page.locator(f"#{E.FP}{WP}DropDownListExtLocation").select_option("External wall") + page.wait_for_timeout(300) + before = E.window_row_count(page) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}{WP}ButtonAddWindow") + for _ in range(25): + page.wait_for_timeout(200) + if E.window_row_count(page) > before: + break + + +def _grid_rows(page): + return page.evaluate( + """()=>{const t=document.querySelector("[id*=GridViewExtendedWidows]"); + if(!t)return[];return Array.from(t.querySelectorAll('tr')).slice(1) + .map(r=>Array.from(r.querySelectorAll('td')).map(c=>c.innerText.trim()));}""") + + +def _delete_zero_rows(page): + g = 0 + while g < 6 and E.window_row_count(page) > 1: + g += 1 + rows = _grid_rows(page) + bad = next((i for i, c in enumerate(rows) if len(c) > 1 and c[1] in ("0.00", "0", "0.0")), None) + if bad is None: + break + _delete_row(page, bad) + page.wait_for_timeout(400) + + +def _delete_row(page, idx): + before = E.window_row_count(page) + btn = page.evaluate( + """(i)=>{const b=document.querySelectorAll("[id*='GridViewExtendedWidows_DeleteButton_']");return b[i]?b[i].id:null;}""", idx) + if not btn: + return + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", btn) + page.wait_for_selector(f"#{E.FP}DeleteWindowDialog_LinkButtonYes", state="visible", timeout=5000) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}DeleteWindowDialog_LinkButtonYes") + for _ in range(20): + page.wait_for_timeout(200) + if E.window_row_count(page) < before: + break + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "0") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "6") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "No") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + E.goto(page, "Recommendations", "WebFormRecommendations.aspx") + page.wait_for_timeout(1500) + with page.expect_navigation(wait_until="networkidle", timeout=40000): + page.click("#ContentBody_buttonActionSummary_Link", timeout=15000) + page.wait_for_timeout(2000) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60000) as dl: + page.click(f"#{btn}", timeout=15000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +_ORDER = ["property_description", "flats", "dimensions", "walls", "roofs", + "floors", "openings", "ventilation", "space_heating", "water_heating", + "download"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_217091901.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/hyde/build_47084930.py b/scripts/hyde/build_47084930.py new file mode 100644 index 000000000..679a9e56e --- /dev/null +++ b/scripts/hyde/build_47084930.py @@ -0,0 +1,299 @@ +"""Elmhurst build for UPRN 47084930 (RdSAP-21.0.1, TOP-FLOOR FLAT, band E, +CAVITY wall with INTERNAL insulation (100 mm), FLAT ROOF insulated 75 mm, floor +over OTHER PREMISES below, mains-gas COMBI (PCDB 17815), 5 DG windows ~9.9 m², +no doors, TFA 64. Lodged SAP 74; engine 69.51 (Δ −4.49, PE +47 over-count). + +Per-cert worksheet validation. Suspected engine gap: the flat-roof insulation +thickness is lodged in `flat_roof_insulation_thickness` (75 mm) but the U-value +calc reads `roof_insulation_thickness` (None) → bills the roof at the age-E flat +default 1.5 (96 W/K) instead of the 75 mm insulated ~0.5 (~30 W/K). This build +gets the accredited flat-roof + floor U. Run: + DISPLAY=:99 python scripts/hyde/build_47084930.py +""" +from __future__ import annotations +import sys +from pathlib import Path +import elmhurst_lib as E + +DIM = "TabContainer_TabPanelMain_WebUserControlDimensionsMain_" +WALL = ("TabContainer_TabPanelMain_InnerTabContainerMain_" + "TabPanelExternalWallMain_WebUserControlWallMain_") +ROOF = "TabContainer_TabPanelMain_WebUserControlRoofMain_" +FLOOR = "TabContainer_TabPanelMain_WebUserControlFloorsMain_" +WP = "TabContainer_TabPanelWindowsPanel_" +DP = "TabContainer_TabPanelDoorsPanel_" +VP = "TabContainer_TabPanelVentilationPanel_" +APT = "TabContainer_TabPanelAirPressureTest_" +LP = "TabContainer_TabPanelLighting_" +MV = "TabContainer_TabPanelMechVent_" +WH = "TabContainer_TabPanelWaterHeating_" +MH1B = "TabContainer_TabPanelMainHeating1_WebUserControlMainHeating1_" +_SAMPLE_DIR = (Path(__file__).parent.parent.parent + / "backend/epc_api/json_samples/real_life_examples" + / "RdSAP-Schema-21.0.1/uprn_47084930") + + +def _pick(page, suffix, contains): + val = page.evaluate( + """(a)=>{const s=document.getElementById(a[0]);if(!s)return null; + for(const o of s.options){if(o.text.toLowerCase().includes(a[1].toLowerCase()))return o.value;}return null;}""", + [f"{E.FP}{suffix}", contains]) + if val is not None: + E.set_select(page, suffix, val) + return val + + +def _options(page, suffix): + return page.evaluate( + """(id)=>{const s=document.getElementById(id);if(!s)return []; + return Array.from(s.options).map(o=>o.text);}""", f"{E.FP}{suffix}") + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + _pick(page, "DropDownListPropertyType1", "flat") or \ + E.set_select(page, "DropDownListPropertyType1", "F Flat") + E.set_text(page, "TextBoxStoreys", "1") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1967-1975")) + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.save_close(page) + + +def flats(page): + E.goto(page, "Flats", "WebFormFlats.aspx") + print("flat positions:", _options(page, "" if False else "DropDownListPositionOfFlat")) + _pick(page, "DropDownListPositionOfFlat", "top") or \ + E.set_select(page, "DropDownListPositionOfFlat", "Top Floor") + E.set_text(page, "TextBoxFloor", "3") + E.set_select(page, "RadioButtonListFlatCoridor", "None") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "64.26") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.32") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "18.15") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "18.15") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + E.set_select(page, f"{WALL}DropDownListType", "CA Cavity") + page.wait_for_timeout(500) + print("insulation opts:", _options(page, f"{WALL}DropDownListInsulation")) + _pick(page, f"{WALL}DropDownListInsulation", "internal") + page.wait_for_timeout(500) + for suf in (f"{WALL}DropDownListInsulationThickness",): + if page.locator(f"#{E.FP}{suf}").count(): + print("wall ins thickness opts:", _options(page, suf)) + _pick(page, suf, "100") + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + print("ROOF TYPE opts:", _options(page, f"{ROOF}DropDownListType")) + _pick(page, f"{ROOF}DropDownListType", "flat") + page.wait_for_timeout(600) + # discover flat-roof insulation fields + for suf in (f"{ROOF}DropDownListInsulationAt", f"{ROOF}DropDownListThickness", + f"{ROOF}DropDownListInsulation"): + if page.locator(f"#{E.FP}{suf}").count(): + print(f" {suf.split('_')[-1]} opts:", _options(page, suf)) + # flat roof insulated 75 mm + if page.locator(f"#{E.FP}{ROOF}DropDownListThickness").count(): + _pick(page, f"{ROOF}DropDownListThickness", "75") + E.save_close(page) + + +def floors(page): + E.goto(page, "Floors", "WebFormFloors.aspx") + print("FLOOR LOCATION opts:", _options(page, f"{FLOOR}DropDownListLocation")) + # "(other premises below)" = above a partially-heated space + (_pick(page, f"{FLOOR}DropDownListLocation", "partially heated") + or _pick(page, f"{FLOOR}DropDownListLocation", "other premises") + or _pick(page, f"{FLOOR}DropDownListLocation", "unheated")) + page.wait_for_timeout(400) + tsel = page.locator(f"#{E.FP}{FLOOR}DropDownListType") + if tsel.count(): + _pick(page, f"{FLOOR}DropDownListType", "solid") + E.save_close(page) + + +def openings(page): + E.goto(page, "Openings", "WebFormOpenings.aspx") + E.click_tab(page, "TabContainer_TabPanelWindowsPanel") + _add_window(page, 9.9, "North", _glazing(page)) + _delete_zero_rows(page) + E.click_tab(page, "TabContainer_TabPanelDoorsPanel") + E.set_text(page, f"{DP}TextBoxDoors", "0") + E.set_text(page, f"{DP}TextBoxDoorsInsulated", "0") + E.set_text(page, f"{DP}TextBoxDraughtProofedDoors", "0") + E.save_close(page) + + +def _glazing(page): + for needle in ("unknown install date", "before 2002", "pre 2002"): + for opt in _options(page, f"{WP}DropDownListExtGlazing"): + low = opt.lower() + if needle in low and "triple" not in low and "single" not in low and "known data" not in low: + return opt + return "Double post or during 2022" + + +def _add_window(page, area, orientation, glazing): + print("glazing ->", glazing) + E.set_select(page, f"{WP}DropDownListExtGlazing", glazing) + page.wait_for_timeout(400) + ft = page.locator(f"#{E.FP}{WP}DropDownListExtFrameType") + if ft.count(): + ft.select_option("PVC") + gg = page.locator(f"#{E.FP}{WP}DropDownListExtGlazingGap") + if gg.count(): + gg.select_option("12 mm") + wid = f"{E.FP}{WP}TextBoxExtWidth" + page.evaluate( + """(a)=>{const e=document.getElementById(a[0]);if(e){e.value=a[1]; + e.dispatchEvent(new Event('input',{bubbles:true})); + e.dispatchEvent(new Event('change',{bubbles:true})); + e.dispatchEvent(new Event('blur',{bubbles:true}));}}""", [wid, str(area)]) + page.locator(f"#{E.FP}{WP}TextBoxExtHeight").fill("1.00") + page.locator(f"#{E.FP}{WP}DropDownListExtOrientation").select_option(orientation) + page.locator(f"#{E.FP}{WP}DropDownListExtBuildingPartId").select_option("Main") + page.locator(f"#{E.FP}{WP}DropDownListExtLocation").select_option("External wall") + page.wait_for_timeout(300) + before = E.window_row_count(page) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}{WP}ButtonAddWindow") + for _ in range(25): + page.wait_for_timeout(200) + if E.window_row_count(page) > before: + break + + +def _grid_rows(page): + return page.evaluate( + """()=>{const t=document.querySelector("[id*=GridViewExtendedWidows]"); + if(!t)return[];return Array.from(t.querySelectorAll('tr')).slice(1) + .map(r=>Array.from(r.querySelectorAll('td')).map(c=>c.innerText.trim()));}""") + + +def _delete_zero_rows(page): + g = 0 + while g < 6 and E.window_row_count(page) > 1: + g += 1 + rows = _grid_rows(page) + bad = next((i for i, c in enumerate(rows) if len(c) > 1 and c[1] in ("0.00", "0", "0.0")), None) + if bad is None: + break + _delete_row(page, bad) + page.wait_for_timeout(400) + + +def _delete_row(page, idx): + before = E.window_row_count(page) + btn = page.evaluate( + """(i)=>{const b=document.querySelectorAll("[id*='GridViewExtendedWidows_DeleteButton_']");return b[i]?b[i].id:null;}""", idx) + if not btn: + return + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", btn) + page.wait_for_selector(f"#{E.FP}DeleteWindowDialog_LinkButtonYes", state="visible", timeout=5000) + page.evaluate("(id)=>{const e=document.getElementById(id); if(e)e.click();}", f"{E.FP}DeleteWindowDialog_LinkButtonYes") + for _ in range(20): + page.wait_for_timeout(200) + if E.window_row_count(page) < before: + break + + +def ventilation(page): + E.goto(page, "VentilationAndCooling", "WebFormVentilationAndCooling.aspx") + E.click_tab(page, "TabContainer_TabPanelVentilationPanel") + E.set_text(page, f"{VP}TextBoxIntermittentFans", "0") + cool = page.locator(f"#{E.FP}{VP}CheckBoxFixedSpaceCooling") + if cool.count() and cool.is_checked(): + E.commit(page, cool.uncheck) + E.click_tab(page, "TabContainer_TabPanelMechVent") + mv = page.locator(f"#{E.FP}{MV}CheckBoxMechanicalVentilation") + if mv.count() and mv.is_checked(): + E.commit(page, mv.uncheck) + E.click_tab(page, "TabContainer_TabPanelAirPressureTest") + E.set_select(page, f"{APT}DropDownListTestMethod", "Not available") + E.click_tab(page, "TabContainer_TabPanelLighting") + E.set_text(page, f"{LP}TextBoxLightsTotal", "6") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "0") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + mhc = page.locator(f"#{E.MH1}TextBoxMainHeatingCode") + code = mhc.input_value() if mhc.count() else "" + if code and code not in ("0",): + print(f"clearing leftover MainHeatingCode {code}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value=''; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.MH1}TextBoxMainHeatingCode") + page.wait_for_timeout(400) + E.save_close(page) + return + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Post 1998", "Condensing", + "Combi condens") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBE Programmer, room thermostat and TRVs") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.set_select(page, "DropDownListSecondaryHeatingPresent", "No") + E.save_close(page) + + +def water_heating(page): + E.goto(page, "WaterHeating", "WebFormWaterHeating.aspx") + E.click_tab(page, "TabContainer_TabPanelWaterHeating") + page.wait_for_timeout(400) + E.clear_hot_water_cylinder(page) + E.set_heating_dialog(page, f"{WH}ButtonWaterHeatingCode", + "From Space Heating", "From the primary heating system") + print("water code:", page.locator(f"#{E.FP}{WH}TextBoxWaterHeatingCode").input_value()) + E.save_close(page) + + +def download(page): + _SAMPLE_DIR.mkdir(parents=True, exist_ok=True) + E.goto(page, "Recommendations", "WebFormRecommendations.aspx") + page.wait_for_timeout(1500) + with page.expect_navigation(wait_until="networkidle", timeout=40000): + page.click("#ContentBody_buttonActionSummary_Link", timeout=15000) + page.wait_for_timeout(2000) + for btn, fname in (("ContentBody_ContentPlaceHolder1_LinkButtonSummary", "elmhurst_summary.pdf"), + ("ContentBody_ContentPlaceHolder1_ButtonDebugInforPdf", "elmhurst_worksheet.pdf")): + try: + with page.expect_download(timeout=60000) as dl: + page.click(f"#{btn}", timeout=15000) + dl.value.save_as(str(_SAMPLE_DIR / fname)) + print("saved", fname) + except Exception as e: + print("!! download failed", fname, type(e).__name__, str(e)[:120]) + + +_ORDER = ["property_description", "flats", "dimensions", "walls", "roofs", + "floors", "openings", "ventilation", "space_heating", "water_heating", + "download"] + + +def main(): + if len(sys.argv) < 2 or sys.argv[1] not in _ORDER: + print("usage: build_47084930.py <" + "|".join(_ORDER) + ">") + return 2 + with E.session() as (ctx, page): + globals()[sys.argv[1]](page) + print("done:", sys.argv[1], "->", page.url) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/hyde/elmhurst_lib.py b/scripts/hyde/elmhurst_lib.py index 71d1ba792..72f2fb9bc 100644 --- a/scripts/hyde/elmhurst_lib.py +++ b/scripts/hyde/elmhurst_lib.py @@ -235,24 +235,129 @@ def add_combined_window( ) -> None: """Add ONE window row of `total_area_m2` (width=area, height=1.0). Sets the required per-row fields (orientation/location/building-part) so the - Recommendations validation passes. Caller then deletes the prior rows.""" + Recommendations validation passes. Caller then deletes the prior rows. + + Glazing MUST be selected first (it AutoPostBacks and re-renders the form); + width/height are then set via a Playwright `.fill()` + Tab so the ASP.NET + AutoPostBack fires and the server-side Area (w×h) commits — a JS-set of the + value bypasses the postback and Elmhurst persists a 0.00-area row. + Frame Type + Glazing Gap are REQUIRED by the Recommendations validation + gate (else "Frame Type/Glazing Gap must be entered" blocks the worksheet).""" set_select(page, f"{_WP}DropDownListExtGlazing", glazing) - page.locator(f"#{FP}{_WP}TextBoxExtWidth").fill(str(total_area_m2)) - h = page.locator(f"#{FP}{_WP}TextBoxExtHeight") - h.fill("1.00") - commit(page, lambda: h.press("Tab")) - page.locator(f"#{FP}{_WP}DropDownListExtOrientation").select_option(orientation) - page.locator(f"#{FP}{_WP}DropDownListExtBuildingPartId").select_option("Main") - page.locator(f"#{FP}{_WP}DropDownListExtLocation").select_option("External wall") - page.wait_for_timeout(200) + page.wait_for_timeout(SETTLE_MS) + + def _fill_tab(suffix: str, value: str) -> None: + loc = page.locator(f"#{FP}{suffix}") + loc.fill(value) + loc.press("Tab") + page.wait_for_timeout(1200) # AutoPostBack settle + + _fill_tab(f"{_WP}TextBoxExtWidth", str(total_area_m2)) + _fill_tab(f"{_WP}TextBoxExtHeight", "1.00") + # Frame Type (PVC) + Glazing Gap (12 mm) are validation-required per row. + for suffix, opt in ( + (f"{_WP}DropDownListExtFrameType", "PVC"), + (f"{_WP}DropDownListExtGlazingGap", "12 mm"), + (f"{_WP}DropDownListExtOrientation", orientation), + (f"{_WP}DropDownListExtBuildingPartId", "Main"), + (f"{_WP}DropDownListExtLocation", "External wall"), + ): + loc = page.locator(f"#{FP}{suffix}") + if loc.count(): + try: + loc.select_option(opt) + except Exception: + pass + page.wait_for_timeout(250) + page.wait_for_timeout(300) before = window_row_count(page) _jsclick(page, f"{FP}{_WP}ButtonAddWindow") for _ in range(20): - page.wait_for_timeout(200) + page.wait_for_timeout(250) if window_row_count(page) > before: break +def _delete_window_at_index(page: Page, i: int) -> bool: + """Delete the window grid row at DOM index `i` via its per-row Delete + image button + the Yes modal (JS-clicked to bypass the modal background + that intercepts real clicks). Returns True if a delete fired.""" + bid = ( + "ContentBody_ContentPlaceHolder1_TabContainer_TabPanelWindowsPanel_" + f"GridViewExtendedWidows_DeleteButton_{i}" + ) + if not page.evaluate("(id)=>!!document.getElementById(id)", bid): + return False + page.evaluate("(id)=>{const e=document.getElementById(id);if(e)e.click();}", bid) + page.wait_for_timeout(2000) + yid = "ContentBody_ContentPlaceHolder1_DeleteWindowDialog_LinkButtonYes" + if not page.evaluate( + "(id)=>{const e=document.getElementById(id);return e?e.offsetParent!==null:false;}", + yid, + ): + return False + page.evaluate("(id)=>{const e=document.getElementById(id);if(e)e.click();}", yid) + page.wait_for_timeout(2500) + return True + + +def set_single_window( + page: Page, total_area_m2: float, orientation: str = "North", + glazing: str = "Double post or during 2022", +) -> None: + """Leave the window grid holding EXACTLY one correct row of + `total_area_m2`, cleaning any rows carried over from a prior build of the + SHARED assessment. + + The grid can't be emptied (Elmhurst refuses to delete the last row) and it + has no inline edit, so per [[window-grid]] the reliable pattern is: ADD the + fresh window (it inserts at DOM index 0), then delete the STALE rows BELOW + it (indices high->low, never index 0) so the freshly-added row survives as + the single remaining window. Deleting index 0 (delete_first_window) would + drop the good row and strand a 0.00-area junk row that then blocks the + Recommendations gate.""" + add_combined_window(page, total_area_m2, orientation, glazing) + page.wait_for_timeout(500) + guard = 0 + while window_row_count(page) > 1 and guard < 25: + guard += 1 + i = window_row_count(page) - 1 # bottom-most (oldest) stale row + if not _delete_window_at_index(page, i): + break + + +def reset_transient_state(page: Page) -> None: + """Return the shared assessment to a NEUTRAL state after a run so the next + build (or Khalim's) is not polluted by this cert's carried-over settings. + Clears the room-in-roof age band, forces secondary-heating present = No, + and the electricity meter back to Single. The window grid is left to the + next build's `set_single_window` (Elmhurst can't empty it to zero rows). + Call once at the end of a build session.""" + goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + rr = page.locator("#ContentBody_ContentPlaceHolder1_DropDownListRoomInRoofMain") + if rr.count() and rr.input_value(): + rr.select_option("") + page.wait_for_timeout(SETTLE_MS) + save_close(page) + goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(SETTLE_MS) + sec = page.locator(f"#{FP}DropDownListSecondaryHeatingPresent") + if sec.count(): + try: + set_select(page, "DropDownListSecondaryHeatingPresent", "No") + except Exception: + pass + meters = "TabContainer_TabPanelMeters" + click_tab(page, meters) + et = page.locator(f"#{FP}{meters}_RadioButtonListElectricityType") + if et.count(): + try: + set_select(page, f"{meters}_RadioButtonListElectricityType", "Single") + except Exception: + pass + save_close(page) + + def delete_first_window(page: Page) -> None: """Delete the first window row via the Yes/No modal. Will refuse to drop the LAST row (Elmhurst blocks it) — so add the replacement BEFORE deleting.""" @@ -362,6 +467,63 @@ def select_boiler(page: Page, query: str, ref: str) -> str: return "ok" +def clear_main_heating_code(page: Page) -> None: + """Empty Main Heating 1's SAP code via a real server postback (set the + cascade's top-level dropdown to '' + OK). REQUIRED before `set_pcdb_boiler`: + while any code is set, the PCDF reference textbox and the boiler-search + magnifying glass both render `aspNetDisabled`. They only enable when the + code is empty server-side (a JS-clear alone flips the class cosmetically but + leaves the postback unwired).""" + page.evaluate( + "(id)=>{const e=document.getElementById(id); if(e)e.click();}", + f"{MH1}ButtonMainHeatingCode", + ) + page.wait_for_timeout(SETTLE_MS * 3) + page.evaluate( + """(id)=>{const s=document.getElementById(id);if(s){s.value=''; + s.dispatchEvent(new Event('change',{bubbles:true}));}}""", + f"{HEATING_DIALOG}DropDownList1", + ) + page.wait_for_timeout(SETTLE_MS * 3) + dialog_commit(page, "OK") + page.wait_for_timeout(SETTLE_MS * 2) + + +def set_pcdb_boiler(page: Page, pcdb_index: "int | str") -> str: + """Set Main Heating 1 to the EXACT PCDB boiler by its EPC + `main_heating_index_number` (e.g. 18908 = Worcester Greenstar 4000, + GR4700iW 25 C NG, 88.70%). Elmhurst resolves it to the product's PCDB + winter efficiency — the same value the SAP engine uses — so the worksheet + and our calculator compare like-for-like (not against the generic BGW + SAP-Table 84%). Returns the resolved boiler description. + + Hard-won mechanism (supersedes the old "PCDB disabled" note): + 1. The PCDF reference textbox is only writable while the main heating CODE + is empty — call `clear_main_heating_code(page)` first. + 2. The index must be entered via REAL keyboard + Tab. A JS-set `.value` + does NOT survive the field's AutoPostBack, so the boiler never + resolves (the original failure mode). Ctrl-A + type + Tab works. + 3. The `TextBoxPCDFBoilerReference` direct-entry path is far simpler than + the magnifying-glass grid (whose modal has no layout box, so + mouse/Playwright clicks can't target rows). The grid search DOES work + (JS-focus the FullSearch box + `keyboard.type` + fire + HyperLinkActionBoilerSearch → "Ref No" column == the PCDB index) if a + name lookup is ever needed, but direct entry is preferred.""" + fld = f"{MH1}TextBoxPCDFBoilerReference" + page.evaluate( + "(id)=>{const e=document.getElementById(id);if(e){e.focus();e.select();}}", fld + ) + page.wait_for_timeout(SETTLE_MS) + page.keyboard.press("Control+a") + page.keyboard.type(str(pcdb_index), delay=40) + page.keyboard.press("Tab") + page.wait_for_timeout(SETTLE_MS * 5) # AutoPostBack resolves the PCDB record + return page.evaluate( + """()=>{const e=document.querySelector('[id*=LabelMHSSapCodeDescription]'); + return e?e.innerText.trim():'';}""" + ) + + def read_default_uvalue( page: Page, suffix: Optional[str] = None, label_regex: str = r"Default U-value" ) -> Optional[float]: diff --git a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py index c8836a92b..e387c73c9 100644 --- a/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py +++ b/tests/domain/sap10_calculator/rdsap/test_cert_to_inputs.py @@ -27,6 +27,7 @@ from datatypes.epc.surveys.elmhurst_site_notes import ( ) from datatypes.epc.domain.epc_property_data import ( + EnergyElement, EpcPropertyData, MainHeatingDetail, PhotovoltaicArray, @@ -738,6 +739,30 @@ def test_cylinder_present_but_size_not_determined_defaults_to_normal_110l() -> N assert volume_l is not None and abs(volume_l - 110.0) <= 1e-9 +def test_cylinder_size_not_determined_still_incurs_storage_loss() -> None: + # Arrange — the size-0 (not determined) cylinder's Table 28 default of + # 110 L must flow into the STORAGE-LOSS override too, not just the Table + # 13 high-rate fraction. `_cylinder_storage_loss_override` read the + # volume via `_cylinder_volume_l_from_code` (None for size 0) and bailed + # `if volume_l is None: return None`, dropping the loss entirely — while + # the rest of the DHW cascade used `_hot_water_cylinder_volume_l` + # (110 L). A present cylinder with no storage loss under-costs the DHW + # and over-rates the dwelling (7 corpus certs lodge cylinder_size=0 + + # has_cylinder=true). RdSAP 10 §10.5 Table 28: a present-but-unsized + # cylinder is a 110 L cylinder and incurs the Table 2 storage loss. + from domain.sap10_calculator.rdsap.cert_to_inputs import ( + _cylinder_storage_loss_override, # pyright: ignore[reportPrivateUsage] + ) + epc = _cylinder_epc(cylinder_size=0) + + # Act + storage_56m = _cylinder_storage_loss_override(epc, None) + + # Assert — a real 110 L cylinder loss series, not the dropped None. + assert storage_56m is not None + assert sum(storage_56m) > 0.0 + + def test_cylinder_size_inaccessible_code_5_solid_fuel_boiler_uses_160l() -> None: # Arrange — RdSAP 10 §10.5 Table 28: an "Inaccessible" cylinder (code 5) # heated "from a solid fuel boiler" uses 160 litres. @@ -1867,6 +1892,79 @@ def test_main_floor_u_value_routes_suspended_timber_via_floor_construction_type( assert sealed is False +def test_has_suspended_timber_floor_per_spec_falls_back_to_floors_description() -> None: + """RdSAP 10 §5 (12) reads the Main bp's `floor_construction_type` + lodgement, but the gov-API mapper often leaves that field `None` + while the global `epc.floors[].description` still carries the + assessor's "Suspended, ..." observation (cert 100061275133: Main bp + `floor_construction_type=None`, `epc.floors[0].description= + "Suspended, no insulation (assumed)"`). `_main_floor_u_value` already + falls back to this joined description (`effective_floor_description`); + the (12) infiltration rule must apply the same fallback so a + suspended-timber ground floor doesn't silently enter (12)=0.""" + from dataclasses import replace + # Arrange + main = replace( + make_building_part( + construction_age_band="B", + floor_dimensions=[make_floor_dimension(floor=0)], + ), + floor_type="Ground floor", + floor_construction_type=None, + ) + epc = make_minimal_sap10_epc(sap_building_parts=[main]) + epc.floors = [ + EnergyElement( + description="Suspended, no insulation (assumed)", + energy_efficiency_rating=0, + environmental_efficiency_rating=0, + ), + ] + + # Act + has_susp, sealed = _has_suspended_timber_floor_per_spec(epc) + + # Assert — description signal routes to the suspended-timber branch; + # band B is A-E with no supplied U-value and no retrofit insulation + # signal, so rule (b) applies "unsealed" → (12) = 0.2. + assert has_susp is True + assert sealed is False + + +def test_has_suspended_timber_floor_per_spec_excludes_suspended_not_timber() -> None: + """"Suspended, not timber" (e.g. suspended concrete) starts with the + same "Suspended" prefix as timber floors but must NOT trigger the + §5 (12) rule — the rule is specifically about air infiltration + through timber floorboard gaps (see the API mapper's + `_API_FLOOR_CONSTRUCTION_TO_STR` comment: "only 'Suspended timber' + triggers the §5 (12)... adjustment").""" + from dataclasses import replace + # Arrange + main = replace( + make_building_part( + construction_age_band="B", + floor_dimensions=[make_floor_dimension(floor=0)], + ), + floor_type="Ground floor", + floor_construction_type=None, + ) + epc = make_minimal_sap10_epc(sap_building_parts=[main]) + epc.floors = [ + EnergyElement( + description="Suspended, not timber", + energy_efficiency_rating=0, + environmental_efficiency_rating=0, + ), + ] + + # Act + has_susp, sealed = _has_suspended_timber_floor_per_spec(epc) + + # Assert + assert has_susp is False + assert sealed is False + + def test_rdsap_extract_fans_default_per_table_5() -> None: # Arrange — RdSAP 10 §4.1 Table 5 (PDF p.28) "Extract fans" default # when the lodged number is unknown. The Summary §12.0 "No. of @@ -2686,6 +2784,46 @@ def test_dual_fuel_secondary_api_enum_9_prices_as_dual_fuel_not_lpg() -> None: assert secondary_factor_code == 10 +def test_fuel_cost_secondary_colliding_fuel_priced_at_canonical_rate() -> None: + # Arrange — the SAP-DRIVING `_fuel_cost` cascade prices the secondary + # via its own inline `secondary_high_rate_gbp_per_kwh`, distinct from + # the CO2/display `_secondary_fuel_cost_gbp_per_kwh`. It must apply the + # SAME `_GOV_API_COLLISION_FUELS` canonicalisation, else an ANTHRACITE + # secondary (gov-API `secondary_fuel_type=5`) resolves to the same-value + # Table-32 code 5 = bulk LPG (12.19 p/kWh) instead of anthracite + # (3.64 p/kWh) — a 3× over-cost that sank corpus cert 100050355518 + # (lodged 36, engine 20.8). Anthracite room-heater secondary on a + # mains-gas boiler main. + gas_boiler_main = MainHeatingDetail( + has_fghrs=False, main_fuel_type=26, heat_emitter_type=1, + emitter_temperature=1, main_heating_control=2106, + main_heating_category=2, sap_main_heating_code=102, + ) + anthracite_secondary_epc = make_minimal_sap10_epc( + total_floor_area_m2=_TYPICAL_TFA_M2, + habitable_rooms_count=4, + country_code="ENG", + sap_building_parts=[make_building_part(construction_age_band="D")], + sap_heating=make_sap_heating( + main_heating_details=[gas_boiler_main], + secondary_fuel_type=5, # gov-API enum: anthracite + secondary_heating_type=631, # room heater + ), + ) + + # Act + inputs = cert_to_inputs(anthracite_secondary_epc) + result = Sap10Calculator().calculate(anthracite_secondary_epc) + fc = inputs.fuel_cost + secondary_kwh = result.secondary_heating_fuel_kwh_per_yr + + # Assert — anthracite 3.64 p/kWh (0.0364), NOT the collision LPG + # 12.19 p/kWh the raw same-value Table-32 lookup returns. + assert secondary_kwh > 0.0 + assert abs(fc.secondary_total_cost_gbp - secondary_kwh * 0.0364) <= 1e-6 + assert abs(fc.secondary_total_cost_gbp - secondary_kwh * 0.1219) > 1.0 + + def test_is_electric_water_dual_fuel_table_32_code_10_is_not_electric() -> None: # Arrange — same API/Table 32 collision as `_is_electric_main` per # S0380.136 docstring. @@ -4891,6 +5029,42 @@ def test_hot_water_from_pcdb_heat_pump_bills_at_app_n_wh_high_rate() -> None: assert abs(rate_immersion - 0.0750) <= 1e-6 +def test_instantaneous_electric_dhw_off_peak_bills_at_high_rate() -> None: + # Arrange — SAP 10.2 §12 (PDF line 2680): the off-peak on-peak HW + # proportion (Table 13) is "dependent on the total floor area and the + # CYLINDER SIZE" — it presumes a stored-water cylinder that can be + # charged overnight. An INSTANTANEOUS point-of-use electric heater + # (WHC 907/909, no cylinder) heats water on demand and CANNOT shift to + # the off-peak window, so 100% of its consumption is at the high rate + # (Table 12a high-rate fraction 1.0). The generic off-peak else-branch + # billed it at 100% off-peak LOW rate (5.50 p/kWh at 7-hour), 3× under- + # costing the DHW and over-rating the dwelling — corpus cert 74061136 + # (HHR-storage flat, WHC 909) lodged 73, engine 80.7. + from domain.sap10_calculator.tables.table_12a import Tariff + from domain.sap10_calculator.rdsap.cert_to_inputs import ( + _hot_water_fuel_cost_gbp_per_kwh, # pyright: ignore[reportPrivateUsage] + _hot_water_high_rate_fraction, # pyright: ignore[reportPrivateUsage] + ) + storage_main = MainHeatingDetail( + has_fghrs=False, main_fuel_type=29, heat_emitter_type=0, + emitter_temperature="NA", main_heating_control=2404, + main_heating_category=7, sap_main_heating_code=409, + ) + + # Act — instantaneous electric DHW (WHC 909) on a 7-hour off-peak tariff. + rate = _hot_water_fuel_cost_gbp_per_kwh( + 29, storage_main, Tariff.SEVEN_HOUR, SAP_10_2_SPEC_PRICES, + water_heating_code=909, + ) + fraction = _hot_water_high_rate_fraction( + 29, storage_main, Tariff.SEVEN_HOUR, water_heating_code=909, + ) + + # Assert — 100% at the 7-hour HIGH rate (15.29 p/kWh), NOT the low 5.50. + assert abs(rate - 0.1529) <= 1e-6 + assert fraction == 1.0 + + def test_heat_pump_water_efficiency_is_floored_at_100pct_per_app_n3_7() -> None: # Arrange — SAP 10.2 Appendix N3.7 ("Thermal efficiency for water # heating – heat pumps", PDF p.109): "multiply the thermal efficiency 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 70a93637b..f792c519a 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -727,6 +727,313 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="0018-2049-6232-4431-6934", sap_score=54, ), + # UPRN 4510053280 (corpus-1000 C001; the corpus doc lodges no cert number). + # RdSAP-Schema-21.0.1 native — GROUND-FLOOR FLAT 47 m², band B, solid brick + # 520 mm uninsulated (+ 8.12 m² sheltered alternative wall), roof "(another + # dwelling above)", ASHP radiators PCDB 100053 (Mitsubishi Ecodan 5 kW, + # 2010 record: PSR table 0.2–2.0, η_space 332.8% @ 2.0, η_water 187.5%, + # duration "24"), no cylinder, electric room-heater secondary, no PV. + # Lodged 51 / engine 74.94 (Δ +23.9, the corpus' worst cert). Dwelling PSR + # = 4.62 kW / (94.0 W/K × 24.2 K) = 2.031, just past the record's largest + # 2.0 → SAP 10.2 N2 (PDF p.101 footnotes 44/45) heat-pump extension: + # reciprocal-interpolate η_space toward 100% at PSR 4.0 → 321% × 0.95 = + # 305%. That is what the engine does, and what accredited Elmhurst did on + # the SAME record family / same PSR shape (golden case 56, record 100061, + # PSR 3.107 → 139.66%). The LODGED software instead treated the + # out-of-range record as invalid and billed direct electric: forcing + # η_space = η_water = 100% + the standard 9-h schedule reproduces the + # lodged CO2 to 1% (0.808 vs 0.800 t) and PE within 6% (178 vs 190), + # whereas the engine's spec path gives 0.444 t / 98.8. A lodged-software + # methodology gap (worklist ⚠), NOT an engine bug — do not tune. PINNED to + # the observed engine 75. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_4510053280", + cert_num="uprn-4510053280", + sap_score=75, + ), + # UPRN 10094975827 (corpus; no cert number lodged). RdSAP-Schema-21.0.1 + # native — TOP-FLOOR FLAT, band B, solid brick, pitched roof lodged + # thickness "NI" + description "Pitched, insulated (assumed)", electric + # room heaters. The "insulated (assumed)" Table-18 cert: presence-assumed + # insulation is NOT the §5.11.4 observed-retrofit 50 mm row (0.68) — it + # takes the Table 18 age-band default (band B pitched → 0.40), the same + # value the "ND" lodgement of this description reaches. Was engine 64.13 + # (Δ −1.87 vs lodged 66); the fix lands 65.83 → rounds to 66 = lodged. + # PINNED to the observed engine 66 = lodged. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_10094975827", + cert_num="uprn-10094975827", + sap_score=66, + ), + # UPRN 100050355518 (corpus C003; no cert number lodged). RdSAP-21.0.1 + # native — SEMI-DETACHED HOUSE, 122 m², 2 extensions (3 building parts), + # mains-gas boiler main (SAP 117) + ANTHRACITE room-heater secondary + # (gov-API secondary_fuel_type=5, SAP 631). The secondary-fuel collision + # cert: enum 5 collides with Table-32 code 5 (bulk LPG 12.19 p/kWh); the + # SAP-driving _fuel_cost path priced the anthracite secondary at the LPG + # rate instead of anthracite 3.64 p/kWh — a 3× over-cost on ~1431 kWh + # (+£100/yr → ECF 6.24 vs 4.67). Engine was 20.8 (Δ −15.2 vs lodged 36); + # canonicalising the secondary fuel lands 35.5 = lodged 36. CO2/PE + # already matched lodged (0.055 t / 1.7 kWh) — a pure cost-side gap, the + # signature that localised it. PINNED to the observed engine 36 = lodged. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_100050355518", + cert_num="uprn-100050355518", + sap_score=36, + ), + # UPRN 74061136 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # MID-FLOOR FLAT 24 m², band B, HHR electric storage heaters (SAP 409) on + # an Unknown meter (type 3 → off-peak 7-hour per RdSAP 10 §12 Rule 2), + # INSTANTANEOUS electric point-of-use DHW (WHC 909, no cylinder). The + # instantaneous-DHW off-peak cert: its DHW was billed 100% at the 7-hour + # LOW rate (5.50 p) but SAP 10.2 §12 (Table-13 on-peak split is keyed on + # CYLINDER size) presumes stored water — an instantaneous heater has no + # cylinder, heats on demand, so 100% bills at the HIGH rate (15.29 p). + # Mid-floor flat → roof/floor both zero-loss, so PE matched lodged (+1.6) + # and the +7.72 over-rate isolated cleanly to the DHW tariff. Fix lands + # 71.75 (Δ −1.25 vs lodged 73); the tariff error is gone, the residual is + # a separate small fabric effect. PINNED to the observed engine 72. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_74061136", + cert_num="uprn-74061136", + sap_score=72, + ), + # UPRN 200004296092 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # END-TERRACE HOUSE, TFA 62, age B, mains-gas COMBI (PCDB 16137), SOLID + # BRICK 360 mm "with external insulation" (wall_insulation_type 1) but + # thickness lodged "NI" (unknown). The wall added-insulation unknown- + # thickness cert: the §5.8 R-value gate needs thickness > 0, so the + # externally-insulated wall fell through to its UNINSULATED §5.6 U (1.40, + # walls 101.7 W/K, HLP 3.46) → PE +59.6, engine 64.35 (Δ −6.65 vs lodged + # 71). RdSAP 10 §5.4 (PDF p.32) "assume 100 mm if thickness is unknown" + # applies the 100 mm §5.8 default → U ~0.29, engine 71.74 = lodged. PINNED + # to the observed engine 72. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_200004296092", + cert_num="uprn-200004296092", + sap_score=72, + ), + # UPRN 200004017091 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # END-TERRACE HOUSE, mains-gas boiler, hot-water cylinder lodged with + # `cylinder_size=0` (present but "size not determined") + has_cylinder=true. + # The unsized-cylinder storage-loss cert: `_cylinder_storage_loss_override` + # read the volume via `_cylinder_volume_l_from_code` → None for size 0 → + # bailed and DROPPED the cylinder's Table-2 storage loss, under-costing the + # DHW → engine 72.75 (Δ +1.75 vs lodged 71). RdSAP 10 §10.5 Table 28: an + # unsized present cylinder is the 110 L "Normal" default and still incurs + # the loss → engine 71.39 = lodged 71. PINNED to the observed engine 71. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_200004017091", + cert_num="uprn-200004017091", + sap_score=71, + ), + # UPRN 47084930 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # TOP-FLOOR FLAT, band E, cavity wall + 100 mm internal insulation, FLAT + # ROOF insulated 75 mm, floor over other premises, mains-gas combi. The + # flat-roof insulation-thickness cert: the 75 mm is lodged in + # `flat_roof_insulation_thickness`, but heat_transmission read + # `roof_insulation_thickness` (None) → billed the flat roof at the + # uninsulated age-E default 1.5 (roof 96.4 W/K) → PE +47, engine 69.51 + # (Δ −4.49 vs lodged 74). Preferring the flat field → U 0.5 (roof 32.1 + # W/K), engine 74.34 = lodged 74. VALIDATED against the accredited + # Elmhurst worksheet (built on the lodged inputs, evidence saved: + # elmhurst_summary.pdf / elmhurst_worksheet.pdf): "insulated flat roof" + # U 0.5, floor 0.70 and wall 0.25 both matching the engine. PINNED 74. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_47084930", + cert_num="uprn-47084930", + sap_score=74, + ), + # UPRN 100050881708 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # SEMI-DETACHED HOUSE, band B, cavity FILLED wall, pitched 225 mm loft, + # SUSPENDED ground floor "to unheated space", mains-gas combi, no cylinder. + # Lodged 70 / engine 72 (71.55). Built in accredited Elmhurst RdSAP10 + # (evidence saved: elmhurst_summary.pdf / elmhurst_worksheet.pdf): the WALL + # (cavity, U 0.70, 69.56 m²) and ROOF (insulated slope 225 mm, U 0.19) + # match the engine EXACTLY (walls 48.8 W/K, roof 6.0 W/K). The engine is + # faithful on the checkable fabric; the +1.55 vs lodged is a small + # methodology gap. (Elmhurst''s worksheet SAP 61 is NOT comparable — the + # build entered the suspended ground floor as an upper "above unheated + # space" floor, which Elmhurst bills via Table-20 exposed 1.20; the cert''s + # §3.12 suspended-ground-floor U is 0.74, which the engine uses.) PINNED to + # the observed engine 72. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_100050881708", + cert_num="uprn-100050881708", + sap_score=72, + ), + # UPRN 217091901 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # TOP-FLOOR FLAT, band A (before 1900), SOLID BRICK 280 mm uninsulated, + # FLAT ROOF no insulation (As Built), floor over ANOTHER DWELLING below + # (zero loss), mains-gas COMBI, SINGLE glazing (glazed_type 5), TFA 63. + # Lodged 62 / engine 61 (60.82). Built in accredited Elmhurst RdSAP10 + # (evidence saved: elmhurst_summary.pdf / elmhurst_worksheet.pdf): EVERY + # heat-loss element matches the engine EXACTLY — walls (solid U 1.70, + # 53.18 W/K), flat roof (uninsulated U 2.30, 145.57 W/K), floor (0), + # party (0), and — with the faithful SINGLE glazing entered — WINDOWS + # (8.62 m² × effective U 4.0268 = 34.7114 W/K, identical to the engine). + # This confirms the mapper''s glazed_type 5 → single (raw U 4.8) is + # spec-correct (epc_codes.csv: glazed_type 5 = single glazing), NOT the + # double it superficially resembles. The −1.18 vs lodged is a cost-side + # methodology residual (PE +8.7 kWh/m², CO2/PE-driven), not a fabric bug. + # PINNED to the observed engine 61. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_217091901", + cert_num="uprn-217091901", + sap_score=61, + ), + # UPRN 100061275133 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # 2-storey SEMI-DETACHED HOUSE, band B, SOLID BRICK 400 mm with EXTERNAL + # insulation, pitched 300 mm loft, SUSPENDED uninsulated ground floor, + # mains-gas COMBI, double glazing (glazed_type 13, 2022+), TFA 78. + # Lodged 76 / engine 76 (76.33, was 77.24 before the §5 (12) fix below). + # Built in accredited Elmhurst RdSAP10 (evidence saved: elmhurst_summary.pdf + # / elmhurst_worksheet.pdf): the checkable FABRIC matches the engine + # closely — ROOF (300 mm loft, U 0.14) and WINDOWS (15.32 m² × eff U + # 1.3258 = 20.3106 W/K) match EXACTLY; the externally-insulated WALL is + # U 0.29 (engine) vs 0.30 (Elmhurst) — which VALIDATES the slice-5 + # external-insulation default (100 mm added over solid brick, + # `_WALL_ADDED_INSULATION_UNKNOWN_THICKNESS_MM`); the suspended ground + # floor is U 0.68 (engine) vs 0.68 (Elmhurst) — EXACT after rebuilding + # with 0 extract fans + PCDB 18908 (was 0.70 pre-rebuild). Ventilation + # (21) shelter-adjusted ACH is EXACT too (0.6938 = 0.6938), and dwelling + # volume (5) 196.8995 m³ matches (confirming the mapper's +0.25 m + # upper-floor height convention mirrors Elmhurst's own internal one). + # §5 (12) fix: the Main bp lodges no `floor_construction_type` (gov-API + # leaves it None), but `epc.floors[0].description` = "Suspended, no + # insulation (assumed)" — `_has_suspended_timber_floor_per_spec` was + # only reading the per-bp field and silently entered (12)=0 for a + # genuinely suspended-timber floor. Now falls back to the joined + # description (mirroring `_main_floor_u_value`'s existing fallback), + # applying (12)=0.2 unsealed; engine converges EXACTLY on lodged (76). + # Elmhurst's OWN overall worksheet SAP (72) still differs from ours + # (76.33) even on these now-identical inputs — traced to SAP 10.2 + # Table 11: Elmhurst's (201)/(202)/(215) show it assumes 10% of space + # heat comes from a portable-electric secondary (658 kWh/yr @ the + # electric rate) purely from the main system's category (gas boiler), + # with NO secondary lodged (`secondary_heating.description == "None"`). + # `_secondary_fraction` only applies Table 11 when a secondary is + # actually lodged or forced by §A.2.2 — deliberately, per the S-B30 + # note a few lines below: applying Table 11 unconditionally regressed + # the full 1000-cert corpus MAE by +0.16 (lodged software doesn't + # apply Elmhurst's blanket convention). Verified: forcing Table 11 on + # for just this cert moves 76.33 -> 73.62, ~62% of the 76.33-vs-72 gap. + # The remaining ~1.6 pts is a second, separate cause: (6) Solar gains — + # the BUILD entered all 12 windows as one 15.32 m2 "North" group + # (E.set_single_window), but the cert's real sap_windows lodge 3 + # orientations (NW 7.05 m2, NE 1.21 m2, SE 7.06 m2 incl. the largest + # single window) — collapsing to due-north understates solar gain + # (Elmhurst Jan (83)=56.9 W vs our real-orientation 123.4 W). Verified: + # forcing our engine to ALSO use a single synthetic North window (i.e. + # replicating the build's simplification, not a cert or engine fact) + # plus the forced Table 11 above reproduces 72.62 (precise Elmhurst + # value is 72.0681, not the rounded "72" -- true residual after Table + # 11 + windows was ~0.55, not ~1.6). Third cause found by walking the + # rest of the worksheet monthly: (43) Average daily hot water use is + # 117.4056 L/day (Elmhurst) vs our 110.7281 L/day -- SAME occupancy + # (42)=2.4234 both sides, so the gap is in shower/bath demand, not + # occupancy. Root cause: cert's `mixer_shower_count` is unlodged (raw + # `shower_outlets=None`), which `_mixer_shower_flow_rates_from_cert` + # maps to 0 showers (see its docstring: gov-API "no shower_outlets + # entry" convention, validated on cert 2225) -- but Elmhurst's build + # shows a "Non-electric shower" fixture (1 vented mixer @ Table J4), + # since its UI silently defaults one when the build script never + # explicitly configured "0 showers" to match the cert. Verified: a + # single 7 L/min vented mixer reproduces Elmhurst's (42a) monthly + # series EXACTLY (4 d.p., all 12 months) and closes hot water to + # 2616.04 vs Elmhurst's 2616.03 (Δ0.005). Corpus-wide check (170 + # certs sharing "bath present, no shower data lodged") shows NO + # systematic bias (mean dSAP +0.12, median -0.04, 46.5% over-rated) -- + # confirms the mapper's 0-showers convention is correct on average; + # this is a THIRD build-entry artifact, not a mapper bug. Combining + # all three (windows + Table 11 + 1 shower): SAP 72.4567 vs Elmhurst's + # precise 72.0681 -- residual 0.39, ~91% of the original 4.26-point + # gap (76.33 vs 72.07) now precisely explained. Conclusion: the + # calculator is faithful (matches lodged 76 exactly using the cert's + # REAL windows and REAL shower data); all three residuals are Elmhurst + # -reconciliation-build artifacts or deliberate spec choices, not + # mapping or calculator bugs. PINNED to the observed exact match vs + # lodged. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_100061275133", + cert_num="uprn-100061275133", + sap_score=76, + ), + # UPRN 100051051866 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # DETACHED BUNGALOW, band I, CAVITY wall as-built insulated, pitched + # insulated loft, SUSPENDED limited-insulation floor, mains-gas regular + # boiler + cylinder (size 2, insulation type 1, 50 mm — a properly + # insulated cylinder, so NOT the type-0/NULL zero-storage-loss bug), TFA 60. + # Lodged 70 / engine 71 (71.04). Reduced-field cavity fabric already + # Elmhurst-validated on sibling certs; the +1.04 is a cost-side residual + # (PE −13.6 kWh/m² under-count) with no fabric anomaly — walls 29.9, roof + # 15.6, floor 29.4, windows 15.6 W/K all register-explained. PINNED to the + # observed engine 71; the register data fully accounts for the engine output. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_100051051866", + cert_num="uprn-100051051866", + sap_score=71, + ), + # UPRN 10070056075 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # DETACHED HOUSE, band K, CAVITY wall as-built insulated, pitched insulated + # loft, SUSPENDED insulated floor, mains-gas regular boiler + cylinder + # (size 4, insulation type 1, 80 mm — properly insulated), dual meter, + # TFA 139. Lodged 80 / engine 79 (78.99). Cavity fabric already + # Elmhurst-validated on sibling certs; the −1.01 is a cost-side residual + # (PE +5.4 kWh/m² over-count) with no fabric anomaly — walls 50.0, roof + # 20.1, floor 16.7, windows 26.7 W/K all register-explained. PINNED to the + # observed engine 79; the register data fully accounts for the engine output. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_10070056075", + cert_num="uprn-10070056075", + sap_score=79, + ), + # UPRN 10012334488 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # mid-floor FLAT, mains-electric with SAP heating code 195 ("Electric water + # storage boiler", Table 4a PDF p.170) serving underfloor heating, on an + # off-peak (7-hour) meter, TFA 62. Lodged 72 / engine 85 (85.20). This is a + # PURE COST gap, NOT a fabric bug: PE (−1.4 kWh/m²) and CO2 (+0.01 t) both + # match lodged, so demand is right. Code 195 is a STORAGE boiler → SAP 10.2 + # §12 Rule 2 routes it to the 7-hour tariff and bills space+water heat mostly + # at the off-peak low rate (5.5 p/kWh) — the spec-faithful treatment. The + # lodged software billed it far higher (implying peak-rate billing of a + # storage system), the same lodged-outlier pattern as the §12/PSR xfail + # cohort. PINNED to the spec-faithful engine 85 — the engine follows SAP + # §12/Table-4a; matching lodged 72 would require billing a storage boiler at + # peak rate, against spec. (Not Elmhurst-verified: my RdSAP10 builds carry a + # combi/heating artifact that makes them unreliable on the E7 storage side.) + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_10012334488", + cert_num="uprn-10012334488", + sap_score=85, + ), + # UPRN 10091578598 (corpus; no cert number lodged). RdSAP-21.0.1 native — + # FLAT, mains-electric SAP code 195 ("Electric water storage boiler"), + # off-peak meter, TFA 60. Lodged 71 / engine 79 (78.81). Same signature as + # 10012334488: PURE COST gap (PE +1.6, CO2 −0.04 both match lodged → demand + # right); code 195 is a §12-Rule-2 storage system billed at the 7-hour + # off-peak rate per spec. Lodged over-billed the storage boiler at a higher + # rate. PINNED to the spec-faithful engine 79 — matching lodged would tune + # against SAP §12/Table-4a. + RealCertExpectation( + schema="RdSAP-Schema-21.0.1", + sample="uprn_10091578598", + cert_num="uprn-10091578598", + sap_score=79, + ), ) diff --git a/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py b/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py index 213bf2ffb..2df247a2d 100644 --- a/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py +++ b/tests/domain/sap10_calculator/worksheet/test_heat_transmission.py @@ -245,15 +245,18 @@ def test_part_geometry_floorless_part_honours_full_key_contract() -> None: assert early["cantilever_floor_area_m2"] == 0.0 -def test_roof_insulated_assumed_with_ni_thickness_uses_50mm_per_section_5_11_4() -> None: - # Arrange — 346 corpus certs lodge roof_insulation_thickness="NI" - # with descriptions like "Pitched, insulated (assumed)". The - # retrofit-insulation signal in the description must flow from - # epc.roofs[0].description through heat_transmission_from_cert - # into u_roof so the 50 mm assumption fires per RdSAP 10 §5.11.4. - # Geometry: 100 m² ground floor → top floor area also 100 m² → - # roof_area = 100 m². roof_w_per_k expected = 0.68 × 100 = 68 - # W/K (vs uninsulated 2.30 × 100 = 230 W/K). +def test_roof_insulated_assumed_with_ni_thickness_uses_table18_default() -> None: + # Arrange — corpus certs lodge roof_insulation_thickness="NI" with + # descriptions like "Pitched, insulated (assumed)". The description + # must flow from epc.roofs[0].description through + # heat_transmission_from_cert into u_roof, where "(assumed)" + # (presence assumed, not observed retrofit) routes to the Table 18 + # age-band default per RdSAP 10 §5.11.4 — band C pitched → 0.40 — + # matching the "ND" lodgement of the same description. (The bare + # "insulated" form keeps the §5.11.4 50 mm row; unit-pinned in + # test_rdsap_uvalues.) Geometry: 100 m² ground floor → top floor + # area also 100 m² → roof_area = 100 m². roof_w_per_k expected = + # 0.40 × 100 = 40 W/K (vs uninsulated 2.30 × 100 = 230 W/K). main = make_building_part( identifier="Main Dwelling", construction_age_band="C", @@ -287,7 +290,7 @@ def test_roof_insulated_assumed_with_ni_thickness_uses_50mm_per_section_5_11_4() result = heat_transmission_from_cert(epc) # Assert - assert result.roof_w_per_k == pytest.approx(68.0, abs=2.0) + assert result.roof_w_per_k == pytest.approx(40.0, abs=2.0) def test_roof_insulation_location_rafters_drives_table16_column_2_api_int_path() -> None: @@ -367,6 +370,46 @@ def test_rafter_insulation_thickness_field_drives_table16_column_2() -> None: assert abs(result.roof_w_per_k - 25.0) <= 1e-4 +def test_flat_roof_insulation_thickness_field_drives_insulated_u() -> None: + # Arrange — a FLAT roof lodges its insulation thickness in the DEDICATED + # gov-EPC API `flat_roof_insulation_thickness` field (e.g. "75mm"), + # leaving `roof_insulation_thickness` None (that field is for pitched-loft + # joists). heat_transmission must prefer the flat field when the part is a + # flat roof so the measured thickness bills at its RdSAP 10 §5.11 Table-16 + # U (75 mm → 0.5) instead of the uninsulated age-band flat default (age E + # → 1.5). Cert 47084930 (top-floor flat, flat roof "75mm"): roof 96.4 -> + # 32.1 W/K, engine 69.51 -> 74.34 = lodged 74, matching the accredited + # Elmhurst worksheet ("insulated flat roof", U 0.5). Mirrors the rafter + # field. Geometry: 100 m² plan → roof 100 m². 0.5 × 100 = 50 W/K. + main = make_building_part( + construction_age_band="E", + wall_construction=4, + wall_insulation_type=4, + party_wall_construction=1, + roof_construction=1, # flat + floor_dimensions=[ + make_floor_dimension( + total_floor_area_m2=100.0, room_height_m=2.5, + party_wall_length_m=0.0, heat_loss_perimeter_m=40.0, floor=0, + ), + ], + ) + main.roof_construction_type = "Flat" + main.roof_insulation_thickness = None # gov leaves this None for flat roofs + main.flat_roof_insulation_thickness = "75mm" # the thickness lives here + epc = make_minimal_sap10_epc( + total_floor_area_m2=100.0, + country_code="ENG", + sap_building_parts=[main], + ) + + # Act + result = heat_transmission_from_cert(epc) + + # Assert — 75 mm insulated flat roof at U 0.5, not the age-E default 1.5. + assert abs(result.roof_w_per_k - 50.0) <= 1e-4 + + def test_lodged_roof_u_value_overrides_construction_default() -> None: # Arrange — RdSAP 10 §5.1: where an element's U-value is known from the # assessment (documentary evidence / the lodged RdSAP output) it is used diff --git a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py index 20a0eeae8..ff14c1fa7 100644 --- a/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py +++ b/tests/infrastructure/epc_client/test_sap_accuracy_corpus.py @@ -196,7 +196,50 @@ _CORPUS = Path( # 0.74 -> 0.742 via the heat-pump water-heating 100% floor (App N3.7): cert # 100110101713 moves inside +-0.5 (|err| 4.97 -> 0.49). See the _MAX_SAP_MAE # log below for the paired space-heating PSR-extension + water-floor slices. -_MIN_WITHIN_HALF_SAP = 0.742 +# 0.742 -> 0.755 (MAE 0.722 -> 0.708, CO2 0.09 -> 0.075, PE 3.5 -> 3.2) via +# the "insulated (assumed)" roof Table-18 fix (RdSAP 10 §5.11.4): a pitched +# roof lodging thickness "NI" + description "insulated (assumed)" was hitting +# the §5.11.4 retrofit-50 mm row (0.68) while the SAME description lodged +# with "ND" fell through to the Table 18 age-band default (e.g. 0.40 A-G) — +# the sentinel choice is lodging-software noise, and "(assumed)" means the +# insulation PRESENCE is an age-band assumption, not an observed retrofit, +# so Table 18's "thickness cannot be determined" clause governs both forms. +# The bare "insulated" description (observed retrofit) keeps the 50 mm row. +# The 27-cert loc4+NI cohort was systematically under-rated ~1 SAP (e.g. +# 10094975827 band B -1.87 -> inside). Unit-pinned in test_rdsap_uvalues. +# 0.755 -> 0.770 (MAE 0.708 -> 0.668) via the secondary-fuel collision fix +# on the SAP-DRIVING cost path (`_fuel_cost`): the gov-API secondary fuel +# enums 5 (anthracite) / 9 (dual fuel) / 33 (coal) collide with same-valued +# Table-32 codes for OTHER fuels, and `_fuel_cost`'s inline secondary rate +# passed the raw enum to the price lookup (unlike the already-canonicalised +# main-fuel boundary + CO2/display helper). Anthracite priced at the bulk-LPG +# code-5 rate (12.19 vs 3.64 p/kWh) 3x over-cost the secondary -> under-rate. +# Worst: cert 100050355518 (2 extensions, anthracite room-heater 2ndary) +# lodged 36 / engine 20.8 -> 35.9. 55 corpus certs carry a colliding +# secondary. Unit-pinned in test_cert_to_inputs (fuel_cost cost path, not +# just the display helper the prior enum-9 test guarded). +# 0.770 -> 0.773 via the unsized-cylinder storage-loss fix: a present +# cylinder lodging gov-API cylinder_size=0 ("size not determined") resolved +# to None volume in `_cylinder_storage_loss_override`, so `if volume_l is +# None: return None` DROPPED its storage loss (under-costing the DHW -> +# over-rate). RdSAP 10 §10.5 Table 28: an unsized present cylinder is the +# 110 L "Normal" default and still incurs the Table-2 loss (the value the +# Table-13 fraction path already used). Gated on the explicit 0 so a +# full-SAP unlodged size (None) keeps its own handling. 7 corpus certs; +# within 77.0% -> 77.3%, PE 3.2 -> 3.05, CO2 0.074 -> 0.073. +# 0.773 -> 0.777 via the flat-roof insulation-thickness fix: a FLAT roof +# lodges its thickness in the dedicated `flat_roof_insulation_thickness` +# field (e.g. "75mm"), but heat_transmission read `roof_insulation_thickness` +# (None for flat roofs) -> billed the roof at the uninsulated age-band flat +# default (age E 1.5) instead of the insulated Table-16 U. Prefer the flat +# field when the part is flat (mirrors the rafter-thickness branch). Cert +# 47084930 (top-floor flat, flat roof 75mm): roof 96.4 -> 32.1 W/K, engine +# 69.51 -> 74.34 = lodged 74, VALIDATED against the accredited Elmhurst +# worksheet ("insulated flat roof" U 0.5). within 77.3% -> 77.7%, PE 3.1 -> +# 2.97, CO2 0.074 -> 0.072. +# 77.7% -> 77.8% via the §5 (12) suspended-timber floor-infiltration +# fallback (see the `_MAX_SAP_MAE` note below for the mechanism). +_MIN_WITHIN_HALF_SAP = 0.778 # 0.793 -> 0.789 via the §12 Unknown-meter + dual-electric-immersion off-peak # trigger (RdSAP 10 PDF p.62): Apartment 241 (main 691 + 903 dual immersion) # -5.38 -> -1.05. Worksheet-validated on "simulated case 48" (Elmhurst SAP 57, @@ -266,9 +309,34 @@ _MIN_WITHIN_HALF_SAP = 0.742 # oversized-PSR water eff 0.60 x 128.55% = 77.13% is floored to 100% (= # accredited Elmhurst (216)), taking the cert 68.03 -> 72.51 (|err| 4.97 -> # 0.49, now inside +-0.5). In-range heat pumps keep their > 100% water COP. -_MAX_SAP_MAE = 0.722 -_MAX_CO2_MAE_TONNES = 0.09 # t CO2 / yr vs co2_emissions_current -_MAX_PE_PER_M2_MAE = 3.5 # kWh / m2 / yr vs energy_consumption_current +# 0.669 -> 0.659 via the instantaneous-electric-DHW off-peak fix: WHC 907/909 +# (point-of-use, no cylinder) on an off-peak tariff was billed 100% at the +# off-peak LOW rate, but SAP 10.2 §12 (Table 13 on-peak proportion is keyed on +# CYLINDER size) presumes stored water; an instantaneous heater has no cylinder +# and heats on demand -> 100% high rate. Cert 74061136 (HHR-storage flat, +# WHC 909) +7.72 -> -1.25. Both the cost rate and the ADR-0014/CO2-PE fraction +# fixed (fraction 0 -> 1.0). Unit-pinned in test_cert_to_inputs. +# 0.659 -> 0.648 via the wall added-insulation unknown-thickness fix: a +# SOLID-BRICK/STONE wall lodging External/Internal insulation (type 1/3) with +# thickness "NI" (unknown) was billed UNINSULATED (§5.8 R-value gate needs a +# thickness > 0), over-counting wall heat loss. RdSAP 10 §5.4 (PDF p.32): +# "assume 100 mm if thickness is unknown" -> apply the 100 mm §5.8 default. +# Cert 200004296092 (age-B solid brick 360 mm + external, NI): walls 101.7 W/K +# (U~1.4) -> ~0.29, PE +59.6 -> ~0, SAP 64.35 -> 71.74 (lodged 71). Scoped to +# brick/stone (the only §5.8 R-value path); within-0.5 held at 77.0%, MAE +# 0.658 -> 0.647, PE 3.2 -> 3.1. Unit-pinned in test_rdsap_uvalues. +# 77.7% -> 77.8% (MAE 0.637 -> 0.636) via the §5 (12) suspended-timber +# floor-infiltration fallback: `_has_suspended_timber_floor_per_spec` +# only read the Main bp's per-part `floor_construction_type` lodgement, +# which the gov-API mapper frequently leaves `None` even when the global +# `epc.floors[].description` carries an explicit "Suspended, ..." +# observation (`_main_floor_u_value` already fell back to this joined +# description for the U-value calc — the infiltration rule did not). +# Cert 100061275133 (Elmhurst-validated build): SAP 77.24 -> 76.33, now +# an EXACT match to lodged (76). Unit-pinned in test_cert_to_inputs. +_MAX_SAP_MAE = 0.637 +_MAX_CO2_MAE_TONNES = 0.072 # t CO2 / yr vs co2_emissions_current +_MAX_PE_PER_M2_MAE = 3.0 # kWh / m2 / yr vs energy_consumption_current def _load_corpus() -> list[dict[str, Any]]: