mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
adding non-intrusive sap points and survey flag pick up for multiple recommendations
This commit is contained in:
parent
3e8a1bc4fd
commit
477504abd1
8 changed files with 60 additions and 11 deletions
|
|
@ -426,6 +426,18 @@ class Property:
|
|||
if phase_epc_transformation[k] == v:
|
||||
continue
|
||||
|
||||
if k == "hotwater-description":
|
||||
if (
|
||||
v == "From main system"
|
||||
) and (
|
||||
phase_epc_transformation["mainheat-description"] == "Electric storage heaters"
|
||||
) and (
|
||||
"Electric immersion" in phase_epc_transformation["hotwater-description"]
|
||||
):
|
||||
# It means we've recommended HHR with electric immersion, and shouldn't overwrite
|
||||
# the hot water description
|
||||
continue
|
||||
|
||||
raise NotImplementedError(
|
||||
"Already have this key in the phase_epc_transformation - implement me"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -50,4 +50,5 @@ DESCRIPTIONS_TO_FUEL_TYPES = {
|
|||
},
|
||||
"Gas instantaneous at point of use": {"fuel": "Natural Gas", "cop": 0.85},
|
||||
"Room heaters, wood logs": {"fuel": "Wood Logs", "cop": 1},
|
||||
"Boiler and radiators, coal": {"fuel": "Coal", "cop": 0.85},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ def app():
|
|||
asset_list["uprn"] = asset_list["uprn"].astype(int)
|
||||
|
||||
extracted_data = []
|
||||
model_asset_list = []
|
||||
for _, home in tqdm(asset_list.iterrows(), total=len(asset_list)):
|
||||
add1 = home["address1"]
|
||||
pc = home["postcode"]
|
||||
|
|
@ -63,6 +64,14 @@ def app():
|
|||
}
|
||||
)
|
||||
|
||||
model_asset_list.append(
|
||||
{
|
||||
"uprn": home["uprn"],
|
||||
"address": epc_searcher.newest_epc["address1"],
|
||||
"postcode": epc_searcher.newest_epc["postcode"],
|
||||
}
|
||||
)
|
||||
|
||||
non_invasive_recommendations = [
|
||||
{
|
||||
"uprn": r["uprn"],
|
||||
|
|
@ -72,7 +81,7 @@ def app():
|
|||
|
||||
filename = f"{USER_ID}/{PORTFOLIO_ID}/asset_list.csv"
|
||||
save_csv_to_s3(
|
||||
dataframe=pd.DataFrame(asset_list),
|
||||
dataframe=pd.DataFrame(model_asset_list),
|
||||
bucket_name="retrofit-plan-inputs-dev",
|
||||
file_name=filename
|
||||
)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ class DraughtProofingRecommendations:
|
|||
if not draught_proofing_recommendation_config:
|
||||
return
|
||||
|
||||
# Cost is based on a £50 cost per window, based on Checkatrade
|
||||
cost = draught_proofing_recommendation_config.get("cost", self.property.number_of_windows * 50)
|
||||
|
||||
description = (
|
||||
"Draught proof doors and windows to improve energy efficiency" if
|
||||
not draught_proofing_recommendation_config.get("description")
|
||||
|
|
@ -48,7 +51,7 @@ class DraughtProofingRecommendations:
|
|||
"kwh_savings": 0,
|
||||
"co2_equivalent_savings": 0,
|
||||
"energy_cost_savings": 0,
|
||||
"total": draught_proofing_recommendation_config["cost"],
|
||||
"total": cost,
|
||||
# We use a very simple and rough estimate of 4 hours per unit
|
||||
"labour_hours": draught_proofing_recommendation_config.get("labour_hours", 8),
|
||||
"labour_days": draught_proofing_recommendation_config.get("labour_days", 1), # Assume 8 hour day
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import re
|
||||
import backend.app.assumptions as assumptions
|
||||
from etl.customers.immo.pilot.asset_list import non_invasive_recommendations
|
||||
from recommendations.Costs import Costs, BOILER_UPGRADE_SCHEME_ASHP_VALUE
|
||||
from recommendations.recommendation_utils import (
|
||||
check_simulation_difference, override_costs, combine_recommendation_configs
|
||||
|
|
@ -981,6 +982,10 @@ class HeatingRecommender:
|
|||
self.property.data["hot-water-energy-eff"] in ["Very Poor", "Poor", "Average"]
|
||||
)
|
||||
|
||||
non_invasive_recommendation = next((
|
||||
r for r in self.property.non_invasive_recommendations if r["type"] == "boiler_upgrade"
|
||||
), {})
|
||||
|
||||
if has_inefficient_space_heating or has_inefficient_water:
|
||||
boiler_size = self.estimate_boiler_size(
|
||||
property_type=self.property.data["property-type"],
|
||||
|
|
@ -1079,12 +1084,13 @@ class HeatingRecommender:
|
|||
"description": description,
|
||||
"starting_u_value": None,
|
||||
"new_u_value": None,
|
||||
"sap_points": None,
|
||||
"sap_points": non_invasive_recommendation.get("sap_points", None),
|
||||
"already_installed": already_installed,
|
||||
"simulation_config": simulation_config,
|
||||
"description_simulation": description_simulation,
|
||||
**boiler_costs,
|
||||
"system_type": "boiler_upgrade",
|
||||
"survey": non_invasive_recommendation.get("survey", None)
|
||||
}
|
||||
|
||||
# We recommend the heating controls
|
||||
|
|
@ -1105,6 +1111,11 @@ class HeatingRecommender:
|
|||
if not controls_recommender.recommendation and not boiler_recommendation:
|
||||
return
|
||||
|
||||
# If this is true, we set SAP points to None and survey to False for the boiler recommendation
|
||||
if boiler_recommendation:
|
||||
boiler_recommendation["sap_points"] = None
|
||||
boiler_recommendation["survey"] = False
|
||||
|
||||
if not system_change and len(boiler_recommendation):
|
||||
# If there is not a system change, we add the boiler recommendation at point.
|
||||
self.heating_recommendations.extend([boiler_recommendation])
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ class HotwaterRecommendations:
|
|||
:return:
|
||||
"""
|
||||
# Reset the recommendations
|
||||
recommendations_phase = phase
|
||||
|
||||
self.recommendations = []
|
||||
non_invasive_recommendations = self.property.non_invasive_recommendations
|
||||
if non_invasive_recommendations:
|
||||
|
|
@ -28,7 +30,6 @@ class HotwaterRecommendations:
|
|||
r["type"] in ["hot_water_tank_insulation", "cylinder_thermostat"]
|
||||
]
|
||||
|
||||
recommendations_phase = phase
|
||||
for m in measures:
|
||||
non_invasive_rec = [
|
||||
r for r in non_invasive_recommendations if r["type"] == m
|
||||
|
|
@ -55,7 +56,7 @@ class HotwaterRecommendations:
|
|||
|
||||
if self.property.hotwater["clean_description"] == "Gas boiler/circulator, no cylinder thermostat":
|
||||
# Handle this case specifically:
|
||||
self.recommend_cylinder_thermostat_gas_boiler_circulator(phase=phase)
|
||||
self.recommend_cylinder_thermostat_gas_boiler_circulator(phase=recommendations_phase)
|
||||
return
|
||||
|
||||
# If there is no system present, but access to the mains, we
|
||||
|
|
@ -68,14 +69,14 @@ class HotwaterRecommendations:
|
|||
(self.property.hotwater["no_system_present"] is None) &
|
||||
(len(has_tank_recommendation) == 0)
|
||||
):
|
||||
self.recommend_tank_insulation(phase=phase)
|
||||
self.recommend_tank_insulation(phase=recommendations_phase)
|
||||
return
|
||||
|
||||
has_cylinder_recommendation = [r for r in self.recommendations if r["type"] == "cylinder_thermostat"]
|
||||
|
||||
if ((self.property.hotwater["clean_description"] == "From main system, no cylinder thermostat") &
|
||||
(len(has_cylinder_recommendation) == 0)):
|
||||
self.recommend_cylinder_thermostat(phase=phase)
|
||||
self.recommend_cylinder_thermostat(phase=recommendations_phase)
|
||||
return
|
||||
|
||||
def recommend_tank_insulation(self, phase, sap_points=None, survey=False, _return=False):
|
||||
|
|
|
|||
|
|
@ -290,6 +290,11 @@ class RoofRecommendations:
|
|||
|
||||
insulation_materials = pd.DataFrame(insulation_materials)
|
||||
|
||||
non_invasive_recommendations = next(
|
||||
(r for r in self.property.non_invasive_recommendations if
|
||||
r["type"] == insulation_materials["type"].values[0]), {}
|
||||
)
|
||||
|
||||
lowest_selected_u_value = None
|
||||
recommendations = []
|
||||
for _, insulation_material_group in insulation_materials.groupby("description"):
|
||||
|
|
@ -429,14 +434,15 @@ class RoofRecommendations:
|
|||
"description": self.make_roof_insulation_description(material),
|
||||
"starting_u_value": u_value,
|
||||
"new_u_value": new_u_value,
|
||||
"sap_points": None,
|
||||
"sap_points": non_invasive_recommendations.get("sap_points", 0),
|
||||
"already_installed": already_installed,
|
||||
"simulation_config": simulation_config,
|
||||
"description_simulation": {
|
||||
"roof-description": new_description,
|
||||
"roof-energy-eff": new_efficiency
|
||||
},
|
||||
**cost_result
|
||||
**cost_result,
|
||||
"survey": non_invasive_recommendations.get("survey", False)
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -385,6 +385,11 @@ class WallRecommendations(Definitions):
|
|||
if insulation_thickness == "below average":
|
||||
cavity_width = cavity_width * (1 - PARTIALLY_FILLED_PERCENTAGE_ASSUMPTION)
|
||||
|
||||
non_invasive_recommendations = next(
|
||||
(r for r in self.property.non_invasive_recommendations if
|
||||
r["type"] == insulation_materials["type"].values[0]), {}
|
||||
)
|
||||
|
||||
# Test the different fill options
|
||||
lowest_selected_u_value = None
|
||||
recommendations = []
|
||||
|
|
@ -475,14 +480,15 @@ class WallRecommendations(Definitions):
|
|||
"description": description,
|
||||
"starting_u_value": u_value,
|
||||
"new_u_value": new_u_value,
|
||||
"sap_points": None,
|
||||
"sap_points": non_invasive_recommendations.get("sap_points", None),
|
||||
"already_installed": already_installed,
|
||||
"simulation_config": simulation_config,
|
||||
"description_simulation": {
|
||||
"walls-description": "Cavity wall, filled cavity",
|
||||
"walls-energy-eff": "Good"
|
||||
},
|
||||
**cost_result
|
||||
**cost_result,
|
||||
"survey": non_invasive_recommendations.get("survey", False)
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue