mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
update flat roof insulation recommendations
This commit is contained in:
parent
0c6d8121c2
commit
e6fc34741c
3 changed files with 12 additions and 113 deletions
|
|
@ -290,9 +290,9 @@ class Costs:
|
||||||
"labour_days": labour_days
|
"labour_days": labour_days
|
||||||
}
|
}
|
||||||
|
|
||||||
def loft_insulation(self, floor_area, material):
|
def loft_and_flat_insulation(self, floor_area, material):
|
||||||
"""
|
"""
|
||||||
Calculates the total cost for cavity wall insulation based on material and labor costs,
|
Calculates the total cost for loft/flat roof insulation based on material and labor costs,
|
||||||
including contingency, preliminaries, profit, and VAT.
|
including contingency, preliminaries, profit, and VAT.
|
||||||
|
|
||||||
:return: A dictionary containing detailed cost breakdown.
|
:return: A dictionary containing detailed cost breakdown.
|
||||||
|
|
@ -624,92 +624,6 @@ class Costs:
|
||||||
"labour_cost": labour_cost
|
"labour_cost": labour_cost
|
||||||
}
|
}
|
||||||
|
|
||||||
def flat_roof_insulation(self, floor_area, material, non_insulation_materials):
|
|
||||||
"""
|
|
||||||
A model of a warm, flat roof construction can be seen in this video:
|
|
||||||
https://www.youtube.com/watch?v=WZ6Ng6YI9OA
|
|
||||||
Warm, flat roof insulation will normally be 100-125mm in depth
|
|
||||||
|
|
||||||
We break this measure down into the following jobs to be done
|
|
||||||
1) Preparation of the room. This involves cleaning the existing roof surface, removing any debris and repairing
|
|
||||||
any damage. Additionally, an edge barrier will likely need to be installed, to protect the sides of the
|
|
||||||
roof from water ingress.
|
|
||||||
2) Primer Application. A layer of primer is applied to the clean roof surface to enhance the adhestia of
|
|
||||||
subsequent layers, and seal the existing roof surface.
|
|
||||||
3) Vapour Proof Layer Installation. Lay a vapour control layer to prevent moisture ingress from inside the
|
|
||||||
building, which is essential in warm roof construction.
|
|
||||||
4) Insulation Layer Application. Place and securely fix insulation boards over the roof. These could be rigid
|
|
||||||
boards like PIR (Polyisocyanurate).
|
|
||||||
5) Waterproofing Membrane Installation: Cover the insulation (and timber layer, if used) with a
|
|
||||||
waterproofing membrane, like EPDM, PVC, or bituminous felt. Carefully seal all joints, edges, and around any
|
|
||||||
roof penetrations to ensure water tightness
|
|
||||||
|
|
||||||
:param floor_area: Area of the flat roof to be insulated, based on the area of the floor
|
|
||||||
:param material: Selected insulation material
|
|
||||||
:param non_insulation_materials: Non-insulation materials required for the job
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
|
|
||||||
preparation_data_m2 = [
|
|
||||||
x for x in non_insulation_materials if
|
|
||||||
(x["type"] == "flat_roof_preparation") and (x["cost_unit"] == "gbp_per_m2")
|
|
||||||
]
|
|
||||||
vapour_barrier_data = [x for x in non_insulation_materials if x["type"] == "flat_roof_vapour_barrier"]
|
|
||||||
waterproofing_data = [x for x in non_insulation_materials if x["type"] == "flat_roof_waterproofing"]
|
|
||||||
|
|
||||||
if (len(preparation_data_m2) != 2) or (len(vapour_barrier_data) != 1) or (
|
|
||||||
len(waterproofing_data) != 1):
|
|
||||||
raise ValueError("Incorrect number of data entries for non-insulation materials")
|
|
||||||
|
|
||||||
# Break out the individual material costs
|
|
||||||
preparation_m2_material_costs = sum([x["material_cost"] * floor_area for x in preparation_data_m2])
|
|
||||||
vapour_barrier_material_costs = vapour_barrier_data[0]["material_cost"] * floor_area
|
|
||||||
insulation_material_costs = material["material_cost"] * floor_area
|
|
||||||
|
|
||||||
preparation_m2_labour_costs = sum([x["labour_cost"] * floor_area for x in preparation_data_m2])
|
|
||||||
vapour_barrier_labour_costs = vapour_barrier_data[0]["labour_cost"] * floor_area
|
|
||||||
|
|
||||||
# For waterproofing and upstand, we only have a total cost
|
|
||||||
waterproofing_total_costs = waterproofing_data[0]["total_cost"] * floor_area
|
|
||||||
|
|
||||||
labour_costs = preparation_m2_labour_costs + vapour_barrier_labour_costs
|
|
||||||
labour_costs = labour_costs * self.labour_adjustment_factor
|
|
||||||
|
|
||||||
materials_costs = preparation_m2_material_costs + vapour_barrier_material_costs + insulation_material_costs
|
|
||||||
|
|
||||||
subtotal_before_profit = labour_costs + materials_costs + waterproofing_total_costs
|
|
||||||
|
|
||||||
contingency_cost = subtotal_before_profit * self.FLAT_ROOF_CONTINGENCY
|
|
||||||
preliminaries_cost = subtotal_before_profit * self.PRELIMINARIES
|
|
||||||
profit_cost = subtotal_before_profit * self.PROFIT_MARGIN
|
|
||||||
|
|
||||||
subtotal_before_vat = subtotal_before_profit + contingency_cost + preliminaries_cost + profit_cost
|
|
||||||
vat_cost = subtotal_before_vat * self.VAT_RATE
|
|
||||||
total_cost = subtotal_before_vat + vat_cost
|
|
||||||
|
|
||||||
preparation_m2_labour_hours = sum([x["labour_hours_per_unit"] * floor_area for x in preparation_data_m2])
|
|
||||||
vapour_barrier_labour_hours = vapour_barrier_data[0]["labour_hours_per_unit"] * floor_area
|
|
||||||
waterproofing_labour_hours = waterproofing_data[0]["labour_hours_per_unit"] * floor_area
|
|
||||||
|
|
||||||
labour_hours = preparation_m2_labour_hours + vapour_barrier_labour_hours + waterproofing_labour_hours
|
|
||||||
|
|
||||||
# To install flat roof insulation, assume a small/medium project might be conducted by a team of 2-4.
|
|
||||||
# We'll assume a team of 2 since a lot of the roofs will be on the smaller side and will review this later
|
|
||||||
labour_days = (labour_hours / 8) / 2
|
|
||||||
|
|
||||||
return {
|
|
||||||
"total": total_cost,
|
|
||||||
"subtotal": subtotal_before_vat,
|
|
||||||
"vat": vat_cost,
|
|
||||||
"contingency": contingency_cost,
|
|
||||||
"preliminaries": preliminaries_cost,
|
|
||||||
"material": materials_costs,
|
|
||||||
"profit": profit_cost,
|
|
||||||
"labour_hours": labour_hours,
|
|
||||||
"labour_days": labour_days,
|
|
||||||
"labour_cost": labour_costs
|
|
||||||
}
|
|
||||||
|
|
||||||
def window_glazing(self, number_of_windows, material, is_secondary_glazing=False):
|
def window_glazing(self, number_of_windows, material, is_secondary_glazing=False):
|
||||||
"""
|
"""
|
||||||
We characterise the jobs to be done for window glazing as the following:
|
We characterise the jobs to be done for window glazing as the following:
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ class FireplaceRecommendations(Definitions):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# This is our base assumption for the cost of the work
|
# This is our base assumption for the cost of the work
|
||||||
COST_OF_WORK = 300
|
COST_OF_WORK = 235
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
|
|
||||||
|
|
@ -46,19 +46,12 @@ class RoofRecommendations:
|
||||||
self.loft_insulation_materials = [
|
self.loft_insulation_materials = [
|
||||||
part for part in materials if (part["type"] == "loft_insulation") and (part["is_installer_quote"])
|
part for part in materials if (part["type"] == "loft_insulation") and (part["is_installer_quote"])
|
||||||
]
|
]
|
||||||
self.loft_non_insulation_materials = []
|
|
||||||
|
|
||||||
# We don't have proper installer quotes for flat roof insulation
|
# We don't have proper installer quotes for flat roof insulation
|
||||||
self.flat_roof_insulation_materials = [
|
self.flat_roof_insulation_materials = [
|
||||||
part for part in materials if part["type"] == "flat_roof_insulation"
|
part for part in materials if part["type"] == "flat_roof_insulation"
|
||||||
]
|
]
|
||||||
|
|
||||||
self.flat_roof_non_insulation_materials = [
|
|
||||||
part for part in materials if part["type"] in [
|
|
||||||
"flat_roof_preparation", "flat_roof_vapour_barrier", "flat_roof_waterproofing"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
|
|
||||||
# Extract the insulation thickness from the roof, which is used throughout this method
|
# Extract the insulation thickness from the roof, which is used throughout this method
|
||||||
self.insulation_thickness = convert_thickness_to_numeric(
|
self.insulation_thickness = convert_thickness_to_numeric(
|
||||||
self.property.roof["insulation_thickness"],
|
self.property.roof["insulation_thickness"],
|
||||||
|
|
@ -252,10 +245,8 @@ class RoofRecommendations:
|
||||||
|
|
||||||
if is_pitched:
|
if is_pitched:
|
||||||
insulation_materials = self.loft_insulation_materials
|
insulation_materials = self.loft_insulation_materials
|
||||||
non_insulation_materials = self.loft_non_insulation_materials
|
|
||||||
elif is_flat:
|
elif is_flat:
|
||||||
insulation_materials = self.flat_roof_insulation_materials
|
insulation_materials = self.flat_roof_insulation_materials
|
||||||
non_insulation_materials = self.flat_roof_non_insulation_materials
|
|
||||||
else:
|
else:
|
||||||
raise ValueError("Roof is not pitched or flat")
|
raise ValueError("Roof is not pitched or flat")
|
||||||
|
|
||||||
|
|
@ -297,14 +288,16 @@ class RoofRecommendations:
|
||||||
if new_u_value <= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
|
if new_u_value <= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
|
||||||
lowest_selected_u_value = update_lowest_selected_u_value(lowest_selected_u_value, new_u_value)
|
lowest_selected_u_value = update_lowest_selected_u_value(lowest_selected_u_value, new_u_value)
|
||||||
|
|
||||||
|
cost_result = self.costs.loft_and_flat_insulation(
|
||||||
|
floor_area=self.property.insulation_floor_area,
|
||||||
|
material=material
|
||||||
|
)
|
||||||
|
|
||||||
|
already_installed = material["type"] in self.property.already_installed
|
||||||
|
if already_installed:
|
||||||
|
cost_result = override_costs(cost_result)
|
||||||
|
|
||||||
if material["type"] == "loft_insulation":
|
if material["type"] == "loft_insulation":
|
||||||
cost_result = self.costs.loft_insulation(
|
|
||||||
floor_area=self.property.insulation_floor_area,
|
|
||||||
material=material
|
|
||||||
)
|
|
||||||
already_installed = "loft_insulation" in self.property.already_installed
|
|
||||||
if already_installed:
|
|
||||||
cost_result = override_costs(cost_result)
|
|
||||||
new_thickness = insulation_thickness + material["depth"]
|
new_thickness = insulation_thickness + material["depth"]
|
||||||
|
|
||||||
# This is based on the values we have in the training data
|
# This is based on the values we have in the training data
|
||||||
|
|
@ -341,14 +334,6 @@ class RoofRecommendations:
|
||||||
new_description = f"Pitched, {int(proposed_depth)}mm loft insulation"
|
new_description = f"Pitched, {int(proposed_depth)}mm loft insulation"
|
||||||
|
|
||||||
elif material["type"] == "flat_roof_insulation":
|
elif material["type"] == "flat_roof_insulation":
|
||||||
cost_result = self.costs.flat_roof_insulation(
|
|
||||||
floor_area=self.property.insulation_floor_area,
|
|
||||||
material=material,
|
|
||||||
non_insulation_materials=non_insulation_materials
|
|
||||||
)
|
|
||||||
already_installed = "flat_roof_insulation" in self.property.already_installed
|
|
||||||
if already_installed:
|
|
||||||
cost_result = override_costs(cost_result)
|
|
||||||
new_description = "Flat, insulated"
|
new_description = "Flat, insulated"
|
||||||
new_efficiency = "Good"
|
new_efficiency = "Good"
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue