mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +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
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
:return: A dictionary containing detailed cost breakdown.
|
||||
|
|
@ -624,92 +624,6 @@ class Costs:
|
|||
"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):
|
||||
"""
|
||||
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
|
||||
COST_OF_WORK = 300
|
||||
COST_OF_WORK = 235
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -46,19 +46,12 @@ class RoofRecommendations:
|
|||
self.loft_insulation_materials = [
|
||||
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
|
||||
self.flat_roof_insulation_materials = [
|
||||
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
|
||||
self.insulation_thickness = convert_thickness_to_numeric(
|
||||
self.property.roof["insulation_thickness"],
|
||||
|
|
@ -252,10 +245,8 @@ class RoofRecommendations:
|
|||
|
||||
if is_pitched:
|
||||
insulation_materials = self.loft_insulation_materials
|
||||
non_insulation_materials = self.loft_non_insulation_materials
|
||||
elif is_flat:
|
||||
insulation_materials = self.flat_roof_insulation_materials
|
||||
non_insulation_materials = self.flat_roof_non_insulation_materials
|
||||
else:
|
||||
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:
|
||||
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":
|
||||
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"]
|
||||
|
||||
# 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"
|
||||
|
||||
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_efficiency = "Good"
|
||||
else:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue