added measures recs into heating

This commit is contained in:
Khalim Conn-Kowlessar 2024-09-05 13:51:13 +01:00
parent fffdaa0392
commit 0eb81b6e7c
4 changed files with 66 additions and 66 deletions

View file

@ -1231,12 +1231,12 @@ class Property:
else: else:
raise Exception("Investiage me") raise Exception("Investiage me")
def is_ashp_valid(self, exclusions): def is_ashp_valid(self, measures):
if "air_source_heat_pump" in self.non_invasive_recommendations: if "air_source_heat_pump" in self.non_invasive_recommendations:
return True return True
if "air_source_heat_pump" in exclusions: if "air_source_heat_pump" not in measures:
return False return False
suitable_property_type = self.data["property-type"] in ["House", "Bungalow"] suitable_property_type = self.data["property-type"] in ["House", "Bungalow"]

View file

@ -1,6 +1,7 @@
from recommendations.Costs import Costs, BOILER_UPGRADE_SCHEME_ASHP_VALUE from recommendations.Costs import Costs, BOILER_UPGRADE_SCHEME_ASHP_VALUE
from recommendations.recommendation_utils import check_simulation_difference, override_costs from recommendations.recommendation_utils import check_simulation_difference, override_costs
from backend.Property import Property from backend.Property import Property
from backend.app.plan.schemas import MEASURE_MAP
from etl.epc_clean.epc_attributes.MainheatAttributes import MainHeatAttributes from etl.epc_clean.epc_attributes.MainheatAttributes import MainHeatAttributes
from etl.epc_clean.epc_attributes.HotWaterAttributes import HotWaterAttributes from etl.epc_clean.epc_attributes.HotWaterAttributes import HotWaterAttributes
from etl.epc_clean.epc_attributes.MainFuelAttributes import MainFuelAttributes from etl.epc_clean.epc_attributes.MainFuelAttributes import MainFuelAttributes
@ -28,7 +29,7 @@ class HeatingRecommender:
self.property.main_heating["clean_description"] in self.ELECTRIC_HEATING_DESCRIPTIONS self.property.main_heating["clean_description"] in self.ELECTRIC_HEATING_DESCRIPTIONS
) )
def is_high_heat_retention_valid(self, ashp_only_heating_recommendation, exclusions): def is_high_heat_retention_valid(self, ashp_only_heating_recommendation, measures):
""" """
Check conditions if high heat retention storage is valid Check conditions if high heat retention storage is valid
:return: :return:
@ -43,10 +44,11 @@ class HeatingRecommender:
has_electric = self.has_electric_heating_description or electric_heating_assumed has_electric = self.has_electric_heating_description or electric_heating_assumed
return ( return (
has_electric and (not ashp_only_heating_recommendation) and ("boiler_upgrade" not in exclusions) has_electric and (not ashp_only_heating_recommendation) and
("high_heat_retention_storage_heater" in measures)
) )
def is_boiler_upgrade_suitable(self, exclusions, ashp_only_heating_recommendation): def is_boiler_upgrade_suitable(self, measures, ashp_only_heating_recommendation):
""" """
These are the conditions we apply to recommend a boiler installation These are the conditions we apply to recommend a boiler installation
:return: :return:
@ -84,12 +86,12 @@ class HeatingRecommender:
portable_heaters_has_mains portable_heaters_has_mains
) and ) and
(not ashp_only_heating_recommendation) and (not ashp_only_heating_recommendation) and
("boiler_upgrade" not in exclusions) ("boiler_upgrade" in measures)
) )
return is_valid, has_boiler return is_valid, has_boiler
def recommend(self, has_cavity_or_loft_recommendations, phase=0, exclusions=None): def recommend(self, has_cavity_or_loft_recommendations, phase=0, measures=None):
""" """
Produces heating recommendations Produces heating recommendations
@ -97,16 +99,17 @@ class HeatingRecommender:
recommendation. If there are cavity or loft recommendations, the property would need to complete those measures recommendation. If there are cavity or loft recommendations, the property would need to complete those measures
before being able to get the boiler upgrade scheme benefits. The messaging in the front end would be to before being able to get the boiler upgrade scheme benefits. The messaging in the front end would be to
:param phase: indicates the phase of the retrofit programme :param phase: indicates the phase of the retrofit programme
:param exclusions: A list of exclusions for the recommendations :param measures: A list of measures for the recommendations
""" """
measures = MEASURE_MAP["heating"] if measures is None else measures
# TODO: We could have a system flush recommendation for an existing boiler, where there is no need to replace # TODO: We could have a system flush recommendation for an existing boiler, where there is no need to replace
# the boiler, but instead flushing the system will make it run more efficiently. There is a cost for this # the boiler, but instead flushing the system will make it run more efficiently. There is a cost for this
# in the Costs class, stored as SYSTEM_FLUSH_COST # in the Costs class, stored as SYSTEM_FLUSH_COST
# TODO: Right now, we don't have recommendations for electric boilers - we should probably have one # TODO: Right now, we don't have recommendations for electric boilers - we should probably have one
exclusions = [] if exclusions is None else exclusions
non_invasive_ashp_recommendation = next( non_invasive_ashp_recommendation = next(
(r for r in self.property.non_invasive_recommendations if r["type"] == "air_source_heat_pump"), (r for r in self.property.non_invasive_recommendations if r["type"] == "air_source_heat_pump"),
{"suitable": True} {"suitable": True}
@ -122,7 +125,7 @@ class HeatingRecommender:
# This first iteration of the recommender will provide very basic recommendation # This first iteration of the recommender will provide very basic recommendation
# We recommend heating controls based on the main heating system # We recommend heating controls based on the main heating system
hhr_valid = self.is_high_heat_retention_valid(ashp_only_heating_recommendation, exclusions) hhr_valid = self.is_high_heat_retention_valid(ashp_only_heating_recommendation, measures)
if hhr_valid: if hhr_valid:
# Recommend high heat retention storage heaters # Recommend high heat retention storage heaters
@ -131,7 +134,7 @@ class HeatingRecommender:
self.recommend_hhr_storage_heaters(phase=phase, system_change=True, heating_controls_only=False) self.recommend_hhr_storage_heaters(phase=phase, system_change=True, heating_controls_only=False)
gas_boiler_suitable, has_boiler = self.is_boiler_upgrade_suitable( gas_boiler_suitable, has_boiler = self.is_boiler_upgrade_suitable(
exclusions=exclusions, ashp_only_heating_recommendation=ashp_only_heating_recommendation measures=measures, ashp_only_heating_recommendation=ashp_only_heating_recommendation
) )
if gas_boiler_suitable: if gas_boiler_suitable:
@ -153,7 +156,7 @@ class HeatingRecommender:
# In the future, we'll allow overrides, so that non-intrusive surveys can contradict these conditions # In the future, we'll allow overrides, so that non-intrusive surveys can contradict these conditions
# and either allow or prevent the recommendation of an air source heat pump # and either allow or prevent the recommendation of an air source heat pump
if self.property.is_ashp_valid(exclusions=exclusions) and non_invasive_ashp_recommendation["suitable"]: if self.property.is_ashp_valid(measures=measures) and non_invasive_ashp_recommendation["suitable"]:
self.recommend_air_source_heat_pump( self.recommend_air_source_heat_pump(
phase=phase, phase=phase,
has_cavity_or_loft_recommendations=has_cavity_or_loft_recommendations, has_cavity_or_loft_recommendations=has_cavity_or_loft_recommendations,

View file

@ -121,8 +121,11 @@ class Recommendations:
# real impact on the SAP score. Therefore, we don't need to include phasing for ventilation. If we # real impact on the SAP score. Therefore, we don't need to include phasing for ventilation. If we
# have any # have any
# wall or roof recommendations, we will ensure that ventilation is included in the simulation # wall or roof recommendations, we will ensure that ventilation is included in the simulation
if self.wall_recomender.recommendations or self.roof_recommender.recommendations: if (
self.ventilation_recomender.recommend(measures=measures) (self.wall_recomender.recommendations or self.roof_recommender.recommendations) and
("ventilation" in measures)
):
self.ventilation_recomender.recommend()
if self.ventilation_recomender.recommendation: if self.ventilation_recomender.recommendation:
property_recommendations.append(self.ventilation_recomender.recommendation) property_recommendations.append(self.ventilation_recomender.recommendation)
@ -144,57 +147,54 @@ class Recommendations:
property_recommendations.append(self.fireplace_recommender.recommendation) property_recommendations.append(self.fireplace_recommender.recommendation)
phase += 1 phase += 1
# Heating and Electical systems cavity_or_loft_recommendations = [
if "heating" in measures: r for r in self.wall_recomender.recommendations + self.roof_recommender.recommendations
if r["type"] in ["cavity_wall_insulation", "loft_insulation"]
]
has_cavity_or_loft_recommendations = len(cavity_or_loft_recommendations) > 0
cavity_or_loft_recommendations = [ self.heating_recommender.recommend(
r for r in self.wall_recomender.recommendations + self.roof_recommender.recommendations phase=phase,
if r["type"] in ["cavity_wall_insulation", "loft_insulation"] measures=measures,
] has_cavity_or_loft_recommendations=has_cavity_or_loft_recommendations,
has_cavity_or_loft_recommendations = len(cavity_or_loft_recommendations) > 0 )
if (
self.heating_recommender.heating_recommendations or
self.heating_recommender.heating_control_recommendations
):
self.heating_recommender.recommend( # We split into first and second phase recommendations
phase=phase, first_phase_recommendations = [
has_cavity_or_loft_recommendations=has_cavity_or_loft_recommendations, r for r in (
exclusions=self.exclusions self.heating_recommender.heating_recommendations +
) self.heating_recommender.heating_control_recommendations
if (
self.heating_recommender.heating_recommendations or
self.heating_recommender.heating_control_recommendations
):
# We split into first and second phase recommendations
first_phase_recommendations = [
r for r in (
self.heating_recommender.heating_recommendations +
self.heating_recommender.heating_control_recommendations
)
if r["phase"] == phase
]
second_phase_recommendations = [
r for r in (
self.heating_recommender.heating_recommendations +
self.heating_recommender.heating_control_recommendations
)
if r["phase"] == phase + 1
]
if first_phase_recommendations:
property_recommendations.append(first_phase_recommendations)
if second_phase_recommendations:
property_recommendations.append(second_phase_recommendations)
# We check if we have distinct heating and heating controls recommendations
# If so, we increment by 2 (one of the heating system, one for the heating controls)
# otherwise we incremenet by 1
max_used_phase = max(
[rec["phase"] for rec in
self.heating_recommender.heating_recommendations +
self.heating_recommender.heating_control_recommendations]
) )
amount_to_increment = max_used_phase - phase + 1 if r["phase"] == phase
phase += amount_to_increment ]
second_phase_recommendations = [
r for r in (
self.heating_recommender.heating_recommendations +
self.heating_recommender.heating_control_recommendations
)
if r["phase"] == phase + 1
]
if first_phase_recommendations:
property_recommendations.append(first_phase_recommendations)
if second_phase_recommendations:
property_recommendations.append(second_phase_recommendations)
# We check if we have distinct heating and heating controls recommendations
# If so, we increment by 2 (one of the heating system, one for the heating controls)
# otherwise we incremenet by 1
max_used_phase = max(
[rec["phase"] for rec in
self.heating_recommender.heating_recommendations +
self.heating_recommender.heating_control_recommendations]
)
amount_to_increment = max_used_phase - phase + 1
phase += amount_to_increment
# Hot water # Hot water
if "hot_water" in measures: if "hot_water" in measures:

View file

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