mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
basic implementation of pitched roof area estimate
This commit is contained in:
parent
22a0bb1ffd
commit
c96fafa701
4 changed files with 83 additions and 2 deletions
|
|
@ -11,7 +11,9 @@ from utils.s3 import read_dataframe_from_s3_parquet
|
||||||
from epc_api.client import EpcClient
|
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 estimate_floors, estimate_perimeter, get_wall_type, estimate_wall_area
|
from recommendations.recommendation_utils import (
|
||||||
|
estimate_floors, estimate_perimeter, get_wall_type, estimate_wall_area, esimtate_pitched_roof_area
|
||||||
|
)
|
||||||
|
|
||||||
ENVIRONMENT = os.environ.get('ENVIRONMENT', 'dev')
|
ENVIRONMENT = os.environ.get('ENVIRONMENT', 'dev')
|
||||||
EPC_AUTH_TOKEN = os.environ.get('EPC_AUTH_TOKEN')
|
EPC_AUTH_TOKEN = os.environ.get('EPC_AUTH_TOKEN')
|
||||||
|
|
@ -79,6 +81,7 @@ class Property(Definitions):
|
||||||
self.floor_height = None
|
self.floor_height = None
|
||||||
self.insulation_wall_area = None
|
self.insulation_wall_area = None
|
||||||
self.floor_area = None
|
self.floor_area = None
|
||||||
|
self.pitched_roof_area = None
|
||||||
|
|
||||||
if epc_client:
|
if epc_client:
|
||||||
self.epc_client = epc_client
|
self.epc_client = epc_client
|
||||||
|
|
@ -587,6 +590,10 @@ class Property(Definitions):
|
||||||
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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self.pitched_roof_area = esimtate_pitched_roof_area(
|
||||||
|
floor_area=self.floor_area / self.number_of_floors, floor_height=self.floor_height
|
||||||
|
)
|
||||||
|
|
||||||
def set_wall_type(self):
|
def set_wall_type(self):
|
||||||
"""
|
"""
|
||||||
This method sets the wall type of the property, using a simple approach based on the wall description
|
This method sets the wall type of the property, using a simple approach based on the wall description
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,13 @@ 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"]:
|
||||||
# We recommend loft insulation
|
|
||||||
self.recommend_loft_insulation(u_value, insulation_thickness)
|
self.recommend_loft_insulation(u_value, insulation_thickness)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.property.roof["is_roof_room"]:
|
||||||
|
self.recommend_room_roof_insulation(u_value, insulation_thickness)
|
||||||
|
return
|
||||||
|
|
||||||
raise NotImplementedError("Implement me")
|
raise NotImplementedError("Implement me")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
@ -132,3 +135,21 @@ class RoofRecommendations:
|
||||||
)
|
)
|
||||||
|
|
||||||
self.recommendations = recommendations
|
self.recommendations = recommendations
|
||||||
|
|
||||||
|
def recommend_room_roof_insulation(self, u_value, insulation_thickness):
|
||||||
|
"""
|
||||||
|
This method recommends room in roof insulation for properties that have been identified
|
||||||
|
to possess a room in roof.
|
||||||
|
|
||||||
|
Because we currently have limited data about the construction of the roof, we make the following
|
||||||
|
assumptions:
|
||||||
|
1) The room in roof has a sloped roof.
|
||||||
|
We will make some basic estimations about the area of the roof given the floor area and the height of the
|
||||||
|
floors
|
||||||
|
2) Insulation of external walls is covered by the wall recommendation class
|
||||||
|
3) We assume a "Gable" roof type
|
||||||
|
|
||||||
|
:param u_value:
|
||||||
|
:param insulation_thickness:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import math
|
import math
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
from recommendations.rdsap_tables import (
|
from recommendations.rdsap_tables import (
|
||||||
|
|
@ -594,3 +595,33 @@ def convert_thickness_to_numeric(string_thickness):
|
||||||
return int(string_thickness.replace("+", ""))
|
return int(string_thickness.replace("+", ""))
|
||||||
|
|
||||||
return int(string_thickness)
|
return int(string_thickness)
|
||||||
|
|
||||||
|
|
||||||
|
def esimtate_pitched_roof_area(floor_area: float, floor_height: float) -> float:
|
||||||
|
"""
|
||||||
|
This function will estimate the area of a pitched roof, given the floor area below the roof and the floor
|
||||||
|
height of the property.
|
||||||
|
|
||||||
|
Given limited information about the home, this is a very rough method to estimate the roof area and we
|
||||||
|
assume the the room is a gable roof.
|
||||||
|
|
||||||
|
We assume a roughly average pitch of 45 degrees
|
||||||
|
|
||||||
|
Note that both floor area and height should be in the same units. E.g. if floor area is meters squared,
|
||||||
|
floor height should be in meters
|
||||||
|
|
||||||
|
:param floor_area: area of the home's floor
|
||||||
|
:param floor_height: height of the home's floors
|
||||||
|
:return: Numerical estimate of the surface area of the top of the pitched roof
|
||||||
|
"""
|
||||||
|
|
||||||
|
# We estimate the length of the wall by just modelling the house as a square
|
||||||
|
wall_width = np.sqrt(floor_area)
|
||||||
|
|
||||||
|
# We're modelling the roof as two triangles where we know two of the three sides.
|
||||||
|
# The floor height makes up one side and half of the wall width makes up the other side
|
||||||
|
slope = np.sqrt(np.square(wall_width / 2) + np.square(floor_height))
|
||||||
|
|
||||||
|
area = 2 * (slope * wall_width)
|
||||||
|
|
||||||
|
return area
|
||||||
|
|
|
||||||
|
|
@ -192,3 +192,25 @@ class TestRoofRecommendations:
|
||||||
roof_recommender6.recommend()
|
roof_recommender6.recommend()
|
||||||
|
|
||||||
assert len(roof_recommender6.recommendations) == 0
|
assert len(roof_recommender6.recommendations) == 0
|
||||||
|
|
||||||
|
def test_uninsulated_room_in_roof(self):
|
||||||
|
property_instance7 = Property(id=0, address1="fake", postcode="fake", epc_client=Mock())
|
||||||
|
property_instance7.age_band = "F"
|
||||||
|
property_instance7.floor_area = 100
|
||||||
|
property_instance7.roof = {
|
||||||
|
'original_description': 'Roof room(s), no insulation (assumed)',
|
||||||
|
'clean_description': 'Roof room(s), no insulation',
|
||||||
|
'thermal_transmittance': None, 'thermal_transmittance_unit': None, 'is_pitched': False,
|
||||||
|
'is_roof_room': True, 'is_loft': False, 'is_flat': False, 'is_thatched': False, 'is_at_rafters': False,
|
||||||
|
'is_assumed': True, 'has_dwelling_above': False, 'is_valid': True, 'insulation_thickness': 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
property_instance7
|
||||||
|
|
||||||
|
roof_recommender7 = RoofRecommendations(
|
||||||
|
property_instance=property_instance7, materials=loft_insulation_materials
|
||||||
|
)
|
||||||
|
|
||||||
|
assert not roof_recommender7.recommendations
|
||||||
|
|
||||||
|
roof_recommender7.recommend()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue