mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +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 BaseUtility import Definitions
|
||||
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')
|
||||
EPC_AUTH_TOKEN = os.environ.get('EPC_AUTH_TOKEN')
|
||||
|
|
@ -79,6 +81,7 @@ class Property(Definitions):
|
|||
self.floor_height = None
|
||||
self.insulation_wall_area = None
|
||||
self.floor_area = None
|
||||
self.pitched_roof_area = None
|
||||
|
||||
if 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
|
||||
)
|
||||
|
||||
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):
|
||||
"""
|
||||
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})
|
||||
|
||||
if self.property.roof["is_pitched"]:
|
||||
# We recommend loft insulation
|
||||
self.recommend_loft_insulation(u_value, insulation_thickness)
|
||||
return
|
||||
|
||||
if self.property.roof["is_roof_room"]:
|
||||
self.recommend_room_roof_insulation(u_value, insulation_thickness)
|
||||
return
|
||||
|
||||
raise NotImplementedError("Implement me")
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -132,3 +135,21 @@ class RoofRecommendations:
|
|||
)
|
||||
|
||||
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
|
||||
from copy import deepcopy
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
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)
|
||||
|
||||
|
||||
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()
|
||||
|
||||
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