mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
using data classes in recommendation classes
This commit is contained in:
parent
6e73d807a9
commit
737147897b
5 changed files with 30 additions and 422 deletions
|
|
@ -1,392 +0,0 @@
|
|||
import itertools
|
||||
from utils.logger import setup_logger
|
||||
from backend.Property import Property
|
||||
from recommendations.FloorRecommendations import FloorRecommendations
|
||||
from recommendations.WallRecommendations import WallRecommendations
|
||||
from recommendations.RoofRecommendations import RoofRecommendations
|
||||
from recommendations.VentilationRecommendations import VentilationRecommendations
|
||||
from recommendations.FireplaceRecommendations import FireplaceRecommendations
|
||||
from recommendations.LightingRecommendations import LightingRecommendations
|
||||
from recommendations.SolarPvRecommendations import SolarPvRecommendations
|
||||
from recommendations.WindowsRecommendations import WindowsRecommendations
|
||||
from recommendations.HeatingRecommender import HeatingRecommender
|
||||
from recommendations.HotwaterRecommendations import HotwaterRecommendations
|
||||
from recommendations.SecondaryHeating import SecondaryHeating
|
||||
from recommendations.Recommendations import Recommendations
|
||||
|
||||
logger = setup_logger()
|
||||
|
||||
|
||||
class Mds:
|
||||
"""
|
||||
Handles the contruction of the MDS report
|
||||
"""
|
||||
|
||||
format_map = {
|
||||
"external_wall_insulation": "EWI (Trad Const)",
|
||||
"internal_wall_insualtion": "IWI",
|
||||
"cavity_wall_insulation": "CWI",
|
||||
"loft_insulation": "LI",
|
||||
"air_source_heat_pump": "ASHP Htg",
|
||||
"high_heat_retention_storage_heaters": "High Heat Retention Storage Heaters",
|
||||
"solar_pv": "Solar PV",
|
||||
}
|
||||
|
||||
def __init__(self, property_instance: Property, materials, optimise_measures: bool = False):
|
||||
self.property_instance = property_instance
|
||||
|
||||
self.floor_recommender = FloorRecommendations(property_instance=property_instance, materials=materials)
|
||||
self.wall_recommender = WallRecommendations(property_instance=property_instance, materials=materials)
|
||||
self.roof_recommender = RoofRecommendations(property_instance=property_instance, materials=materials)
|
||||
self.ventilation_recomender = VentilationRecommendations(
|
||||
property_instance=property_instance, materials=materials
|
||||
)
|
||||
self.fireplace_recommender = FireplaceRecommendations(property_instance=property_instance)
|
||||
self.lighting_recommender = LightingRecommendations(property_instance=property_instance, materials=materials)
|
||||
self.windows_recommender = WindowsRecommendations(property_instance=property_instance, materials=materials)
|
||||
self.solar_recommender = SolarPvRecommendations(property_instance=property_instance)
|
||||
self.heating_recommender = HeatingRecommender(property_instance=property_instance)
|
||||
self.hotwater_recommender = HotwaterRecommendations(property_instance=property_instance)
|
||||
self.secondary_heating_recommender = SecondaryHeating(property_instance=property_instance)
|
||||
|
||||
# This flag indicates that we wish to optimise the measures, to the property, depending on the set of measures
|
||||
# we have been provided
|
||||
self.optimise_measures = optimise_measures
|
||||
|
||||
def select_optimal_measure_set(self, measures):
|
||||
|
||||
# This is the set
|
||||
all_considered_measures = [
|
||||
'external_wall_insulation',
|
||||
'cavity_wall_insulation',
|
||||
'loft_insulation',
|
||||
'air_source_heat_pump',
|
||||
'high_heat_retention_storage_heaters',
|
||||
'solar_pv'
|
||||
]
|
||||
|
||||
# Check if our measures are within the ones we've handled
|
||||
new = [m for m in measures if m not in all_considered_measures]
|
||||
if new:
|
||||
raise NotImplementedError("New measures - handle me")
|
||||
|
||||
def prune_options(options, measures):
|
||||
options_pruned = []
|
||||
for _group in options:
|
||||
group_pruned = [m for m in _group if m in measures]
|
||||
if not group_pruned:
|
||||
continue
|
||||
options_pruned.append(group_pruned)
|
||||
|
||||
return options_pruned
|
||||
|
||||
# For options in here, a property could only possibly have one of these
|
||||
one_choice_options = [
|
||||
["external_wall_insulation", "cavity_wall_insulation", "internal_wall_insulation"],
|
||||
["loft_insulation", "flat_roof_insulation", "room_in_roof_insulation"],
|
||||
["solid_floor_insulation", "suspended_floor_insulation"],
|
||||
]
|
||||
# prune one_choice_options based on the measure set considered for this property
|
||||
one_choice_options_pruned = prune_options(one_choice_options, measures)
|
||||
|
||||
# For options in here, a property could have one or the other so all should be considered
|
||||
multi_path_options = [
|
||||
["air_source_heat_pump", "high_heat_retention_storage_heaters", "gas_boiler"]
|
||||
]
|
||||
|
||||
multi_path_options_pruned = prune_options(multi_path_options, measures)
|
||||
|
||||
one_choice_combinations = [list(itertools.product(*one_choice_options_pruned))]
|
||||
one_choice_combinations = [list(x) for sublist in one_choice_combinations for x in sublist]
|
||||
multi_path_combinations = [list(itertools.product(*multi_path_options_pruned))]
|
||||
multi_path_combinations = [list(x) for sublist in multi_path_combinations for x in sublist]
|
||||
|
||||
one_choice_flat = [item for sublist in one_choice_options_pruned for item in sublist]
|
||||
multi_path_flat = [item for sublist in multi_path_options_pruned for item in sublist]
|
||||
|
||||
remaining_measures = [
|
||||
measure for measure in measures
|
||||
if measure not in one_choice_flat and measure not in multi_path_flat
|
||||
]
|
||||
|
||||
# Combine one_choice and multi_path combinations with remaining measures
|
||||
final_combinations = []
|
||||
for one_choice in one_choice_combinations:
|
||||
for multi_path in multi_path_combinations:
|
||||
final_combinations.append([m for m in one_choice + multi_path + remaining_measures])
|
||||
|
||||
pruned_combinations = []
|
||||
# TODO: We can do these checks once, outside of the loop and prune the combinations
|
||||
for combination in final_combinations:
|
||||
pruned_measures = []
|
||||
for measure in combination:
|
||||
if measure not in measures:
|
||||
continue
|
||||
# There are certain measures where we need to
|
||||
if measure == "external_wall_insulation":
|
||||
# Check if the wall is not cavity since the other wall types can take external wall insulation
|
||||
if (
|
||||
self.wall_recommender.ewi_valid() and
|
||||
not self.property_instance.walls["insulation_thickness"] in ["average", "above average"]
|
||||
):
|
||||
pruned_measures.append(measure)
|
||||
continue
|
||||
|
||||
if measure == "cavity_wall_insulation":
|
||||
# Check if the wall is cavity
|
||||
if (
|
||||
self.property_instance.walls['is_cavity_wall'] and
|
||||
not self.property_instance.walls['is_filled_cavity']
|
||||
):
|
||||
pruned_measures.append(measure)
|
||||
continue
|
||||
|
||||
if measure == "loft_insulation":
|
||||
# Check if the roof is suitable for loft insulation and the loft isn't already done
|
||||
# Or, if the home had a u-value for the roof, we don't recommend loft insulation
|
||||
if (
|
||||
self.property_instance.roof["is_pitched"] and
|
||||
not self.roof_recommender.is_loft_already_insulated() and
|
||||
self.property_instance.roof["thermal_transmittance_unit"] is None
|
||||
):
|
||||
pruned_measures.append(measure)
|
||||
continue
|
||||
|
||||
if measure == "solid_floor_insulation":
|
||||
# Check if the floor is solid
|
||||
if (
|
||||
self.property_instance.floor["is_solid"] and
|
||||
self.property_instance.floor["insulation_thickness"] not in ["average", "above average"] and
|
||||
self.property_instance.floor["thermal_transmittance_unit"] is not None
|
||||
):
|
||||
pruned_measures.append(measure)
|
||||
continue
|
||||
|
||||
if measure == "suspended_floor_insulation":
|
||||
# Check if the floor is suspended
|
||||
if (
|
||||
self.property_instance.floor["is_suspended"] and
|
||||
self.property_instance.floor["insulation_thickness"] not in ["average", "above average"] and
|
||||
self.property_instance.floor["thermal_transmittance_unit"] is not None
|
||||
):
|
||||
pruned_measures.append(measure)
|
||||
continue
|
||||
|
||||
if measure == "high_heat_retention_storage_heaters":
|
||||
|
||||
# For the moment, we recommend storage heaters if the property doesn't already
|
||||
# and don't make it contngent on controls
|
||||
already_has_hhr = self.heating_recommender.is_hhr_already_installed()
|
||||
|
||||
if (
|
||||
self.heating_recommender.is_high_heat_retention_valid() and
|
||||
not already_has_hhr
|
||||
):
|
||||
pruned_measures.append(measure)
|
||||
continue
|
||||
|
||||
if measure == "air_source_heat_pump":
|
||||
if self.heating_recommender.is_ashp_valid():
|
||||
pruned_measures.append(measure)
|
||||
continue
|
||||
|
||||
if measure == "solar_pv":
|
||||
if self.solar_recommender.is_solar_pv_valid():
|
||||
pruned_measures.append(measure)
|
||||
continue
|
||||
|
||||
raise NotImplementedError("Implement me")
|
||||
|
||||
if not pruned_measures:
|
||||
continue
|
||||
|
||||
pruned_measures_formatted = []
|
||||
for pm in pruned_measures:
|
||||
pruned_measures_formatted.append({pm: self.format_map[pm]})
|
||||
|
||||
pruned_combinations.append(pruned_measures_formatted)
|
||||
|
||||
# We're left with the subset of measures that are possible for this property
|
||||
# These are the possible groups of measures that could be applied to this home
|
||||
|
||||
return pruned_combinations
|
||||
|
||||
def _build(self, measure_config_list, measures):
|
||||
not_implemented_measures = [
|
||||
"party_wall_insulation",
|
||||
"ground_source_heat_pump",
|
||||
"shared_ground_loops",
|
||||
"communal_heat_networks",
|
||||
"district_heating_networks",
|
||||
"solar_thermal",
|
||||
"draught_proofing",
|
||||
"ev_charging",
|
||||
"battery",
|
||||
]
|
||||
# Check if we have a not implemented measure
|
||||
if any([m in not_implemented_measures for m in measure_config_list]):
|
||||
raise NotImplementedError("Not implemented measure in the property - implement me")
|
||||
|
||||
mds_recommendations = []
|
||||
errors = []
|
||||
phase = 0
|
||||
|
||||
# TODO: Could use a decarator to reduce the boilerplate code - insert_recommendation_id and then the append
|
||||
|
||||
if "external_wall_insulation" in measure_config_list:
|
||||
recs = self.wall_recommender.mds_recommend_ewi(phase=phase)
|
||||
if not recs:
|
||||
raise Exception("No recommendations for external wall insulation")
|
||||
recs = self.insert_recommendation_id(recs, measures, "external_wall_insulation")
|
||||
mds_recommendations.append(recs)
|
||||
if self.optimise_measures and len(recs):
|
||||
phase += 1
|
||||
|
||||
if "cavity_wall_insulation" in measure_config_list:
|
||||
recs = self.wall_recommender.mds_recommend_cavity_wall_insulation(phase=phase)
|
||||
recs = self.insert_recommendation_id(recs, measures, "cavity_wall_insulation")
|
||||
mds_recommendations.append(recs)
|
||||
if self.optimise_measures and len(recs):
|
||||
phase += 1
|
||||
|
||||
if "loft_insulation" in measure_config_list:
|
||||
# Check if the roof is suitable for loft insulation
|
||||
if self.property_instance.roof['is_roof_room']:
|
||||
errors.append("Roof is a room")
|
||||
else:
|
||||
recs = self.roof_recommender.mds_loft_insulation(phase=phase)
|
||||
if not recs:
|
||||
raise Exception("No recommendations for loft insulation")
|
||||
recs = self.insert_recommendation_id(recs, measures, "loft_insulation")
|
||||
mds_recommendations.append(recs)
|
||||
if self.optimise_measures and len(recs):
|
||||
phase += 1
|
||||
|
||||
if "internal_wall_insulation" in measure_config_list:
|
||||
raise Exception("check me out 4")
|
||||
self.wall_recommender.recommend(phase=phase)
|
||||
|
||||
if "suspended_floor_insulation" in measure_config_list:
|
||||
raise Exception("check me out 5")
|
||||
self.floor_recommender.recommend(phase=phase)
|
||||
|
||||
if "solid_floor_insulation" in measure_config_list:
|
||||
raise Exception("check me out 6")
|
||||
self.floor_recommender.recommend(phase=phase)
|
||||
|
||||
if "air_source_heat_pump" in measure_config_list:
|
||||
recs = self.heating_recommender.recommend_air_source_heat_pump(
|
||||
phase=phase, has_cavity_or_loft_recommendations=False, _return=True
|
||||
)
|
||||
recs = self.insert_recommendation_id(recs, measures, "air_source_heat_pump")
|
||||
mds_recommendations.append(recs)
|
||||
if self.optimise_measures and len(recs):
|
||||
phase += 1
|
||||
|
||||
if "high_heat_retention_storage_heaters" in measure_config_list:
|
||||
recs = self.heating_recommender.recommend_hhr_storage_heaters(
|
||||
phase=phase, system_change=True, heating_controls_only=False, _return=True
|
||||
)
|
||||
if recs is None:
|
||||
logger.info(
|
||||
f"No recommendations for high heat retention storage heaters, current heating "
|
||||
f"{self.property_instance.main_heating['clean_description']}"
|
||||
)
|
||||
else:
|
||||
recs = self.insert_recommendation_id(recs, measures, "high_heat_retention_storage_heaters")
|
||||
mds_recommendations.append(recs)
|
||||
if self.optimise_measures and len(recs):
|
||||
phase += 1
|
||||
|
||||
if "low_energy_lighting" in measure_config_list:
|
||||
raise Exception("check me out 9")
|
||||
self.lighting_recommender.recommend(phase=phase)
|
||||
|
||||
if "cylinder_insulation" in measure_config_list:
|
||||
raise Exception("check me out 10")
|
||||
self.hotwater_recommender.recommend(phase=phase)
|
||||
|
||||
if "smart_controls" in measure_config_list:
|
||||
raise Exception("check me out 11")
|
||||
self.heating_recommender.recommend(phase=phase)
|
||||
|
||||
if "zone_controls" in measure_config_list:
|
||||
raise Exception("check me out 12")
|
||||
self.heating_recommender.recommend(phase=phase)
|
||||
|
||||
if "trvs" in measure_config_list:
|
||||
raise Exception("check me out 13")
|
||||
self.heating_recommender.recommend(phase=phase)
|
||||
|
||||
if "solar_pv" in measure_config_list:
|
||||
recs = self.solar_recommender.mds_recommend(phase=phase, solar_pv_percentage=0.5)
|
||||
recs = self.insert_recommendation_id(recs, measures, "solar_pv")
|
||||
mds_recommendations.append(recs)
|
||||
if self.optimise_measures and len(recs):
|
||||
phase += 1
|
||||
|
||||
if "double_glazing" in measure_config_list:
|
||||
raise Exception("check me out 15")
|
||||
self.windows_recommender.recommend(phase=phase)
|
||||
|
||||
if "mechanical_ventilation" in measure_config_list:
|
||||
raise Exception("check me out 16")
|
||||
self.ventilation_recomender.recommend(phase=phase)
|
||||
|
||||
if "gas_boiler" in measure_config_list:
|
||||
raise Exception("check me out 17")
|
||||
self.heating_recommender.recommend(phase=phase)
|
||||
|
||||
if "flat_roof_insulation" in measure_config_list:
|
||||
raise Exception("check me out 18")
|
||||
self.roof_recommender.recommend(phase=phase)
|
||||
|
||||
if "room_in_roof_insulation" in measure_config_list:
|
||||
raise Exception("check me out 19")
|
||||
self.roof_recommender.recommend(phase=phase)
|
||||
|
||||
property_representative_recommendations = Recommendations.create_representative_recommendations(
|
||||
mds_recommendations, non_invasive_recommendations=[]
|
||||
)
|
||||
|
||||
return mds_recommendations, property_representative_recommendations, errors
|
||||
|
||||
def build(self):
|
||||
if self.property_instance.measures is None:
|
||||
raise NotImplementedError("No measures in the property - implement me")
|
||||
|
||||
if self.optimise_measures:
|
||||
measures_set = self.select_optimal_measure_set(self.property_instance.measures)
|
||||
mds_recommendations_map = {}
|
||||
representative_recommendations_map = {}
|
||||
errors_map = {}
|
||||
for measures in measures_set:
|
||||
measure_config_list = [list(x.keys())[0] for x in measures]
|
||||
mds_recommendations, rep_recommendations, errors = self._build(
|
||||
measure_config_list=measure_config_list,
|
||||
measures=measures
|
||||
)
|
||||
if errors:
|
||||
logger.info(f"Errors: {errors}")
|
||||
|
||||
mds_recommendations_map[str(measure_config_list)] = mds_recommendations
|
||||
representative_recommendations_map[str(measure_config_list)] = rep_recommendations
|
||||
errors_map[str(measure_config_list)] = errors
|
||||
|
||||
return mds_recommendations_map, representative_recommendations_map, errors_map
|
||||
|
||||
else:
|
||||
measure_config_list = [list(m.keys())[0] for m in self.property_instance.measures]
|
||||
return self._build(measure_config_list=measure_config_list, measures=self.property_instance.measures)
|
||||
|
||||
@staticmethod
|
||||
def insert_recommendation_id(recommendations, measures, measure_name):
|
||||
# Insert the recommendation identifier into this recommendation
|
||||
measure_config = [m for m in measures if measure_name in m][0]
|
||||
|
||||
idx = 0
|
||||
for r in recommendations:
|
||||
r["recommendation_id"] = list(measure_config.values())[0] + "-" + str(idx)
|
||||
idx += 1
|
||||
|
||||
return recommendations
|
||||
|
|
@ -581,10 +581,10 @@ class Recommendations:
|
|||
) -> dict:
|
||||
if rec_phase == starting_phase:
|
||||
return {
|
||||
"sap": float(property_instance.data["current-energy-efficiency"]),
|
||||
"sap_prediction": float(property_instance.data["current-energy-efficiency"]),
|
||||
"carbon": float(property_instance.data["co2-emissions-current"]),
|
||||
"heat_demand": float(property_instance.data["energy-consumption-current"]),
|
||||
"sap": float(property_instance.epc_record.current_energy_efficiency),
|
||||
"sap_prediction": float(property_instance.epc_record.current_energy_efficiency),
|
||||
"carbon": float(property_instance.epc_record.co2_emissions_current),
|
||||
"heat_demand": float(property_instance.epc_record.energy_consumption_current),
|
||||
}
|
||||
|
||||
previous_phase_reps = [
|
||||
|
|
@ -599,10 +599,10 @@ class Recommendations:
|
|||
# run the next step and run a median of nothing, which will return None
|
||||
if not previous_phase_reps:
|
||||
return {
|
||||
"sap": float(property_instance.data["current-energy-efficiency"]),
|
||||
"sap_prediction": float(property_instance.data["current-energy-efficiency"]),
|
||||
"carbon": float(property_instance.data["co2-emissions-current"]),
|
||||
"heat_demand": float(property_instance.data["energy-consumption-current"]),
|
||||
"sap": property_instance.epc_record.current_energy_efficiency,
|
||||
"sap_prediction": property_instance.epc_record.current_energy_efficiency,
|
||||
"carbon": property_instance.epc_record.co2_emissions_current,
|
||||
"heat_demand": property_instance.epc_record.energy_consumption_current,
|
||||
}
|
||||
|
||||
# Median fallback (including zero-length case)
|
||||
|
|
@ -707,7 +707,7 @@ class Recommendations:
|
|||
# For the moment, we cap the number of SAP points that can be achieved by LEDs at 2
|
||||
if rec["type"] == "low_energy_lighting":
|
||||
lighting_sap_limit = LightingRecommendations.get_sap_limit(
|
||||
property_instance.data["lighting-energy-eff"],
|
||||
property_instance.epc_record.lighting_energy_eff,
|
||||
property_instance.lighting["low_energy_proportion"]
|
||||
)
|
||||
|
||||
|
|
@ -802,7 +802,7 @@ class Recommendations:
|
|||
# By limiting here, we don't change the value in current_phase_values. This means that the
|
||||
# future recommendations won't have an impact that is too large
|
||||
li_sap_limit = RoofRecommendations.get_loft_insulation_sap_limit(
|
||||
property_instance.data["roof-energy-eff"], property_instance.roof["insulation_thickness"]
|
||||
property_instance.epc_record.roof_energy_eff, property_instance.roof["insulation_thickness"]
|
||||
)
|
||||
if li_sap_limit is not None:
|
||||
new_value = min(property_phase_impact["sap"], li_sap_limit)
|
||||
|
|
@ -1246,9 +1246,9 @@ class Recommendations:
|
|||
{
|
||||
"id": STARTING_DUMMY_ID_VALUE,
|
||||
**cls.map_descriptions_to_fuel(
|
||||
property_instance.data["mainheat-description"],
|
||||
property_instance.data["hotwater-description"],
|
||||
property_instance.data["main-fuel"],
|
||||
property_instance.epc_record.mainheat_description,
|
||||
property_instance.epc_record.hotwater_description,
|
||||
property_instance.epc_record.main_fuel,
|
||||
descriptions_to_fuel_types
|
||||
)
|
||||
}
|
||||
|
|
@ -1271,7 +1271,7 @@ class Recommendations:
|
|||
# 2) Have an average efficiency boiler, we adjust the COP of the existing boiler down to 75%
|
||||
heating_upgrades = [x for x in property_recommendations if x[0]["type"] == "heating"]
|
||||
boiler_upgrade = [r for recs in heating_upgrades for r in recs if r["measure_type"] == "boiler_upgrade"]
|
||||
existing_heating_efficiency = property_instance.data["mainheat-energy-eff"]
|
||||
existing_heating_efficiency = property_instance.epc_record.mainheat_energy_eff
|
||||
|
||||
if len(boiler_upgrade) and existing_heating_efficiency in ["Very Poor", "Poor", "Average"]:
|
||||
efficiency_map = {"Very Poor": 0.6, "Poor": 0.65, "Average": 0.7}
|
||||
|
|
|
|||
|
|
@ -800,7 +800,7 @@ class RoofRecommendations:
|
|||
if proposed_depth >= 300:
|
||||
new_efficiency = "Very Good"
|
||||
else:
|
||||
if self.property.data["roof-energy-eff"] not in ["Good", "Very Good"]:
|
||||
if self.property.epc_record.roof_energy_eff not in ["Good", "Very Good"]:
|
||||
new_efficiency = "Good"
|
||||
else:
|
||||
new_efficiency = "Very Good"
|
||||
|
|
@ -959,10 +959,10 @@ class RoofRecommendations:
|
|||
roof_simulation_config = check_simulation_difference(
|
||||
new_config=roof_ending_config, old_config=self.property.roof, prefix="roof_"
|
||||
)
|
||||
if self.property.data["roof-energy-eff"] in ["Very Poor", "Poor"]:
|
||||
if self.property.epc_record.roof_energy_eff in ["Very Poor", "Poor"]:
|
||||
new_efficiency = "Average"
|
||||
else:
|
||||
new_efficiency = self.property.data["roof-energy-eff"]
|
||||
new_efficiency = self.property.epc_record.roof_energy_eff
|
||||
|
||||
if default_u_values:
|
||||
new_u_value = get_roof_u_value(
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class WallRecommendations(Definitions):
|
|||
# Current logic: If the property is in a conservation area/heritage building/listed building or a flat,
|
||||
# it is not suitable for EWI
|
||||
if self.property.restricted_measures or (
|
||||
self.property.data["property-type"].lower() == "flat"
|
||||
self.property.epc_record.property_type.lower() == "flat"
|
||||
) or (
|
||||
self.property.walls['is_cob'] or
|
||||
self.property.walls['is_sandstone_or_limestone'] or
|
||||
|
|
@ -181,7 +181,7 @@ class WallRecommendations(Definitions):
|
|||
|
||||
# If the property is a new build and the U-value is below 0.75, we don't recommend insulation because it's
|
||||
# not practical
|
||||
if (self.property.data["transaction-type"] == "new dwelling") and (
|
||||
if (self.property.epc_record.transaction_type == "new dwelling") and (
|
||||
u_value <= self.NEW_BUILD_INSULATED
|
||||
):
|
||||
# Recommend nothing
|
||||
|
|
@ -480,13 +480,13 @@ class WallRecommendations(Definitions):
|
|||
x["construction-age-band"] == self.property.construction_age_band
|
||||
][0]
|
||||
|
||||
if self.property.data["walls-energy-eff"] == "Good" and efficiency_data["walls-energy-eff"] not in [
|
||||
if self.property.epc_record.walls_energy_eff == "Good" and efficiency_data["walls-energy-eff"] not in [
|
||||
"Good", "Very Good"
|
||||
]:
|
||||
simulation_config = {
|
||||
"walls_energy_eff_ending": self.property.data["walls-energy-eff"]
|
||||
"walls_energy_eff_ending": self.property.epc_record.walls_energy_eff
|
||||
}
|
||||
elif self.property.data["walls-energy-eff"] == "Very Good":
|
||||
elif self.property.epc_record.walls_energy_eff == "Very Good":
|
||||
simulation_config = {
|
||||
"walls_energy_eff_ending": "Very Good"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class WindowsRecommendations:
|
|||
# If the property currently has some secondary glazing but isn't in a conservation area
|
||||
#
|
||||
is_secondary_glazing = self.property.restricted_measures and (
|
||||
self.property.data["windows-energy-eff"] in ["Poor", "Very Poor"]
|
||||
self.property.epc_record.windows_energy_eff in ["Poor", "Very Poor"]
|
||||
)
|
||||
|
||||
# We check if the windows are partially insulated but we're recommending double glazing as a complete
|
||||
|
|
@ -90,17 +90,17 @@ class WindowsRecommendations:
|
|||
raise ValueError("Number of windows not specified")
|
||||
|
||||
# We scale the number of windows based on the proportion of existing glazing
|
||||
if self.property.data["multi-glaze-proportion"] != "":
|
||||
if self.property.epc_record.multi_glaze_proportion != "":
|
||||
|
||||
if (self.property.windows["clean_description"] == "Some double glazing") and (
|
||||
self.property.data["windows-energy-eff"] == "Very Poor") and (
|
||||
self.property.data["multi-glaze-proportion"] == 100
|
||||
self.property.epc_record.windows_energy_eff == "Very Poor") and (
|
||||
self.property.epc_record.multi_glaze_proportion == 100
|
||||
):
|
||||
# In this case, we assume all of the dinwos need replacing
|
||||
n_windows_scalar = 1
|
||||
else:
|
||||
n_windows_scalar = 1 - (
|
||||
int(self.property.data["multi-glaze-proportion"]) / 100
|
||||
int(self.property.epc_record.multi_glaze_proportion) / 100
|
||||
)
|
||||
else:
|
||||
n_windows_scalar = self.COVERAGE_MAP.get(
|
||||
|
|
@ -186,7 +186,7 @@ class WindowsRecommendations:
|
|||
glazed_type_ending = "double glazing installed during or after 2002"
|
||||
new_windows_description = "Fully double glazed"
|
||||
else:
|
||||
if self.property.data["multi-glaze-proportion"] < 50:
|
||||
if self.property.epc_record.multi_glaze_proportion < 50:
|
||||
glazed_type_ending = "secondary glazing"
|
||||
else:
|
||||
glazed_type_ending = "double glazing installed during or after 2002"
|
||||
|
|
@ -203,7 +203,7 @@ class WindowsRecommendations:
|
|||
glazed_type_ending = "secondary glazing"
|
||||
new_windows_description = "Full secondary glazing"
|
||||
else:
|
||||
if self.property.data["multi-glaze-proportion"] < 50:
|
||||
if self.property.epc_record.multi_glaze_proportion < 50:
|
||||
glazed_type_ending = "double glazing installed during or after 2002"
|
||||
else:
|
||||
glazed_type_ending = "secondary glazing"
|
||||
|
|
@ -214,7 +214,7 @@ class WindowsRecommendations:
|
|||
else:
|
||||
raise ValueError("Invalid glazing type - implement me")
|
||||
|
||||
if self.property.data["windows-energy-eff"] == "Very Good":
|
||||
if self.property.epc_record.windows_energy_eff == "Very Good":
|
||||
windows_energy_eff = "Very Good"
|
||||
|
||||
# For post 2002 windows, the energy efficiency is "Good" and so for the simulation, we simulate with "Good"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue