Added insulated flat roof recommendations

This commit is contained in:
Khalim Conn-Kowlessar 2023-11-17 10:55:16 +00:00
parent 7ae49d35e4
commit 4537c7deab
3 changed files with 81 additions and 16 deletions

View file

@ -38,7 +38,10 @@ class RoofRecommendations:
def recommend(self):
u_value = self.property.roof["thermal_transmittance"]
insulation_thickness = convert_thickness_to_numeric(self.property.roof["insulation_thickness"])
insulation_thickness = convert_thickness_to_numeric(
self.property.roof["insulation_thickness"],
self.property.roof["is_pitched"]
)
# We check if the roof is already insulated and if so, we exit
@ -53,7 +56,7 @@ class RoofRecommendations:
u_value = get_roof_u_value(**{**self.property.roof, "age_band": self.property.age_band})
if self.property.roof["is_pitched"]:
if self.property.roof["is_pitched"] or self.property.roof["is_flat"]:
self.recommend_roof_insulation(u_value, insulation_thickness, self.property.roof)
return
@ -61,10 +64,6 @@ class RoofRecommendations:
self.recommend_room_roof_insulation(u_value, insulation_thickness)
return
if self.property.roof["is_flat"]:
self.recommend_flat_roof_insulation(u_value, insulation_thickness)
return
raise NotImplementedError("Implement me")
@staticmethod
@ -117,7 +116,7 @@ class RoofRecommendations:
raise ValueError("Roof is not pitched or flat")
if not materials:
raise ValueError("No loft insulation materials found")
raise ValueError("No roof insulation materials found")
lowest_selected_u_value = None
recommendations = []

View file

@ -571,20 +571,34 @@ def calculate_r_value_per_mm(thickness_mm, thermal_conductivity_w_mK):
return r_value_per_mm
def convert_thickness_to_numeric(string_thickness):
def convert_thickness_to_numeric(string_thickness, is_pitched):
"""
Roof insulation thickness could be a string like "None", "300mm+" or a numeric string.
This function will convert these strings to a number for easy usage
we handle loft insulation differently to flat roof or room in roof insulation, since for loft insulation,
we are presented with an insulation thickness, whereas for the other forms of roof, we are just told whether or not
the roof is insulated or not.
:param string_thickness: string measure of insulation thickness
:param is_pitched: boolean indicating if the roof is a pitched roof
:return: integer measure of insulation thickness
"""
lookup = {
"none": 0,
"below average": 50,
"average": 100,
"above average": 270
}
if is_pitched:
lookup = {
"none": 0,
"below average": 50,
"average": 100,
"above average": 270
}
else:
lookup = {
"none": 0,
"below average": 100,
"average": 270,
"above average": 270
}
mapped = lookup.get(string_thickness)
@ -621,7 +635,7 @@ def esimtate_pitched_roof_area(floor_area: float, floor_height: float) -> float:
# We're modelling the roof as two triangles where we know two of the three sides.
# The floor height makes up one side and half of the wall width makes up the other side
slope = np.sqrt(np.square(wall_width / 2) + np.square(floor_height))
area = 2 * (slope * wall_width)
return area

View file

@ -48,6 +48,19 @@ room_roof_insulation_materials = [
}
]
flat_roof_insulation_materials = [
{
'id': 18,
'type': 'flat_roof_insulation',
'description': 'Example flat roof insulation',
'depths': [50, 150, 220, 270, 300], 'depth_unit': 'mm', 'cost': [9, 10, 11, 12, 13],
'cost_unit': 'gbp_sq_meter',
'r_value_per_mm': 0.022727273, 'r_value_unit': 'square_meter_kelvin_per_watt',
'thermal_conductivity': 0.044, 'thermal_conductivity_unit': 'watt_per_meter_kelvin',
'link': None, 'is_active': True
}
]
class TestRoofRecommendations:
@ -347,9 +360,48 @@ class TestRoofRecommendations:
}
roof_recommender11 = RoofRecommendations(
property_instance=property_instance11, materials=room_roof_insulation_materials
property_instance=property_instance11, materials=flat_roof_insulation_materials
)
assert not roof_recommender11.recommendations
roof_recommender11.recommend()
assert len(roof_recommender11.recommendations) == 2
assert roof_recommender11.recommendations[0]["parts"][0]["depths"] == [270]
assert roof_recommender11.recommendations[1]["parts"][0]["depths"] == [300]
assert roof_recommender11.recommendations[0]["new_u_value"] == 0.16
assert roof_recommender11.recommendations[1]["new_u_value"] == 0.14
assert roof_recommender11.recommendations[0]["starting_u_value"] == 2.3
assert roof_recommender11.recommendations[1]["starting_u_value"] == 2.3
assert roof_recommender11.recommendations[0]["description"] == \
"Insulate the home's flat roof with 270mm of Example flat roof insulation"
assert roof_recommender11.recommendations[1]["description"] == \
"Insulate the home's flat roof with 300mm of Example flat roof insulation"
def test_flat_insulated(self):
property_instance12 = Property(id=12, address1="fake", postcode="fake", epc_client=Mock())
property_instance12.age_band = "D"
property_instance12.floor_area = 150
property_instance12.roof = {
'original_description': 'Flat, insulated (assumed)',
'clean_description': 'Flat, insulated',
'thermal_transmittance': None, 'thermal_transmittance_unit': None, 'is_pitched': False,
'is_roof_room': False,
'is_loft': False, 'is_flat': True, 'is_thatched': False, 'is_at_rafters': False, 'is_assumed': True,
'has_dwelling_above': False, 'is_valid': True, 'insulation_thickness': 'average'
}
roof_recommender12 = RoofRecommendations(
property_instance=property_instance12, materials=flat_roof_insulation_materials
)
assert not roof_recommender12.recommendations
roof_recommender12.recommend()
assert not roof_recommender12.recommendations