mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +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"?>
|
||||
<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" />
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue