mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
tweaking heating rec logic
This commit is contained in:
parent
f732ce0be5
commit
87c36a80d3
4 changed files with 74 additions and 39 deletions
|
|
@ -438,6 +438,10 @@ class Property:
|
|||
|
||||
# Replace the understores with hyphens
|
||||
simulation_epc = {k.replace("_", "-"): v for k, v in simulation_epc.items()}
|
||||
# Add in today's costs (unadjusted
|
||||
simulation_epc["heating-cost-current"] = int(self.energy_cost_estimates["unadjusted"]["heating"])
|
||||
simulation_epc["hot-water-cost-current"] = int(self.energy_cost_estimates["unadjusted"]["hot_water"])
|
||||
simulation_epc["lighting-cost-current"] = int(self.energy_cost_estimates["unadjusted"]["lighting"])
|
||||
simulation_epc.update(phase_epc_transformation)
|
||||
self.simulation_epcs[phase] = simulation_epc
|
||||
|
||||
|
|
|
|||
|
|
@ -62,8 +62,6 @@ class HeatingRecommender:
|
|||
{"suitable": True}
|
||||
)
|
||||
# We allow for the non-invasive recommendation to be that ASHP is not suitable
|
||||
if not non_invasive_ashp_recommendation["suitable"]:
|
||||
return
|
||||
|
||||
# This option will prevent other heating recommendations from being specified, other than an ASHP
|
||||
ashp_only_heating_recommendation = non_invasive_ashp_recommendation.get(
|
||||
|
|
@ -127,7 +125,7 @@ class HeatingRecommender:
|
|||
# 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
|
||||
|
||||
if self.property.is_ashp_valid(exclusions=exclusions):
|
||||
if self.property.is_ashp_valid(exclusions=exclusions) and non_invasive_ashp_recommendation["suitable"]:
|
||||
self.recommend_air_source_heat_pump(
|
||||
phase=phase,
|
||||
has_cavity_or_loft_recommendations=has_cavity_or_loft_recommendations,
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ class Recommendations:
|
|||
float(property_instance.data["energy-consumption-current"]) - new_heat_demand
|
||||
)
|
||||
|
||||
if rec["type"] == "lighting":
|
||||
if rec["type"] == "low_energy_lighting":
|
||||
new_heating_cost = property_instance.energy_cost_estimates["adjusted"]["heating"]
|
||||
new_hot_water_cost = property_instance.energy_cost_estimates["adjusted"]["hot_water"]
|
||||
new_lighting_cost = min(
|
||||
|
|
@ -556,10 +556,12 @@ class Recommendations:
|
|||
new_heating_kwh = energy_consumption_client.score_new_data(
|
||||
new_data=scoring_df, target="heating_kwh"
|
||||
)[0]
|
||||
new_heating_kwh = 0 if new_heating_kwh < 0 else new_heating_kwh
|
||||
|
||||
new_hot_water_kwh = energy_consumption_client.score_new_data(
|
||||
new_data=scoring_df, target="hot_water_kwh"
|
||||
)[0]
|
||||
new_hot_water_kwh = 0 if new_hot_water_kwh < 0 else new_hot_water_kwh
|
||||
|
||||
# Adjust these figures
|
||||
new_heating_kwh_adjusted = AnnualBillSavings.adjust_energy_to_metered(
|
||||
|
|
|
|||
|
|
@ -405,18 +405,23 @@ class RoofRecommendations:
|
|||
:return:
|
||||
"""
|
||||
|
||||
roof_roof_insulation_materials = [m for m in self.materials if m["type"] == "room_roof_insulation"]
|
||||
if not roof_roof_insulation_materials:
|
||||
raise ValueError("No room in roof insulation materials found")
|
||||
# TODO: We temporarilty use costs from SCIS for RIR insulation. The costing was £180/m2 floor
|
||||
roof_roof_insulation_materials = [
|
||||
{
|
||||
"type": "room_roof_insulation",
|
||||
"description": "Insulating the ceiling of the roof roof and re-decorate",
|
||||
"depths": [100],
|
||||
"depth_unit": "mm",
|
||||
"r_value_per_mm": 0.038,
|
||||
"thermal_conductivity": 0.022,
|
||||
"cost": [180],
|
||||
}
|
||||
]
|
||||
|
||||
if self.property.pitched_roof_area is None:
|
||||
raise ValueError("pitched_roof_area not included as property attribute")
|
||||
|
||||
lowest_selected_u_value = None
|
||||
# lowest_selected_u_value = None
|
||||
recommendations = []
|
||||
for material in roof_roof_insulation_materials:
|
||||
for depth, cost_per_unit in zip(material["depths"], material["cost"]):
|
||||
|
||||
part_u_value = r_value_per_mm_to_u_value(depth, material["r_value_per_mm"])
|
||||
|
||||
_, new_u_value = calculate_u_value_uplift(u_value, part_u_value)
|
||||
|
|
@ -428,36 +433,62 @@ class RoofRecommendations:
|
|||
# If I have a lowest U value and my new u value is lower than the lowest value, it's
|
||||
# further into the diminishing returns threshold and can shouldn't be
|
||||
|
||||
if is_diminishing_returns(
|
||||
recommendations, new_u_value, lowest_selected_u_value, self.DIMINISHING_RETURNS_U_VALUE
|
||||
):
|
||||
continue
|
||||
# if is_diminishing_returns(
|
||||
# recommendations, new_u_value, lowest_selected_u_value, self.DIMINISHING_RETURNS_U_VALUE
|
||||
# ):
|
||||
# continue
|
||||
|
||||
# We allow a small tolerance for error so we don't discount the recommendation entirely
|
||||
if new_u_value <= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
|
||||
lowest_selected_u_value = update_lowest_selected_u_value(lowest_selected_u_value, new_u_value)
|
||||
# if new_u_value <= self.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE:
|
||||
# lowest_selected_u_value = update_lowest_selected_u_value(lowest_selected_u_value, new_u_value)
|
||||
|
||||
estimated_cost = cost_per_unit * self.property.pitched_roof_area
|
||||
estimated_cost = cost_per_unit * self.property.insulation_floor_area
|
||||
|
||||
recommendations.append(
|
||||
{
|
||||
"phase": phase,
|
||||
"parts": [
|
||||
get_recommended_part(
|
||||
part=material,
|
||||
selected_depth=depth,
|
||||
quantity=self.property.pitched_roof_area,
|
||||
quantity_unit=QuantityUnits.m2.value,
|
||||
selected_total_cost=estimated_cost
|
||||
)
|
||||
],
|
||||
"type": "room_roof_insulation",
|
||||
"description": self.make_room_roof_insulation_description(material, depth),
|
||||
"starting_u_value": u_value,
|
||||
"new_u_value": new_u_value,
|
||||
"sap_points": None,
|
||||
"cost": estimated_cost,
|
||||
}
|
||||
)
|
||||
# Could also be Roof room(s), ceiling insulated
|
||||
new_descriptin = "Pitched, insulated at rafters"
|
||||
roof_ending_config = RoofAttributes(new_descriptin).process()
|
||||
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"]:
|
||||
new_efficiency = "Average"
|
||||
else:
|
||||
new_efficiency = self.property.data["roof-energy-eff"]
|
||||
|
||||
simulation_config = {
|
||||
**roof_simulation_config,
|
||||
"roof_thermal_transmittance_ending": new_u_value,
|
||||
"roof_energy_eff_ending": new_efficiency
|
||||
}
|
||||
|
||||
already_installed = "flat_roof_insulation" in self.property.already_installed
|
||||
cost_result = {
|
||||
"total": estimated_cost,
|
||||
"labour_hours": 80,
|
||||
"labour_days": 5,
|
||||
}
|
||||
if already_installed:
|
||||
cost_result = override_costs(cost_result)
|
||||
|
||||
recommendations.append(
|
||||
{
|
||||
"phase": phase,
|
||||
"parts": [
|
||||
# TODO
|
||||
],
|
||||
"type": "room_roof_insulation",
|
||||
"description": "Insulate room in roof at rafters and re-decorate",
|
||||
"starting_u_value": u_value,
|
||||
"new_u_value": None,
|
||||
"sap_points": None,
|
||||
"simulation_config": simulation_config,
|
||||
"description_simulation": {
|
||||
"roof-description": new_descriptin,
|
||||
"roof-energy-eff": new_efficiency
|
||||
},
|
||||
**cost_result,
|
||||
"already_installed": already_installed
|
||||
}
|
||||
)
|
||||
|
||||
self.recommendations = recommendations
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue