Added phasing figures into recommender

This commit is contained in:
Khalim Conn-Kowlessar 2024-02-14 12:00:49 +00:00
parent ec80473f3e
commit 925a6c1887
9 changed files with 66 additions and 59 deletions

View file

@ -20,7 +20,7 @@ class FireplaceRecommendations(Definitions):
self.has_ventilaion = None
self.recommendation = None
def recommend(self):
def recommend(self, phase=0):
"""
Based on the number of open fireplcaes found, we recommend sealing each one at a cost of
around £500
@ -37,6 +37,7 @@ class FireplaceRecommendations(Definitions):
# We recommend installing two mechanical ventilation systems
self.recommendation = [
{
"phase": phase,
"parts": [],
"type": "sealing_open_fireplace",
"description": "Seal %s open fireplaces" % str(number_open_fireplaces),

View file

@ -69,7 +69,7 @@ class FloorRecommendations(Definitions):
# TODO: To be completed
self.exposed_floor_non_insulation_materials = []
def recommend(self):
def recommend(self, phase=0):
u_value = self.property.floor["thermal_transmittance"]
property_type = self.property.data["property-type"]
@ -129,7 +129,8 @@ class FloorRecommendations(Definitions):
self.recommend_floor_insulation(
u_value=u_value,
insulation_materials=self.solid_floor_insulation_materials,
non_insulation_materials=self.solid_floor_non_insulation_materials
non_insulation_materials=self.solid_floor_non_insulation_materials,
phase=phase
)
return
@ -156,7 +157,7 @@ class FloorRecommendations(Definitions):
raise ValueError("Invalid material type - implement me!")
def recommend_floor_insulation(self, u_value, insulation_materials, non_insulation_materials):
def recommend_floor_insulation(self, u_value, insulation_materials, non_insulation_materials, phase):
"""
This method is tasked with estimating the impact of performing suspended floor insulation
:return:
@ -198,6 +199,7 @@ class FloorRecommendations(Definitions):
self.recommendations.append(
{
"phase": phase,
"parts": [
get_recommended_part(
part=material.to_dict(),

View file

@ -51,7 +51,7 @@ class LightingRecommendations:
return total_energy_savings_per_year, carbon_reduction_tonnes
def recommend(self):
def recommend(self, phase=0):
"""
This method will check if there are any lighting fittings that aren't low energy.
@ -90,6 +90,7 @@ class LightingRecommendations:
self.recommendation = [
{
"phase": phase,
"parts": [],
"type": "low_energy_lighting",
"description": description,

View file

@ -51,48 +51,58 @@ class Recommendations:
"""
property_recommendations = []
# Floor recommendations
self.floor_recommender.recommend()
if self.floor_recommender.recommendations:
property_recommendations.append(self.floor_recommender.recommendations)
phase = 0
# Wall recommendations
self.wall_recomender.recommend()
self.wall_recomender.recommend(phase=phase)
if self.wall_recomender.recommendations:
property_recommendations.append(self.wall_recomender.recommendations)
# Roof recommendations
self.roof_recommender.recommend()
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 insulation
# We will not attribute a SAP impact to the ventilation recommendation, since we've seen that this has no
# 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 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)
# Fireplace sealing recommendations
self.fireplace_recommender.recommend()
if self.fireplace_recommender.recommendation:
property_recommendations.append(self.fireplace_recommender.recommendation)
# Roof recommendations
self.roof_recommender.recommend(phase=phase)
if self.roof_recommender.recommendations:
property_recommendations.append(self.roof_recommender.recommendations)
phase += 1
# Lighting recommendations
self.lighting_recommender.recommend()
if self.lighting_recommender.recommendation:
property_recommendations.append(self.lighting_recommender.recommendation)
# Floor recommendations
self.floor_recommender.recommend(phase=phase)
if self.floor_recommender.recommendations:
property_recommendations.append(self.floor_recommender.recommendations)
phase += 1
# Windows recommendations
self.windows_recommender.recommend()
self.windows_recommender.recommend(phase=phase)
if self.windows_recommender.recommendation:
property_recommendations.append(self.windows_recommender.recommendation)
phase += 1
# Fireplace sealing recommendations
self.fireplace_recommender.recommend(phase=phase)
if self.fireplace_recommender.recommendation:
property_recommendations.append(self.fireplace_recommender.recommendation)
phase += 1
# Lighting recommendations
self.lighting_recommender.recommend(phase=phase)
if self.lighting_recommender.recommendation:
property_recommendations.append(self.lighting_recommender.recommendation)
phase += 1
# Solar recommendations
self.solar_recommender.recommend()
self.solar_recommender.recommend(phase=phase)
if self.solar_recommender.recommendation:
property_recommendations.append(self.solar_recommender.recommendation)
phase += 1
# We insert temporary ids into the recommendations which is important for the optimiser later
property_recommendations = self.insert_temp_recommendation_id(property_recommendations)

View file

@ -53,7 +53,7 @@ class RoofRecommendations:
]
]
def recommend(self):
def recommend(self, phase):
if self.property.roof["has_dwelling_above"]:
return
@ -98,11 +98,11 @@ class RoofRecommendations:
return
if self.property.roof["is_pitched"] or self.property.roof["is_flat"]:
self.recommend_roof_insulation(u_value, insulation_thickness, self.property.roof)
self.recommend_roof_insulation(u_value, insulation_thickness, self.property.roof, phase)
return
if self.property.roof["is_roof_room"]:
self.recommend_room_roof_insulation(u_value)
self.recommend_room_roof_insulation(u_value, phase)
return
raise NotImplementedError("Implement me")
@ -124,7 +124,7 @@ class RoofRecommendations:
raise ValueError("Invalid material type")
def recommend_roof_insulation(
self, u_value, insulation_thickness, roof
self, u_value, insulation_thickness, roof, phase
):
"""
@ -217,6 +217,7 @@ class RoofRecommendations:
recommendations.append(
{
"phase": phase,
"parts": [
get_recommended_part(
part=material.to_dict(),
@ -236,7 +237,7 @@ class RoofRecommendations:
self.recommendations = recommendations
def recommend_room_roof_insulation(self, u_value):
def recommend_room_roof_insulation(self, u_value, phase):
"""
This method recommends room in roof insulation for properties that have been identified
to possess a room in roof.
@ -314,6 +315,7 @@ class RoofRecommendations:
recommendations.append(
{
"phase": phase,
"parts": [
get_recommended_part(
part=material,

View file

@ -18,7 +18,7 @@ class SolarPvRecommendations:
self.recommendation = []
def recommend(self):
def recommend(self, phase):
"""
We check if a property is potentially suitable for solar PV based on the following criteria:
- The property is a house or bungalow
@ -77,6 +77,7 @@ class SolarPvRecommendations:
self.recommendation.append(
{
"phase": phase,
"parts": [],
"type": "solar_pv",
"description": description,
@ -86,22 +87,6 @@ class SolarPvRecommendations:
**cost_result,
# This is required for simulating the SAP impact. solar_pv_percentage is between 0 & 1 so we scale
# back up here
"photo_supply": 100 * scenario
"photo_supply": 100 * roof_coverage
}
)
self.recommendation = [
{
"parts": [],
"type": "solar_pv",
"description": f"Install a {kw} kilowatt-peak (kWp) solar photovoltaic (PV) panel system on "
f"{roof_coverage_percent}% the roof",
"starting_u_value": None,
"new_u_value": None,
"sap_points": None,
**cost_result,
# This is required for simulating the SAP impact. solar_pv_percentage is between 0 & 1 so we scale
# back up here
"photo_supply": 100 * self.property.solar_pv_percentage
}
]

View file

@ -62,6 +62,7 @@ class VentilationRecommendations(Definitions):
# We recommend installing two mechanical ventilation systems
self.recommendation = [
{
"phase": None,
"parts": part,
"type": part[0]["type"],
"description": f"Install {n_units} {part[0]['description']} units",

View file

@ -97,7 +97,7 @@ class WallRecommendations(Definitions):
return True
def recommend(self):
def recommend(self, phase=0):
# if building built after 1990 + we're able to identify U-value +
# U-value less than 0.18 and if in or close to a conversation area,
# recommend internal wall insulation as a possible measure
@ -146,19 +146,19 @@ class WallRecommendations(Definitions):
if is_cavity_wall:
if u_value >= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
# Test filling cavity
self.find_cavity_insulation(u_value, insulation_thickness)
self.find_cavity_insulation(u_value, insulation_thickness, phase)
return
# Remaining wall types are treated with IWI or EWI
if u_value >= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
self.find_insulation(u_value)
self.find_insulation(u_value, phase)
return
# If the u-value is within regulations, we don't do anything
return
def find_cavity_insulation(self, u_value, insulation_thickness):
def find_cavity_insulation(self, u_value, insulation_thickness, phase):
"""
This method tests different materials to fill the cavity wall, determining which
material will give us the best U-value.
@ -210,6 +210,7 @@ class WallRecommendations(Definitions):
recommendations.append(
{
"phase": phase,
"parts": [
get_recommended_part(
part=material.to_dict(),
@ -229,7 +230,7 @@ class WallRecommendations(Definitions):
self.recommendations = recommendations
def _find_insulation(self, u_value, insulation_materials, non_insulation_materials):
def _find_insulation(self, u_value, insulation_materials, non_insulation_materials, phase):
lowest_selected_u_value = None
recommendations = []
@ -274,6 +275,7 @@ class WallRecommendations(Definitions):
recommendations.append(
{
"phase": phase,
"parts": [
get_recommended_part(
part=material.to_dict(),
@ -293,7 +295,7 @@ class WallRecommendations(Definitions):
return recommendations
def find_insulation(self, u_value):
def find_insulation(self, u_value, phase):
"""
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
@ -310,13 +312,15 @@ class WallRecommendations(Definitions):
ewi_recommendations = self._find_insulation(
u_value=u_value,
insulation_materials=pd.DataFrame(self.external_wall_insulation_materials),
non_insulation_materials=self.external_wall_non_insulation_materials
non_insulation_materials=self.external_wall_non_insulation_materials,
phase=phase
)
iwi_recommendations = self._find_insulation(
u_value=u_value,
insulation_materials=pd.DataFrame(self.internal_wall_insulation_materials),
non_insulation_materials=self.internal_wall_non_insulation_materials
non_insulation_materials=self.internal_wall_non_insulation_materials,
phase=phase
)
self.recommendations += ewi_recommendations + iwi_recommendations

View file

@ -30,7 +30,7 @@ class WindowsRecommendations:
raise ValueError("There should only be one window glazing material")
self.glazing_material = self.glazing_material[0]
def recommend(self):
def recommend(self, phase=0):
"""
This method will recommend the best possible glazing options for a property.
@ -85,6 +85,7 @@ class WindowsRecommendations:
self.recommendation = [
{
"phase": phase,
"parts": [],
"type": "windows_glazing",
"description": description,