adding measures into individual measures classes wip

This commit is contained in:
Khalim Conn-Kowlessar 2024-09-05 13:36:27 +01:00
parent 85eaeccad8
commit efbcd0f0b8
5 changed files with 43 additions and 37 deletions

View file

@ -37,12 +37,15 @@ SPECIFIC_MEASURES = [
"trickle_vents",
"draught_proofing",
"mixed_glazing", # This covers partial double glazing and secondary glazing
"cavity_extract_and_refill",
]
# This allows us to extend high level categories for measures such as "wall_insulation" to the specific measures
# such as "external_wall_insulation", "internal_wall_insulation", "cavity_wall_insulation"
MEASURE_MAP = {
"wall_insulation": ["internal_wall_insulation", "external_wall_insulation", "cavity_wall_insulation"],
"wall_insulation": [
"internal_wall_insulation", "external_wall_insulation", "cavity_wall_insulation", "cavity_extract_and_refill"
],
"roof_insulation": ["loft_insulation", "flat_roof_insulation", "room_roof_insulation"],
"floor_insulation": ["suspended_floor_insulation", "solid_floor_insulation"],
"heating": ["boiler_upgrade", "high_heat_retention_storage_heater", "air_source_heat_pump"],

View file

@ -71,6 +71,9 @@ class Recommendations:
Determines the set of measures to be included in recommendations
"""
if self.property_instance.non_invasive_recommendations:
raise Exception("IMPLEMENT ME")
inclusions_full = [MEASURE_MAP[x] if x in MEASURE_MAP else x for x in self.inclusions]
exclusions_full = [MEASURE_MAP[x] if x in MEASURE_MAP else x for x in self.exclusions]
@ -96,24 +99,19 @@ class Recommendations:
property_recommendations = []
phase = 0
# TODO: We should form measures form non-intrusive recommendations too
measures = self.find_included_measures()
# Building Fabric
if (
("wall_insulation" in measures) or
("internal_wall_insulation" in measures) or
("external_wall_insulation" in measures)
):
self.wall_recomender.recommend(phase=phase, measures=measures)
if self.wall_recomender.recommendations:
property_recommendations.append(self.wall_recomender.recommendations)
phase += 1
self.wall_recomender.recommend(phase=phase, measures=measures)
if self.wall_recomender.recommendations:
property_recommendations.append(self.wall_recomender.recommendations)
phase += 1
if "roof_insulation" in measures:
self.roof_recommender.recommend(phase=phase)
if self.roof_recommender.recommendations:
property_recommendations.append(self.roof_recommender.recommendations)
phase += 1
self.roof_recommender.recommend(phase=phase, measures=measures)
if self.roof_recommender.recommendations:
property_recommendations.append(self.roof_recommender.recommendations)
phase += 1
# Ventilation recommendations
# We only produce a ventilation recommendation if the property is recommended to have wall or roof
@ -123,11 +121,10 @@ class Recommendations:
# real impact on the SAP score. Therefore, we don't need to include phasing for ventilation. If we
# have any
# wall or roof recommendations, we will ensure that ventilation is included in the simulation
if "ventilation" in measures:
if self.wall_recomender.recommendations or self.roof_recommender.recommendations:
self.ventilation_recomender.recommend()
if self.ventilation_recomender.recommendation:
property_recommendations.append(self.ventilation_recomender.recommendation)
if self.wall_recomender.recommendations or self.roof_recommender.recommendations:
self.ventilation_recomender.recommend(measures=measures)
if self.ventilation_recomender.recommendation:
property_recommendations.append(self.ventilation_recomender.recommendation)
if "floor_insulation" in measures:
self.floor_recommender.recommend(phase=phase)

View file

@ -1,6 +1,7 @@
import math
import pandas as pd
from backend.Property import Property
from backend.app.plan.schemas import MEASURE_MAP
from typing import List
from datatypes.enums import QuantityUnits
from recommendations.recommendation_utils import (
@ -108,11 +109,13 @@ class RoofRecommendations:
return full_insulated_room_roof or room_roof_insulated_at_rafters
def recommend(self, phase):
def recommend(self, phase, measures=None):
if self.property.roof["has_dwelling_above"]:
return
measures = MEASURE_MAP["roof_insulation"] if measures is None else measures
u_value = self.property.roof["thermal_transmittance"]
# We check if the roof is already insulated and if so, we exit
@ -153,19 +156,19 @@ class RoofRecommendations:
self.estimated_u_value = u_value
if (u_value <= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE) and (
"loft_insulation" not in self.property.non_invasive_recommendations
"loft_insulation" not in measures
):
# The Roof is already compliant
return
if self.property.roof["is_pitched"] or self.property.roof["is_flat"]:
insulation_thickness = (
0 if "loft_insulation" not in self.property.non_invasive_recommendations else self.insulation_thickness
)
if (self.property.roof["is_pitched"] and "loft_insulation" in measures) or (
self.property.roof["is_flat"] and "flat_roof_insulation"
):
insulation_thickness = 0 if "loft_insulation" not in measures else self.insulation_thickness
self.recommend_roof_insulation(u_value, insulation_thickness, self.property.roof, phase)
return
if self.property.roof["is_roof_room"]:
if self.property.roof["is_roof_room"] and ("room_roof_insulation" in measures):
self.recommend_room_roof_insulation(u_value, phase)
return

View file

@ -29,7 +29,7 @@ class VentilationRecommendations(Definitions):
def identify_ventilation(self):
self.has_ventilaion = self.property.data["mechanical-ventilation"] in self.VENTILATION_DESCRIPTIONS
def recommend(self):
def recommend(self, measures=None):
"""
If there is no ventilation, we recommend installing ventilation
@ -37,6 +37,9 @@ class VentilationRecommendations(Definitions):
ventilation if there is natural ventilation
:return:
"""
measures = ["ventilation"] if measures is None else measures
if "ventilation" not in measures:
return
self.identify_ventilation()
if self.has_ventilaion:

View file

@ -5,6 +5,7 @@ import pandas as pd
from datatypes.enums import QuantityUnits
from backend.Property import Property
from backend.app.plan.schemas import MEASURE_MAP
from BaseUtility import Definitions
from etl.epc_clean.epc_attributes.WallAttributes import WallAttributes
from recommendations.recommendation_utils import (
@ -195,6 +196,10 @@ class WallRecommendations(Definitions):
# U-value less than 0.18 and if in or close to a conversation area,
# recommend internal wall insulation as a possible measure
measures = MEASURE_MAP["wall_insulation"] if measures is None else measures
if not measures:
return
u_value = self.property.walls["thermal_transmittance"]
u_value = None if pd.isnull(u_value) else u_value
@ -235,7 +240,7 @@ class WallRecommendations(Definitions):
and (u_value >= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE)
):
# Recommend insulation
self.find_insulation(u_value, phase)
self.find_insulation(u_value, phase, measures)
return
# We can't detect it's a cavity wall, but it was built after 1990 so likely built with insulation already
@ -259,7 +264,7 @@ class WallRecommendations(Definitions):
self.estimated_u_value = u_value
if is_cavity_wall or "cavity_extract_and_refill" in self.property.non_invasive_recommendations:
if (is_cavity_wall and "cavity_wall_insulation" in measures) or "cavity_extract_and_refill" in measures:
if u_value >= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
# Test filling cavity
self.find_cavity_insulation(u_value, insulation_thickness, phase)
@ -558,7 +563,7 @@ class WallRecommendations(Definitions):
return recommendations
def find_insulation(self, u_value, phase, measures=None):
def find_insulation(self, u_value, phase, measures):
"""
This function contains the logic for finding potential insulation measures for a property, depending
on the parts available and whether the property can have external wall insulation installed
@ -570,13 +575,8 @@ class WallRecommendations(Definitions):
# we separate the logic for for recommending them, therefore we don't
# consider diminishing returns between the two as they are considered to be separate measures
if measures is None:
ewi_valid = self.ewi_valid()
else:
ewi_valid = self.ewi_valid() and "external_wall_insulation" in measures
ewi_recommendations = []
if ewi_valid:
if self.ewi_valid() and "external_wall_insulation" in measures:
ewi_recommendations = self._find_insulation(
u_value=u_value,
insulation_materials=pd.DataFrame(