Adding flat roof insulation

This commit is contained in:
Khalim Conn-Kowlessar 2023-11-17 10:43:14 +00:00
parent 15e48c2165
commit 7ae49d35e4
3 changed files with 73 additions and 10 deletions

3
.idea/misc.xml generated
View file

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.10 (backend)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (backend)" project-jdk-type="Python SDK" />
<component name="PythonCompatibilityInspectionAdvertiser">
<option name="version" value="3" />

View file

@ -54,29 +54,54 @@ class RoofRecommendations:
u_value = get_roof_u_value(**{**self.property.roof, "age_band": self.property.age_band})
if self.property.roof["is_pitched"]:
self.recommend_loft_insulation(u_value, insulation_thickness)
self.recommend_roof_insulation(u_value, insulation_thickness, self.property.roof)
return
if self.property.roof["is_roof_room"]:
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
def make_loft_insulation_description(material, depth):
return f"Install {depth}{material['depth_unit']} of {material['description']}"
return f"Install {depth}{material['depth_unit']} of {material['description']} in your loft"
@staticmethod
def make_room_roof_insulation(material, depth):
def make_room_roof_insulation_description(material, depth):
return f"Insulate your room roof with {depth}{material['depth_unit']} of {material['description']}"
def recommend_loft_insulation(self, u_value, insulation_thickness):
@staticmethod
def make_flat_roof_insulation_description(material, depth):
return f"Insulate the home's flat roof with {depth}{material['depth_unit']} of {material['description']}"
def recommend_roof_insulation(self, u_value, insulation_thickness, roof):
"""
This method will recommend which insulation materials to use
This function handles both the case of loft insulation and flat roof insulation
We also follow advide provided in this article on the Energy Saving Trust website, providing
high level guidance around roof insulation:
https://energysavingtrust.org.uk/advice/roof-and-loft-insulation/
The process roughly looks like the following:
- Remove the Existing Weatherproof Layer: If the roof is being replaced, remove the old weatherproof layer to
expose the timber roof surface.
- Install Insulation Boards: Lay the rigid insulation boards directly on the timber roof surface.
Ensure the boards fit tightly together to prevent thermal bridging (heat loss through the gaps).
- Add a Vapour Control Layer (VCL): This is crucial to prevent moisture from entering the insulation layer,
which can lead to dampness and rot. The VCL is placed over the insulation.
- Install a New Weatherproof Layer: On top of the insulation and VCL, install a new weatherproof layer. This
could be traditional roofing materials like bitumen-based felt, rubber membranes like EPDM, or fiberglass.
:param u_value: U-value of the roof before any retrofit measures have been installed
:param insulation_thickness: Existing Insulation thickness of the loft
:param roof: dictionary describing the make-up of the roof
:return:
"""
@ -84,13 +109,19 @@ class RoofRecommendations:
# Therefore the price is 100mm + whatever thickness is rolled on top, rolled at a 90 degree angle
# from the base layer
loft_insulation_materials = [m for m in self.materials if m["type"] == "loft_insulation"]
if not loft_insulation_materials:
if roof["is_pitched"]:
materials = [m for m in self.materials if m["type"] == "loft_insulation"]
elif roof["is_flat"]:
materials = [m for m in self.materials if m["type"] == "flat_roof_insulation"]
else:
raise ValueError("Roof is not pitched or flat")
if not materials:
raise ValueError("No loft insulation materials found")
lowest_selected_u_value = None
recommendations = []
for material in loft_insulation_materials:
for material in materials:
for depth, cost_per_unit in zip(material["depths"], material["cost"]):
# We make sure we hit a depth of 270mm. We should factor in any existing insulation if the
@ -120,6 +151,11 @@ class RoofRecommendations:
estimated_cost = cost_per_unit * self.property.floor_area
if roof["is_pitched"]:
description = self.make_loft_insulation_description(material, depth)
else:
description = self.make_flat_roof_insulation_description(material, depth)
recommendations.append(
{
"parts": [
@ -132,7 +168,7 @@ class RoofRecommendations:
)
],
"type": "roof_insulation",
"description": self.make_loft_insulation_description(material, depth),
"description": description,
"starting_u_value": u_value,
"new_u_value": new_u_value,
"sap_points": None,
@ -179,7 +215,6 @@ class RoofRecommendations:
but with a layer of plasterboard on the inside of the insulation.
- Vertical walls can be insulated in the same way.
- Flat ceilings can be insulated like a standard loft.
"
:param u_value: Current u-value of the roof
:param insulation_thickness: Current insulation thickness of the roof
@ -236,7 +271,7 @@ class RoofRecommendations:
)
],
"type": "roof_insulation",
"description": self.make_room_roof_insulation(material, depth),
"description": self.make_room_roof_insulation_description(material, depth),
"starting_u_value": u_value,
"new_u_value": new_u_value,
"sap_points": None,

View file

@ -328,3 +328,28 @@ class TestRoofRecommendations:
"Insulate your room roof with 220mm of Example room roof insulation"
assert roof_recommender10.recommendations[1]["description"] == \
"Insulate your room roof with 270mm of Example room roof insulation"
def test_flat_no_insulation(self):
# Desriptions to handle:
# 'Flat, limited insulation (assumed)',
#
# 'Flat, insulated (assumed)'
property_instance11 = Property(id=11, address1="fake", postcode="fake", epc_client=Mock())
property_instance11.age_band = "D"
property_instance11.floor_area = 150
property_instance11.roof = {
'original_description': 'Flat, no insulation (assumed)',
'clean_description': 'Flat, no insulation',
'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': 'none'
}
roof_recommender11 = RoofRecommendations(
property_instance=property_instance11, materials=room_roof_insulation_materials
)
assert not roof_recommender11.recommendations
roof_recommender11.recommend()