adding ventilation handling to prevent extremem values

This commit is contained in:
Khalim Conn-Kowlessar 2025-12-28 16:26:21 +08:00
parent aa515a9797
commit ff5bc2f834
2 changed files with 43 additions and 6 deletions

View file

@ -980,12 +980,12 @@ async def model_engine(body: PlanTriggerRequest):
logger.info("Preparing data for scoring in sap change api")
recommendations_scoring_data = pd.DataFrame(recommendations_scoring_data)
# Temp putting this here
recommendations_scoring_data["is_post_sap10_ending"] = True
recommendations_scoring_data = recommendations_scoring_data.drop(
columns=[
"rdsap_change", "heat_demand_change", "carbon_change", "sap_ending", "heat_demand_ending",
"carbon_ending"
]
columns=["rdsap_change", "heat_demand_change", "carbon_change", "sap_ending", "heat_demand_ending",
"carbon_ending"]
)
all_predictions = await model_api.async_paginated_predictions(

View file

@ -615,7 +615,7 @@ class Recommendations:
if metric == "sap":
property_phase_impact[metric] = round(property_phase_impact[metric], 2)
else:
# We prevent these from being positive
# We prevent mechanical ventilation from being positive
property_phase_impact[metric] = (
0 if property_phase_impact[metric] > 0 else property_phase_impact[metric]
)
@ -632,6 +632,38 @@ class Recommendations:
property_phase_impact["carbon"], rec["co2_equivalent_savings"]
)
# Update the current phase values
current_phase_values["sap"] = previous_phase_values["sap"] + property_phase_impact["sap"]
current_phase_values["carbon"] = previous_phase_values["carbon"] - property_phase_impact["carbon"]
# We also ensure that mechanical ventilation doesn't have an ovely strong negative SAP impact
if rec["type"] == "mechanical_ventilation":
# ventilation is capped by having no greater and a -4 impact
ventilation_sap_limit = -4
def _check_veniltation_out_of_bounds(sap_impact):
return (sap_impact < ventilation_sap_limit) or (sap_impact >= 0)
def _adjust_ventilation_sap(sap_impact):
if sap_impact >= 0:
return -1
if sap_impact < ventilation_sap_limit:
return ventilation_sap_limit
ventilation_out_of_bounds = _check_veniltation_out_of_bounds(property_phase_impact["sap"])
if ventilation_out_of_bounds:
previous_modelled_sap = previous_phase_values.get("sap_prediction", 0)
proposed_sap_impact = current_phase_sap - previous_modelled_sap
proposal_out_of_bounds = _check_veniltation_out_of_bounds(proposed_sap_impact)
if proposal_out_of_bounds:
property_phase_impact["sap"] = _adjust_ventilation_sap(proposed_sap_impact)
else:
property_phase_impact["sap"] = proposed_sap_impact
# Update the current phase values
current_phase_values["sap"] = previous_phase_values["sap"] + property_phase_impact["sap"]
if rec["type"] == "loft_insulation":
# When we have a loft insulation recommendation, where there is an extension and the existing
# amount of loft insulation is already good, we limit the SAP points
@ -642,6 +674,8 @@ class Recommendations:
)
if li_sap_limit is not None:
property_phase_impact["sap"] = min(property_phase_impact["sap"], li_sap_limit)
# Update the current phase values
current_phase_values["sap"] = previous_phase_values["sap"] + property_phase_impact["sap"]
if rec["type"] == "solar_pv":
# We use the SAP points in the recommendation as a minimum
@ -649,6 +683,8 @@ class Recommendations:
rec["sap_points"] if property_phase_impact["sap"] < rec["sap_points"] else
property_phase_impact["sap"]
)
# Update the current phase values
current_phase_values["sap"] = previous_phase_values["sap"] + property_phase_impact["sap"]
# Insert this information into the recommendation.
if not rec.get("survey", False):
@ -669,7 +705,8 @@ class Recommendations:
"representative": rec["recommendation_id"] in representative_ids,
"recommendation_id": rec["recommendation_id"],
"measure_type": rec["measure_type"],
**current_phase_values
**current_phase_values,
"sap_prediction": phase_energy_efficiency_metrics["sap_change"]
}
)