mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
cleaning up data dictionary references
This commit is contained in:
parent
737147897b
commit
69af82a5db
8 changed files with 24 additions and 38 deletions
|
|
@ -378,10 +378,7 @@ class Property:
|
|||
|
||||
self.recommendations_scoring_data.append(scoring_dict)
|
||||
|
||||
simulation_epc = vars(self.epc_record).copy()
|
||||
# Insert static values
|
||||
simulation_epc["lodgement_date"] = simulation_lodgment_date
|
||||
simulation_epc = {k.replace("_", "-"): v for k, v in simulation_epc.items()}
|
||||
simulation_epc = self.epc_record.to_dict(case="kebab", source="prepared")
|
||||
|
||||
types = [x["type"] for x in previous_phase_representatives]
|
||||
if "external_wall_insulation" in types and "internal_wall_insulation" in types:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import string
|
|||
import secrets
|
||||
import logging
|
||||
from io import BytesIO
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def setup_logger(log_file=None, level=logging.INFO, overwrite_handler=False):
|
||||
|
|
@ -73,7 +74,7 @@ def sap_to_epc(sap_points: int | float):
|
|||
return "G"
|
||||
|
||||
|
||||
def epc_to_sap_lower_bound(epc: str):
|
||||
def epc_to_sap_lower_bound(epc: Optional[str]):
|
||||
"""
|
||||
Given an EPC rating, returns the lower bound SAP score required
|
||||
to hit that EPC rating
|
||||
|
|
|
|||
|
|
@ -1076,8 +1076,7 @@ async def model_engine(body: PlanTriggerRequest):
|
|||
property_required_measures, recommendations, p, needs_ventilation
|
||||
)
|
||||
gain = optimiser_functions.calculate_gain(
|
||||
body=body, p=p, fixed_gain=fixed_gain, eco_packages=eco_packages,
|
||||
already_installed_gain=already_installed_sap
|
||||
body=body, p=p, fixed_gain=fixed_gain, already_installed_gain=already_installed_sap
|
||||
)
|
||||
|
||||
# We insert the innovation uplift
|
||||
|
|
|
|||
|
|
@ -858,7 +858,7 @@ class Costs:
|
|||
n_radiators = self._estimate_n_radiators(
|
||||
number_habitable_rooms=n_rooms,
|
||||
total_floor_area=self.property.floor_area,
|
||||
property_type=self.property.epc_record.property - type,
|
||||
property_type=self.property.epc_record.property_type,
|
||||
built_form=self.property.epc_record.built_form
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import pandas as pd
|
||||
import numpy as np
|
||||
from backend.Property import Property
|
||||
from typing import List, Mapping, Any
|
||||
from typing import List, Mapping, Any, Optional
|
||||
from itertools import groupby
|
||||
from recommendations.FloorRecommendations import FloorRecommendations
|
||||
from recommendations.WallRecommendations import WallRecommendations
|
||||
|
|
@ -49,7 +49,7 @@ class Recommendations:
|
|||
materials: List,
|
||||
exclusions: List[str] = None,
|
||||
inclusions: List[str] = None,
|
||||
default_u_values: bool = False,
|
||||
default_u_values: Optional[bool] = False,
|
||||
):
|
||||
"""
|
||||
:param property_instance: Instance of the Property class, for the home associated to property_id
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ class SecondaryHeating:
|
|||
# No secondary heating system, so no recommendation to remove it
|
||||
return
|
||||
|
||||
if self.property.data['number-habitable-rooms'] > self.property.data['number-heated-rooms']:
|
||||
n_rooms = self.property.data['number-habitable-rooms'] - self.property.data['number-heated-rooms']
|
||||
if self.property.epc_record.number_habitable_rooms > self.property.epc_record.number_heated_rooms:
|
||||
n_rooms = self.property.epc_record.number_habitable_rooms - self.property.epc_record.number_heated_rooms
|
||||
else:
|
||||
n_rooms = self.property.data["number-heated-rooms"]
|
||||
n_rooms = self.property.epc_record.number_heated_rooms
|
||||
|
||||
costs = self.costs.heater_removal(n_rooms=n_rooms)
|
||||
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ def optimise_with_funding_paths(
|
|||
# We add in generic insulation funding paths (where there is no fixed measure)
|
||||
# Heating controls are only eligible if installed as part of a heating upgrade and so we do not include them
|
||||
# here. We don't have an option if the property is a C or above
|
||||
if housing_type == "Social" and p.data["current-energy-rating"] not in ["C", "B", "A"]:
|
||||
if housing_type == "Social" and p.epc_record.current_energy_rating not in ["C", "B", "A"]:
|
||||
funding_paths = (
|
||||
[
|
||||
{
|
||||
|
|
@ -297,7 +297,7 @@ def optimise_with_funding_paths(
|
|||
)
|
||||
|
||||
needs_pre_eco_hhrsh_upgrade = (
|
||||
(p.data["current-energy-rating"] == "D") and work_package == "solar_hhrsh_eco4"
|
||||
(p.epc_record.current_energy_rating == "D") and work_package == "solar_hhrsh_eco4"
|
||||
)
|
||||
|
||||
for path_spec in funding_paths:
|
||||
|
|
@ -306,7 +306,7 @@ def optimise_with_funding_paths(
|
|||
if isinstance(path_spec, dict) and path_spec.get("reference") == "fabric-only:eco4":
|
||||
sub_measures = _filter_measures_by_types(optimisation_input_measures, path_spec["allowed_types"])
|
||||
# If the property is EPC D and socil, we also include just innovation measures
|
||||
if housing_type == "Social" and p.data["current-energy-rating"] == "D":
|
||||
if housing_type == "Social" and p.epc_record.current_energy_rating == "D":
|
||||
# We add in a second option which is just innovation measures
|
||||
sub_measures_innovation = []
|
||||
for measures in sub_measures:
|
||||
|
|
@ -354,7 +354,7 @@ def optimise_with_funding_paths(
|
|||
"path": path_spec,
|
||||
"scheme": scheme,
|
||||
"is_eligible": _is_eligible_funding_package(
|
||||
scheme, float(p.data["current-energy-efficiency"]), sub_gain
|
||||
scheme, p.epc_record.current_energy_efficiency, sub_gain
|
||||
),
|
||||
"unfunded_items": unfunded_picked,
|
||||
"already_installed_gain": already_installed_gain
|
||||
|
|
@ -500,9 +500,7 @@ def optimise_with_funding_paths(
|
|||
"total_gain": total_gain,
|
||||
"path": path_spec,
|
||||
"scheme": scheme,
|
||||
"is_eligible": _is_eligible_funding_package(
|
||||
scheme, int(p.data["current-energy-efficiency"]), total_gain
|
||||
),
|
||||
"is_eligible": _is_eligible_funding_package(scheme, p.epc_record.current_energy_efficiency, total_gain),
|
||||
"unfunded_items": unfunded_picked,
|
||||
"already_installed_gain": already_installed_gain
|
||||
})
|
||||
|
|
@ -523,7 +521,7 @@ def optimise_with_funding_paths(
|
|||
# logger.info("We have some packages that are fundable but do not meet the target gain")
|
||||
|
||||
# We now can calculate the project ABS, which subtracts from the cost, but this is only relevant for ECO4
|
||||
solutions["starting_sap"] = int(p.data["current-energy-efficiency"])
|
||||
solutions["starting_sap"] = p.epc_record.current_energy_efficiency
|
||||
solutions["floor_area"] = p.floor_area
|
||||
solutions["ending_sap"] = solutions["starting_sap"] + solutions["total_gain"]
|
||||
# We flag projects that are including batteries
|
||||
|
|
@ -677,7 +675,7 @@ def optimise_with_scenarios(
|
|||
for x in measures:
|
||||
if x["has_battery"]:
|
||||
x["battery_gain"] = BatterySAPScorer.score(
|
||||
starting_sap=int(p.data["current-energy-efficiency"]) + target_gain + 1,
|
||||
starting_sap=p.epc_record.current_energy_efficiency + target_gain + 1,
|
||||
pv_size=x["array_size"]
|
||||
)
|
||||
x["gain"] += x["battery_gain"]
|
||||
|
|
@ -893,7 +891,7 @@ def append_solution_metrics(solutions, target_gain, p, already_installed_sap=0):
|
|||
# We need the ending SAP, but we'll need to remove the battery SAP uplift first
|
||||
|
||||
solutions_df["ending_sap_without_battery"] = solutions_df.apply(
|
||||
lambda x: int(p.data["current-energy-efficiency"]) + already_installed_sap + _get_ending_sap_without_battery(x),
|
||||
lambda x: p.epc_record.current_energy_efficiency + already_installed_sap + _get_ending_sap_without_battery(x),
|
||||
axis=1
|
||||
)
|
||||
|
||||
|
|
@ -1162,7 +1160,7 @@ def _make_solar_heating_funding_paths(
|
|||
p, input_measures, funding_paths, remaining_insulation_type, housing_type, funding: Funding
|
||||
):
|
||||
# If a property is private and EPC D or above, it's not eligible
|
||||
if housing_type == "Private" and p.data["current-energy-rating"] in ["D", "C", "B", "A"]:
|
||||
if housing_type == "Private" and p.epc_record.current_energy_rating in ["D", "C", "B", "A"]:
|
||||
return funding_paths
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# Solar PV with existing eligible heating system
|
||||
|
|
@ -1288,7 +1286,7 @@ def make_funding_paths(p, input_measures, housing_type, funding: Funding, work_p
|
|||
"""
|
||||
|
||||
# If the property is currently EPC C, there is no funding availability
|
||||
if p.data["current-energy-rating"] in ["C", "B", "A"]:
|
||||
if p.epc_record.current_energy_rating in ["C", "B", "A"]:
|
||||
return [], input_measures
|
||||
|
||||
# We handle the case of minimum insulation requirements. Whenever we have a heating system recommendation,
|
||||
|
|
@ -1316,7 +1314,7 @@ def make_funding_paths(p, input_measures, housing_type, funding: Funding, work_p
|
|||
|
||||
funding_paths = []
|
||||
|
||||
if housing_type == "Social" and p.data["current-energy-rating"] == "D":
|
||||
if housing_type == "Social" and p.epc_record.current_energy_rating == "D":
|
||||
# If the property is currently EPC D, we can only include innovation measures or measures to meet the
|
||||
# minimum insulation requirements. We make an exception if we have a measure that is
|
||||
# already installed, specifically a heat pump
|
||||
|
|
@ -1362,7 +1360,7 @@ def make_funding_paths(p, input_measures, housing_type, funding: Funding, work_p
|
|||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# 1) The package must include EWI or IWI if the property is private rental sector
|
||||
# We check if we have any EWI or IWI measures available - only for EPC E or below
|
||||
if p.data["current-energy-rating"] in ["E", "F", "G"]:
|
||||
if p.epc_record.current_energy_rating in ["E", "F", "G"]:
|
||||
ewi_or_iwi = [{"OR": []}]
|
||||
reference_measures = []
|
||||
# If we have EWI we add it in
|
||||
|
|
|
|||
|
|
@ -207,7 +207,6 @@ def calculate_gain(
|
|||
body: PlanTriggerRequest,
|
||||
p: Property,
|
||||
fixed_gain: float,
|
||||
eco_packages: None | dict = None,
|
||||
already_installed_gain: float = 0,
|
||||
) -> float | None:
|
||||
"""
|
||||
|
|
@ -226,7 +225,6 @@ def calculate_gain(
|
|||
Property object with EPC data (must have p.data["current-energy-efficiency"]).
|
||||
fixed_gain : float
|
||||
Total fixed gain from required measures (returned by calculate_fixed_gain).
|
||||
eco_packages : dict, optional
|
||||
already_installed_gain: float, optional
|
||||
|
||||
Returns
|
||||
|
|
@ -235,15 +233,8 @@ def calculate_gain(
|
|||
Required SAP gain for EPC, or None for non-EPC goals.
|
||||
"""
|
||||
if body.goal == "Increasing EPC":
|
||||
current_sap = int(p.data["current-energy-efficiency"]) + already_installed_gain
|
||||
|
||||
if eco_packages is None:
|
||||
target_sap = epc_to_sap_lower_bound(body.goal_value)
|
||||
else:
|
||||
target_sap = (
|
||||
eco_packages.get(p.id)[1] if eco_packages.get(p.id)[1] is not None
|
||||
else epc_to_sap_lower_bound(body.goal_value)
|
||||
)
|
||||
current_sap = p.epc_record.current_energy_efficiency + already_installed_gain
|
||||
target_sap = epc_to_sap_lower_bound(body.goal_value)
|
||||
|
||||
if target_sap <= current_sap:
|
||||
# We've already met or exceeded the target EPC
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue