mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
checking hhr recommendations|
This commit is contained in:
parent
a1175c04a8
commit
1393a99b8b
4 changed files with 115 additions and 29 deletions
|
|
@ -858,14 +858,6 @@ class Property:
|
||||||
self.floor_level = 1
|
self.floor_level = 1
|
||||||
return
|
return
|
||||||
|
|
||||||
def is_mid_floor_flat(self):
|
|
||||||
"""
|
|
||||||
Simple utility function to check if the property is a mid-floor flat
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self.data["property-type"] == "Flat" and self.epc_record.original_epc["floor-level"] == "mid floor"
|
|
||||||
|
|
||||||
def set_wall_type(self):
|
def set_wall_type(self):
|
||||||
"""
|
"""
|
||||||
This method sets the wall type of the property, using a simple approach based on the wall description
|
This method sets the wall type of the property, using a simple approach based on the wall description
|
||||||
|
|
|
||||||
|
|
@ -970,6 +970,7 @@ async def build_mds(body: MdsRequest):
|
||||||
results.append({
|
results.append({
|
||||||
"config_address": config["address"],
|
"config_address": config["address"],
|
||||||
"config_postcode": config["postcode"],
|
"config_postcode": config["postcode"],
|
||||||
|
"uprn": p.uprn,
|
||||||
"address": p.address,
|
"address": p.address,
|
||||||
"postcode": p.postcode,
|
"postcode": p.postcode,
|
||||||
"measures": package_comparison["measures"],
|
"measures": package_comparison["measures"],
|
||||||
|
|
@ -988,6 +989,74 @@ async def build_mds(body: MdsRequest):
|
||||||
|
|
||||||
results = pd.DataFrame(results)
|
results = pd.DataFrame(results)
|
||||||
|
|
||||||
|
# For the different measures, we check the impact with a few debugging functions
|
||||||
|
|
||||||
|
def check_mds(results, input_properties, recommendations):
|
||||||
|
import ast
|
||||||
|
walls_check = []
|
||||||
|
hhr_check = []
|
||||||
|
for p in input_properties:
|
||||||
|
res = results[results["uprn"] == p.uprn]
|
||||||
|
wall = p.walls
|
||||||
|
heating = p.main_heating
|
||||||
|
wall_recommendation = [
|
||||||
|
x for x in res["measures"].values[0] if
|
||||||
|
x in ["internal_wall_insulation", "external_wall_insulation", "cavity_wall_insulation"]
|
||||||
|
]
|
||||||
|
|
||||||
|
hhr_recommendation = [
|
||||||
|
x for x in res["measures"].values[0] if
|
||||||
|
x in ["high_heat_retention_storage_heaters"]
|
||||||
|
]
|
||||||
|
|
||||||
|
possible_measures = [ast.literal_eval(x) for x in list(recommendations[p.id].keys())]
|
||||||
|
# Unlist them
|
||||||
|
possible_measures = [x for sublist in possible_measures for x in sublist]
|
||||||
|
possible_measures = list(set(possible_measures))
|
||||||
|
|
||||||
|
if wall_recommendation:
|
||||||
|
if len(wall_recommendation) > 1:
|
||||||
|
raise Exception("something went wrong")
|
||||||
|
wall_recommendation = wall_recommendation[0]
|
||||||
|
else:
|
||||||
|
wall_recommendation = None
|
||||||
|
|
||||||
|
hhr_recommendation = hhr_recommendation[0] if hhr_recommendation else None
|
||||||
|
|
||||||
|
walls_check.append(
|
||||||
|
{
|
||||||
|
"uprn": p.uprn,
|
||||||
|
"address": p.address,
|
||||||
|
"postcode": p.postcode,
|
||||||
|
"conservation_status": p.spatial["conservation_status"],
|
||||||
|
"is_listed_building": p.spatial["is_listed_building"],
|
||||||
|
"is_heritage_building": p.spatial["is_heritage_building"],
|
||||||
|
"wall": wall["clean_description"],
|
||||||
|
"recommendation": wall_recommendation,
|
||||||
|
"possible_measures": possible_measures,
|
||||||
|
"selected_measures": res["measures"].values[0],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
hhr_check.append(
|
||||||
|
{
|
||||||
|
"uprn": p.uprn,
|
||||||
|
"address": p.address,
|
||||||
|
"postcode": p.postcode,
|
||||||
|
"heating": heating["clean_description"],
|
||||||
|
"recommendation": hhr_recommendation,
|
||||||
|
"possible_measures": possible_measures,
|
||||||
|
"selected_measures": res["measures"].values[0],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
walls_check = pd.DataFrame(walls_check)
|
||||||
|
hhr_check = pd.DataFrame(hhr_check)
|
||||||
|
|
||||||
|
return walls_check, hhr_check
|
||||||
|
|
||||||
|
walls_check, hhr_check = check_mds(results, input_properties, recommendations)
|
||||||
|
|
||||||
results = []
|
results = []
|
||||||
for p in input_properties:
|
for p in input_properties:
|
||||||
measures = p.measures
|
measures = p.measures
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,12 @@ class HeatingRecommender:
|
||||||
ELECTRIC_HEATING_DESCRIPTIONS = [
|
ELECTRIC_HEATING_DESCRIPTIONS = [
|
||||||
"Room heaters, electric",
|
"Room heaters, electric",
|
||||||
"Electric storage heaters",
|
"Electric storage heaters",
|
||||||
"Electric storage heaters, radiators"
|
"Electric storage heaters, radiators",
|
||||||
|
"Portable electric heaters assumed for most rooms",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
high_heat_retention_contols_desc = "Controls for high heat retention storage heaters"
|
||||||
|
|
||||||
def __init__(self, property_instance: Property):
|
def __init__(self, property_instance: Property):
|
||||||
self.property = property_instance
|
self.property = property_instance
|
||||||
self.costs = Costs(self.property)
|
self.costs = Costs(self.property)
|
||||||
|
|
@ -31,12 +34,13 @@ class HeatingRecommender:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
no_heating_no_mains = (
|
# If the property has assumed electric heating, regardless of whether or not it has a mains connection, we
|
||||||
self.property.main_heating["clean_description"] in ["No system present, electric heaters assumed"] and
|
# can consider hhr storage heaters
|
||||||
not self.property.data["mains-gas-flag"]
|
electric_heating_assumed = (
|
||||||
|
self.property.main_heating["clean_description"] in ["No system present, electric heaters assumed"]
|
||||||
)
|
)
|
||||||
|
|
||||||
return self.has_electric_heating_description or no_heating_no_mains
|
return self.has_electric_heating_description or electric_heating_assumed
|
||||||
|
|
||||||
def recommend(self, has_cavity_or_loft_recommendations, phase=0):
|
def recommend(self, has_cavity_or_loft_recommendations, phase=0):
|
||||||
"""
|
"""
|
||||||
|
|
@ -330,6 +334,25 @@ class HeatingRecommender:
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
def is_hhr_already_installed(self):
|
||||||
|
"""
|
||||||
|
Check if the property already has high heat retention storage heaters
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
already_has_hhr = "Electric storage heaters" in self.property.main_heating["clean_description"]
|
||||||
|
already_has_hhr_contols = (
|
||||||
|
self.property.main_heating_controls[
|
||||||
|
"clean_description"
|
||||||
|
].lower() == self.high_heat_retention_contols_desc.lower()
|
||||||
|
)
|
||||||
|
|
||||||
|
# Conditions for not needing this recommendation
|
||||||
|
# Modern hhr storage heaters will have the specific controls so we can check for this
|
||||||
|
already_installed_hh_retention = already_has_hhr and already_has_hhr_contols
|
||||||
|
|
||||||
|
return already_installed_hh_retention
|
||||||
|
|
||||||
def recommend_hhr_storage_heaters(self, phase, system_change, heating_controls_only, _return=False):
|
def recommend_hhr_storage_heaters(self, phase, system_change, heating_controls_only, _return=False):
|
||||||
"""
|
"""
|
||||||
We will recommend upgrading to a high heat retention storage system, if the current system is not already
|
We will recommend upgrading to a high heat retention storage system, if the current system is not already
|
||||||
|
|
@ -346,19 +369,13 @@ class HeatingRecommender:
|
||||||
|
|
||||||
controls_recommender = HeatingControlRecommender(self.property)
|
controls_recommender = HeatingControlRecommender(self.property)
|
||||||
# The heating controls we're recommending for are based on the recommended heating system
|
# The heating controls we're recommending for are based on the recommended heating system
|
||||||
high_heat_retention_contols_desc = "Controls for high heat retention storage heaters"
|
|
||||||
# We only recommend Celect-type controls if the current heating system is not Celect-type controls
|
# We only recommend Celect-type controls if the current heating system is not Celect-type controls
|
||||||
if self.property.main_heating_controls["clean_description"] != high_heat_retention_contols_desc:
|
if self.property.main_heating_controls["clean_description"] != self.high_heat_retention_contols_desc:
|
||||||
controls_recommender.recommend(heating_description="Electric storage heaters, radiators")
|
controls_recommender.recommend(heating_description="Electric storage heaters, radiators")
|
||||||
|
|
||||||
# Conditions for not needing this recommendation
|
|
||||||
already_installed_hh_retention = (
|
|
||||||
"Electric storage heaters" in self.property.main_heating["clean_description"] and
|
|
||||||
self.property.main_heating_controls["clean_description"].lower() == high_heat_retention_contols_desc.lower()
|
|
||||||
)
|
|
||||||
|
|
||||||
# Conditions for not recommending electric storage heaters
|
# Conditions for not recommending electric storage heaters
|
||||||
if already_installed_hh_retention:
|
if self.is_hhr_already_installed():
|
||||||
# No recommendation needed
|
# No recommendation needed
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@ class Mds:
|
||||||
final_combinations.append([m for m in one_choice + multi_path + remaining_measures])
|
final_combinations.append([m for m in one_choice + multi_path + remaining_measures])
|
||||||
|
|
||||||
pruned_combinations = []
|
pruned_combinations = []
|
||||||
|
# TODO: We can do these checks once, outside of the loop and prune the combinations
|
||||||
for combination in final_combinations:
|
for combination in final_combinations:
|
||||||
pruned_measures = []
|
pruned_measures = []
|
||||||
for measure in combination:
|
for measure in combination:
|
||||||
|
|
@ -142,10 +143,12 @@ class Mds:
|
||||||
|
|
||||||
if measure == "loft_insulation":
|
if measure == "loft_insulation":
|
||||||
# Check if the roof is suitable for loft insulation and the loft isn't already done
|
# 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 (
|
if (
|
||||||
self.property_instance.roof["is_pitched"] and
|
self.property_instance.roof["is_pitched"] and
|
||||||
not self.roof_recommender.is_loft_already_insulated()
|
not self.roof_recommender.is_loft_already_insulated() and
|
||||||
) or self.property_instance.is_mid_floor_flat():
|
self.property_instance.roof["thermal_transmittance_unit"] is None
|
||||||
|
):
|
||||||
pruned_measures.append(measure)
|
pruned_measures.append(measure)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
@ -153,8 +156,9 @@ class Mds:
|
||||||
# Check if the floor is solid
|
# Check if the floor is solid
|
||||||
if (
|
if (
|
||||||
self.property_instance.floor["is_solid"] and
|
self.property_instance.floor["is_solid"] and
|
||||||
self.property_instance.floor["insulation_thickness"] not in ["average", "above average"]
|
self.property_instance.floor["insulation_thickness"] not in ["average", "above average"] and
|
||||||
) or self.property_instance.is_mid_floor_flat():
|
self.property_instance.floor["thermal_transmittance_unit"] is not None
|
||||||
|
):
|
||||||
pruned_measures.append(measure)
|
pruned_measures.append(measure)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
@ -162,13 +166,17 @@ class Mds:
|
||||||
# Check if the floor is suspended
|
# Check if the floor is suspended
|
||||||
if (
|
if (
|
||||||
self.property_instance.floor["is_suspended"] and
|
self.property_instance.floor["is_suspended"] and
|
||||||
self.property_instance.floor["insulation_thickness"] not in ["average", "above average"]
|
self.property_instance.floor["insulation_thickness"] not in ["average", "above average"] and
|
||||||
) or self.property_instance.is_mid_floor_flat():
|
self.property_instance.floor["thermal_transmittance_unit"] is not None
|
||||||
|
):
|
||||||
pruned_measures.append(measure)
|
pruned_measures.append(measure)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if measure == "high_heat_retention_storage_heaters":
|
if measure == "high_heat_retention_storage_heaters":
|
||||||
if self.heating_recommender.is_high_heat_retention_valid():
|
if (
|
||||||
|
self.heating_recommender.is_high_heat_retention_valid() and
|
||||||
|
not self.heating_recommender.is_hhr_already_installed()
|
||||||
|
):
|
||||||
pruned_measures.append(measure)
|
pruned_measures.append(measure)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue