From c9fc2c6baf2ff5d6c2619d96c77e06231eebbcd5 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 9 Jul 2026 18:30:08 +0000 Subject: [PATCH 1/7] Map SAP-Schema-15.0 certs (LIG-lodged, 2011-era reduced-field RdSAP shape) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task a40e71c4-fd56-4a33-8677-e8643e6a5bb4 (portfolio 824, scenario 1278) failed 2 of 29 properties with "Unsupported EPC schema: 'SAP-Schema-15.0'" (property_id 748445/748451). Traced to two real 2011 lodgements (schema_version "LIG-15.0", assessment_type "RdSAP") for UPRNs 100010359769/100010359788 — structurally the same reduced-field RdSAP-17.1 shape as the already-handled SAP-Schema-16.x family, one revision older. from_sap_schema_15_0 reuses _normalize_sap_schema_16_x and adds three schema-wide defaults this older generation never lodges at all (confirmed absent on both real certs, not just sparse on one): - door_count=1 (single external door, standard RdSAP assumption) - instantaneous_wwhrs=0/0/0 and has_fghrs="N" (predates WWHRS/FGHRS lodging — absence-means-none-fitted, same convention used elsewhere) - percent_draughtproofed=0 (mirrors the existing has_draught_lobby "assume none if unknown" convention in cert_to_inputs.py) - energy_rating_average=60 (inert metadata, never read by the calculator) Both real certs now map and run end-to-end through the SAP-10 engine, matching (or within 1 point of) their lodged SAP score. --- datatypes/epc/domain/mapper.py | 60 +++++ .../domain/tests/test_from_sap_schema_15_0.py | 67 +++++ .../fixtures/sap_15_0_uprn_100010359769.json | 255 ++++++++++++++++++ .../fixtures/sap_15_0_uprn_100010359788.json | 248 +++++++++++++++++ 4 files changed, 630 insertions(+) create mode 100644 datatypes/epc/domain/tests/test_from_sap_schema_15_0.py create mode 100644 datatypes/epc/schema/tests/fixtures/sap_15_0_uprn_100010359769.json create mode 100644 datatypes/epc/schema/tests/fixtures/sap_15_0_uprn_100010359788.json diff --git a/datatypes/epc/domain/mapper.py b/datatypes/epc/domain/mapper.py index e3cdde0be..33b3cd840 100644 --- a/datatypes/epc/domain/mapper.py +++ b/datatypes/epc/domain/mapper.py @@ -1101,6 +1101,62 @@ class EpcPropertyDataMapper: schema convention.""" return EpcPropertyDataMapper.from_sap_schema_17_1(schema) + @staticmethod + def from_sap_schema_15_0(data: Dict[str, Any]) -> EpcPropertyData: + """Map a reduced-field `SAP-Schema-15.0` cert. + + Structurally the same LIG-lodged reduced-field shape as the + `SAP-Schema-16.x` family (`schema_version: "LIG-15.0"`, `assessment_type: + "RdSAP"`) — see `from_sap_schema_16_2`. One further gap on top of that + family's normalisation: these 2011-era certs never lodge `door_count` + at all (confirmed on two real certs, UPRNs 100010359769/100010359788 — + it is absent from the payload entirely, not blank). Unlike a 16.x cert + that omits `door_count` on an otherwise-complete lodgement (a per-cert + data gap the mapper correctly fails loud on), the whole 15.0 schema + never carried the field — so default to 1 (a single external door, + the standard RdSAP assumption when unrecorded) rather than treating it + as insufficient data. + + These certs also predate WWHRS and FGHRS lodging altogether — + `sap_heating` has no `wwhrs` key for `_normalize_sap_schema_16_x` to + rename, and `main_heating_details[]` never carries `has_fghrs`. Both + default to "not present" ("N" / all-zero counts), the same + absence-means-none-fitted convention used elsewhere in this mapper + (e.g. the full-SAP mappers' bare `InstantaneousWwhrs()`). + """ + from datatypes.epc.schema.rdsap_schema_17_1 import RdSapSchema17_1 + + normalized = _normalize_sap_schema_16_x(data) + normalized.setdefault("door_count", 1) + # `energy_rating_average` is the fixed national-average marker (60 on + # every fixture in this repo, `RdSapSchema17_1`-required, inert + # metadata never read by the SAP calculator) — these certs omit it. + normalized.setdefault("energy_rating_average", 60) + # Draught-proofing extent is unrecorded on these certs; 0% is the same + # "assume none if unknown" convention the cascade already applies to + # `has_draught_lobby` (see `_has_draught_lobby` in cert_to_inputs.py) — + # conservative (no draught-proofing credit), not a guessed value. + normalized.setdefault("percent_draughtproofed", 0) + sap_heating: Any = normalized.get("sap_heating") + if isinstance(sap_heating, dict): + heating: Dict[str, Any] = cast(Dict[str, Any], sap_heating) + heating.setdefault( + "instantaneous_wwhrs", + { + "rooms_with_bath_and_or_shower": 0, + "rooms_with_mixer_shower_no_bath": 0, + "rooms_with_bath_and_mixer_shower": 0, + }, + ) + main_heating_details: Any = heating.get("main_heating_details") or [] + for mh in cast(List[Any], main_heating_details): + if isinstance(mh, dict): + cast(Dict[str, Any], mh).setdefault("has_fghrs", "N") + + return EpcPropertyDataMapper.from_rdsap_schema_17_1( + from_dict(RdSapSchema17_1, normalized) + ) + @staticmethod def from_sap_schema_16_0(data: Dict[str, Any]) -> EpcPropertyData: """Map a reduced-field `SAP-Schema-16.0` cert (see `from_sap_schema_16_2`).""" @@ -2974,6 +3030,10 @@ class EpcPropertyDataMapper: mapped = EpcPropertyDataMapper.from_sap_schema_19_1_0( from_dict(SapSchema17_1, data) ) + # SAP-Schema-15.0: same reduced-field (RdSAP-shaped) family as 16.x, one + # revision older — see `from_sap_schema_15_0`. + elif schema == "SAP-Schema-15.0": + mapped = EpcPropertyDataMapper.from_sap_schema_15_0(data) # SAP-Schema-16.x family: reduced-field (RdSAP-shaped) certs. Each gets a # dedicated mapper that normalises onto the RdSAP-17.1 shape via the # shared `_normalize_sap_schema_16_x` and reuses `from_rdsap_schema_17_1`. diff --git a/datatypes/epc/domain/tests/test_from_sap_schema_15_0.py b/datatypes/epc/domain/tests/test_from_sap_schema_15_0.py new file mode 100644 index 000000000..570b84df9 --- /dev/null +++ b/datatypes/epc/domain/tests/test_from_sap_schema_15_0.py @@ -0,0 +1,67 @@ +"""SAP-Schema-15.0 — the same LIG-lodged reduced-field RdSAP-17.1 shape as +`SAP-Schema-16.x` (`schema_version: "LIG-15.0"`), one revision older, from a +2011 lodgement generation that predates `door_count`, WWHRS, and FGHRS +lodging entirely (unlike a 16.x cert omitting one of those fields, which is a +per-cert data gap, this is schema-wide — see `from_sap_schema_15_0`). + +`from_api_response` normalises it onto the RdSAP-17.1 shape via +`_normalize_sap_schema_16_x` plus the three extra defaults, then reuses that +mapper. Regression for the task that first surfaced this gap +(a40e71c4-fd56-4a33-8677-e8643e6a5bb4, portfolio 824 / scenario 1278, +property_id 748445 / 748451 — "Unsupported EPC schema: 'SAP-Schema-15.0'"). +""" + +from typing import Any, Dict +import json +import os + +from datatypes.epc.domain.epc_property_data import EpcPropertyData +from datatypes.epc.domain.mapper import EpcPropertyDataMapper + +FIXTURES = os.path.join(os.path.dirname(__file__), "../../schema/tests/fixtures") + + +def load(filename: str) -> Dict[str, Any]: + with open(os.path.join(FIXTURES, filename)) as f: + return json.load(f) # type: ignore[no-any-return] + + +class TestFromSapSchema15_0: + def test_dispatches_and_maps_via_rdsap_17_1(self) -> None: + # Arrange / Act — the raw 15.0 doc must dispatch (no "Unsupported + # schema") and map the 16.x-family seams plus the three schema-wide + # gaps unique to 15.0 (door_count, instantaneous_wwhrs, has_fghrs). + epc = EpcPropertyDataMapper.from_api_response( + load("sap_15_0_uprn_100010359769.json") + ) + + # Assert + assert isinstance(epc, EpcPropertyData) + assert epc.uprn == 100010359769 + assert epc.dwelling_type == "Mid-terrace house" + assert epc.door_count == 1 + mh = epc.sap_heating.main_heating_details[0] + assert mh.main_fuel_type == 26 # mains gas + + def test_produces_a_sap_score(self) -> None: + # The mapped cert must run end-to-end through the SAP-10 engine. + from domain.sap10_calculator.calculator import Sap10Calculator + + epc = EpcPropertyDataMapper.from_api_response( + load("sap_15_0_uprn_100010359769.json") + ) + result = Sap10Calculator().calculate(epc) + # Lodged 68; engine also produces 68. + assert result.sap_score == 68 + + def test_second_property_produces_a_sap_score(self) -> None: + # Second real cert from the same failing task, confirms the fix isn't + # a one-cert coincidence. + from domain.sap10_calculator.calculator import Sap10Calculator + + epc = EpcPropertyDataMapper.from_api_response( + load("sap_15_0_uprn_100010359788.json") + ) + result = Sap10Calculator().calculate(epc) + # Lodged 73; engine produces 72 (Elmhurst validation not yet run). + assert result.sap_score == 72 diff --git a/datatypes/epc/schema/tests/fixtures/sap_15_0_uprn_100010359769.json b/datatypes/epc/schema/tests/fixtures/sap_15_0_uprn_100010359769.json new file mode 100644 index 000000000..572bbb0e3 --- /dev/null +++ b/datatypes/epc/schema/tests/fixtures/sap_15_0_uprn_100010359769.json @@ -0,0 +1,255 @@ +{ + "uprn": 100010359769, + "roofs": [ + { + "description": "Pitched, 250 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + { + "description": "Flat, limited insulation (assumed)", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "walls": [ + { + "description": "Cavity wall, filled cavity", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Suspended, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 91% of fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "BB12 7BY", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 4, + "created_at": "2011-07-25 16:35:41", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "secondary_fuel_type": 29, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 8358, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "secondary_heating_type": 691, + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Mid-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "3, Warwick Drive", + "address_line_2": "Padiham", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-07-25", + "inspection_date": "2011-07-25", + "extensions_count": 1, + "measurement_type": 1, + "total_floor_area": 76, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 5, + "registration_date": "2011-07-25", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "Room heaters, electric", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.58, + "floor_insulation": 1, + "total_floor_area": 35.59, + "floor_construction": 2, + "heat_loss_perimeter": 9 + }, + { + "floor": 1, + "room_height": 2.43, + "total_floor_area": 34.75, + "heat_loss_perimeter": 10.86 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "C", + "roof_insulation_location": 2, + "roof_insulation_thickness": "250mm" + }, + { + "identifier": "Extension 1", + "floor_heat_loss": 7, + "roof_construction": 1, + "wall_construction": 4, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.33, + "floor_insulation": 1, + "total_floor_area": 5.37, + "floor_construction": 1, + "heat_loss_perimeter": 4.66 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "E", + "roof_insulation_location": 4, + "roof_insulation_thickness": "NI" + } + ], + "low_energy_lighting": 91, + "solar_water_heating": "N", + "bedf_revision_number": 311, + "habitable_room_count": 5, + "heating_cost_current": 501, + "co2_emissions_current": 2.8, + "energy_rating_current": 68, + "lighting_cost_current": 45, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 3, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 471, + "hot_water_cost_current": 95, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 41, + "indicative_cost": "\u00a31,500 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 70, + "environmental_impact_rating": 71 + }, + { + "sequence": 2, + "typical_saving": 24, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 71, + "environmental_impact_rating": 73 + }, + { + "sequence": 3, + "typical_saving": 214, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 82, + "environmental_impact_rating": 83 + } + ], + "co2_emissions_potential": 2.6, + "energy_rating_potential": 70, + "lighting_cost_potential": 45, + "hot_water_cost_potential": 83, + "renewable_heat_incentive": { + "water_heating": 2071, + "space_heating_existing_dwelling": 6949, + "space_heating_with_loft_and_cavity_insulation": 6949 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 196, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.05r12", + "energy_consumption_potential": 180, + "environmental_impact_current": 69, + "fixed_lighting_outlets_count": 11, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 71, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 37, + "low_energy_fixed_lighting_outlets_count": 10 +} \ No newline at end of file diff --git a/datatypes/epc/schema/tests/fixtures/sap_15_0_uprn_100010359788.json b/datatypes/epc/schema/tests/fixtures/sap_15_0_uprn_100010359788.json new file mode 100644 index 000000000..1a80fde24 --- /dev/null +++ b/datatypes/epc/schema/tests/fixtures/sap_15_0_uprn_100010359788.json @@ -0,0 +1,248 @@ +{ + "uprn": 100010359788, + "roofs": [ + { + "description": "Pitched, 150 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + { + "description": "Flat, limited insulation (assumed)", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 89% of fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "BB12 7BY", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 4, + "created_at": "2011-08-04 07:03:30", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 8358, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Mid-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "22, Warwick Drive", + "address_line_2": "Padiham", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-08-04", + "inspection_date": "2011-08-04", + "extensions_count": 1, + "measurement_type": 1, + "total_floor_area": 77, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 5, + "registration_date": "2011-08-04", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.35, + "floor_insulation": 1, + "total_floor_area": 35, + "floor_construction": 1, + "heat_loss_perimeter": 8.3 + }, + { + "floor": 1, + "room_height": 2.4, + "total_floor_area": 35, + "heat_loss_perimeter": 11 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "C", + "roof_insulation_location": 2, + "roof_insulation_thickness": "150mm" + }, + { + "identifier": "Extension 1", + "floor_heat_loss": 7, + "roof_construction": 1, + "wall_construction": 4, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2, + "floor_insulation": 1, + "total_floor_area": 6.63, + "floor_construction": 1, + "heat_loss_perimeter": 5.16 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "F", + "roof_insulation_location": 4, + "roof_insulation_thickness": "NI" + } + ], + "low_energy_lighting": 89, + "solar_water_heating": "N", + "bedf_revision_number": 312, + "habitable_room_count": 5, + "heating_cost_current": 409, + "co2_emissions_current": 2.4, + "energy_rating_current": 73, + "lighting_cost_current": 46, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 1, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 379, + "hot_water_cost_current": 95, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 41, + "indicative_cost": "\u00a31,500 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 75, + "environmental_impact_rating": 76 + }, + { + "sequence": 2, + "typical_saving": 25, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 76, + "environmental_impact_rating": 77 + }, + { + "sequence": 3, + "typical_saving": 214, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 86, + "environmental_impact_rating": 87 + } + ], + "co2_emissions_potential": 2.2, + "energy_rating_potential": 75, + "lighting_cost_potential": 46, + "hot_water_cost_potential": 84, + "renewable_heat_incentive": { + "water_heating": 2080, + "space_heating_existing_dwelling": 6207, + "space_heating_with_loft_and_cavity_insulation": 6207 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 166, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.05r15", + "energy_consumption_potential": 150, + "environmental_impact_current": 73, + "fixed_lighting_outlets_count": 9, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 76, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 32, + "low_energy_fixed_lighting_outlets_count": 8 +} \ No newline at end of file From ce5899c5ec21bdcb42737465c80cca80dd250674 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 9 Jul 2026 19:06:21 +0000 Subject: [PATCH 2/7] Validate SAP-Schema-15.0 mapper against 20 real certs from the failing task MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sampled all 20 unique property_ids that failed with "Unsupported EPC schema: 'SAP-Schema-15.0'" across the sub_task history (114 total across 72 subtask rows), captured 20 real live certs, and pinned each as a RealCertExpectation regression in the accuracy corpus. 16/20 land exact or within 1-3 SAP of the lodged rating, confirming the door_count/WWHRS/FGHRS/draught-proofing defaults generalise beyond the original two properties. The other 4 (all solid-brick, uninsulated, age band C) diverge +6 to +12 — traced to a legitimate SAP-2009-vintage- lodgement vs RdSAP10-recalculation methodology gap (u_wall() checked directly against RdSAP10's own Table 6, returns the correct 1.70 — no mapper defect), not a mapper bug, so pinned to the engine's observed value rather than tuned to lodged. --- .../expand-sap-accuracy-corpus/worklist.md | 29 ++ .../uprn_100010074470/epc.json | 299 +++++++++++++++++ .../uprn_100010086084/epc.json | 286 ++++++++++++++++ .../uprn_100010090369/epc.json | 305 +++++++++++++++++ .../uprn_100010100813/epc.json | 274 +++++++++++++++ .../uprn_100010333531/epc.json | 207 ++++++++++++ .../uprn_100010341489/epc.json | 198 +++++++++++ .../uprn_100010341491/epc.json | 247 ++++++++++++++ .../uprn_100010347637/epc.json | 249 ++++++++++++++ .../uprn_100010347646/epc.json | 197 +++++++++++ .../uprn_100010350459/epc.json | 230 +++++++++++++ .../uprn_100010350468/epc.json | 275 +++++++++++++++ .../uprn_100010359769/epc.json | 255 ++++++++++++++ .../uprn_100010359788/epc.json | 248 ++++++++++++++ .../SAP-Schema-15.0/uprn_10070394806/epc.json | 253 ++++++++++++++ .../SAP-Schema-15.0/uprn_10070400618/epc.json | 261 +++++++++++++++ .../SAP-Schema-15.0/uprn_10070400619/epc.json | 242 ++++++++++++++ .../SAP-Schema-15.0/uprn_77179816/epc.json | 242 ++++++++++++++ .../SAP-Schema-15.0/uprn_77179820/epc.json | 242 ++++++++++++++ .../SAP-Schema-15.0/uprn_77180626/epc.json | 312 ++++++++++++++++++ .../SAP-Schema-15.0/uprn_77181233/epc.json | 243 ++++++++++++++ .../test_real_cert_sap_accuracy.py | 141 ++++++++ 22 files changed, 5235 insertions(+) create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010074470/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010086084/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010090369/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010100813/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010333531/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010341489/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010341491/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010347637/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010347646/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010350459/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010350468/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010359769/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010359788/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070394806/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070400618/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070400619/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77179816/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77179820/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77180626/epc.json create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77181233/epc.json diff --git a/.claude/skills/expand-sap-accuracy-corpus/worklist.md b/.claude/skills/expand-sap-accuracy-corpus/worklist.md index 58f3b9842..dbb1cea00 100644 --- a/.claude/skills/expand-sap-accuracy-corpus/worklist.md +++ b/.claude/skills/expand-sap-accuracy-corpus/worklist.md @@ -385,3 +385,32 @@ Skip the 🚩 MVHR / 🚩 heat-pump-fuel and ⛔ sparse certs. - [⚠] 10090343767 — SAP-17.0 · eng 79 / lodged 91 · 🚩 MVHR idx 500352 not credited (flagged) - [ ] 10090845805 — SAP-17.0 · eng 82 / lodged 87 - [ ] 10013924858 — SAP-17.0 · eng 81 / lodged 84 + +# SAP-Schema-15.0 mapper validation (task a40e71c4-fd56-4a33-8677-e8643e6a5bb4) +🔧 New schema — `from_sap_schema_15_0` added in mapper.py (PR #1531). No full +Elmhurst rebuild done for this batch: 16/20 land exact or within 1-3 of lodged +(strong signal alone, given each other case in this file needed a full rebuild +to reach that confidence); the other 4 share a diagnosed, non-mapper cause +(solid-brick U-value confirmed correct against RdSAP10 Table 6 directly — see +comment in test_real_cert_sap_accuracy.py) so pinned without a rebuild too. All +20 pinned as `RealCertExpectation`s. +- [x] 🔧 100010359769 — SAP-15.0 · eng 68 (lodged 68) +- [x] 🔧 100010359788 — SAP-15.0 · eng 72 (lodged 73) +- [x] 🔍 100010086084 — SAP-15.0 · eng 53 (lodged 45) · solid-brick vintage-methodology gap, not mapper — see test file comment +- [x] 🔍 100010090369 — SAP-15.0 · eng 53 (lodged 47) · ditto +- [x] 🔍 100010074470 — SAP-15.0 · eng 46 (lodged 39) · ditto +- [x] 🔍 100010100813 — SAP-15.0 · eng 59 (lodged 47) · ditto (largest gap, +12) +- [x] 🔧 77179816 — SAP-15.0 · eng 76 (lodged 75) +- [x] 🔧 10070400619 — SAP-15.0 · eng 77 (lodged 77) +- [x] 🔧 77179820 — SAP-15.0 · eng 77 (lodged 77) +- [x] 🔧 10070394806 — SAP-15.0 · eng 78 (lodged 77) +- [x] 🔧 77181233 — SAP-15.0 · eng 68 (lodged 69) +- [x] 🔧 77180626 — SAP-15.0 · eng 68 (lodged 68) +- [x] 🔧 10070400618 — SAP-15.0 · eng 70 (lodged 69) +- [x] 🔧 100010350459 — SAP-15.0 · eng 65 (lodged 65) +- [x] 🔧 100010350468 — SAP-15.0 · eng 66 (lodged 66) +- [x] 🔧 100010333531 — SAP-15.0 · eng 73 (lodged 74) +- [x] 🔧 100010341489 — SAP-15.0 · eng 65 (lodged 64) +- [x] 🔧 100010341491 — SAP-15.0 · eng 62 (lodged 59) +- [x] 🔧 100010347646 — SAP-15.0 · eng 75 (lodged 75) +- [x] 🔧 100010347637 — SAP-15.0 · eng 72 (lodged 72) diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010074470/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010074470/epc.json new file mode 100644 index 000000000..973dd30bd --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010074470/epc.json @@ -0,0 +1,299 @@ +{ + "uprn": 100010074470, + "roofs": [ + { + "description": "Pitched, 75 mm loft insulation", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "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", + "windows": [ + { + "description": "Some double glazing", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "lighting": { + "description": "Low energy lighting in 78% of fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "CW2 7RZ", + "hot_water": { + "description": "From main system, no cylinderstat", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "post_town": "CREWE", + "built_form": 2, + "created_at": "2012-02-28 17:44:26", + "glazed_area": 1, + "region_code": 9, + "report_type": 2, + "sap_heating": { + "cylinder_size": 2, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "N", + "secondary_fuel_type": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 1, + "fan_flue_present": "N", + "heat_emitter_type": 1, + "main_heating_number": 1, + "main_heating_control": 2104, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 119, + "main_heating_data_source": 2 + } + ], + "secondary_heating_type": 604, + "cylinder_insulation_type": 2, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 38 + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 3 + } + ], + "dwelling_type": "Semi-detached house", + "language_code": 1, + "property_type": 0, + "address_line_1": "23, Davenham Crescent", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2012-02-28", + "inspection_date": "2012-02-28", + "extensions_count": 0, + "measurement_type": 2, + "total_floor_area": 87, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 4, + "registration_date": "2012-02-28", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "Room heaters, mains gas", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.62, + "floor_insulation": 1, + "total_floor_area": 49.83, + "floor_construction": 1, + "heat_loss_perimeter": 22.56 + }, + { + "floor": 1, + "room_height": 2.5, + "total_floor_area": 48.18, + "heat_loss_perimeter": 21.36 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "B", + "roof_insulation_location": 2, + "roof_insulation_thickness": "75mm" + } + ], + "low_energy_lighting": 78, + "solar_water_heating": "N", + "bedf_revision_number": 317, + "habitable_room_count": 4, + "heating_cost_current": 1042, + "co2_emissions_current": 7.1, + "energy_rating_current": 39, + "lighting_cost_current": 57, + "main_heating_controls": [ + { + "description": "Programmer and room thermostat", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "multiple_glazing_type": 3, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "true", + "heating_cost_potential": 762, + "hot_water_cost_current": 245, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 30, + "indicative_cost": "?100 - ?300", + "improvement_type": "A", + "improvement_details": { + "improvement_number": 5 + }, + "improvement_category": 1, + "energy_performance_rating": 40, + "environmental_impact_rating": 37 + }, + { + "sequence": 2, + "typical_saving": 30, + "indicative_cost": "?15 - ?30", + "improvement_type": "C", + "improvement_details": { + "improvement_number": 2 + }, + "improvement_category": 1, + "energy_performance_rating": 42, + "environmental_impact_rating": 38 + }, + { + "sequence": 3, + "typical_saving": 107, + "indicative_cost": "?200 - ?400", + "improvement_type": "F", + "improvement_details": { + "improvement_number": 4 + }, + "improvement_category": 1, + "energy_performance_rating": 46, + "environmental_impact_rating": 42 + }, + { + "sequence": 4, + "typical_saving": 32, + "indicative_cost": "?350 - ?450", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 13 + }, + "improvement_category": 1, + "energy_performance_rating": 48, + "environmental_impact_rating": 43 + }, + { + "sequence": 5, + "typical_saving": 226, + "indicative_cost": "?1,500 - ?3,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 58, + "environmental_impact_rating": 54 + }, + { + "sequence": 6, + "typical_saving": 33, + "indicative_cost": "?4,000 - ?6,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 60, + "environmental_impact_rating": 56 + }, + { + "sequence": 7, + "typical_saving": 54, + "indicative_cost": "?2,500 - ?6,500", + "improvement_type": "O", + "improvement_details": { + "improvement_number": 8 + }, + "improvement_category": 3, + "energy_performance_rating": 62, + "environmental_impact_rating": 59 + }, + { + "sequence": 8, + "typical_saving": 243, + "indicative_cost": "?5,500 - ?14,500", + "improvement_type": "Q", + "improvement_details": { + "improvement_number": 7 + }, + "improvement_category": 3, + "energy_performance_rating": 72, + "environmental_impact_rating": 73 + }, + { + "sequence": 9, + "typical_saving": 219, + "indicative_cost": "?11,000 - ?20,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 82, + "environmental_impact_rating": 82 + } + ], + "co2_emissions_potential": 4.6, + "energy_rating_potential": 58, + "lighting_cost_potential": 57, + "hot_water_cost_potential": 101, + "renewable_heat_incentive": { + "water_heating": 4086, + "space_heating_existing_dwelling": 17203, + "space_heating_with_loft_insulation": 16856, + "space_heating_with_loft_and_cavity_insulation": 16856 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 421, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 30, + "calculation_software_version": "1.3.1.0", + "energy_consumption_potential": 273, + "environmental_impact_current": 36, + "fixed_lighting_outlets_count": 9, + "current_energy_efficiency_band": "E", + "environmental_impact_potential": 54, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "D", + "co2_emissions_current_per_floor_area": 81, + "low_energy_fixed_lighting_outlets_count": 7 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010086084/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010086084/epc.json new file mode 100644 index 000000000..e2d4ab3b9 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010086084/epc.json @@ -0,0 +1,286 @@ +{ + "uprn": 100010086084, + "roofs": [ + { + "description": "Pitched, 300+ mm loft insulation", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "walls": [ + { + "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", + "windows": [ + { + "description": "Partial double glazing", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "lighting": { + "description": "Low energy lighting in 43% of fixed outlets", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "postcode": "CW1 3SH", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "post_town": "CREWE", + "built_form": 2, + "created_at": "2011-12-14 15:24:30", + "glazed_area": 1, + "region_code": 9, + "report_type": 2, + "sap_heating": { + "cylinder_size": 2, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "Y", + "secondary_fuel_type": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 1, + "fan_flue_present": "N", + "heat_emitter_type": 1, + "main_heating_number": 1, + "main_heating_control": 2104, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 115, + "main_heating_data_source": 2 + } + ], + "secondary_heating_type": 603, + "cylinder_insulation_type": 1, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 25 + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 3 + } + ], + "dwelling_type": "Semi-detached house", + "language_code": 1, + "property_type": 0, + "address_line_1": "9, Pear Tree Avenue", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-12-14", + "inspection_date": "2011-12-13", + "extensions_count": 0, + "measurement_type": 2, + "total_floor_area": 68, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2011-12-14", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "Room heaters, mains gas", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.41, + "floor_insulation": 0, + "total_floor_area": 37.74, + "floor_construction": 1, + "heat_loss_perimeter": 21.05 + }, + { + "floor": 1, + "room_height": 2.45, + "total_floor_area": 39.48, + "heat_loss_perimeter": 18.45 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "C", + "roof_insulation_location": 2, + "roof_insulation_thickness": "300mm+" + } + ], + "low_energy_lighting": 43, + "solar_water_heating": "N", + "bedf_revision_number": 316, + "habitable_room_count": 3, + "heating_cost_current": 816, + "co2_emissions_current": 5.2, + "energy_rating_current": 45, + "lighting_cost_current": 59, + "main_heating_controls": [ + { + "description": "Programmer and room thermostat", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "multiple_glazing_type": 1, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "true", + "heating_cost_potential": 647, + "hot_water_cost_current": 146, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 18, + "indicative_cost": "?10", + "improvement_type": "E", + "improvement_details": { + "improvement_number": 35 + }, + "improvement_category": 1, + "energy_performance_rating": 46, + "environmental_impact_rating": 43 + }, + { + "sequence": 2, + "typical_saving": 20, + "indicative_cost": "?350 - ?450", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 13 + }, + "improvement_category": 1, + "energy_performance_rating": 47, + "environmental_impact_rating": 44 + }, + { + "sequence": 3, + "typical_saving": 193, + "indicative_cost": "?1,500 - ?3,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 58, + "environmental_impact_rating": 54 + }, + { + "sequence": 4, + "typical_saving": 33, + "indicative_cost": "?4,000 - ?6,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 59, + "environmental_impact_rating": 57 + }, + { + "sequence": 5, + "typical_saving": 40, + "indicative_cost": "?2,500 - ?6,500", + "improvement_type": "O", + "improvement_details": { + "improvement_number": 8 + }, + "improvement_category": 3, + "energy_performance_rating": 62, + "environmental_impact_rating": 59 + }, + { + "sequence": 6, + "typical_saving": 207, + "indicative_cost": "?5,500 - ?14,500", + "improvement_type": "Q", + "improvement_details": { + "improvement_number": 7 + }, + "improvement_category": 3, + "energy_performance_rating": 72, + "environmental_impact_rating": 73 + }, + { + "sequence": 7, + "typical_saving": 214, + "indicative_cost": "?11,000 - ?20,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 84, + "environmental_impact_rating": 84 + }, + { + "sequence": 8, + "typical_saving": 18, + "indicative_cost": "?1,500 - ?4,000", + "improvement_type": "V", + "improvement_details": { + "improvement_number": 44 + }, + "improvement_category": 3, + "energy_performance_rating": 85, + "environmental_impact_rating": 85 + } + ], + "co2_emissions_potential": 3.9, + "energy_rating_potential": 58, + "lighting_cost_potential": 38, + "hot_water_cost_potential": 105, + "renewable_heat_incentive": { + "water_heating": 2634, + "space_heating_existing_dwelling": 13795, + "space_heating_with_loft_and_cavity_insulation": 13795 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 396, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 50, + "calculation_software_version": "1.3.1.0", + "energy_consumption_potential": 295, + "environmental_impact_current": 42, + "fixed_lighting_outlets_count": 7, + "current_energy_efficiency_band": "E", + "environmental_impact_potential": 54, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "D", + "co2_emissions_current_per_floor_area": 76, + "low_energy_fixed_lighting_outlets_count": 3 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010090369/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010090369/epc.json new file mode 100644 index 000000000..742010b81 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010090369/epc.json @@ -0,0 +1,305 @@ +{ + "uprn": 100010090369, + "roofs": [ + { + "description": "Pitched, 200 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Solid brick, as built, no insulation (assumed)", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "floors": [ + { + "description": "Suspended, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "No low energy lighting", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + }, + "postcode": "CW2 7RW", + "hot_water": { + "description": "From main system, no cylinder thermostat", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "post_town": "CREWE", + "built_form": 4, + "created_at": "2012-01-19 20:19:08", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 2, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "N", + "secondary_fuel_type": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "heat_emitter_type": 1, + "main_heating_number": 1, + "main_heating_control": 2102, + "main_heating_category": 2, + "main_heating_fraction": 1, + "sap_main_heating_code": 119, + "main_heating_data_source": 2 + } + ], + "secondary_heating_type": 601, + "cylinder_insulation_type": 2, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 80 + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Mid-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "3, Stewart Street", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2012-01-19", + "inspection_date": "2012-01-19", + "extensions_count": 1, + "measurement_type": 1, + "total_floor_area": 80, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2012-01-19", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 1, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 1 + }, + "secondary_heating": { + "description": "Room heaters, mains gas", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.78, + "floor_insulation": 1, + "total_floor_area": 32.92, + "floor_construction": 2, + "heat_loss_perimeter": 6.48 + }, + { + "floor": 1, + "room_height": 2.71, + "total_floor_area": 33.2, + "heat_loss_perimeter": 6.48 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "A", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm" + }, + { + "identifier": "Extension 1", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 3, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.75, + "floor_insulation": 1, + "total_floor_area": 6.91, + "floor_construction": 1, + "heat_loss_perimeter": 5.28 + }, + { + "floor": 1, + "room_height": 2.39, + "total_floor_area": 6.9, + "heat_loss_perimeter": 5.25 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "A", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm" + } + ], + "low_energy_lighting": 0, + "solar_water_heating": "N", + "bedf_revision_number": 317, + "habitable_room_count": 4, + "heating_cost_current": 791, + "co2_emissions_current": 5.5, + "energy_rating_current": 47, + "lighting_cost_current": 95, + "main_heating_controls": [ + { + "description": "Programmer, no room thermostat", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "multiple_glazing_type": 1, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "true", + "heating_cost_potential": 570, + "hot_water_cost_current": 212, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 39, + "indicative_cost": "\u00a325", + "improvement_type": "E", + "improvement_details": { + "improvement_number": 35 + }, + "improvement_category": 1, + "energy_performance_rating": 49, + "environmental_impact_rating": 45 + }, + { + "sequence": 2, + "typical_saving": 33, + "indicative_cost": "\u00a3200 - \u00a3400", + "improvement_type": "F", + "improvement_details": { + "improvement_number": 4 + }, + "improvement_category": 1, + "energy_performance_rating": 50, + "environmental_impact_rating": 46 + }, + { + "sequence": 3, + "typical_saving": 144, + "indicative_cost": "\u00a3350 - \u00a3450", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 12 + }, + "improvement_category": 1, + "energy_performance_rating": 57, + "environmental_impact_rating": 53 + }, + { + "sequence": 4, + "typical_saving": 153, + "indicative_cost": "\u00a31,500 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 65, + "environmental_impact_rating": 63 + }, + { + "sequence": 5, + "typical_saving": 33, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 66, + "environmental_impact_rating": 65 + }, + { + "sequence": 6, + "typical_saving": 123, + "indicative_cost": "\u00a35,500 - \u00a314,500", + "improvement_type": "Q", + "improvement_details": { + "improvement_number": 7 + }, + "improvement_category": 3, + "energy_performance_rating": 72, + "environmental_impact_rating": 73 + }, + { + "sequence": 7, + "typical_saving": 227, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 83, + "environmental_impact_rating": 83 + } + ], + "co2_emissions_potential": 3.5, + "energy_rating_potential": 65, + "lighting_cost_potential": 48, + "hot_water_cost_potential": 111, + "renewable_heat_incentive": { + "water_heating": 3531, + "space_heating_existing_dwelling": 11202, + "space_heating_with_loft_and_cavity_insulation": 11202 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 360, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.06r14", + "energy_consumption_potential": 225, + "environmental_impact_current": 44, + "fixed_lighting_outlets_count": 10, + "current_energy_efficiency_band": "E", + "environmental_impact_potential": 63, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "D", + "co2_emissions_current_per_floor_area": 69, + "low_energy_fixed_lighting_outlets_count": 0 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010100813/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010100813/epc.json new file mode 100644 index 000000000..0829e2df5 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010100813/epc.json @@ -0,0 +1,274 @@ +{ + "uprn": 100010100813, + "roofs": [ + { + "description": "Pitched, 100 mm loft insulation", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "lighting": { + "description": "Low energy lighting in all fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "CW5 5NJ", + "hot_water": { + "description": "From main system, no cylinderstat", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + }, + "post_town": "NANTWICH", + "built_form": 3, + "created_at": "2011-10-16 22:45:08", + "glazed_area": 1, + "region_code": 9, + "report_type": 2, + "sap_heating": { + "cylinder_size": 2, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "N", + "secondary_fuel_type": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "main_heating_number": 1, + "main_heating_control": 2104, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 2 + } + ], + "secondary_heating_type": 603, + "cylinder_insulation_type": 1, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 25 + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "End-Terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "15, Weaver Road", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-10-16", + "inspection_date": "2011-10-14", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 67, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2011-10-16", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "Room heaters, mains gas", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 3, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.42, + "floor_insulation": 0, + "total_floor_area": 33.32, + "floor_construction": 1, + "heat_loss_perimeter": 16.6 + }, + { + "floor": 1, + "room_height": 2.58, + "total_floor_area": 33.32, + "heat_loss_perimeter": 16.6 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "B", + "roof_insulation_location": 2, + "roof_insulation_thickness": "100mm" + } + ], + "low_energy_lighting": 100, + "solar_water_heating": "N", + "bedf_revision_number": 314, + "habitable_room_count": 3, + "heating_cost_current": 742, + "co2_emissions_current": 4.9, + "energy_rating_current": 47, + "lighting_cost_current": 37, + "main_heating_controls": [ + { + "description": "Programmer and room thermostat", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "multiple_glazing_type": 2, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "true", + "heating_cost_potential": 585, + "hot_water_cost_current": 197, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 85, + "indicative_cost": "?200 - ?400", + "improvement_type": "F", + "improvement_details": { + "improvement_number": 4 + }, + "improvement_category": 1, + "energy_performance_rating": 52, + "environmental_impact_rating": 48 + }, + { + "sequence": 2, + "typical_saving": 24, + "indicative_cost": "?350 - ?450", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 13 + }, + "improvement_category": 1, + "energy_performance_rating": 53, + "environmental_impact_rating": 49 + }, + { + "sequence": 3, + "typical_saving": 139, + "indicative_cost": "?1,500 - ?3,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 61, + "environmental_impact_rating": 58 + }, + { + "sequence": 4, + "typical_saving": 33, + "indicative_cost": "?4,000 - ?6,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 63, + "environmental_impact_rating": 60 + }, + { + "sequence": 5, + "typical_saving": 177, + "indicative_cost": "?5,500 - ?14,500", + "improvement_type": "Q", + "improvement_details": { + "improvement_number": 7 + }, + "improvement_category": 3, + "energy_performance_rating": 72, + "environmental_impact_rating": 73 + }, + { + "sequence": 6, + "typical_saving": 214, + "indicative_cost": "?11,000 - ?20,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 83, + "environmental_impact_rating": 84 + }, + { + "sequence": 7, + "typical_saving": 18, + "indicative_cost": "?1,500 - ?4,000", + "improvement_type": "V", + "improvement_details": { + "improvement_number": 44 + }, + "improvement_category": 3, + "energy_performance_rating": 84, + "environmental_impact_rating": 85 + } + ], + "co2_emissions_potential": 3.5, + "energy_rating_potential": 61, + "lighting_cost_potential": 37, + "hot_water_cost_potential": 105, + "renewable_heat_incentive": { + "water_heating": 3413, + "space_heating_existing_dwelling": 11875, + "space_heating_with_loft_insulation": 11728, + "space_heating_with_loft_and_cavity_insulation": 11728 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 383, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "1.3.1.0", + "energy_consumption_potential": 271, + "environmental_impact_current": 44, + "fixed_lighting_outlets_count": 9, + "current_energy_efficiency_band": "E", + "environmental_impact_potential": 58, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "D", + "co2_emissions_current_per_floor_area": 74, + "low_energy_fixed_lighting_outlets_count": 9 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010333531/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010333531/epc.json new file mode 100644 index 000000000..96678f6eb --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010333531/epc.json @@ -0,0 +1,207 @@ +{ + "uprn": 100010333531, + "roofs": [ + { + "description": "Pitched, 200 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": "(other premises below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 29% of fixed outlets", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "postcode": "BB10 4NX", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 3, + "created_at": "2011-11-14 07:10:26", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 8358, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Top-floor maisonette", + "language_code": 1, + "property_type": 3, + "address_line_1": "13, Chatburn Avenue", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-11-14", + "inspection_date": "2011-11-14", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 3, + "top_storey": "Y", + "flat_location": 1, + "heat_loss_corridor": 0 + }, + "total_floor_area": 70, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 2, + "registration_date": "2011-11-14", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 6, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.48, + "total_floor_area": 70, + "heat_loss_perimeter": 25.8 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "E", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm" + } + ], + "low_energy_lighting": 29, + "solar_water_heating": "N", + "bedf_revision_number": 315, + "habitable_room_count": 2, + "heating_cost_current": 338, + "co2_emissions_current": 2.1, + "energy_rating_current": 74, + "lighting_cost_current": 69, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 1, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 320, + "hot_water_cost_current": 92, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 24, + "indicative_cost": "\u00a313", + "improvement_type": "E", + "improvement_details": { + "improvement_number": 35 + }, + "improvement_category": 1, + "energy_performance_rating": 75, + "environmental_impact_rating": 77 + }, + { + "sequence": 2, + "typical_saving": 33, + "indicative_cost": "\u00a31,500 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 77, + "environmental_impact_rating": 79 + } + ], + "co2_emissions_potential": 1.8, + "energy_rating_potential": 77, + "lighting_cost_potential": 40, + "hot_water_cost_potential": 81, + "renewable_heat_incentive": { + "water_heating": 2005, + "space_heating_existing_dwelling": 4620, + "space_heating_with_loft_and_cavity_insulation": 4620 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 158, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.05r18", + "energy_consumption_potential": 136, + "environmental_impact_current": 75, + "fixed_lighting_outlets_count": 7, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 79, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 30, + "low_energy_fixed_lighting_outlets_count": 2 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010341489/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010341489/epc.json new file mode 100644 index 000000000..0e2736e1c --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010341489/epc.json @@ -0,0 +1,198 @@ +{ + "uprn": 100010341489, + "roofs": [ + { + "description": "(another dwelling above)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in all fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "BB11 4EB", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 3, + "created_at": "2012-01-23 08:15:11", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 10110, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Ground-floor maisonette", + "language_code": 1, + "property_type": 3, + "address_line_1": "83, Harold Street", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2012-01-23", + "inspection_date": "2012-01-23", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 1, + "top_storey": "N", + "flat_location": 0, + "heat_loss_corridor": 0 + }, + "total_floor_area": 43, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2012-01-23", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 3, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.6, + "floor_insulation": 1, + "total_floor_area": 42.7, + "floor_construction": 2, + "heat_loss_perimeter": 23 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "C", + "roof_insulation_location": "ND", + "roof_insulation_thickness": "ND" + } + ], + "low_energy_lighting": 100, + "solar_water_heating": "N", + "bedf_revision_number": 317, + "habitable_room_count": 3, + "heating_cost_current": 408, + "co2_emissions_current": 2.3, + "energy_rating_current": 64, + "lighting_cost_current": 26, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 1, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 321, + "hot_water_cost_current": 84, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 87, + "indicative_cost": "\u00a3100 - \u00a3300", + "improvement_type": "B", + "improvement_details": { + "improvement_number": 6 + }, + "improvement_category": 1, + "energy_performance_rating": 70, + "environmental_impact_rating": 73 + } + ], + "co2_emissions_potential": 1.8, + "energy_rating_potential": 70, + "lighting_cost_potential": 26, + "hot_water_cost_potential": 84, + "renewable_heat_incentive": { + "water_heating": 2051, + "space_heating_existing_dwelling": 6808, + "space_heating_with_cavity_insulation": 4625, + "space_heating_with_loft_and_cavity_insulation": 4625 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 279, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.06r14", + "energy_consumption_potential": 217, + "environmental_impact_current": 65, + "fixed_lighting_outlets_count": 4, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 73, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 54, + "low_energy_fixed_lighting_outlets_count": 4 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010341491/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010341491/epc.json new file mode 100644 index 000000000..e33bd3d61 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010341491/epc.json @@ -0,0 +1,247 @@ +{ + "uprn": 100010341491, + "roofs": [ + { + "description": "Pitched, 200 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "Cavity wall, as built, no insulation (assumed)", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + }, + { + "description": "Timber frame, as built, no insulation (assumed)", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "floors": [ + { + "description": "Suspended, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 88% of fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "BB11 4EB", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 2, + "created_at": "2012-01-26 20:02:54", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "secondary_fuel_type": 29, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 10315, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "secondary_heating_type": 691, + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Semi-detached house", + "language_code": 1, + "property_type": 0, + "address_line_1": "87, Harold Street", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2012-01-26", + "inspection_date": "2012-01-26", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 63, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 4, + "registration_date": "2012-01-26", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "Room heaters, electric", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.5, + "floor_insulation": 1, + "total_floor_area": 31.58, + "floor_construction": 2, + "heat_loss_perimeter": 16 + }, + { + "floor": 1, + "room_height": 2.5, + "total_floor_area": 31.58, + "heat_loss_perimeter": 16 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "C", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm" + }, + { + "wall_area": 27.5, + "wall_location": 0, + "wall_construction": 5, + "wall_insulation_type": 4 + } + ], + "low_energy_lighting": 88, + "solar_water_heating": "N", + "bedf_revision_number": 317, + "habitable_room_count": 4, + "heating_cost_current": 614, + "co2_emissions_current": 3.3, + "energy_rating_current": 59, + "lighting_cost_current": 41, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 1, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 534, + "hot_water_cost_current": 75, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 79, + "indicative_cost": "\u00a3100 - \u00a3300", + "improvement_type": "B", + "improvement_details": { + "improvement_number": 6 + }, + "improvement_category": 1, + "energy_performance_rating": 64, + "environmental_impact_rating": 65 + }, + { + "sequence": 2, + "typical_saving": 22, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 65, + "environmental_impact_rating": 67 + }, + { + "sequence": 3, + "typical_saving": 219, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 77, + "environmental_impact_rating": 78 + }, + { + "sequence": 4, + "typical_saving": 18, + "indicative_cost": "\u00a31,500 - \u00a34,000", + "improvement_type": "V", + "improvement_details": { + "improvement_number": 44 + }, + "improvement_category": 3, + "energy_performance_rating": 78, + "environmental_impact_rating": 79 + } + ], + "co2_emissions_potential": 2.8, + "energy_rating_potential": 64, + "lighting_cost_potential": 41, + "hot_water_cost_potential": 76, + "renewable_heat_incentive": { + "water_heating": 1910, + "space_heating_existing_dwelling": 9884, + "space_heating_with_cavity_insulation": 8246, + "space_heating_with_loft_and_cavity_insulation": 8246 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 273, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.06r14", + "energy_consumption_potential": 238, + "environmental_impact_current": 59, + "fixed_lighting_outlets_count": 8, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 65, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "D", + "co2_emissions_current_per_floor_area": 52, + "low_energy_fixed_lighting_outlets_count": 7 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010347637/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010347637/epc.json new file mode 100644 index 000000000..f95b4a741 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010347637/epc.json @@ -0,0 +1,249 @@ +{ + "uprn": 100010347637, + "roofs": [ + { + "description": "Pitched, 200 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "System built, with external insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + { + "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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 50% of fixed outlets", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "postcode": "BB12 7DT", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 3, + "created_at": "2011-10-17 19:02:44", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 10031, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "End-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "45, Malvern Avenue", + "address_line_2": "Padiham", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-10-17", + "inspection_date": "2011-10-17", + "extensions_count": 1, + "measurement_type": 1, + "total_floor_area": 89, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 5, + "registration_date": "2011-10-17", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 8, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.3, + "floor_insulation": 1, + "total_floor_area": 42.3, + "floor_construction": 1, + "heat_loss_perimeter": 18.47 + }, + { + "floor": 1, + "room_height": 2.3, + "total_floor_area": 42.37, + "heat_loss_perimeter": 21 + } + ], + "wall_insulation_type": 1, + "construction_age_band": "E", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm" + }, + { + "identifier": "Extension 1", + "floor_heat_loss": 7, + "roof_construction": 5, + "wall_construction": 4, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 1.9, + "floor_insulation": 1, + "total_floor_area": 4.28, + "floor_construction": 1, + "heat_loss_perimeter": 6 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "E", + "roof_insulation_location": 4, + "roof_insulation_thickness": "NI" + } + ], + "low_energy_lighting": 50, + "solar_water_heating": "N", + "bedf_revision_number": 313, + "habitable_room_count": 5, + "heating_cost_current": 472, + "co2_emissions_current": 2.9, + "energy_rating_current": 72, + "lighting_cost_current": 70, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 1, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 476, + "hot_water_cost_current": 87, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 20, + "indicative_cost": "\u00a313", + "improvement_type": "E", + "improvement_details": { + "improvement_number": 35 + }, + "improvement_category": 1, + "energy_performance_rating": 73, + "environmental_impact_rating": 72 + }, + { + "sequence": 2, + "typical_saving": 25, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 74, + "environmental_impact_rating": 74 + }, + { + "sequence": 3, + "typical_saving": 214, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 83, + "environmental_impact_rating": 83 + } + ], + "co2_emissions_potential": 2.8, + "energy_rating_potential": 73, + "lighting_cost_potential": 47, + "hot_water_cost_potential": 87, + "renewable_heat_incentive": { + "water_heating": 2183, + "space_heating_existing_dwelling": 8680, + "space_heating_with_loft_insulation": 8455, + "space_heating_with_loft_and_cavity_insulation": 8455 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 168, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.05r18", + "energy_consumption_potential": 163, + "environmental_impact_current": 71, + "fixed_lighting_outlets_count": 10, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 72, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 32, + "low_energy_fixed_lighting_outlets_count": 5 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010347646/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010347646/epc.json new file mode 100644 index 000000000..7f074e073 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010347646/epc.json @@ -0,0 +1,197 @@ +{ + "uprn": 100010347646, + "roofs": [ + { + "description": "Pitched, 200 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "walls": [ + { + "description": "System built, with external insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "(other premises below)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 80% of fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "BB12 7DT", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 4, + "created_at": "2011-10-18 16:31:58", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 1749, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Top-floor flat", + "language_code": 1, + "property_type": 2, + "address_line_1": "62, Malvern Avenue", + "address_line_2": "Padiham", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-10-18", + "inspection_date": "2011-10-18", + "extensions_count": 0, + "measurement_type": 1, + "sap_flat_details": { + "level": 3, + "top_storey": "Y", + "flat_location": 1, + "heat_loss_corridor": 2, + "unheated_corridor_length": 2.8 + }, + "total_floor_area": 47, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 2, + "registration_date": "2011-10-18", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 6, + "roof_construction": 4, + "wall_construction": 8, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.3, + "total_floor_area": 47.3, + "heat_loss_perimeter": 17.2 + } + ], + "wall_insulation_type": 1, + "construction_age_band": "E", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm" + } + ], + "low_energy_lighting": 80, + "solar_water_heating": "N", + "bedf_revision_number": 313, + "habitable_room_count": 2, + "heating_cost_current": 265, + "co2_emissions_current": 1.5, + "energy_rating_current": 75, + "lighting_cost_current": 33, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 1, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 247, + "hot_water_cost_current": 79, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 30, + "indicative_cost": "\u00a31,500 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 77, + "environmental_impact_rating": 81 + } + ], + "co2_emissions_potential": 1.3, + "energy_rating_potential": 77, + "lighting_cost_potential": 33, + "hot_water_cost_potential": 67, + "renewable_heat_incentive": { + "water_heating": 1660, + "space_heating_existing_dwelling": 2877, + "space_heating_with_loft_and_cavity_insulation": 2877 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 161, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.05r18", + "energy_consumption_potential": 143, + "environmental_impact_current": 79, + "fixed_lighting_outlets_count": 5, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 81, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 31, + "low_energy_fixed_lighting_outlets_count": 4 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010350459/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010350459/epc.json new file mode 100644 index 000000000..1e6b9cf9a --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010350459/epc.json @@ -0,0 +1,230 @@ +{ + "uprn": 100010350459, + "roofs": [ + { + "description": "Pitched, 200 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": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 40% of fixed outlets", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "postcode": "BB10 3NS", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 2, + "created_at": "2011-09-22 14:53:31", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "secondary_fuel_type": 29, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 10030, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "secondary_heating_type": 691, + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Semi-detached bungalow", + "language_code": 1, + "property_type": 1, + "address_line_1": "5, Old Hall Square", + "address_line_2": "Worsthorne", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-09-22", + "inspection_date": "2011-09-22", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 42, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 2, + "registration_date": "2011-09-22", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 3 + }, + "secondary_heating": { + "description": "Room heaters, electric", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.3, + "floor_insulation": 1, + "total_floor_area": 41.5, + "floor_construction": 1, + "heat_loss_perimeter": 23.2 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "D", + "roof_insulation_location": 2, + "roof_insulation_thickness": "200mm" + } + ], + "low_energy_lighting": 40, + "solar_water_heating": "N", + "bedf_revision_number": 313, + "habitable_room_count": 2, + "heating_cost_current": 391, + "co2_emissions_current": 2.0, + "energy_rating_current": 65, + "lighting_cost_current": 39, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 3, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 393, + "hot_water_cost_current": 62, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 12, + "indicative_cost": "\u00a38", + "improvement_type": "E", + "improvement_details": { + "improvement_number": 35 + }, + "improvement_category": 1, + "energy_performance_rating": 66, + "environmental_impact_rating": 70 + }, + { + "sequence": 2, + "typical_saving": 19, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 68, + "environmental_impact_rating": 72 + }, + { + "sequence": 3, + "typical_saving": 214, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 83, + "environmental_impact_rating": 86 + }, + { + "sequence": 4, + "typical_saving": 76, + "indicative_cost": "\u00a31,500 - \u00a34,000", + "improvement_type": "V", + "improvement_details": { + "improvement_number": 44 + }, + "improvement_category": 3, + "energy_performance_rating": 88, + "environmental_impact_rating": 91 + } + ], + "co2_emissions_potential": 2.0, + "energy_rating_potential": 66, + "lighting_cost_potential": 25, + "hot_water_cost_potential": 62, + "renewable_heat_incentive": { + "water_heating": 1571, + "space_heating_existing_dwelling": 5377, + "space_heating_with_loft_and_cavity_insulation": 5377 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 255, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.05r15", + "energy_consumption_potential": 249, + "environmental_impact_current": 69, + "fixed_lighting_outlets_count": 5, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 70, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "D", + "co2_emissions_current_per_floor_area": 48, + "low_energy_fixed_lighting_outlets_count": 2 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010350468/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010350468/epc.json new file mode 100644 index 000000000..5bf9addd9 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010350468/epc.json @@ -0,0 +1,275 @@ +{ + "uprn": 100010350468, + "roofs": [ + { + "description": "Pitched, 100 mm loft insulation", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + { + "description": "Flat, no insulation (assumed)", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 38% of fixed outlets", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "postcode": "BB10 3NS", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 3, + "created_at": "2011-05-25 20:30:10", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "secondary_fuel_type": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 8358, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "secondary_heating_type": 603, + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "End-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "14, Old Hall Square", + "address_line_2": "Worsthorne", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-05-25", + "inspection_date": "2011-05-25", + "extensions_count": 1, + "measurement_type": 1, + "total_floor_area": 94, + "transaction_type": 5, + "conservatory_type": 1, + "heated_room_count": 5, + "registration_date": "2011-05-25", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 3 + }, + "secondary_heating": { + "description": "Room heaters, mains gas", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.5, + "floor_insulation": 1, + "total_floor_area": 43.7, + "floor_construction": 1, + "heat_loss_perimeter": 19.37 + }, + { + "floor": 1, + "room_height": 2.5, + "total_floor_area": 43.7, + "heat_loss_perimeter": 21.5 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "D", + "roof_insulation_location": 2, + "roof_insulation_thickness": "100mm" + }, + { + "identifier": "Extension 1", + "floor_heat_loss": 7, + "roof_construction": 1, + "wall_construction": 4, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.1, + "floor_insulation": 1, + "total_floor_area": 6.52, + "floor_construction": 1, + "heat_loss_perimeter": 8.12 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "D", + "roof_insulation_location": 4, + "roof_insulation_thickness": "NI" + } + ], + "low_energy_lighting": 38, + "solar_water_heating": "N", + "bedf_revision_number": 309, + "habitable_room_count": 5, + "heating_cost_current": 597, + "co2_emissions_current": 3.8, + "energy_rating_current": 66, + "lighting_cost_current": 77, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 1, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 558, + "hot_water_cost_current": 97, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 25, + "indicative_cost": "\u00a313", + "improvement_type": "E", + "improvement_details": { + "improvement_number": 35 + }, + "improvement_category": 1, + "energy_performance_rating": 67, + "environmental_impact_rating": 64 + }, + { + "sequence": 2, + "typical_saving": 55, + "indicative_cost": "\u00a31,500 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 69, + "environmental_impact_rating": 68 + }, + { + "sequence": 3, + "typical_saving": 24, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 70, + "environmental_impact_rating": 69 + }, + { + "sequence": 4, + "typical_saving": 207, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 80, + "environmental_impact_rating": 78 + }, + { + "sequence": 5, + "typical_saving": 74, + "indicative_cost": "\u00a31,500 - \u00a34,000", + "improvement_type": "V", + "improvement_details": { + "improvement_number": 44 + }, + "improvement_category": 3, + "energy_performance_rating": 83, + "environmental_impact_rating": 81 + } + ], + "co2_emissions_potential": 3.4, + "energy_rating_potential": 69, + "lighting_cost_potential": 47, + "hot_water_cost_potential": 86, + "renewable_heat_incentive": { + "water_heating": 2212, + "space_heating_existing_dwelling": 10467, + "space_heating_with_loft_insulation": 10267, + "space_heating_with_loft_and_cavity_insulation": 10267 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 210, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.03r10", + "energy_consumption_potential": 186, + "environmental_impact_current": 63, + "fixed_lighting_outlets_count": 8, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 68, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 40, + "low_energy_fixed_lighting_outlets_count": 3 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010359769/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010359769/epc.json new file mode 100644 index 000000000..572bbb0e3 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010359769/epc.json @@ -0,0 +1,255 @@ +{ + "uprn": 100010359769, + "roofs": [ + { + "description": "Pitched, 250 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + { + "description": "Flat, limited insulation (assumed)", + "energy_efficiency_rating": 1, + "environmental_efficiency_rating": 1 + } + ], + "walls": [ + { + "description": "Cavity wall, filled cavity", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "floors": [ + { + "description": "Suspended, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + { + "description": "Solid, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 91% of fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "BB12 7BY", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 4, + "created_at": "2011-07-25 16:35:41", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "secondary_fuel_type": 29, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 8358, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "secondary_heating_type": 691, + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Mid-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "3, Warwick Drive", + "address_line_2": "Padiham", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-07-25", + "inspection_date": "2011-07-25", + "extensions_count": 1, + "measurement_type": 1, + "total_floor_area": 76, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 5, + "registration_date": "2011-07-25", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "Room heaters, electric", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.58, + "floor_insulation": 1, + "total_floor_area": 35.59, + "floor_construction": 2, + "heat_loss_perimeter": 9 + }, + { + "floor": 1, + "room_height": 2.43, + "total_floor_area": 34.75, + "heat_loss_perimeter": 10.86 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "C", + "roof_insulation_location": 2, + "roof_insulation_thickness": "250mm" + }, + { + "identifier": "Extension 1", + "floor_heat_loss": 7, + "roof_construction": 1, + "wall_construction": 4, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.33, + "floor_insulation": 1, + "total_floor_area": 5.37, + "floor_construction": 1, + "heat_loss_perimeter": 4.66 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "E", + "roof_insulation_location": 4, + "roof_insulation_thickness": "NI" + } + ], + "low_energy_lighting": 91, + "solar_water_heating": "N", + "bedf_revision_number": 311, + "habitable_room_count": 5, + "heating_cost_current": 501, + "co2_emissions_current": 2.8, + "energy_rating_current": 68, + "lighting_cost_current": 45, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 3, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 471, + "hot_water_cost_current": 95, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 41, + "indicative_cost": "\u00a31,500 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 70, + "environmental_impact_rating": 71 + }, + { + "sequence": 2, + "typical_saving": 24, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 71, + "environmental_impact_rating": 73 + }, + { + "sequence": 3, + "typical_saving": 214, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 82, + "environmental_impact_rating": 83 + } + ], + "co2_emissions_potential": 2.6, + "energy_rating_potential": 70, + "lighting_cost_potential": 45, + "hot_water_cost_potential": 83, + "renewable_heat_incentive": { + "water_heating": 2071, + "space_heating_existing_dwelling": 6949, + "space_heating_with_loft_and_cavity_insulation": 6949 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 196, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.05r12", + "energy_consumption_potential": 180, + "environmental_impact_current": 69, + "fixed_lighting_outlets_count": 11, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 71, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 37, + "low_energy_fixed_lighting_outlets_count": 10 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010359788/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010359788/epc.json new file mode 100644 index 000000000..1a80fde24 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010359788/epc.json @@ -0,0 +1,248 @@ +{ + "uprn": 100010359788, + "roofs": [ + { + "description": "Pitched, 150 mm loft insulation", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + { + "description": "Flat, limited insulation (assumed)", + "energy_efficiency_rating": 2, + "environmental_efficiency_rating": 2 + } + ], + "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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 89% of fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "BB12 7BY", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "BURNLEY", + "built_form": 4, + "created_at": "2011-08-04 07:03:30", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 8358, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Mid-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "22, Warwick Drive", + "address_line_2": "Padiham", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-08-04", + "inspection_date": "2011-08-04", + "extensions_count": 1, + "measurement_type": 1, + "total_floor_area": 77, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 5, + "registration_date": "2011-08-04", + "restricted_access": 0, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.35, + "floor_insulation": 1, + "total_floor_area": 35, + "floor_construction": 1, + "heat_loss_perimeter": 8.3 + }, + { + "floor": 1, + "room_height": 2.4, + "total_floor_area": 35, + "heat_loss_perimeter": 11 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "C", + "roof_insulation_location": 2, + "roof_insulation_thickness": "150mm" + }, + { + "identifier": "Extension 1", + "floor_heat_loss": 7, + "roof_construction": 1, + "wall_construction": 4, + "building_part_number": 2, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2, + "floor_insulation": 1, + "total_floor_area": 6.63, + "floor_construction": 1, + "heat_loss_perimeter": 5.16 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "F", + "roof_insulation_location": 4, + "roof_insulation_thickness": "NI" + } + ], + "low_energy_lighting": 89, + "solar_water_heating": "N", + "bedf_revision_number": 312, + "habitable_room_count": 5, + "heating_cost_current": 409, + "co2_emissions_current": 2.4, + "energy_rating_current": 73, + "lighting_cost_current": 46, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 1, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": 379, + "hot_water_cost_current": 95, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": 41, + "indicative_cost": "\u00a31,500 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 75, + "environmental_impact_rating": 76 + }, + { + "sequence": 2, + "typical_saving": 25, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 76, + "environmental_impact_rating": 77 + }, + { + "sequence": 3, + "typical_saving": 214, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 86, + "environmental_impact_rating": 87 + } + ], + "co2_emissions_potential": 2.2, + "energy_rating_potential": 75, + "lighting_cost_potential": 46, + "hot_water_cost_potential": 84, + "renewable_heat_incentive": { + "water_heating": 2080, + "space_heating_existing_dwelling": 6207, + "space_heating_with_loft_and_cavity_insulation": 6207 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 166, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": "19.05r15", + "energy_consumption_potential": 150, + "environmental_impact_current": 73, + "fixed_lighting_outlets_count": 9, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 76, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": 32, + "low_energy_fixed_lighting_outlets_count": 8 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070394806/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070394806/epc.json new file mode 100644 index 000000000..577b83ab2 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070394806/epc.json @@ -0,0 +1,253 @@ +{ + "uprn": 10070394806, + "roofs": [ + { + "description": "Pitched, 300+ mm loft insulation", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "walls": [ + { + "description": "System built, as built, insulated (assumed)", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + { + "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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in all fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "M11 4TL", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "MANCHESTER", + "built_form": 4, + "created_at": "2011-05-17 16:23:24", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 10032, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Mid-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "4, Stillwater Drive", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-05-17", + "inspection_date": "2011-05-17", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 73, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 4, + "registration_date": "2011-05-17", + "restricted_access": 1, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 3, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.38, + "floor_insulation": 0, + "total_floor_area": 36.63, + "floor_construction": 2, + "heat_loss_perimeter": 10.81 + }, + { + "floor": 1, + "room_height": 2.36, + "total_floor_area": 36.63, + "heat_loss_perimeter": 10.81 + } + ], + "wall_insulation_type": 5, + "construction_age_band": "J", + "roof_insulation_location": 2, + "roof_insulation_thickness": "300mm+" + }, + { + "wall_area": 20.33, + "wall_location": 0, + "wall_construction": 8, + "wall_insulation_type": 5 + } + ], + "low_energy_lighting": 100, + "solar_water_heating": "N", + "bedf_revision_number": 308, + "habitable_room_count": 4, + "heating_cost_current": { + "value": 315, + "currency": "GBP" + }, + "co2_emissions_current": { + "value": 1.8, + "quantity": "tonnes per year" + }, + "energy_rating_current": 77, + "lighting_cost_current": { + "value": 42, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 3, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 315, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 79, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 23, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 78, + "environmental_impact_rating": 81 + }, + { + "sequence": 2, + "typical_saving": { + "value": 207, + "currency": "GBP" + }, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 89, + "environmental_impact_rating": 91 + } + ], + "co2_emissions_potential": { + "value": 1.8, + "quantity": "tonnes per year" + }, + "energy_rating_potential": 77, + "lighting_cost_potential": { + "value": 42, + "currency": "GBP" + }, + "hot_water_cost_potential": { + "value": 79, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2044, + "space_heating_existing_dwelling": 4689, + "space_heating_with_loft_and_cavity_insulation": 4689 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 130, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": 4.0, + "energy_consumption_potential": 130, + "environmental_impact_current": 79, + "fixed_lighting_outlets_count": 6, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 79, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": { + "value": 25, + "quantity": "kg/m2 per year" + }, + "low_energy_fixed_lighting_outlets_count": 6 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070400618/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070400618/epc.json new file mode 100644 index 000000000..d607204fd --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070400618/epc.json @@ -0,0 +1,261 @@ +{ + "uprn": 10070400618, + "roofs": [ + { + "description": "Pitched, 300+ mm loft insulation", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "walls": [ + { + "description": "Cavity wall, as built, partial insulation (assumed)", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "floors": [ + { + "description": "Suspended, no insulation (assumed)", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + } + ], + "status": "entered", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in all fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "M11 4DN", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "MANCHESTER", + "built_form": 3, + "created_at": "2011-10-24 15:47:53", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 4, + "water_heating_code": 901, + "water_heating_fuel": 26, + "cylinder_thermostat": "Y", + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 10314, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "cylinder_insulation_type": 1, + "has_fixed_air_conditioning": "false", + "cylinder_insulation_thickness": 50 + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "End-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "10, Stuart Street", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-10-24", + "inspection_date": "2011-10-24", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 79, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 4, + "registration_date": "2011-10-24", + "restricted_access": 1, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 3, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.37, + "floor_insulation": 0, + "total_floor_area": 39.46, + "floor_construction": 2, + "heat_loss_perimeter": 18.85 + }, + { + "floor": 1, + "room_height": 2.31, + "total_floor_area": 39.46, + "heat_loss_perimeter": 18.85 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "F", + "roof_insulation_location": 2, + "roof_insulation_thickness": "300mm+" + } + ], + "low_energy_lighting": 100, + "solar_water_heating": "N", + "bedf_revision_number": 314, + "habitable_room_count": 4, + "heating_cost_current": { + "value": 488, + "currency": "GBP" + }, + "co2_emissions_current": { + "value": 3.0, + "quantity": "tonnes per year" + }, + "energy_rating_current": 69, + "lighting_cost_current": { + "value": 43, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 3, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "true", + "heating_cost_potential": { + "value": 413, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 109, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 74, + "currency": "GBP" + }, + "indicative_cost": "\u00a3100 - \u00a3300", + "improvement_type": "B", + "improvement_details": { + "improvement_number": 6 + }, + "improvement_category": 1, + "energy_performance_rating": 72, + "environmental_impact_rating": 73 + }, + { + "sequence": 2, + "typical_saving": { + "value": 37, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 74, + "environmental_impact_rating": 75 + }, + { + "sequence": 3, + "typical_saving": { + "value": 214, + "currency": "GBP" + }, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 85, + "environmental_impact_rating": 85 + } + ], + "co2_emissions_potential": { + "value": 2.5, + "quantity": "tonnes per year" + }, + "energy_rating_potential": 72, + "lighting_cost_potential": { + "value": 43, + "currency": "GBP" + }, + "hot_water_cost_potential": { + "value": 110, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2720, + "space_heating_existing_dwelling": 9003, + "space_heating_with_cavity_insulation": 7103, + "space_heating_with_loft_and_cavity_insulation": 7103 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 196, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": 4.0, + "energy_consumption_potential": 167, + "environmental_impact_current": 68, + "fixed_lighting_outlets_count": 7, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 73, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": { + "value": 38, + "quantity": "kg/m2 per year" + }, + "low_energy_fixed_lighting_outlets_count": 7 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070400619/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070400619/epc.json new file mode 100644 index 000000000..df07a7f69 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_10070400619/epc.json @@ -0,0 +1,242 @@ +{ + "uprn": 10070400619, + "roofs": [ + { + "description": "Pitched, 300+ mm loft insulation", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in all fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "M11 4DN", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "MANCHESTER", + "built_form": 4, + "created_at": "2011-06-22 16:05:03", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 10032, + "main_heating_number": 1, + "main_heating_control": 2104, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Mid-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "12, Stuart Street", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-06-22", + "inspection_date": "2011-06-22", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 73, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2011-06-22", + "restricted_access": 1, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 3, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.39, + "floor_insulation": 0, + "total_floor_area": 36.55, + "floor_construction": 2, + "heat_loss_perimeter": 10.79 + }, + { + "floor": 1, + "room_height": 2.28, + "total_floor_area": 36.55, + "heat_loss_perimeter": 10.79 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "J", + "roof_insulation_location": 2, + "roof_insulation_thickness": "300mm+" + } + ], + "low_energy_lighting": 100, + "solar_water_heating": "N", + "bedf_revision_number": 310, + "habitable_room_count": 3, + "heating_cost_current": { + "value": 324, + "currency": "GBP" + }, + "co2_emissions_current": { + "value": 1.9, + "quantity": "tonnes per year" + }, + "energy_rating_current": 77, + "lighting_cost_current": { + "value": 42, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer and room thermostat", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "multiple_glazing_type": 3, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 324, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 79, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 23, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 78, + "environmental_impact_rating": 80 + }, + { + "sequence": 2, + "typical_saving": { + "value": 207, + "currency": "GBP" + }, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 89, + "environmental_impact_rating": 91 + } + ], + "co2_emissions_potential": { + "value": 1.9, + "quantity": "tonnes per year" + }, + "energy_rating_potential": 77, + "lighting_cost_potential": { + "value": 42, + "currency": "GBP" + }, + "hot_water_cost_potential": { + "value": 79, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2042, + "space_heating_existing_dwelling": 4940, + "space_heating_with_loft_and_cavity_insulation": 4940 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 135, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": 4.0, + "energy_consumption_potential": 135, + "environmental_impact_current": 79, + "fixed_lighting_outlets_count": 7, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 79, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": { + "value": 26, + "quantity": "kg/m2 per year" + }, + "low_energy_fixed_lighting_outlets_count": 7 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77179816/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77179816/epc.json new file mode 100644 index 000000000..c9b6146c0 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77179816/epc.json @@ -0,0 +1,242 @@ +{ + "uprn": 77179816, + "roofs": [ + { + "description": "Pitched, 300+ mm loft insulation", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in all fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "M11 4NL", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "MANCHESTER", + "built_form": 3, + "created_at": "2011-05-17 16:16:10", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 15710, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "End-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "55, Canberra Street", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-05-17", + "inspection_date": "2011-05-17", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 71, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2011-05-17", + "restricted_access": 1, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 3, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.77, + "floor_insulation": 0, + "total_floor_area": 38.12, + "floor_construction": 2, + "heat_loss_perimeter": 19.03 + }, + { + "floor": 1, + "room_height": 2.9, + "total_floor_area": 33.07, + "heat_loss_perimeter": 16.31 + } + ], + "wall_insulation_type": 5, + "construction_age_band": "K", + "roof_insulation_location": 2, + "roof_insulation_thickness": "300mm+" + } + ], + "low_energy_lighting": 100, + "solar_water_heating": "N", + "bedf_revision_number": 308, + "habitable_room_count": 3, + "heating_cost_current": { + "value": 347, + "currency": "GBP" + }, + "co2_emissions_current": { + "value": 2.0, + "quantity": "tonnes per year" + }, + "energy_rating_current": 75, + "lighting_cost_current": { + "value": 41, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 3, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 347, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 78, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 23, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 77, + "environmental_impact_rating": 79 + }, + { + "sequence": 2, + "typical_saving": { + "value": 207, + "currency": "GBP" + }, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 88, + "environmental_impact_rating": 89 + } + ], + "co2_emissions_potential": { + "value": 2.0, + "quantity": "tonnes per year" + }, + "energy_rating_potential": 75, + "lighting_cost_potential": { + "value": 41, + "currency": "GBP" + }, + "hot_water_cost_potential": { + "value": 78, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2020, + "space_heating_existing_dwelling": 5555, + "space_heating_with_loft_and_cavity_insulation": 5555 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 147, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": 4.0, + "energy_consumption_potential": 147, + "environmental_impact_current": 77, + "fixed_lighting_outlets_count": 5, + "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": { + "value": 28, + "quantity": "kg/m2 per year" + }, + "low_energy_fixed_lighting_outlets_count": 5 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77179820/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77179820/epc.json new file mode 100644 index 000000000..11b3a3fce --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77179820/epc.json @@ -0,0 +1,242 @@ +{ + "uprn": 77179820, + "roofs": [ + { + "description": "Pitched, 300+ mm loft insulation", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + } + ], + "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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in all fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "M11 4NL", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "MANCHESTER", + "built_form": 4, + "created_at": "2011-05-17 16:13:22", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 15710, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Mid-terrace house", + "language_code": 1, + "property_type": 0, + "address_line_1": "63, Canberra Street", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-05-17", + "inspection_date": "2011-05-17", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 74, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 3, + "registration_date": "2011-05-17", + "restricted_access": 1, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 3, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.85, + "floor_insulation": 0, + "total_floor_area": 40.7, + "floor_construction": 2, + "heat_loss_perimeter": 12.97 + }, + { + "floor": 1, + "room_height": 2.81, + "total_floor_area": 33.01, + "heat_loss_perimeter": 9.64 + } + ], + "wall_insulation_type": 5, + "construction_age_band": "K", + "roof_insulation_location": 2, + "roof_insulation_thickness": "300mm+" + } + ], + "low_energy_lighting": 100, + "solar_water_heating": "N", + "bedf_revision_number": 308, + "habitable_room_count": 3, + "heating_cost_current": { + "value": 325, + "currency": "GBP" + }, + "co2_emissions_current": { + "value": 1.9, + "quantity": "tonnes per year" + }, + "energy_rating_current": 77, + "lighting_cost_current": { + "value": 42, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 3, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 325, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 79, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 23, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 78, + "environmental_impact_rating": 80 + }, + { + "sequence": 2, + "typical_saving": { + "value": 207, + "currency": "GBP" + }, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 89, + "environmental_impact_rating": 91 + } + ], + "co2_emissions_potential": { + "value": 1.9, + "quantity": "tonnes per year" + }, + "energy_rating_potential": 77, + "lighting_cost_potential": { + "value": 42, + "currency": "GBP" + }, + "hot_water_cost_potential": { + "value": 79, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2049, + "space_heating_existing_dwelling": 4978, + "space_heating_with_loft_and_cavity_insulation": 4978 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 134, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": 4.0, + "energy_consumption_potential": 134, + "environmental_impact_current": 79, + "fixed_lighting_outlets_count": 5, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 79, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": { + "value": 26, + "quantity": "kg/m2 per year" + }, + "low_energy_fixed_lighting_outlets_count": 5 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77180626/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77180626/epc.json new file mode 100644 index 000000000..038611142 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77180626/epc.json @@ -0,0 +1,312 @@ +{ + "uprn": 77180626, + "roofs": [ + { + "description": "Pitched, 100mm 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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "lighting": { + "description": "Low energy lighting in 40% of fixed outlets", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + }, + "postcode": "M11 4PG", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "MANCHESTER", + "built_form": 4, + "created_at": "2011-11-29 20:16:44", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 8587, + "main_heating_number": 1, + "main_heating_control": 2107, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Mid-terrace bungalow", + "language_code": 1, + "property_type": 0, + "address_line_1": "45, Seymour Road South", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-11-29", + "inspection_date": "2011-11-29", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 46, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 2, + "registration_date": "2011-11-29", + "restricted_access": 1, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.482, + "floor_insulation": 1, + "total_floor_area": 45.611, + "floor_construction": 0, + "heat_loss_perimeter": 13.73 + } + ], + "wall_insulation_type": 2, + "construction_age_band": "E", + "roof_insulation_location": 2, + "roof_insulation_thickness": "100mm" + } + ], + "low_energy_lighting": 40, + "solar_water_heating": "N", + "bedf_revision_number": 314, + "habitable_room_count": 2, + "heating_cost_current": { + "value": 360, + "currency": "GBP" + }, + "co2_emissions_current": { + "value": 2.0, + "quantity": "tonnes per year" + }, + "energy_rating_current": 68, + "lighting_cost_current": { + "value": 43, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, TRVs and bypass", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "multiple_glazing_type": 2, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 300, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 75, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 24, + "currency": "GBP" + }, + "indicative_cost": "\u00a3100 - \u00a3300", + "improvement_type": "A", + "improvement_details": { + "improvement_number": 5 + }, + "improvement_category": 1, + "energy_performance_rating": 70, + "environmental_impact_rating": 72 + }, + { + "sequence": 2, + "typical_saving": { + "value": 13, + "currency": "GBP" + }, + "indicative_cost": "\u00a38", + "improvement_type": "E", + "improvement_details": { + "improvement_number": 35 + }, + "improvement_category": 1, + "energy_performance_rating": 71, + "environmental_impact_rating": 73 + }, + { + "sequence": 3, + "typical_saving": { + "value": 18, + "currency": "GBP" + }, + "indicative_cost": "\u00a3350 - \u00a3450", + "improvement_type": "G", + "improvement_details": { + "improvement_number": 14 + }, + "improvement_category": 1, + "energy_performance_rating": 72, + "environmental_impact_rating": 74 + }, + { + "sequence": 4, + "typical_saving": { + "value": 30, + "currency": "GBP" + }, + "indicative_cost": "\u00a31,500 - \u00a33,500", + "improvement_type": "I", + "improvement_details": { + "improvement_number": 20 + }, + "improvement_category": 2, + "energy_performance_rating": 74, + "environmental_impact_rating": 77 + }, + { + "sequence": 5, + "typical_saving": { + "value": 21, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 75, + "environmental_impact_rating": 79 + }, + { + "sequence": 6, + "typical_saving": { + "value": 214, + "currency": "GBP" + }, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 89, + "environmental_impact_rating": 92 + }, + { + "sequence": 7, + "typical_saving": { + "value": 18, + "currency": "GBP" + }, + "indicative_cost": "\u00a31,500 - \u00a34,000", + "improvement_type": "V", + "improvement_details": { + "improvement_number": 44 + }, + "improvement_category": 3, + "energy_performance_rating": 90, + "environmental_impact_rating": 93 + } + ], + "co2_emissions_potential": { + "value": 1.6, + "quantity": "tonnes per year" + }, + "energy_rating_potential": 74, + "lighting_cost_potential": { + "value": 27, + "currency": "GBP" + }, + "hot_water_cost_potential": { + "value": 66, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 1634, + "space_heating_existing_dwelling": 4686, + "space_heating_with_loft_insulation": 4450, + "space_heating_with_loft_and_cavity_insulation": 4450 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 231, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": 4.0, + "energy_consumption_potential": 178, + "environmental_impact_current": 70, + "fixed_lighting_outlets_count": 5, + "current_energy_efficiency_band": "D", + "environmental_impact_potential": 77, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": { + "value": 44, + "quantity": "kg/m2 per year" + }, + "low_energy_fixed_lighting_outlets_count": 2 +} \ No newline at end of file diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77181233/epc.json b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77181233/epc.json new file mode 100644 index 000000000..a3e09d806 --- /dev/null +++ b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_77181233/epc.json @@ -0,0 +1,243 @@ +{ + "uprn": 77181233, + "roofs": [ + { + "description": "Pitched, 100mm loft insulation", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "walls": [ + { + "description": "Cavity wall, 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", + "windows": [ + { + "description": "Fully double glazed", + "energy_efficiency_rating": 3, + "environmental_efficiency_rating": 3 + } + ], + "lighting": { + "description": "Low energy lighting in 90% of fixed outlets", + "energy_efficiency_rating": 5, + "environmental_efficiency_rating": 5 + }, + "postcode": "M11 4WU", + "hot_water": { + "description": "From main system", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + }, + "post_town": "MANCHESTER", + "built_form": 1, + "created_at": "2011-09-06 16:39:42", + "glazed_area": 1, + "region_code": 19, + "report_type": 2, + "sap_heating": { + "cylinder_size": 1, + "water_heating_code": 901, + "water_heating_fuel": 26, + "main_heating_details": [ + { + "main_fuel_type": 26, + "boiler_flue_type": 2, + "fan_flue_present": "Y", + "heat_emitter_type": 1, + "boiler_index_number": 10328, + "main_heating_number": 1, + "main_heating_control": 2106, + "main_heating_category": 2, + "main_heating_fraction": 1, + "main_heating_data_source": 1 + } + ], + "has_fixed_air_conditioning": "false" + }, + "sap_version": 9.9, + "schema_type": "SAP-Schema-15.0", + "uprn_source": "Energy Assessor", + "country_code": "EAW", + "main_heating": [ + { + "description": "Boiler and radiators, mains gas", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "dwelling_type": "Detached house", + "language_code": 1, + "property_type": 0, + "address_line_1": "48, Hackle Street", + "schema_version": "LIG-15.0", + "assessment_type": "RdSAP", + "completion_date": "2011-09-06", + "inspection_date": "2011-09-06", + "extensions_count": 0, + "measurement_type": 1, + "total_floor_area": 73, + "transaction_type": 3, + "conservatory_type": 1, + "heated_room_count": 5, + "registration_date": "2011-09-06", + "restricted_access": 1, + "sap_energy_source": { + "main_gas": "Y", + "meter_type": 2, + "photovoltaic_supply": { + "percent_roof_area": 0 + }, + "wind_turbines_count": 0, + "wind_turbines_terrain_type": 2 + }, + "secondary_heating": { + "description": "None", + "energy_efficiency_rating": 0, + "environmental_efficiency_rating": 0 + }, + "sap_building_parts": [ + { + "identifier": "Main Dwelling", + "floor_heat_loss": 7, + "roof_construction": 4, + "wall_construction": 4, + "building_part_number": 1, + "sap_floor_dimensions": [ + { + "floor": 0, + "room_height": 2.37, + "floor_insulation": 1, + "total_floor_area": 36.54, + "floor_construction": 1, + "heat_loss_perimeter": 25.8 + }, + { + "floor": 1, + "room_height": 2.36, + "total_floor_area": 36.54, + "heat_loss_perimeter": 25.8 + } + ], + "wall_insulation_type": 4, + "construction_age_band": "G", + "roof_insulation_location": 2, + "roof_insulation_thickness": "100mm" + } + ], + "low_energy_lighting": 90, + "solar_water_heating": "N", + "bedf_revision_number": 312, + "habitable_room_count": 5, + "heating_cost_current": { + "value": 487, + "currency": "GBP" + }, + "co2_emissions_current": { + "value": 2.8, + "quantity": "tonnes per year" + }, + "energy_rating_current": 69, + "lighting_cost_current": { + "value": 44, + "currency": "GBP" + }, + "main_heating_controls": [ + { + "description": "Programmer, room thermostat and TRVs", + "energy_efficiency_rating": 4, + "environmental_efficiency_rating": 4 + } + ], + "multiple_glazing_type": 3, + "open_fireplaces_count": 0, + "has_hot_water_cylinder": "false", + "heating_cost_potential": { + "value": 487, + "currency": "GBP" + }, + "hot_water_cost_current": { + "value": 83, + "currency": "GBP" + }, + "mechanical_ventilation": 0, + "suggested_improvements": [ + { + "sequence": 1, + "typical_saving": { + "value": 24, + "currency": "GBP" + }, + "indicative_cost": "\u00a34,000 - \u00a36,000", + "improvement_type": "N", + "improvement_details": { + "improvement_number": 19 + }, + "improvement_category": 3, + "energy_performance_rating": 70, + "environmental_impact_rating": 70 + }, + { + "sequence": 2, + "typical_saving": { + "value": 214, + "currency": "GBP" + }, + "indicative_cost": "\u00a311,000 - \u00a320,000", + "improvement_type": "U", + "improvement_details": { + "improvement_number": 34 + }, + "improvement_category": 3, + "energy_performance_rating": 81, + "environmental_impact_rating": 80 + } + ], + "co2_emissions_potential": { + "value": 2.8, + "quantity": "tonnes per year" + }, + "energy_rating_potential": 69, + "lighting_cost_potential": { + "value": 44, + "currency": "GBP" + }, + "hot_water_cost_potential": { + "value": 83, + "currency": "GBP" + }, + "renewable_heat_incentive": { + "water_heating": 2082, + "space_heating_existing_dwelling": 9000, + "space_heating_with_loft_insulation": 8839, + "space_heating_with_loft_and_cavity_insulation": 8839 + }, + "seller_commission_report": "Y", + "energy_consumption_current": 201, + "has_fixed_air_conditioning": "false", + "multiple_glazed_proportion": 100, + "calculation_software_version": 4.0, + "energy_consumption_potential": 201, + "environmental_impact_current": 68, + "fixed_lighting_outlets_count": 10, + "current_energy_efficiency_band": "C", + "environmental_impact_potential": 68, + "has_heated_separate_conservatory": "false", + "potential_energy_efficiency_band": "C", + "co2_emissions_current_per_floor_area": { + "value": 39, + "quantity": "kg/m2 per year" + }, + "low_energy_fixed_lighting_outlets_count": 9 +} \ No newline at end of file diff --git a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py index 674cd0ef8..8e5ef0ff8 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -1088,6 +1088,147 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( cert_num="uprn-100031768368", sap_score=61, ), + # SAP-Schema-15.0 campaign (task a40e71c4-fd56-4a33-8677-e8643e6a5bb4, + # portfolio 824 / scenario 1278 — the failing task that surfaced this + # schema gap; see `from_sap_schema_15_0` in mapper.py). 20 real 2011-era + # LIG-15.0 lodgements sampled across the failing portfolio. 16 of 20 land + # exact or within 1-3 of the lodged score, confirming the mapper's three + # schema-wide defaults (door_count=1, WWHRS/FGHRS "none fitted", + # percent_draughtproofed=0) are sound. + # + # The remaining 4 (086084/090369/074470/100813) share solid-brick + # UNINSULATED walls, age band C, and diverge from lodged by +6 to +12 — + # every other affected field (fuel, meter type, secondary heating type) + # varies independently across them, so wall construction is the only + # correlate. Checked `u_wall(Country.ENG, "C", 3, None, + # wall_insulation_type=4)` directly: it returns 1.70, RdSAP10's own + # published Table 6 value for solid 220-280mm brick in that age band — no + # mapper/U-value bug found. These are 2011 lodgements, assessed under the + # older SAP-2009 methodology's (higher/more conservative) solid-wall + # U-values; re-scoring under current RdSAP10 legitimately lands higher. + # Same category as the documented full-SAP-through-RdSAP and reduced- + # field party-wall vintage gaps elsewhere in this file — PINNED to the + # engine's observed value, not lodged; not tuned. + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010359769", + cert_num="0087-2885-6238-9729-0575", + sap_score=68, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010359788", + cert_num="0687-2894-6684-9009-7151", + sap_score=72, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010086084", + cert_num="8493-5079-7429-8996-5293", + sap_score=53, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010090369", + cert_num="8302-5919-9429-6696-2923", + sap_score=53, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010074470", + cert_num="8501-5989-9529-2326-0223", + sap_score=46, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010100813", + cert_num="8797-7949-0029-6396-4093", + sap_score=59, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_77179816", + cert_num="9438-5046-6215-8769-7934", + sap_score=76, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_10070400619", + cert_num="2628-6072-6296-8479-8940", + sap_score=77, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_77179820", + cert_num="9338-7036-6275-8969-7950", + sap_score=77, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_10070394806", + cert_num="0989-2863-6454-9799-9601", + sap_score=78, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_77181233", + cert_num="8159-6821-8860-6966-9902", + sap_score=68, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_77180626", + cert_num="2818-9993-6239-5699-2904", + sap_score=68, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_10070400618", + cert_num="8797-7349-1229-8826-7093", + sap_score=70, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010350459", + cert_num="8669-6321-9270-2022-7926", + sap_score=65, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010350468", + cert_num="8305-5058-8729-2926-8593", + sap_score=66, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010333531", + cert_num="8094-2349-1329-3996-9993", + sap_score=73, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010341489", + cert_num="2678-3089-6249-9142-9900", + sap_score=65, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010341491", + cert_num="2568-6062-6299-9052-1984", + sap_score=62, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010347646", + cert_num="8169-6020-9719-2148-6996", + sap_score=75, + ), + RealCertExpectation( + schema="SAP-Schema-15.0", + sample="uprn_100010347637", + cert_num="8059-6020-9429-4133-0996", + sap_score=72, + ), ) From e31e01e85fa5ca79f5baf90d8eab2a6fcc19a694 Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 9 Jul 2026 20:04:20 +0000 Subject: [PATCH 3/7] Fix framing: lodged rating is not the accuracy target for SAP-Schema-15.0 These are 2011 SAP-2009 lodgements; this calculator implements current RdSAP10, which has since revised several U-value tables. Closeness to lodged was never evidence of mapper correctness (nor is a gap evidence against it) -- the prior commit's comments and worklist entries wrongly framed 16/20 "matching lodged" as validation and the other 4 as anomalies needing explanation. Corrected the comments to state what the batch actually shows: all 20 structurally distinct certs map without error and produce plausible scores. Real accuracy validation still needs an Elmhurst RdSAP10 rebuild on the same methodology as the engine, which remains open. --- .../expand-sap-accuracy-corpus/worklist.md | 63 +++++++++++-------- .../test_real_cert_sap_accuracy.py | 46 +++++++++----- 2 files changed, 65 insertions(+), 44 deletions(-) diff --git a/.claude/skills/expand-sap-accuracy-corpus/worklist.md b/.claude/skills/expand-sap-accuracy-corpus/worklist.md index dbb1cea00..d5c40292c 100644 --- a/.claude/skills/expand-sap-accuracy-corpus/worklist.md +++ b/.claude/skills/expand-sap-accuracy-corpus/worklist.md @@ -387,30 +387,39 @@ Skip the 🚩 MVHR / 🚩 heat-pump-fuel and ⛔ sparse certs. - [ ] 10013924858 — SAP-17.0 · eng 81 / lodged 84 # SAP-Schema-15.0 mapper validation (task a40e71c4-fd56-4a33-8677-e8643e6a5bb4) -🔧 New schema — `from_sap_schema_15_0` added in mapper.py (PR #1531). No full -Elmhurst rebuild done for this batch: 16/20 land exact or within 1-3 of lodged -(strong signal alone, given each other case in this file needed a full rebuild -to reach that confidence); the other 4 share a diagnosed, non-mapper cause -(solid-brick U-value confirmed correct against RdSAP10 Table 6 directly — see -comment in test_real_cert_sap_accuracy.py) so pinned without a rebuild too. All -20 pinned as `RealCertExpectation`s. -- [x] 🔧 100010359769 — SAP-15.0 · eng 68 (lodged 68) -- [x] 🔧 100010359788 — SAP-15.0 · eng 72 (lodged 73) -- [x] 🔍 100010086084 — SAP-15.0 · eng 53 (lodged 45) · solid-brick vintage-methodology gap, not mapper — see test file comment -- [x] 🔍 100010090369 — SAP-15.0 · eng 53 (lodged 47) · ditto -- [x] 🔍 100010074470 — SAP-15.0 · eng 46 (lodged 39) · ditto -- [x] 🔍 100010100813 — SAP-15.0 · eng 59 (lodged 47) · ditto (largest gap, +12) -- [x] 🔧 77179816 — SAP-15.0 · eng 76 (lodged 75) -- [x] 🔧 10070400619 — SAP-15.0 · eng 77 (lodged 77) -- [x] 🔧 77179820 — SAP-15.0 · eng 77 (lodged 77) -- [x] 🔧 10070394806 — SAP-15.0 · eng 78 (lodged 77) -- [x] 🔧 77181233 — SAP-15.0 · eng 68 (lodged 69) -- [x] 🔧 77180626 — SAP-15.0 · eng 68 (lodged 68) -- [x] 🔧 10070400618 — SAP-15.0 · eng 70 (lodged 69) -- [x] 🔧 100010350459 — SAP-15.0 · eng 65 (lodged 65) -- [x] 🔧 100010350468 — SAP-15.0 · eng 66 (lodged 66) -- [x] 🔧 100010333531 — SAP-15.0 · eng 73 (lodged 74) -- [x] 🔧 100010341489 — SAP-15.0 · eng 65 (lodged 64) -- [x] 🔧 100010341491 — SAP-15.0 · eng 62 (lodged 59) -- [x] 🔧 100010347646 — SAP-15.0 · eng 75 (lodged 75) -- [x] 🔧 100010347637 — SAP-15.0 · eng 72 (lodged 72) +🔧 New schema — `from_sap_schema_15_0` added in mapper.py (PR #1531). No +Elmhurst rebuild done for this batch — and unlike every other entry in this +file, **lodged is NOT the comparison target here**: these are 2011 SAP-2009 +lodgements, but this calculator implements current RdSAP10, which has since +revised several U-value tables. A gap from lodged is expected either way and +is not, by itself, evidence of a mapper bug — nor is closeness to lodged +evidence of correctness. What this batch actually validates: all 20 +structurally distinct real certs (different fuels, meters, secondary-heating +types, wall constructions) map without error and produce plausible scores +through `from_sap_schema_15_0`'s three schema-wide defaults. The 4 solid-brick +cases below show the largest gap from lodged; `u_wall` was spot-checked +directly against RdSAP10 Table 6 for that construction/age band and returns +the spec-correct value, so at minimum the wall U-value lookup isn't the +source. Real accuracy validation (engine vs Elmhurst on the SAME RdSAP10 +methodology) is still open — see comment in test_real_cert_sap_accuracy.py. +All 20 pinned as `RealCertExpectation`s to the engine's OWN observed output. +- [x] 🔧 100010359769 — SAP-15.0 · eng 68 (2011 lodged 68, not a target) +- [x] 🔧 100010359788 — SAP-15.0 · eng 72 (2011 lodged 73, not a target) +- [x] 🔧 100010086084 — SAP-15.0 · eng 53 (2011 lodged 45, not a target) · solid-brick, largest-gap group; u_wall spot-checked correct +- [x] 🔧 100010090369 — SAP-15.0 · eng 53 (2011 lodged 47, not a target) · ditto +- [x] 🔧 100010074470 — SAP-15.0 · eng 46 (2011 lodged 39, not a target) · ditto +- [x] 🔧 100010100813 — SAP-15.0 · eng 59 (2011 lodged 47, not a target) · ditto +- [x] 🔧 77179816 — SAP-15.0 · eng 76 (2011 lodged 75, not a target) +- [x] 🔧 10070400619 — SAP-15.0 · eng 77 (2011 lodged 77, not a target) +- [x] 🔧 77179820 — SAP-15.0 · eng 77 (2011 lodged 77, not a target) +- [x] 🔧 10070394806 — SAP-15.0 · eng 78 (2011 lodged 77, not a target) +- [x] 🔧 77181233 — SAP-15.0 · eng 68 (2011 lodged 69, not a target) +- [x] 🔧 77180626 — SAP-15.0 · eng 68 (2011 lodged 68, not a target) +- [x] 🔧 10070400618 — SAP-15.0 · eng 70 (2011 lodged 69, not a target) +- [x] 🔧 100010350459 — SAP-15.0 · eng 65 (2011 lodged 65, not a target) +- [x] 🔧 100010350468 — SAP-15.0 · eng 66 (2011 lodged 66, not a target) +- [x] 🔧 100010333531 — SAP-15.0 · eng 73 (2011 lodged 74, not a target) +- [x] 🔧 100010341489 — SAP-15.0 · eng 65 (2011 lodged 64, not a target) +- [x] 🔧 100010341491 — SAP-15.0 · eng 62 (2011 lodged 59, not a target) +- [x] 🔧 100010347646 — SAP-15.0 · eng 75 (2011 lodged 75, not a target) +- [x] 🔧 100010347637 — SAP-15.0 · eng 72 (2011 lodged 72, not a target) 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 8e5ef0ff8..b3c029dff 100644 --- a/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +++ b/tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py @@ -1091,24 +1091,36 @@ _EXPECTATIONS: Final[tuple[RealCertExpectation, ...]] = ( # SAP-Schema-15.0 campaign (task a40e71c4-fd56-4a33-8677-e8643e6a5bb4, # portfolio 824 / scenario 1278 — the failing task that surfaced this # schema gap; see `from_sap_schema_15_0` in mapper.py). 20 real 2011-era - # LIG-15.0 lodgements sampled across the failing portfolio. 16 of 20 land - # exact or within 1-3 of the lodged score, confirming the mapper's three - # schema-wide defaults (door_count=1, WWHRS/FGHRS "none fitted", - # percent_draughtproofed=0) are sound. + # LIG-15.0 lodgements sampled across the failing portfolio. # - # The remaining 4 (086084/090369/074470/100813) share solid-brick - # UNINSULATED walls, age band C, and diverge from lodged by +6 to +12 — - # every other affected field (fuel, meter type, secondary heating type) - # varies independently across them, so wall construction is the only - # correlate. Checked `u_wall(Country.ENG, "C", 3, None, - # wall_insulation_type=4)` directly: it returns 1.70, RdSAP10's own - # published Table 6 value for solid 220-280mm brick in that age band — no - # mapper/U-value bug found. These are 2011 lodgements, assessed under the - # older SAP-2009 methodology's (higher/more conservative) solid-wall - # U-values; re-scoring under current RdSAP10 legitimately lands higher. - # Same category as the documented full-SAP-through-RdSAP and reduced- - # field party-wall vintage gaps elsewhere in this file — PINNED to the - # engine's observed value, not lodged; not tuned. + # NOTE on what these pins do and don't validate: `sap_score` here is the + # ENGINE'S OWN observed output, not an accuracy claim against the lodged + # `energy_rating_current`. These are 2011 certs, assessed under the SAP + # 2009 methodology of the day; this calculator implements the CURRENT + # RdSAP10 methodology, which has since revised several U-value tables + # (solid-wall thickness bands among them — see `u_wall` §5.7 Table 13). + # A 2011-vs-2026-methodology delta is therefore EXPECTED and tells you + # nothing about mapper correctness either way — closeness to lodged is + # not evidence for the mapper, and a gap from lodged is not evidence + # against it. Real accuracy validation needs an Elmhurst RdSAP10 rebuild + # (the `validate-cert-sap-accuracy` skill) on the SAME methodology as the + # engine, which this batch did not do. + # + # What this batch DOES validate: all 20 structurally distinct real certs + # (different fuels, meter types, secondary-heating types, wall + # constructions, portfolios) map without error through the new + # `from_sap_schema_15_0` path and produce plausible SAP scores — i.e. the + # three schema-wide defaults (door_count=1, WWHRS/FGHRS "none fitted", + # percent_draughtproofed=0) don't crash or produce nonsense on a diverse + # sample. Four of the twenty (086084/090369/074470/100813, sharing + # solid-brick UNINSULATED walls / age band C) show the largest gap from + # lodged; spot-checked `u_wall(Country.ENG, "C", 3, None, + # wall_insulation_type=4)` directly and it returns 1.70, matching RdSAP10's + # own published Table 6 for that construction/age band — so at minimum + # the wall U-value lookup itself is not the source of any divergence. + # PINNED to the engine's observed value on every case (the file's + # standing convention) — not tuned to lodged, and not claimed as an + # accuracy match either. RealCertExpectation( schema="SAP-Schema-15.0", sample="uprn_100010359769", From 283b311fcdae87136f4ca16963f18411381034fc Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Thu, 9 Jul 2026 22:31:01 +0000 Subject: [PATCH 4/7] Real Elmhurst RdSAP10 ground truth for one SAP-Schema-15.0 cert Built UPRN 100010086084 (the largest gov-API-vs-lodged outlier from the 20-cert batch) in Elmhurst's accredited RdSAP10 tool to get real ground truth, per feedback that lodged rating isn't a valid comparison target. Elmhurst worksheet: SAP 46-48 (orientation-dependent), vs this engine's 53 on gov-API inputs -- a real ~5-7pt residual gap. Ruled out with direct empirical tests: total_floor_area, missing party_wall_length, region/climate (SAP rating always uses UK-average weather per Appendix U -- confirmed inert), boiler/secondary efficiency (exact match, 66%/ 63% both sides). Confirmed real but NOT blind-fixed (need more than one cert's evidence, and a wall-U-value patch tested the wrong direction in isolation): a wall-thickness-unknown U-value fallback mismatch (this engine 1.70, Elmhurst's own "unknown" resolution 1.40) and a window U-value divergence (1.85 vs 2.52 W/m2K for the same nominal glazing pick). Single-window orientation confirmed a ~2pt partial contributor. Also fixes a small, separate, evidenced gap the build surfaced: the Elmhurst summary parser didn't recognise the live tool's "Medium (131-170L)" cylinder-size label (only the bare "Medium"). Full write-up is in the RealCertExpectation comment for this cert in test_real_cert_sap_accuracy.py and the worklist. Residual gap is intentionally left open for follow-up, not force-closed. --- .../expand-sap-accuracy-corpus/worklist.md | 2 +- .../uprn_100010086084/elmhurst_summary.pdf | Bin 0 -> 68850 bytes .../uprn_100010086084/elmhurst_worksheet.pdf | Bin 0 -> 46606 bytes datatypes/epc/domain/mapper.py | 4 + scripts/hyde/build_100010086084.py | 289 ++++++++++++++++++ scripts/hyde/download_100010086084.py | 71 +++++ .../test_real_cert_sap_accuracy.py | 36 +++ 7 files changed, 401 insertions(+), 1 deletion(-) create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010086084/elmhurst_summary.pdf create mode 100644 backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010086084/elmhurst_worksheet.pdf create mode 100644 scripts/hyde/build_100010086084.py create mode 100644 scripts/hyde/download_100010086084.py diff --git a/.claude/skills/expand-sap-accuracy-corpus/worklist.md b/.claude/skills/expand-sap-accuracy-corpus/worklist.md index d5c40292c..6bd96ba6a 100644 --- a/.claude/skills/expand-sap-accuracy-corpus/worklist.md +++ b/.claude/skills/expand-sap-accuracy-corpus/worklist.md @@ -405,7 +405,7 @@ methodology) is still open — see comment in test_real_cert_sap_accuracy.py. All 20 pinned as `RealCertExpectation`s to the engine's OWN observed output. - [x] 🔧 100010359769 — SAP-15.0 · eng 68 (2011 lodged 68, not a target) - [x] 🔧 100010359788 — SAP-15.0 · eng 72 (2011 lodged 73, not a target) -- [x] 🔧 100010086084 — SAP-15.0 · eng 53 (2011 lodged 45, not a target) · solid-brick, largest-gap group; u_wall spot-checked correct +- [x] 🔍 100010086084 — SAP-15.0 · eng 53, Elmhurst worksheet 48 (2011 lodged 45, not a target) · FULL Elmhurst RdSAP10 rebuild done (only cert in this batch with one). Real ~5pt residual gap, NOT the mapper's TFA/party-wall/region/boiler-efficiency defaults (all ruled out empirically). Two real bugs flagged, not fixed (need >1 cert's evidence, see test_real_cert_sap_accuracy.py comment): wall-thickness-unknown fallback (engine 1.70 vs Elmhurst 1.40, but patch-tested WRONG DIRECTION alone) and a window U-value divergence (1.85 vs 2.52 W/m2K, root cause open). Single-window orientation approximation confirmed to account for ~2pt of the gap (North->South rebuild: 46->48). - [x] 🔧 100010090369 — SAP-15.0 · eng 53 (2011 lodged 47, not a target) · ditto - [x] 🔧 100010074470 — SAP-15.0 · eng 46 (2011 lodged 39, not a target) · ditto - [x] 🔧 100010100813 — SAP-15.0 · eng 59 (2011 lodged 47, not a target) · ditto diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010086084/elmhurst_summary.pdf b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010086084/elmhurst_summary.pdf new file mode 100644 index 0000000000000000000000000000000000000000..36f53c31e21a94fbc67dfbf2af3aee7edd1e072f GIT binary patch literal 68850 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 O<$>}MFfmCeN&XMnQ`A5J literal 0 HcmV?d00001 diff --git a/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010086084/elmhurst_worksheet.pdf b/backend/epc_api/json_samples/real_life_examples/SAP-Schema-15.0/uprn_100010086084/elmhurst_worksheet.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f5045d7e741905e34be637ff440746a2a5ca0c94 GIT binary patch literal 46606 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≷g(HRFk1>$AvR^H6WQHYuwfY;O>2TVc- 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 o7*~wSc6QE0pCTe@~ literal 0 HcmV?d00001 diff --git a/datatypes/epc/domain/mapper.py b/datatypes/epc/domain/mapper.py index 33b3cd840..da1753453 100644 --- a/datatypes/epc/domain/mapper.py +++ b/datatypes/epc/domain/mapper.py @@ -7552,6 +7552,10 @@ _ELMHURST_CYLINDER_SIZE_LABEL_TO_SAP10: Dict[str, int] = { "Normal": 2, "Medium": 3, "Large": 4, + # The live RdSAP10-Online tool renders the size band WITH its litre range + # suffix (observed on the SAP-Schema-15.0 UPRN 100010086084 build) rather + # than the bare label the cohort fixtures used above. + "Medium (131-170L)": 3, } diff --git a/scripts/hyde/build_100010086084.py b/scripts/hyde/build_100010086084.py new file mode 100644 index 000000000..9e8ca3895 --- /dev/null +++ b/scripts/hyde/build_100010086084.py @@ -0,0 +1,289 @@ +"""Elmhurst build for UPRN 100010086084 (SAP-Schema-15.0, cert +8493-5079-7429-8996-5293, SEMI-DETACHED HOUSE, 9 Pear Tree Avenue, Crewe +CW1 3SH, band C 1930-1949, SOLID BRICK uninsulated (thickness not lodged -- +UNKNOWN, not a specific mm value), pitched 300mm loft insulation, SOLID +ground floor uninsulated, mains-gas generic (no-PCDB) REGULAR boiler — SAP +Table 4b code 115 (pre-1998, balanced/open flue, "BGL Pre 98 Wall mount +BF/OF") + programmer/room-thermostat control (2104/CBC) + radiators + +cylinder (size 2 = "Medium (131-170L)" on the live tool, foam, 25mm), gas +room-heater SECONDARY (603, approximated as RGB "Modern fire with open flue +post 1980" -- the cert gives no finer detail), TFA 68, single meter, +2-storey / 2 floor-dims (no extensions). Partial double glazing +(multiple_glazing_type 1, multiple_glazed_proportion 50 -- NOT modelled as +partial; this mapper's own `_api_cascade_glazing_type(1)` treats it as 100% +double too, so the Elmhurst build matches the mapper's own simplification), +glazed_area band 1 (Normal): 0.148*68=10.06 m^2 combined window. + +2011 lodged 45; this RdSAP10 engine on gov-API inputs produces 53. Elmhurst's +OWN worksheet, built here, gives 46 (window South-facing: 48 -- see below). +NEITHER is the "right answer" to chase blindly -- see the investigation +write-up in tests/domain/sap10_calculator/test_real_cert_sap_accuracy.py +next to this cert's RealCertExpectation for the full comparison, what was +ruled out, and the two real-but-unfixed bugs this build surfaced (wall- +thickness-unknown U-value fallback mismatch; a window U-value divergence). + +GOTCHAS specific to this build (fold into the next SAP-Schema-15.0 cert): + * The shared assessment WILL carry a stale PCDB boiler ref on Main Heating + 1 from a prior build -- clear `TextBoxPCDFBoilerReference` to "0" (JS + + save) BEFORE `ButtonMainHeatingCode` becomes clickable (mirrors the + documented storage-heater "clear the PCDF boiler first" pattern). + * Wall thickness: use `CheckBoxWallThicknessUnknown`, NOT a blank/skipped + field -- an untouched thickness textbox silently keeps whatever a PRIOR + cert set (bit this build once: inherited a stale 280mm, landing on the + exact documented Table 13 200/280mm edge case). + * `set_single_window`'s orientation choice is NOT neutral for a cert this + reduced-field: North gave 46, South gave 48 (max solar gain) on this + cert. South is the fairer bound (this mapper's own N/E/S/W synthesis + spreads solar gain; a single North-facing pick is the worst case). + * The Roof/Cylinder thickness dropdowns need an EXACT option-text match + ("300 mm" not "300 mm or more"; "25 mm" not "25") -- `set_select` fails + silently (no exception) on a non-matching value and leaves the field at + its previous/inherited state. ALWAYS verify with `.input_value()` after + setting, don't trust the call succeeded. + * Address/region are carried over from whatever cert built the shared + assessment last -- explicitly set them (see `address()` below) even + though region is provably inert for the SAP rating itself (UK-average + weather always, `_region_index` in cert_to_inputs.py) -- other summary + fields (post town) still read from it. + +Run: + DISPLAY=:99 python scripts/hyde/build_100010086084.py +""" +from __future__ import annotations +import sys +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_" + + +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 address(page): + page.goto(E.ENTRY_URL, wait_until="networkidle", timeout=60_000) + E.set_text(page, "TextBoxHouseNo", "9") + E.set_text(page, "TextBoxStreet", "Pear Tree Avenue") + E.set_text(page, "TextBoxTown", "Crewe") + E.set_text(page, "TextBoxPostCode", "CW1 3SH") + page.wait_for_timeout(300) + E.set_select(page, "DropDownListRegion", "West Pennines") + page.click("#ContentBody_ContentPlaceHolderNavigations_ButtonSaveClose", timeout=15_000) + page.wait_for_timeout(1000) + + +def property_description(page): + E.goto(page, "PropertyDescription", "WebFormPropertyDescription.aspx") + E.set_select(page, "DropDownListPropertyType1", "H House") + _pick(page, "DropDownListPropertyType2", "semi") # built_form 2 + E.set_text(page, "TextBoxStoreys", "2") + E.set_text(page, "TextBoxHabitableRooms", "3") + E.set_text(page, "TextBoxHeatedHabitableRooms", "3") + print("date ->", _pick(page, "DropDownListDateBuiltMain", "1930-1949")) # band C + E.set_select(page, "DropDownListDateBuiltFirst", "") + E.set_select(page, "DropDownListRoomInRoofMain", "") + E.save_close(page) + + +def dimensions(page): + E.goto(page, "Dimensions", "WebFormDimensions.aspx") + # Ground floor: area 37.74, heat_loss_perimeter 21.05 -> geometry-derived + # party wall (the shared/depth side) ~4.58m. + E.set_text(page, f"{DIM}TextBoxFloorAreaLowestFloor", "37.74") + E.set_text(page, f"{DIM}TextBoxRoomHeightLowestFloor", "2.41") + E.set_text(page, f"{DIM}TextBoxWallPerimeterLowestFloor", "21.05") + E.set_text(page, f"{DIM}TextBoxPartyWallLengthLowestFloor", "4.58") + # First floor: area 39.48, heat_loss_perimeter 18.45 -> party wall ~6.75m. + E.set_text(page, f"{DIM}TextBoxFloorArea1stFloor", "39.48") + E.set_text(page, f"{DIM}TextBoxRoomHeight1stFloor", "2.45") + E.set_text(page, f"{DIM}TextBoxWallPerimeter1stFloor", "18.45") + E.set_text(page, f"{DIM}TextBoxPartyWallLength1stFloor", "6.75") + E.save_close(page) + + +def walls(page): + E.goto(page, "Walls", "WebFormWalls.aspx") + E.set_select(page, f"{WALL}DropDownListType", "SO Solid brick") + page.wait_for_timeout(400) + print("insulation ->", _pick(page, f"{WALL}DropDownListInsulation", "as built")) + # Thickness NOT lodged on this schema -- mark unknown explicitly, don't + # leave the textbox untouched (it silently inherits a stale value). + cb = page.locator(f"#{E.FP}{WALL}CheckBoxWallThicknessUnknown") + if cb.count() and not cb.is_checked(): + E.commit(page, cb.check) + pw = _pick(page, f"{PWALL}DropDownListPartyWallType", "solid") \ + or _pick(page, f"{PWALL}DropDownListPartyWallType", "determine") + print("party wall ->", pw) + E.save_close(page) + + +def roofs(page): + E.goto(page, "Roofs", "WebFormRoofs.aspx") + _pick(page, f"{ROOF}DropDownListType", "access to loft") + _pick(page, f"{ROOF}DropDownListInsulationAt", "joists") + E.set_select(page, f"{ROOF}DropDownListThickness", "300 mm") # exact match + print("roof thickness now:", page.locator(f"#{E.FP}{ROOF}DropDownListThickness").input_value()) + 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") + # glazed_area band 1 (Normal): total = 0.148*68*1.00 = 10.06 m^2. multiple_ + # glazing_type=1 -> this mapper's own _api_cascade_glazing_type(1) treats + # it as 100% double (ignores multiple_glazed_proportion=50 the same way), + # so "Double, unknown install date" matches the mapper's own assumption. + # South (not North) -- max solar gain, the fairer single-orientation + # bound against this mapper's own N/E/S/W synthesis (see module docstring). + E.set_single_window(page, 10.06, "South", "Double with unknown install date") + 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 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") + # low_energy_lighting 43% of 7 fixed outlets -> 3 low-energy. + E.set_text(page, f"{LP}TextBoxLightsTotal", "7") + E.set_text(page, f"{LP}TextBoxLedLightsTotal", "3") + E.set_text(page, f"{LP}TextBoxCflLightsTotal", "0") + E.save_close(page) + + +def space_heating(page): + # SAP Table 4b code 115: pre-1998 gas boiler, balanced/open flue, no PCDB + # index (main_heating_data_source=2). Regular boiler (has_hot_water_ + # cylinder=true, water_heating_code 901 "from primary") + radiators + # (heat_emitter_type=1), fan_flue_present=N. + E.goto(page, "SpaceHeating", "WebFormSpaceHeating.aspx") + page.wait_for_timeout(1000) + # The shared assessment's Main Heating 1 slot carries a stale PCDB boiler + # ref from a prior build -- clear it first (JS + save) so the SAP-code + # button appears; mirrors the documented storage-heater pattern. + ref = page.locator(f"#{E.FP}{MH1B}TextBoxPCDFBoilerReference") + if ref.count() and ref.input_value(): + print(f"clearing leftover PCDF boiler ref {ref.input_value()}") + page.evaluate("""(id)=>{const e=document.getElementById(id);if(e){e.value='0'; + e.dispatchEvent(new Event('change',{bubbles:true}));}}""", f"{E.FP}{MH1B}TextBoxPCDFBoilerReference") + page.wait_for_timeout(500) + E.save_close(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 (no-PCDB) mains-gas REGULAR boiler, pre-1998 balanced/open flue + # (matches boiler_flue_type=1, fan_flue_present=N) -> Gas -> Mains gas -> + # Boilers -> Pre 1998 - Balanced/Open Flue -> Wall mount (regular, not + # combi/back-boiler -- matches has_hot_water_cylinder=true). + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingCode", + "^Gas", "Mains gas", "Boilers", "Balanced.*Open", + "Wall mount") + print("code:", page.locator(f"#{E.MH1}TextBoxMainHeatingCode").input_value()) + # Control 2104 = "Programmer and room thermostat" (matches the cert's own + # main_heating_controls description) -- no TRVs. NB: CBC is "Programmer + # and room thermostat"; CBB is "Room thermostat and TRVs" -- do not swap. + E.set_heating_dialog(page, f"{MH1B}ButtonMainHeatingControls", + "^Boilers", "^Standard", "CBC Programmer and room thermostat") + print("control:", page.locator(f"#{E.MH1}TextBoxMainHeatingControls").input_value()) + E.save_close(page) + + +def secondary(page): + # Lodged secondary: SAP 603 = room heaters, mains gas (no finer detail + # lodged -- RGB "Modern fire with open flue post 1980" is the generic + # approximation). + 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", "RGB Modern fire with open flue") + 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.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()) + # cylinder: size 2 (lodged cylinder_size code -- set_select matches by + #