From 25c07fdc52f4c5b9b60199566a340ed3cfc5262c Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Wed, 7 Aug 2024 17:56:07 +0100 Subject: [PATCH] updating recommender update --- backend/Property.py | 3 ++ backend/app/plan/router.py | 4 ++- recommendations/Recommendations.py | 54 +++++++++++++++--------------- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/backend/Property.py b/backend/Property.py index b040ffee..a5346643 100644 --- a/backend/Property.py +++ b/backend/Property.py @@ -475,6 +475,9 @@ class Property: "lighting-cost-current": phase_impact["unadjusted_lighting_cost"], } ) + updated_simulation_epcs.append(sim_epc) + + return updated_simulation_epcs @staticmethod def create_recommendation_scoring_data( diff --git a/backend/app/plan/router.py b/backend/app/plan/router.py index b2c235d3..e4759b7d 100644 --- a/backend/app/plan/router.py +++ b/backend/app/plan/router.py @@ -802,6 +802,7 @@ async def trigger_plan(body: PlanTriggerRequest): # cylinder jacket), we should add these to the recommendations as default raise Exception("Add the cost impacts into the cost model") logger.info("Optimising recommendations") + scoring_epcs = [] # For scoring the kwh models for property_id in recommendations.keys(): property_instance = [p for p in input_properties if p.id == property_id][0] @@ -816,7 +817,8 @@ async def trigger_plan(body: PlanTriggerRequest): # We use the impact_summary to update the simulation_epcs with the new SAP, heat demand, carbon, cost etc # at each phase - property_instance.update_simulation_epcs(impact_summary) + property_scoring_epcs = property_instance.update_simulation_epcs(impact_summary) + scoring_epcs.extend(property_scoring_epcs) input_measures = prepare_input_measures(recommendations_with_impact, body.goal) diff --git a/recommendations/Recommendations.py b/recommendations/Recommendations.py index c099c8a3..67d38528 100644 --- a/recommendations/Recommendations.py +++ b/recommendations/Recommendations.py @@ -432,32 +432,19 @@ class Recommendations: # We structure this so that depending on the phase, we capture the previous phase impacts and # then just have one piece of code to calculate the difference if rec["phase"] == 0: + # These are just the starting values, from the EPC. When we score the ML models, + # heating_cost_starting and heating_cost_ending are just the values in the EPC. However, with + # heating_cost_ending, we expect that the EPC will predict a heating cost based on what would happen + # if we implemented the recommendation today, so our starting value is the EPC previous_phase_values = { "sap": float(property_instance.data["current-energy-efficiency"]), "carbon": float(property_instance.data["co2-emissions-current"]), "heat_demand": float(property_instance.data["energy-consumption-current"]), + "epc_heating_cost": float(property_instance.data["heating-cost-current"]), + "epc_hot_water_cost": float(property_instance.data["hot-water-cost-current"]), + "epc_lighting_cost": float(property_instance.data["lighting-cost-current"]) } - if rec["type"] == "low_energy_lighting": - # In this instance, heating cost and hot water cost should not change so we set the previous - # value to the new one, so the difference is zero - previous_phase_unadjusted_costs = { - "unadjusted_heating_cost": phase_cost["heating_cost"]["predictions"].values[0], - "unadjusted_hot_water_cost": phase_cost["hot_water_cost"]["predictions"].values[0], - "unadjusted_lighting_cost": ( - property_instance.energy_cost_estimates["unadjusted"]["lighting"] - ) - } - else: - # If the recommendaiton is not for low energy lighting, we expect the heating/hot water - # costs to change but not te lighting - previous_phase_unadjusted_costs = { - "unadjusted_heating_cost": property_instance.energy_cost_estimates["adjusted"]["heating"], - "unadjusted_hot_water_cost": ( - property_instance.energy_cost_estimates["adjusted"]["hot_water"] - ), - "unadjusted_lighting_cost": phase_cost["lighting_cost"]["predictions"].values[0] - } else: previous_phase_values = { "sap": ( @@ -497,8 +484,6 @@ class Recommendations: "unadjusted_lighting_cost": phase_cost["lighting_cost"]["predictions"].values[0] } - previous_phase_values.update(previous_phase_unadjusted_costs) - # We extract the values for the current phase # TODO: For things like lighting costs for heating and hot water recommendations, we should actually # update phase_cost since the phase cost should be the same as the previous phase @@ -507,11 +492,24 @@ class Recommendations: "sap": phase_energy_efficiency_metrics["sap_change"], "carbon": phase_energy_efficiency_metrics["carbon_change"], "heat_demand": phase_energy_efficiency_metrics["heat_demand"], - "unadjusted_heating_cost": phase_cost["heating_cost"]["predictions"].values[0], - "unadjusted_hot_water_cost": phase_cost["hot_water_cost"]["predictions"].values[0], - "unadjusted_lighting_cost": phase_cost["lighting_cost"]["predictions"].values[0] } + static_cost_variables = ( + ["epc_heating_cost", "epc_hot_water_cost"] if + rec["type"] == "low_energy_lighting" else ["epc_lighting_cost"] + ) + dynamic_cost_variables = [ + v for v in ["epc_heating_cost", "epc_hot_water_cost", "epc_lighting_cost"] + if v not in static_cost_variables + ] + # Take the static variables from the previous phase + current_phase_costs = {k: v for k, v in previous_phase_values.items() if k in static_cost_variables} + # Insert the dynamic variables from the current phase + for v in dynamic_cost_variables: + current_phase_costs[v] = phase_cost[v.split("epc_")[1]]["adjusted_cost"].values[0] + + current_phase_values.update(current_phase_costs) + property_phase_impact = { # Increasing "sap": current_phase_values["sap"] - previous_phase_values["sap"], @@ -556,8 +554,10 @@ class Recommendations: rec["co2_equivalent_savings"] = property_phase_impact["carbon"] rec["heat_demand"] = property_phase_impact["heat_demand"] - if (rec["sap_points"] is None) and (rec["co2_equivalent_savings"] is None) or ( - rec["heat_demand"] is None): + if ( + (rec["sap_points"] is None) and (rec["co2_equivalent_savings"] is None) or + (rec["heat_demand"] is None) + ): raise ValueError("sap points, co2 or heat demand is missing") impact_summary.append(