mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
handing HHRSH heating upgrade outside of ECO project
This commit is contained in:
parent
cb70cbf1da
commit
4640fa77bf
4 changed files with 65 additions and 12 deletions
|
|
@ -1302,7 +1302,8 @@ class Property:
|
|||
# If there is no existing solar PV, the photo-supply field will be None or a missing value
|
||||
|
||||
# We use inspections data to tell us this
|
||||
if self.inspections:
|
||||
|
||||
if getattr(self.inspections, "roof_orientation", None):
|
||||
has_no_existing_solar_pv = self.inspections.roof_orientation.value not in [
|
||||
"already has solar pv", "roof too small", "no roof"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ DESCRIPTIONS_TO_FUEL_TYPES = {
|
|||
"Electric ceiling heating, electric": {"fuel": "Electricity", "cop": 1},
|
||||
"Air source heat pump, warm air, electric": {
|
||||
"fuel": "Electricity", "cop": AVERAGE_ASHP_EFFICIENCY / 100
|
||||
}
|
||||
},
|
||||
"Electric heat pump for water heating only": {"fuel": "Electricity", "cop": 1},
|
||||
}
|
||||
|
||||
# These are the measure types where if there is a ventilation recommendation, we force the inclusion of it
|
||||
|
|
|
|||
|
|
@ -911,7 +911,8 @@ async def model_engine(body: PlanTriggerRequest):
|
|||
housing_type=body.housing_type,
|
||||
budget=body.budget,
|
||||
target_gain=gain,
|
||||
funding=funding
|
||||
funding=funding,
|
||||
work_package=eco_packages[p.id][2]
|
||||
)
|
||||
|
||||
# Given the solutions we select the optimal one
|
||||
|
|
@ -944,8 +945,19 @@ async def model_engine(body: PlanTriggerRequest):
|
|||
|
||||
# This is the list of measures that we will recommend
|
||||
scheme = optimal_solution["scheme"]
|
||||
funded_measures = optimal_solution["items"] if scheme != "none" else []
|
||||
solution = optimal_solution["items"] + optimal_solution["unfunded_items"]
|
||||
|
||||
# We create this full list of selected measures, which is used in the next section for setting
|
||||
# default measures
|
||||
solution = deepcopy(optimal_solution["items"]) + deepcopy(optimal_solution["unfunded_items"])
|
||||
funded_measures = deepcopy(optimal_solution["items"]) if scheme != "none" else []
|
||||
unfunded_measures = deepcopy(optimal_solution["unfunded_items"])
|
||||
# If we have an EPC D + HHRSH project, we move HHRSH out of funded measures
|
||||
if eco_packages.get(p.id)[2] == "solar_hhrsh_eco4" and p.data["current-energy-rating"] == "D":
|
||||
unfunded_measures.extend(
|
||||
[x for x in funded_measures if x["type"] == "high_heat_retention_storage_heaters"]
|
||||
)
|
||||
funded_measures = [x for x in funded_measures if x["type"] != "high_heat_retention_storage_heaters"]
|
||||
|
||||
# This is the total amount of funding that the project will produce (EXCLUDING uplifts) (£)
|
||||
project_funding = optimal_solution["full_project_funding"] if scheme == "eco4" else \
|
||||
optimal_solution["partial_project_funding"]
|
||||
|
|
|
|||
|
|
@ -198,7 +198,25 @@ def _ensure_unfunded_costs(groups):
|
|||
return groups
|
||||
|
||||
|
||||
def optimise_with_funding_paths(p, input_measures, housing_type, funding: Funding, budget=None, target_gain=None):
|
||||
def _get_already_installed_gain(selected_measures, needs_pre_eco_hhrsh_upgrade):
|
||||
"""
|
||||
Calculate already installed gain, with special case for pre-ECO4 HHRSH upgrade.
|
||||
:param selected_measures: List of selected measures
|
||||
:param needs_pre_eco_hhrsh_upgrade: Boolean indicating if pre-ECO4 HHRSH upgrade is needed
|
||||
:return:
|
||||
"""
|
||||
if needs_pre_eco_hhrsh_upgrade:
|
||||
return sum(
|
||||
[x["gain"] for x in selected_measures if
|
||||
x["already_installed"] or x["type"] == "high_heat_retention_storage_heaters"]
|
||||
)
|
||||
|
||||
return sum([x["gain"] for x in selected_measures if x["already_installed"]])
|
||||
|
||||
|
||||
def optimise_with_funding_paths(
|
||||
p, input_measures, housing_type, funding: Funding, budget=None, target_gain=None, work_package=None
|
||||
):
|
||||
"""
|
||||
run_optimizer(sub_measures, budget, target_gain) -> (picked_options, sub_cost, sub_gain)
|
||||
"""
|
||||
|
|
@ -227,7 +245,9 @@ def optimise_with_funding_paths(p, input_measures, housing_type, funding: Fundin
|
|||
})
|
||||
|
||||
# This function will filter down on innovation measures if we are social EPC D
|
||||
funding_paths, optimisation_input_measures = make_funding_paths(p, input_measures, housing_type, funding)
|
||||
funding_paths, optimisation_input_measures = make_funding_paths(
|
||||
p, input_measures, housing_type, funding, work_package
|
||||
)
|
||||
|
||||
# We now produce a fabric only path for ECO4
|
||||
# We add in generic insulation funding paths (where there is no fixed measure)
|
||||
|
|
@ -244,6 +264,10 @@ def optimise_with_funding_paths(p, input_measures, housing_type, funding: Fundin
|
|||
] + funding_paths
|
||||
)
|
||||
|
||||
needs_pre_eco_hhrsh_upgrade = (
|
||||
(p.data["current-energy-rating"] == "D") and work_package == "solar_hhrsh_eco4"
|
||||
)
|
||||
|
||||
for path_spec in funding_paths:
|
||||
|
||||
# ECO4 fabric only path = special case
|
||||
|
|
@ -281,8 +305,11 @@ def optimise_with_funding_paths(p, input_measures, housing_type, funding: Fundin
|
|||
|
||||
scheme = _path_scheme([path_spec])
|
||||
|
||||
# We sum of gain, for already installed measures
|
||||
already_installed_gain = sum([x["gain"] for x in picked if x["already_installed"]])
|
||||
# We sum of gain, for already installed measures. In this, we also include HHRSH, when we have
|
||||
# an EPC D property that needs HHRSH but HHRSH isn't an eligible measure
|
||||
already_installed_gain = _get_already_installed_gain(
|
||||
picked, needs_pre_eco_hhrsh_upgrade
|
||||
)
|
||||
|
||||
solutions.append(
|
||||
{
|
||||
|
|
@ -422,7 +449,11 @@ def optimise_with_funding_paths(p, input_measures, housing_type, funding: Fundin
|
|||
total_gain += unfunded_gain
|
||||
|
||||
# We now grab the "already installed gain"
|
||||
already_installed_gain = sum([x["gain"] for x in total_picks if x["already_installed"]])
|
||||
# We sum of gain, for already installed measures. In this, we also include HHRSH, when we have
|
||||
# an EPC D property that needs HHRSH but HHRSH isn't an eligible measure
|
||||
already_installed_gain = _get_already_installed_gain(
|
||||
total_picks, needs_pre_eco_hhrsh_upgrade
|
||||
)
|
||||
|
||||
solutions.append({
|
||||
"fixed_ids": fixed_ids,
|
||||
|
|
@ -837,7 +868,7 @@ def _make_generic_gbis_funding_paths(input_gbis_measures, funding_paths):
|
|||
return funding_paths + gbis_funding_paths
|
||||
|
||||
|
||||
def make_funding_paths(p, input_measures, housing_type, funding: Funding):
|
||||
def make_funding_paths(p, input_measures, housing_type, funding: Funding, work_package=None):
|
||||
"""
|
||||
This function generates funding paths based on the input measures and the tenure of the property.
|
||||
It checks for the presence of specific measures and creates paths that include necessary insulation measures
|
||||
|
|
@ -848,6 +879,8 @@ def make_funding_paths(p, input_measures, housing_type, funding: Funding):
|
|||
:param input_measures:
|
||||
:param housing_type:
|
||||
:param funding: The funding object that provides methods to check eligibility and calculate funding.
|
||||
:param work_package: Optional work package information. We handle the case of an EPC D property needing a heating
|
||||
upgrade, where the heating upgrade needs to be conducted before the solar PV work
|
||||
:return:
|
||||
"""
|
||||
|
||||
|
|
@ -890,6 +923,12 @@ def make_funding_paths(p, input_measures, housing_type, funding: Funding):
|
|||
group_of_innovation_measures = []
|
||||
group_of_gbis_innovation_measures = []
|
||||
for measure in measures:
|
||||
|
||||
if measure["type"] == "high_heat_retention_storage_heaters" and work_package == "solar_hhrsh_eco4":
|
||||
# With this work type, if the property is EPC D and doesn't have an eligible heating system
|
||||
# we install HHRSH as a pre-requisite measure, before the ECO4 project if complete.
|
||||
group_of_innovation_measures.append(measure)
|
||||
|
||||
if measure["innovation_uplift"] or measure["type"] in remaining_insulation_type or measure[
|
||||
"already_installed"]:
|
||||
group_of_innovation_measures.append(measure)
|
||||
|
|
@ -906,7 +945,7 @@ def make_funding_paths(p, input_measures, housing_type, funding: Funding):
|
|||
input_gbis_measures_innovation.extend(group_of_gbis_innovation_measures)
|
||||
|
||||
funding_paths = _make_solar_heating_funding_paths(
|
||||
p, input_measures_innovation, funding_paths, remaining_insulation_type, housing_type, funding
|
||||
p, input_measures_innovation, funding_paths, remaining_insulation_type, housing_type, funding,
|
||||
)
|
||||
|
||||
# Can only be innovation GBIS measures
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue