mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
Adding flat roof insulation
This commit is contained in:
parent
15e48c2165
commit
7ae49d35e4
3 changed files with 73 additions and 10 deletions
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
|
|
@ -1,5 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<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="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (backend)" project-jdk-type="Python SDK" />
|
||||||
<component name="PythonCompatibilityInspectionAdvertiser">
|
<component name="PythonCompatibilityInspectionAdvertiser">
|
||||||
<option name="version" value="3" />
|
<option name="version" value="3" />
|
||||||
|
|
|
||||||
|
|
@ -54,29 +54,54 @@ class RoofRecommendations:
|
||||||
u_value = get_roof_u_value(**{**self.property.roof, "age_band": self.property.age_band})
|
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"]:
|
||||||
self.recommend_loft_insulation(u_value, insulation_thickness)
|
self.recommend_roof_insulation(u_value, insulation_thickness, self.property.roof)
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.property.roof["is_roof_room"]:
|
if self.property.roof["is_roof_room"]:
|
||||||
self.recommend_room_roof_insulation(u_value, insulation_thickness)
|
self.recommend_room_roof_insulation(u_value, insulation_thickness)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.property.roof["is_flat"]:
|
||||||
|
self.recommend_flat_roof_insulation(u_value, insulation_thickness)
|
||||||
|
return
|
||||||
|
|
||||||
raise NotImplementedError("Implement me")
|
raise NotImplementedError("Implement me")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def make_loft_insulation_description(material, depth):
|
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
|
@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']}"
|
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 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 u_value: U-value of the roof before any retrofit measures have been installed
|
||||||
:param insulation_thickness: Existing Insulation thickness of the loft
|
:param insulation_thickness: Existing Insulation thickness of the loft
|
||||||
|
:param roof: dictionary describing the make-up of the roof
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -84,13 +109,19 @@ class RoofRecommendations:
|
||||||
# Therefore the price is 100mm + whatever thickness is rolled on top, rolled at a 90 degree angle
|
# Therefore the price is 100mm + whatever thickness is rolled on top, rolled at a 90 degree angle
|
||||||
# from the base layer
|
# from the base layer
|
||||||
|
|
||||||
loft_insulation_materials = [m for m in self.materials if m["type"] == "loft_insulation"]
|
if roof["is_pitched"]:
|
||||||
if not loft_insulation_materials:
|
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")
|
raise ValueError("No loft insulation materials found")
|
||||||
|
|
||||||
lowest_selected_u_value = None
|
lowest_selected_u_value = None
|
||||||
recommendations = []
|
recommendations = []
|
||||||
for material in loft_insulation_materials:
|
for material in materials:
|
||||||
|
|
||||||
for depth, cost_per_unit in zip(material["depths"], material["cost"]):
|
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
|
# 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
|
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(
|
recommendations.append(
|
||||||
{
|
{
|
||||||
"parts": [
|
"parts": [
|
||||||
|
|
@ -132,7 +168,7 @@ class RoofRecommendations:
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
"type": "roof_insulation",
|
"type": "roof_insulation",
|
||||||
"description": self.make_loft_insulation_description(material, depth),
|
"description": description,
|
||||||
"starting_u_value": u_value,
|
"starting_u_value": u_value,
|
||||||
"new_u_value": new_u_value,
|
"new_u_value": new_u_value,
|
||||||
"sap_points": None,
|
"sap_points": None,
|
||||||
|
|
@ -179,7 +215,6 @@ class RoofRecommendations:
|
||||||
but with a layer of plasterboard on the inside of the insulation.
|
but with a layer of plasterboard on the inside of the insulation.
|
||||||
- Vertical walls can be insulated in the same way.
|
- Vertical walls can be insulated in the same way.
|
||||||
- Flat ceilings can be insulated like a standard loft.
|
- Flat ceilings can be insulated like a standard loft.
|
||||||
"
|
|
||||||
|
|
||||||
:param u_value: Current u-value of the roof
|
:param u_value: Current u-value of the roof
|
||||||
:param insulation_thickness: Current insulation thickness of the roof
|
:param insulation_thickness: Current insulation thickness of the roof
|
||||||
|
|
@ -236,7 +271,7 @@ class RoofRecommendations:
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
"type": "roof_insulation",
|
"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,
|
"starting_u_value": u_value,
|
||||||
"new_u_value": new_u_value,
|
"new_u_value": new_u_value,
|
||||||
"sap_points": None,
|
"sap_points": None,
|
||||||
|
|
|
||||||
|
|
@ -328,3 +328,28 @@ class TestRoofRecommendations:
|
||||||
"Insulate your room roof with 220mm of Example room roof insulation"
|
"Insulate your room roof with 220mm of Example room roof insulation"
|
||||||
assert roof_recommender10.recommendations[1]["description"] == \
|
assert roof_recommender10.recommendations[1]["description"] == \
|
||||||
"Insulate your room roof with 270mm of Example room roof insulation"
|
"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()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue