mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
Added test_external_wall_area
This commit is contained in:
parent
63de7c19df
commit
a9a7d3f3a8
5 changed files with 50 additions and 21 deletions
|
|
@ -12,7 +12,7 @@ from epc_api.client import EpcClient
|
||||||
from BaseUtility import Definitions
|
from BaseUtility import Definitions
|
||||||
from recommendations.rdsap_tables import england_wales_age_band_lookup
|
from recommendations.rdsap_tables import england_wales_age_band_lookup
|
||||||
from recommendations.recommendation_utils import (
|
from recommendations.recommendation_utils import (
|
||||||
estimate_perimeter, get_wall_type, estimate_wall_area, esimtate_pitched_roof_area
|
estimate_perimeter, get_wall_type, estimate_external_wall_area, esimtate_pitched_roof_area
|
||||||
)
|
)
|
||||||
|
|
||||||
ENVIRONMENT = os.environ.get('ENVIRONMENT', 'dev')
|
ENVIRONMENT = os.environ.get('ENVIRONMENT', 'dev')
|
||||||
|
|
@ -612,8 +612,11 @@ class Property(Definitions):
|
||||||
self.floor_area / self.number_of_floors, self.number_of_rooms / self.number_of_floors
|
self.floor_area / self.number_of_floors, self.number_of_rooms / self.number_of_floors
|
||||||
)
|
)
|
||||||
|
|
||||||
self.insulation_wall_area = estimate_wall_area(
|
self.insulation_wall_area = estimate_external_wall_area(
|
||||||
num_floors=self.number_of_floors, floor_height=self.floor_height, perimeter=self.perimeter
|
num_floors=self.number_of_floors,
|
||||||
|
floor_height=self.floor_height,
|
||||||
|
perimeter=self.perimeter,
|
||||||
|
built_form=self.data["built-form"],
|
||||||
)
|
)
|
||||||
|
|
||||||
self.pitched_roof_area = esimtate_pitched_roof_area(
|
self.pitched_roof_area = esimtate_pitched_roof_area(
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,6 @@ p2.search_address_epc()
|
||||||
p1.set_basic_property_dimensions()
|
p1.set_basic_property_dimensions()
|
||||||
p2.set_basic_property_dimensions()
|
p2.set_basic_property_dimensions()
|
||||||
|
|
||||||
import pandas as pd
|
|
||||||
|
|
||||||
df = pd.read_csv("/Users/khalimconn-kowlessar/Downloads/Hestia Materials - external_wall_insulation.csv")
|
|
||||||
df = df.to_dict("records")
|
|
||||||
|
|
||||||
# This data comes from SPONs
|
# This data comes from SPONs
|
||||||
regional_labour_variations = [
|
regional_labour_variations = [
|
||||||
{"Region": "Outer London (Spon’s 2023)", "Adjustment_Factor": 1.00},
|
{"Region": "Outer London (Spon’s 2023)", "Adjustment_Factor": 1.00},
|
||||||
|
|
@ -120,28 +115,25 @@ class Costs:
|
||||||
Calculates the total cost for cavity wall insulation based on material and labor costs,
|
Calculates the total cost for cavity wall insulation based on material and labor costs,
|
||||||
including contingency, preliminaries, profit, and VAT.
|
including contingency, preliminaries, profit, and VAT.
|
||||||
|
|
||||||
|
Because of some limitations in the SPONs data, there are no materials that can be blown through a wall,
|
||||||
|
therefore we have adapted similar materials, basing our estimates on 75mm cavity slabs, and have halved the
|
||||||
|
labour time required. That is why we still price based on wall area despite volume actually being the correct
|
||||||
|
metric.
|
||||||
|
|
||||||
:return: A dictionary containing detailed cost breakdown.
|
:return: A dictionary containing detailed cost breakdown.
|
||||||
"""
|
"""
|
||||||
# Cost per m2
|
# Cost per m2
|
||||||
# material = {
|
# material = {
|
||||||
# "description": "Crown Dritherm Cavity Slab 37 (Thermal conductivity 0.037 W/mK) glass fibre batt or
|
# "description": "cwi",
|
||||||
# other "
|
|
||||||
# "equal; as full or partial cavity fill; including cutting and fitting around wall ties
|
|
||||||
# and "
|
|
||||||
# "retaining discs",
|
|
||||||
# "depth": 75,
|
# "depth": 75,
|
||||||
# "thermal_conductivity": 0.037,
|
# "thermal_conductivity": 0.037,
|
||||||
# "prime_cost": 5.17,
|
# "prime_cost": 5.17,
|
||||||
# "material_cost": 5.62,
|
# "material_cost": 5.62,
|
||||||
# "labour_cost": 2.25,
|
# "labour_cost": 1.125,
|
||||||
# "labour_hours": 0.13
|
# "labour_hours": 0.065
|
||||||
# }
|
# }
|
||||||
|
|
||||||
material_cost_per_m2 = material["material_cost"]
|
material_cost_per_m2 = material["material_cost"]
|
||||||
# wall_area = self.property.insulation_wall_area
|
|
||||||
|
|
||||||
# This is the amount of material required in m3, assuming a standard 75mm depth
|
|
||||||
volume = 0.075 * wall_area
|
|
||||||
|
|
||||||
base_material_cost = material_cost_per_m2 * wall_area
|
base_material_cost = material_cost_per_m2 * wall_area
|
||||||
labour_cost = material["labour_cost"] * wall_area * self.labour_adjustment_factor
|
labour_cost = material["labour_cost"] * wall_area * self.labour_adjustment_factor
|
||||||
|
|
|
||||||
|
|
@ -527,12 +527,31 @@ def get_wall_type(
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def estimate_wall_area(num_floors, floor_height, perimeter):
|
def estimate_external_wall_area(num_floors, floor_height, perimeter, built_form):
|
||||||
|
"""
|
||||||
|
This method estimates the external wall area based on fundamental assumptions about the home
|
||||||
|
|
||||||
|
|
||||||
|
:param num_floors: Number of floors in the building.
|
||||||
|
:param floor_height: Height of one floor in meters.
|
||||||
|
:param perimeter: Total perimeter of the building on one floor in meters.
|
||||||
|
:param built_form: The built form of the property. This is used to determine the number of exposed walls.
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
wall_area_one_floor = perimeter * floor_height
|
wall_area_one_floor = perimeter * floor_height
|
||||||
|
|
||||||
total_wall_area = wall_area_one_floor * num_floors
|
total_wall_area = wall_area_one_floor * num_floors
|
||||||
|
|
||||||
return total_wall_area
|
number_exposed_walls = {
|
||||||
|
'End-Terrace': 3,
|
||||||
|
'Mid-Terrace': 2,
|
||||||
|
'Semi-Detached': 3,
|
||||||
|
'Detached': 4,
|
||||||
|
}
|
||||||
|
|
||||||
|
exposed_wall_area = total_wall_area * (number_exposed_walls[built_form] / 4)
|
||||||
|
|
||||||
|
return exposed_wall_area
|
||||||
|
|
||||||
|
|
||||||
def calculate_r_value_per_mm(thickness_mm, thermal_conductivity_w_mK):
|
def calculate_r_value_per_mm(thickness_mm, thermal_conductivity_w_mK):
|
||||||
|
|
|
||||||
0
recommendations/tests/test_costs.py
Normal file
0
recommendations/tests/test_costs.py
Normal file
|
|
@ -405,3 +405,18 @@ def test_esimtate_pitched_roof_area():
|
||||||
)
|
)
|
||||||
|
|
||||||
assert zero_roof_area2 == 0
|
assert zero_roof_area2 == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_external_wall_area():
|
||||||
|
# Arrange: Define the test cases
|
||||||
|
test_cases = [
|
||||||
|
(2, 3, 40, 'End-Terrace', 180), # 3 exposed walls
|
||||||
|
(2, 3, 40, 'Mid-Terrace', 120), # 2 exposed walls
|
||||||
|
(2, 3, 40, 'Semi-Detached', 180), # 3 exposed walls
|
||||||
|
(2, 3, 40, 'Detached', 240), # 4 exposed walls
|
||||||
|
]
|
||||||
|
|
||||||
|
# Act and Assert: Run the test cases
|
||||||
|
for num_floors, floor_height, perimeter, built_form, expected in test_cases:
|
||||||
|
result = recommendation_utils.estimate_external_wall_area(num_floors, floor_height, perimeter, built_form)
|
||||||
|
assert result == expected, f"Test failed for {built_form}: Expected {expected}, got {result}"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue