mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +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
|
# Replace the understores with hyphens
|
||||||
simulation_epc = {k.replace("_", "-"): v for k, v in simulation_epc.items()}
|
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)
|
simulation_epc.update(phase_epc_transformation)
|
||||||
self.simulation_epcs[phase] = simulation_epc
|
self.simulation_epcs[phase] = simulation_epc
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,8 +62,6 @@ class HeatingRecommender:
|
||||||
{"suitable": True}
|
{"suitable": True}
|
||||||
)
|
)
|
||||||
# We allow for the non-invasive recommendation to be that ASHP is not suitable
|
# 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
|
# This option will prevent other heating recommendations from being specified, other than an ASHP
|
||||||
ashp_only_heating_recommendation = non_invasive_ashp_recommendation.get(
|
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
|
# 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):
|
if self.property.is_ashp_valid(exclusions=exclusions) 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,
|
||||||
|
|
|
||||||
|
|
@ -488,7 +488,7 @@ class Recommendations:
|
||||||
float(property_instance.data["energy-consumption-current"]) - new_heat_demand
|
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_heating_cost = property_instance.energy_cost_estimates["adjusted"]["heating"]
|
||||||
new_hot_water_cost = property_instance.energy_cost_estimates["adjusted"]["hot_water"]
|
new_hot_water_cost = property_instance.energy_cost_estimates["adjusted"]["hot_water"]
|
||||||
new_lighting_cost = min(
|
new_lighting_cost = min(
|
||||||
|
|
@ -556,10 +556,12 @@ class Recommendations:
|
||||||
new_heating_kwh = energy_consumption_client.score_new_data(
|
new_heating_kwh = energy_consumption_client.score_new_data(
|
||||||
new_data=scoring_df, target="heating_kwh"
|
new_data=scoring_df, target="heating_kwh"
|
||||||
)[0]
|
)[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_hot_water_kwh = energy_consumption_client.score_new_data(
|
||||||
new_data=scoring_df, target="hot_water_kwh"
|
new_data=scoring_df, target="hot_water_kwh"
|
||||||
)[0]
|
)[0]
|
||||||
|
new_hot_water_kwh = 0 if new_hot_water_kwh < 0 else new_hot_water_kwh
|
||||||
|
|
||||||
# Adjust these figures
|
# Adjust these figures
|
||||||
new_heating_kwh_adjusted = AnnualBillSavings.adjust_energy_to_metered(
|
new_heating_kwh_adjusted = AnnualBillSavings.adjust_energy_to_metered(
|
||||||
|
|
|
||||||
|
|
@ -405,18 +405,23 @@ class RoofRecommendations:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
roof_roof_insulation_materials = [m for m in self.materials if m["type"] == "room_roof_insulation"]
|
# TODO: We temporarilty use costs from SCIS for RIR insulation. The costing was £180/m2 floor
|
||||||
if not roof_roof_insulation_materials:
|
roof_roof_insulation_materials = [
|
||||||
raise ValueError("No room in roof insulation materials found")
|
{
|
||||||
|
"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:
|
# lowest_selected_u_value = None
|
||||||
raise ValueError("pitched_roof_area not included as property attribute")
|
|
||||||
|
|
||||||
lowest_selected_u_value = None
|
|
||||||
recommendations = []
|
recommendations = []
|
||||||
for material in roof_roof_insulation_materials:
|
for material in roof_roof_insulation_materials:
|
||||||
for depth, cost_per_unit in zip(material["depths"], material["cost"]):
|
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"])
|
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)
|
_, 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
|
# 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
|
# further into the diminishing returns threshold and can shouldn't be
|
||||||
|
|
||||||
if is_diminishing_returns(
|
# if is_diminishing_returns(
|
||||||
recommendations, new_u_value, lowest_selected_u_value, self.DIMINISHING_RETURNS_U_VALUE
|
# recommendations, new_u_value, lowest_selected_u_value, self.DIMINISHING_RETURNS_U_VALUE
|
||||||
):
|
# ):
|
||||||
continue
|
# continue
|
||||||
|
|
||||||
# We allow a small tolerance for error so we don't discount the recommendation entirely
|
# 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:
|
# 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)
|
# 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(
|
# Could also be Roof room(s), ceiling insulated
|
||||||
{
|
new_descriptin = "Pitched, insulated at rafters"
|
||||||
"phase": phase,
|
roof_ending_config = RoofAttributes(new_descriptin).process()
|
||||||
"parts": [
|
roof_simulation_config = check_simulation_difference(
|
||||||
get_recommended_part(
|
new_config=roof_ending_config, old_config=self.property.roof, prefix="roof_"
|
||||||
part=material,
|
)
|
||||||
selected_depth=depth,
|
if self.property.data["roof-energy-eff"] in ["Very Poor", "Poor"]:
|
||||||
quantity=self.property.pitched_roof_area,
|
new_efficiency = "Average"
|
||||||
quantity_unit=QuantityUnits.m2.value,
|
else:
|
||||||
selected_total_cost=estimated_cost
|
new_efficiency = self.property.data["roof-energy-eff"]
|
||||||
)
|
|
||||||
],
|
simulation_config = {
|
||||||
"type": "room_roof_insulation",
|
**roof_simulation_config,
|
||||||
"description": self.make_room_roof_insulation_description(material, depth),
|
"roof_thermal_transmittance_ending": new_u_value,
|
||||||
"starting_u_value": u_value,
|
"roof_energy_eff_ending": new_efficiency
|
||||||
"new_u_value": new_u_value,
|
}
|
||||||
"sap_points": None,
|
|
||||||
"cost": estimated_cost,
|
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
|
self.recommendations = recommendations
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue