mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
added measures recs into heating
This commit is contained in:
parent
fffdaa0392
commit
0eb81b6e7c
4 changed files with 66 additions and 66 deletions
|
|
@ -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"]
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue