mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Default description on bare zero-rated party-wall elements in SAP-15.0 certs
Task 9d271e98-96e6-4be6-bb50-e9be6f954003 (portfolio 796) failed 21
"Top-floor flat" properties with "EnergyElement: missing required
field 'description'". Every one lodges a second walls[] entry that is
a bare zero-rated party-wall boundary element
({"energy_efficiency_rating": 0, "environmental_efficiency_rating": 0},
no description key at all) — unlike the sibling floors/roofs
"(other premises above/below)" sentinel convention, which does carry
text. Confirmed schema-wide across all 21 failing certs.
Default description to "" rather than fabricate construction text:
_joined_descriptions (heat_transmission.py) already filters out falsy
descriptions, so this is calc-neutral — it only unblocks the parse.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
8929a2115f
commit
7f7dcbc059
3 changed files with 267 additions and 0 deletions
|
|
@ -3913,6 +3913,28 @@ def _normalize_sap_schema_16_x(data: Dict[str, Any]) -> Dict[str, Any]:
|
|||
items: List[Any] = cast(List[Any], value)
|
||||
return [cast(Dict[str, Any], x) for x in items if isinstance(x, dict)]
|
||||
|
||||
# Every "Top-floor flat" SAP-Schema-15.0 cert we've seen (confirmed on 21
|
||||
# real certs from task 9d271e98-96e6-4be6-bb50-e9be6f954003, portfolio
|
||||
# 796 — e.g. cert 8204-4998-7729-4026-5693, UPRN 100061740136) lodges a
|
||||
# second `walls[]` entry that is a bare zero-rated party-wall boundary
|
||||
# element — `{"energy_efficiency_rating": 0,
|
||||
# "environmental_efficiency_rating": 0}`, no `description` key at all —
|
||||
# unlike the sibling `floors`/`roofs` "(other premises above/below)"
|
||||
# sentinel convention, which DOES carry text. RdSapSchema17_1 requires
|
||||
# `description`. Default it to "" rather than fabricate construction
|
||||
# text: `_joined_descriptions` (heat_transmission.py) already filters out
|
||||
# falsy descriptions, so a rating-0/no-description element contributes
|
||||
# nothing to the wall U-value derivation either way — this default is
|
||||
# calc-neutral, purely unblocking the parse.
|
||||
for elements_key in ("roofs", "walls", "floors", "windows"):
|
||||
for element in _dicts(d.get(elements_key)):
|
||||
if (
|
||||
"description" not in element
|
||||
and element.get("energy_efficiency_rating") == 0
|
||||
and element.get("environmental_efficiency_rating") == 0
|
||||
):
|
||||
element["description"] = ""
|
||||
|
||||
windows: Any = d.get("windows")
|
||||
if isinstance(windows, list) and windows:
|
||||
window_list: List[Any] = cast(List[Any], windows)
|
||||
|
|
|
|||
|
|
@ -140,3 +140,23 @@ class TestFromSapSchema15_0:
|
|||
|
||||
assert epc.has_hot_water_cylinder is False
|
||||
assert epc.sap_heating.cylinder_size == 1
|
||||
|
||||
def test_defaults_description_on_a_bare_zero_rated_party_wall(self) -> None:
|
||||
# Task 9d271e98-96e6-4be6-bb50-e9be6f954003 (portfolio 796 / scenario
|
||||
# 1268) failed 21 "Top-floor flat" properties with "EnergyElement:
|
||||
# missing required field 'description'": every one lodges a second
|
||||
# `walls[]` entry that is a bare zero-rated party-wall boundary
|
||||
# element (`{"energy_efficiency_rating": 0,
|
||||
# "environmental_efficiency_rating": 0}`, no description key at all)
|
||||
# — property_id 735232 / UPRN 100061740136 / cert
|
||||
# 8204-4998-7729-4026-5693 here. Must default to "" rather than fail
|
||||
# loud (calc-neutral — `_joined_descriptions` already drops falsy
|
||||
# descriptions).
|
||||
epc = EpcPropertyDataMapper.from_api_response(
|
||||
load("sap_15_0_uprn_100061740136.json")
|
||||
)
|
||||
|
||||
assert len(epc.walls) == 2
|
||||
assert epc.walls[0].description == "Cavity wall, as built, no insulation (assumed)"
|
||||
assert epc.walls[1].description == ""
|
||||
assert epc.walls[1].energy_efficiency_rating == 0
|
||||
|
|
|
|||
225
datatypes/epc/schema/tests/fixtures/sap_15_0_uprn_100061740136.json
vendored
Normal file
225
datatypes/epc/schema/tests/fixtures/sap_15_0_uprn_100061740136.json
vendored
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
{
|
||||
"uprn": 100061740136,
|
||||
"roofs": [
|
||||
{
|
||||
"description": "Pitched, no insulation(assumed)",
|
||||
"energy_efficiency_rating": 1,
|
||||
"environmental_efficiency_rating": 1
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
{
|
||||
"description": "Cavity wall, as built, no insulation (assumed)",
|
||||
"energy_efficiency_rating": 2,
|
||||
"environmental_efficiency_rating": 2
|
||||
},
|
||||
{
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
}
|
||||
],
|
||||
"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 all fixed outlets",
|
||||
"energy_efficiency_rating": 5,
|
||||
"environmental_efficiency_rating": 5
|
||||
},
|
||||
"postcode": "PO19 3NG",
|
||||
"hot_water": {
|
||||
"description": "From main system",
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
},
|
||||
"post_town": "CHICHESTER",
|
||||
"built_form": 3,
|
||||
"created_at": "2011-06-25 16:07:44",
|
||||
"glazed_area": 1,
|
||||
"region_code": 14,
|
||||
"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": "N",
|
||||
"heat_emitter_type": 1,
|
||||
"main_heating_number": 1,
|
||||
"main_heating_control": 2107,
|
||||
"main_heating_category": 2,
|
||||
"main_heating_fraction": 1,
|
||||
"main_heating_data_source": 2
|
||||
}
|
||||
],
|
||||
"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": "22, Duncan Road",
|
||||
"schema_version": "LIG-15.0",
|
||||
"assessment_type": "RdSAP",
|
||||
"completion_date": "2011-06-25",
|
||||
"inspection_date": "2011-06-21",
|
||||
"extensions_count": 0,
|
||||
"measurement_type": 1,
|
||||
"sap_flat_details": {
|
||||
"level": 3,
|
||||
"top_storey": "Y",
|
||||
"flat_location": 0,
|
||||
"heat_loss_corridor": 2,
|
||||
"unheated_corridor_length": 8.49
|
||||
},
|
||||
"total_floor_area": 30,
|
||||
"transaction_type": 3,
|
||||
"conservatory_type": 1,
|
||||
"heated_room_count": 1,
|
||||
"registration_date": "2011-06-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": "None",
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
},
|
||||
"sap_building_parts": [
|
||||
{
|
||||
"identifier": "Main Dwelling",
|
||||
"floor_heat_loss": 6,
|
||||
"roof_construction": 5,
|
||||
"wall_construction": 4,
|
||||
"building_part_number": 1,
|
||||
"sap_floor_dimensions": [
|
||||
{
|
||||
"floor": 0,
|
||||
"room_height": 2.28,
|
||||
"total_floor_area": 29.64,
|
||||
"heat_loss_perimeter": 18.41
|
||||
}
|
||||
],
|
||||
"wall_insulation_type": 4,
|
||||
"construction_age_band": "D",
|
||||
"roof_insulation_location": 4,
|
||||
"roof_insulation_thickness": "NI"
|
||||
}
|
||||
],
|
||||
"low_energy_lighting": 100,
|
||||
"solar_water_heating": "N",
|
||||
"bedf_revision_number": 310,
|
||||
"habitable_room_count": 1,
|
||||
"heating_cost_current": 457,
|
||||
"co2_emissions_current": 2.5,
|
||||
"energy_rating_current": 55,
|
||||
"lighting_cost_current": 18,
|
||||
"main_heating_controls": [
|
||||
{
|
||||
"description": "Programmer, TRVs and bypass",
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
}
|
||||
],
|
||||
"multiple_glazing_type": 1,
|
||||
"open_fireplaces_count": 0,
|
||||
"has_hot_water_cylinder": "false",
|
||||
"heating_cost_potential": 361,
|
||||
"hot_water_cost_current": 66,
|
||||
"mechanical_ventilation": 0,
|
||||
"suggested_improvements": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"typical_saving": 32,
|
||||
"indicative_cost": "?100 - ?300",
|
||||
"improvement_type": "B",
|
||||
"improvement_details": {
|
||||
"improvement_number": 6
|
||||
},
|
||||
"improvement_category": 1,
|
||||
"energy_performance_rating": 58,
|
||||
"environmental_impact_rating": 58
|
||||
},
|
||||
{
|
||||
"sequence": 2,
|
||||
"typical_saving": 24,
|
||||
"indicative_cost": "?350 - ?450",
|
||||
"improvement_type": "G",
|
||||
"improvement_details": {
|
||||
"improvement_number": 14
|
||||
},
|
||||
"improvement_category": 1,
|
||||
"energy_performance_rating": 60,
|
||||
"environmental_impact_rating": 61
|
||||
},
|
||||
{
|
||||
"sequence": 3,
|
||||
"typical_saving": 52,
|
||||
"indicative_cost": "?1,500 - ?3,500",
|
||||
"improvement_type": "I",
|
||||
"improvement_details": {
|
||||
"improvement_number": 20
|
||||
},
|
||||
"improvement_category": 2,
|
||||
"energy_performance_rating": 64,
|
||||
"environmental_impact_rating": 67
|
||||
}
|
||||
],
|
||||
"co2_emissions_potential": 1.9,
|
||||
"energy_rating_potential": 64,
|
||||
"lighting_cost_potential": 18,
|
||||
"hot_water_cost_potential": 55,
|
||||
"renewable_heat_incentive": {
|
||||
"water_heating": 1418,
|
||||
"space_heating_existing_dwelling": 6225,
|
||||
"space_heating_with_loft_insulation": 3572,
|
||||
"space_heating_with_cavity_insulation": 5600,
|
||||
"space_heating_with_loft_and_cavity_insulation": 2891
|
||||
},
|
||||
"seller_commission_report": "Y",
|
||||
"energy_consumption_current": 438,
|
||||
"has_fixed_air_conditioning": "false",
|
||||
"multiple_glazed_proportion": 100,
|
||||
"calculation_software_version": "1.3.1.0",
|
||||
"energy_consumption_potential": 326,
|
||||
"environmental_impact_current": 55,
|
||||
"fixed_lighting_outlets_count": 4,
|
||||
"current_energy_efficiency_band": "D",
|
||||
"environmental_impact_potential": 67,
|
||||
"has_heated_separate_conservatory": "false",
|
||||
"potential_energy_efficiency_band": "D",
|
||||
"co2_emissions_current_per_floor_area": 85,
|
||||
"low_energy_fixed_lighting_outlets_count": 4
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue