mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
implementing mv
This commit is contained in:
parent
792be8468b
commit
c2062507ca
9 changed files with 120 additions and 81 deletions
|
|
@ -380,7 +380,7 @@ class Property:
|
|||
for rec in property_recommendations_by_phase:
|
||||
# We simulate the impact of the recommendation at this current phase, and all of the prior phases
|
||||
|
||||
if rec["type"] in ["mechanical_ventilation", "trickle_vents", "draught_proofing"]:
|
||||
if rec["type"] in ["trickle_vents", "draught_proofing"]:
|
||||
continue
|
||||
|
||||
scoring_dict = self.create_recommendation_scoring_data(
|
||||
|
|
@ -388,7 +388,6 @@ class Property:
|
|||
recommendation_record=recommendation_record,
|
||||
recommendations=previous_phase_representatives + [rec],
|
||||
primary_recommendation_id=rec["recommendation_id"],
|
||||
non_invasive_recommendations=self.non_invasive_recommendations,
|
||||
)
|
||||
|
||||
self.recommendations_scoring_data.append(scoring_dict)
|
||||
|
|
@ -494,7 +493,6 @@ class Property:
|
|||
recommendation_record,
|
||||
recommendations: list,
|
||||
primary_recommendation_id: int,
|
||||
non_invasive_recommendations: list = None,
|
||||
):
|
||||
"""
|
||||
This function will iterate through a list of recommendations and apply a simulation for each recommendation
|
||||
|
|
@ -503,7 +501,6 @@ class Property:
|
|||
:param recommendation_record: The record of the property, which will be updated
|
||||
:param recommendations: The list of recommendations to apply
|
||||
:param primary_recommendation_id: The id of the primary recommendation, which is used to identify the record
|
||||
:param non_invasive_recommendations: The list of non-invasive recommendations
|
||||
:return: The updated recommendation record
|
||||
"""
|
||||
|
||||
|
|
@ -532,7 +529,7 @@ class Property:
|
|||
"internal_wall_insulation", "external_wall_insulation", "cavity_wall_insulation",
|
||||
"cylinder_thermostat", "loft_insulation", "room_roof_insulation", "flat_roof_insulation",
|
||||
"solid_floor_insulation", "suspended_floor_insulation", "mixed_glazing",
|
||||
"windows_glazing"
|
||||
"windows_glazing", "mechanical_ventilation"
|
||||
]:
|
||||
# We update the data, as defined in the recommendaton
|
||||
for prefix in ["walls", "roof", "floor"]:
|
||||
|
|
@ -558,7 +555,7 @@ class Property:
|
|||
"solid_floor_insulation", "suspended_floor_insulation",
|
||||
"windows_glazing", "solar_pv", "heating", "hot_water_tank_insulation",
|
||||
"heating_control", "secondary_heating", "cylinder_thermostat", "mixed_glazing",
|
||||
"extension_cavity_wall_insulation",
|
||||
"extension_cavity_wall_insulation", "mechanical_ventilation",
|
||||
]:
|
||||
raise NotImplementedError(
|
||||
"Implement me, given type %s" % recommendation["type"]
|
||||
|
|
|
|||
|
|
@ -203,11 +203,11 @@ class TrainingDataset(BaseDataset):
|
|||
common_cols = [[col + "_starting", col + "_ending"] for col in common_cols]
|
||||
|
||||
self.df = self.df.loc[
|
||||
:,
|
||||
no_suffix_cols
|
||||
+ only_ending_cols
|
||||
+ [col for cols in common_cols for col in cols],
|
||||
]
|
||||
:,
|
||||
no_suffix_cols
|
||||
+ only_ending_cols
|
||||
+ [col for cols in common_cols for col in cols],
|
||||
]
|
||||
|
||||
def _remove_abnormal_change_in_floor_area(self):
|
||||
"""
|
||||
|
|
@ -511,7 +511,7 @@ class TrainingDataset(BaseDataset):
|
|||
expanded_df["is_sandstone_or_limestone"]
|
||||
== expanded_df["is_sandstone_or_limestone_ending"]
|
||||
)
|
||||
]
|
||||
]
|
||||
elif component == "floor":
|
||||
expanded_df = expanded_df[
|
||||
(expanded_df["is_suspended"] == expanded_df["is_suspended_ending"])
|
||||
|
|
@ -528,7 +528,7 @@ class TrainingDataset(BaseDataset):
|
|||
expanded_df["is_to_external_air"]
|
||||
== expanded_df["is_to_external_air_ending"]
|
||||
)
|
||||
]
|
||||
]
|
||||
elif component == "roof":
|
||||
expanded_df = expanded_df[
|
||||
(expanded_df["is_pitched"] == expanded_df["is_pitched_ending"])
|
||||
|
|
@ -541,7 +541,7 @@ class TrainingDataset(BaseDataset):
|
|||
expanded_df["has_dwelling_above"]
|
||||
== expanded_df["has_dwelling_above_ending"]
|
||||
)
|
||||
]
|
||||
]
|
||||
|
||||
return expanded_df
|
||||
|
||||
|
|
|
|||
|
|
@ -139,28 +139,22 @@ class EPCRecord:
|
|||
|
||||
self._clean_records_using_epc_records()
|
||||
self._clean_with_data_processor()
|
||||
|
||||
self._expand_prepared_epc_to_attributes()
|
||||
|
||||
self._identify_delta_between_prepared_and_original_records()
|
||||
|
||||
# Process to create uvalues for the single epc record
|
||||
|
||||
# selff.df = self.epc_record_as_dataframe('prepared_epc')
|
||||
|
||||
# self.df = self.epc_record_as_dataframe('prepared_epc')
|
||||
# self._feature_generation()
|
||||
# self._drop_features()
|
||||
|
||||
return
|
||||
|
||||
self._expand_description_to_features()
|
||||
self._expand_description_to_uvalues()
|
||||
|
||||
# self._expand_description_to_features()
|
||||
# self._expand_description_to_uvalues()
|
||||
#
|
||||
# self._generate_uvalues()
|
||||
# self._validate_expanded_description()
|
||||
# self._validate_u_values()
|
||||
# etc
|
||||
pass
|
||||
|
||||
def _drop_features(self):
|
||||
"""
|
||||
|
|
@ -360,6 +354,7 @@ class EPCRecord:
|
|||
self._clean_number_lighting_outlets()
|
||||
self._clean_floor_level()
|
||||
self._clean_floor_height()
|
||||
self._clean_constituency()
|
||||
|
||||
# self._clean_potential_energy_efficiency()
|
||||
# self._clean_environment_impact_potential()
|
||||
|
|
@ -402,6 +397,17 @@ class EPCRecord:
|
|||
if self.prepared_epc["floor-height"] <= 1.665:
|
||||
self.prepared_epc["floor-height"] = average
|
||||
|
||||
def _clean_constituency(self):
|
||||
"""
|
||||
We handle the single case of finding a missing constituency by using the local authority
|
||||
"""
|
||||
if pd.isnull(self.prepared_epc["constituency"]) or (self.prepared_epc["constituency"] == ""):
|
||||
if self.prepared_epc["local-authority"] != "E06000044":
|
||||
raise NotImplementedError(
|
||||
"This function is only implemented for Portsmouth, in the single edgecase seen"
|
||||
)
|
||||
self.prepared_epc["constituency"] = "E14000883"
|
||||
|
||||
def _clean_floor_level(self):
|
||||
"""
|
||||
This method will clean the floor level, if empty or invalid
|
||||
|
|
|
|||
|
|
@ -234,6 +234,13 @@ class Costs:
|
|||
if self.region is None:
|
||||
# Try and grab using the local-authority-label
|
||||
self.region = county_to_region_map.get(self.property.data["local-authority-label"], None)
|
||||
|
||||
if self.region is None:
|
||||
# Try and get the region after converting the keys to lower
|
||||
self.region = {
|
||||
k.lower(): v for k, v in county_to_region_map.items()
|
||||
}.get(self.property.data["local-authority-label"].lower(), None)
|
||||
|
||||
if self.region is None:
|
||||
raise ValueError("Region not found in county map")
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class HeatingControlRecommender:
|
|||
|
||||
self.recommendation = []
|
||||
|
||||
def recommend(self, heating_description, description_prefix="", description_suffix=""):
|
||||
def recommend(self, heating_description, phase, description_prefix="", description_suffix=""):
|
||||
|
||||
# TODO: Many of these functions are quite similar. We can possibly create a single wrapper function that
|
||||
# takes in the heating description and the description prefix/suffix, and then creates the appropriate
|
||||
|
|
@ -23,32 +23,32 @@ class HeatingControlRecommender:
|
|||
# This first iteration of the recommender will provide very basic recommendation
|
||||
# We recommend heating controls based on the main heating system
|
||||
if heating_description in ["Room heaters, electric"]:
|
||||
self.recommend_room_heaters_electric_controls()
|
||||
self.recommend_room_heaters_electric_controls(phase=phase)
|
||||
return
|
||||
|
||||
if heating_description in ["Electric storage heaters", "Electric storage heaters, radiators"]:
|
||||
self.recommend_high_heat_retention_controls(description_prefix=description_prefix)
|
||||
self.recommend_high_heat_retention_controls(description_prefix=description_prefix, phase=phase)
|
||||
return
|
||||
|
||||
if heating_description in ["Boiler and radiators, mains gas"]:
|
||||
# We can recommend roomstat programmer trvs
|
||||
self.recommend_roomstat_programmer_trvs(description_suffix=description_suffix)
|
||||
self.recommend_roomstat_programmer_trvs(description_suffix=description_suffix, phase=phase)
|
||||
# We can also recommend time and temperature zone controls
|
||||
self.recommend_time_temperature_zone_controls(description_suffix=description_suffix)
|
||||
self.recommend_time_temperature_zone_controls(description_suffix=description_suffix, phase=phase)
|
||||
|
||||
return
|
||||
|
||||
if heating_description in ["Boiler and radiators, electric"]:
|
||||
self.recommend_roomstat_programmer_trvs()
|
||||
self.recommend_roomstat_programmer_trvs(phase=phase)
|
||||
return
|
||||
|
||||
if heating_description in ["Air source heat pump, radiators, electric"]:
|
||||
# For an ASHP, we can recommend time and temperature zone controls, as well as programmer, trvs and a bypass
|
||||
# which are common configurations for ASHPs
|
||||
self.recommend_time_temperature_zone_controls()
|
||||
self.recommend_time_temperature_zone_controls(phase=phase)
|
||||
# self.recommend_programmer_trvs_bypass()
|
||||
|
||||
def recommend_room_heaters_electric_controls(self):
|
||||
def recommend_room_heaters_electric_controls(self, phase):
|
||||
"""
|
||||
If the home has Room heaters, electric, we start by identifying potential heating controls that could
|
||||
be upgraded, that would provide a practical impact. This will be the least invasive improvement.
|
||||
|
|
@ -88,6 +88,9 @@ class HeatingControlRecommender:
|
|||
|
||||
self.recommendation.append(
|
||||
{
|
||||
"phase": phase,
|
||||
"type": "heating",
|
||||
"measure_type": "programmer_appliance_thermostat",
|
||||
"description": "upgrade heating controls to Programmer and Appliance or Smart Thermostats",
|
||||
**self.costs.programmer_and_appliance_thermostat(has_programmer=has_programmer),
|
||||
"simulation_config": simulation_config
|
||||
|
|
@ -97,7 +100,7 @@ class HeatingControlRecommender:
|
|||
# We don't implement any other recommendations right now
|
||||
return
|
||||
|
||||
def recommend_high_heat_retention_controls(self, description_prefix=""):
|
||||
def recommend_high_heat_retention_controls(self, phase, description_prefix=""):
|
||||
"""
|
||||
When applicable, we recommend upgrading the heating controls to high heat retention controls. This is a
|
||||
specific type of control system that is designed to work with electric storage heaters. It is a more
|
||||
|
|
@ -133,6 +136,9 @@ class HeatingControlRecommender:
|
|||
|
||||
self.recommendation.append(
|
||||
{
|
||||
"phase": phase,
|
||||
"type": "heating",
|
||||
"measure_type": "celect_type_controls",
|
||||
"description": "Upgrade heating controls to High Heat Retention Storage Heater Controls",
|
||||
**self.costs.celect_type_controls(),
|
||||
"simulation_config": simulation_config,
|
||||
|
|
@ -143,7 +149,7 @@ class HeatingControlRecommender:
|
|||
# We don't implement any other recommendations right now
|
||||
return
|
||||
|
||||
def recommend_roomstat_programmer_trvs(self, description_suffix=""):
|
||||
def recommend_roomstat_programmer_trvs(self, phase, description_suffix=""):
|
||||
"""
|
||||
If the home has a boiler and radiators, mains gas, we start by identifying potential heating controls that could
|
||||
be upgraded, that would provide a practical impact.
|
||||
|
|
@ -208,15 +214,16 @@ class HeatingControlRecommender:
|
|||
|
||||
description = "Upgrade heating controls to Room thermostat, programmer and TRVs"
|
||||
|
||||
already_installed = "heating_control" in self.property.already_installed
|
||||
already_installed = "roomstat_programmer_trvs" in self.property.already_installed
|
||||
if already_installed:
|
||||
cost_result = override_costs(cost_result)
|
||||
description = "Heating controls have already been upgraded, no further action needed."
|
||||
|
||||
self.recommendation.append(
|
||||
{
|
||||
"type": "heating_control",
|
||||
"type": "heating",
|
||||
"measure_type": "roomstat_programmer_trvs",
|
||||
"phase": phase,
|
||||
"parts": [],
|
||||
"description": description,
|
||||
**cost_result,
|
||||
|
|
@ -231,7 +238,7 @@ class HeatingControlRecommender:
|
|||
|
||||
return
|
||||
|
||||
def recommend_time_temperature_zone_controls(self, description_suffix=""):
|
||||
def recommend_time_temperature_zone_controls(self, phase, description_suffix=""):
|
||||
"""
|
||||
If the home has a boiler, we can recommend time and temperature zone controls. This is a more advanced
|
||||
and more efficient control system than the standard controls that come with a boiler. However, it may come
|
||||
|
|
@ -282,14 +289,15 @@ class HeatingControlRecommender:
|
|||
"temperature zone control)"
|
||||
)
|
||||
|
||||
already_installed = "heating_control" in self.property.already_installed
|
||||
already_installed = "time_temperature_zone_control" in self.property.already_installed
|
||||
if already_installed:
|
||||
cost_result = override_costs(cost_result)
|
||||
description = "Heating controls have already been upgraded, no further action needed."
|
||||
|
||||
self.recommendation.append(
|
||||
{
|
||||
"type": "heating_control",
|
||||
"type": "heating",
|
||||
"phase": phase,
|
||||
"measure_type": "time_temperature_zone_control",
|
||||
"parts": [],
|
||||
"description": description,
|
||||
|
|
@ -335,14 +343,15 @@ class HeatingControlRecommender:
|
|||
|
||||
description = "Install a Bypass valve, TRVs and a Programmer"
|
||||
|
||||
already_installed = "heating_control" in self.property.already_installed
|
||||
already_installed = "programmer_trvs_bypass" in self.property.already_installed
|
||||
if already_installed:
|
||||
cost_result = override_costs(cost_result)
|
||||
description = "Heating controls have already been upgraded, no further action needed."
|
||||
|
||||
self.recommendation.append(
|
||||
{
|
||||
"type": "heating_control",
|
||||
"type": "heating",
|
||||
"measure_type": "programmer_trvs_bypass",
|
||||
"parts": [],
|
||||
"description": description,
|
||||
**cost_result,
|
||||
|
|
|
|||
|
|
@ -65,7 +65,6 @@ class HeatingRecommender:
|
|||
self.costs = Costs(self.property)
|
||||
|
||||
self.heating_recommendations = []
|
||||
self.heating_control_recommendations = []
|
||||
|
||||
self.has_electric_heating_description = (
|
||||
self.property.main_heating["has_electric"] or self.property.main_heating["has_electricaire"]
|
||||
|
|
@ -259,7 +258,6 @@ class HeatingRecommender:
|
|||
"ashp_only_heating_recommendation", False
|
||||
)
|
||||
self.heating_recommendations = []
|
||||
self.heating_control_recommendations = []
|
||||
# This first iteration of the recommender will provide very basic recommendation
|
||||
# We recommend heating controls based on the main heating system
|
||||
|
||||
|
|
@ -302,7 +300,6 @@ class HeatingRecommender:
|
|||
self.recommend_air_source_heat_pump(
|
||||
phase=phase,
|
||||
has_cavity_or_loft_recommendations=has_cavity_or_loft_recommendations,
|
||||
|
||||
)
|
||||
|
||||
return
|
||||
|
|
@ -360,7 +357,7 @@ class HeatingRecommender:
|
|||
}
|
||||
|
||||
controls_recommender = HeatingControlRecommender(self.property)
|
||||
controls_recommender.recommend(heating_description="Boiler and radiators, electric")
|
||||
controls_recommender.recommend(heating_description="Boiler and radiators, electric", phase=phase)
|
||||
|
||||
self.heating_recommendations.extend([boiler_recommendation] + controls_recommender.recommendation)
|
||||
return
|
||||
|
|
@ -453,7 +450,7 @@ class HeatingRecommender:
|
|||
), {})
|
||||
|
||||
controls_recommender = HeatingControlRecommender(self.property)
|
||||
controls_recommender.recommend(heating_description="Air source heat pump, radiators, electric")
|
||||
controls_recommender.recommend(heating_description="Air source heat pump, radiators, electric", phase=phase)
|
||||
ashp_size = self.size_heat_pump()
|
||||
|
||||
ashp_costs = self.costs.air_source_heat_pump(ashp_size)
|
||||
|
|
@ -805,7 +802,9 @@ class HeatingRecommender:
|
|||
description_prefix = ""
|
||||
|
||||
controls_recommender.recommend(
|
||||
heating_description="Electric storage heaters", description_prefix=description_prefix
|
||||
heating_description="Electric storage heaters",
|
||||
description_prefix=description_prefix,
|
||||
phase=phase
|
||||
)
|
||||
|
||||
has_hhr = self.is_hhr_already_installed()
|
||||
|
|
@ -1120,10 +1119,10 @@ class HeatingRecommender:
|
|||
description_suffix = ""
|
||||
controls_recommender.recommend(
|
||||
heating_description="Boiler and radiators, mains gas",
|
||||
description_suffix=description_suffix
|
||||
description_suffix=description_suffix,
|
||||
phase=recommendation_phase
|
||||
)
|
||||
# We may have 2 recommendations from the heating controls
|
||||
|
||||
if not controls_recommender.recommendation and not boiler_recommendation:
|
||||
return
|
||||
|
||||
|
|
@ -1161,10 +1160,6 @@ class HeatingRecommender:
|
|||
# 3) Heating controls only
|
||||
# But they are options that are not mutually exclusive
|
||||
# So, we actually set heating controls as a heating recommendation
|
||||
for recommendation in controls_recommender.recommendation:
|
||||
recommendation["phase"] = recommendation_phase
|
||||
# recommendation["type"] = "heating"
|
||||
|
||||
self.heating_control_recommendations.extend(controls_recommender.recommendation)
|
||||
self.heating_recommendations.extend(controls_recommender.recommendation)
|
||||
|
||||
return
|
||||
|
|
|
|||
|
|
@ -149,9 +149,10 @@ class Recommendations:
|
|||
(self.wall_recomender.recommendations or self.roof_recommender.recommendations) and
|
||||
("ventilation" in measures)
|
||||
):
|
||||
self.ventilation_recomender.recommend()
|
||||
self.ventilation_recomender.recommend(phase=phase)
|
||||
if self.ventilation_recomender.recommendation:
|
||||
property_recommendations.append(self.ventilation_recomender.recommendation)
|
||||
phase += 1
|
||||
|
||||
if "trickle_vents" in measures:
|
||||
# This is a recommendatin that typically comes from an energy assessment
|
||||
|
|
@ -208,27 +209,25 @@ class Recommendations:
|
|||
measures=measures,
|
||||
has_cavity_or_loft_recommendations=has_cavity_or_loft_recommendations,
|
||||
)
|
||||
if (
|
||||
self.heating_recommender.heating_recommendations or
|
||||
self.heating_recommender.heating_control_recommendations
|
||||
):
|
||||
if self.heating_recommender.heating_recommendations:
|
||||
|
||||
# We split into first and second phase recommendations
|
||||
first_phase_recommendations = [
|
||||
r for r in (
|
||||
self.heating_recommender.heating_recommendations +
|
||||
self.heating_recommender.heating_control_recommendations
|
||||
self.heating_recommender.heating_recommendations
|
||||
)
|
||||
if r["phase"] == phase
|
||||
]
|
||||
second_phase_recommendations = [
|
||||
r for r in (
|
||||
self.heating_recommender.heating_recommendations +
|
||||
self.heating_recommender.heating_control_recommendations
|
||||
self.heating_recommender.heating_recommendations
|
||||
)
|
||||
if r["phase"] == phase + 1
|
||||
]
|
||||
|
||||
if first_phase_recommendations and second_phase_recommendations:
|
||||
raise Exception("Imeplement me")
|
||||
|
||||
if first_phase_recommendations:
|
||||
property_recommendations.append(first_phase_recommendations)
|
||||
|
||||
|
|
@ -240,8 +239,7 @@ class Recommendations:
|
|||
# otherwise we incremenet by 1
|
||||
max_used_phase = max(
|
||||
[rec["phase"] for rec in
|
||||
self.heating_recommender.heating_recommendations +
|
||||
self.heating_recommender.heating_control_recommendations]
|
||||
self.heating_recommender.heating_recommendations]
|
||||
)
|
||||
amount_to_increment = max_used_phase - phase + 1
|
||||
phase += amount_to_increment
|
||||
|
|
@ -306,7 +304,7 @@ class Recommendations:
|
|||
# want to include the cavity wall insulation recommendation in the defaults
|
||||
|
||||
if recommendations_by_type[0].get("type") in [
|
||||
"mechanical_ventilation", "trickle_vents", "draught_proofing"
|
||||
"trickle_vents", "draught_proofing"
|
||||
]:
|
||||
continue
|
||||
|
||||
|
|
@ -480,12 +478,14 @@ class Recommendations:
|
|||
increasing_variables = ["sap"]
|
||||
decreasing_variables = ["carbon", "heat_demand"]
|
||||
|
||||
# If the recommendation is mechanical ventilation, we don't apply the rule that the new value should be higher
|
||||
mv_increasing_variables = ["carbon", "heat_demand"]
|
||||
mv_decreasing_variables = ["sap"]
|
||||
|
||||
impact_summary = []
|
||||
for recommendations_by_type in property_recommendations:
|
||||
for rec in recommendations_by_type:
|
||||
if rec["type"] in [
|
||||
"mechanical_ventilation", "trickle_vents", "draught_proofing", "extension_cavity_wall_insulation"
|
||||
]:
|
||||
if rec["type"] in ["trickle_vents", "draught_proofing", "extension_cavity_wall_insulation"]:
|
||||
# We don't have a percieved sap impact of mechanical ventilation or trickle vents, and we don't
|
||||
# have the capacity to score draught proofing
|
||||
if rec["type"] == "extension_cavity_wall_insulation":
|
||||
|
|
@ -571,13 +571,23 @@ class Recommendations:
|
|||
# For decreasing variables, the new value should be lower than the previous, otherwise we set it to
|
||||
# the previous
|
||||
# In either case, we adjudge the recommendation to have had no/negligible impact
|
||||
for v in increasing_variables:
|
||||
# However, if the recommendation is mechanical ventilation, this can have a negative SAP impact so
|
||||
# we don't apply this rule
|
||||
|
||||
if rec["type"] == "mechanical_ventilation":
|
||||
phase_increasing_variables = mv_increasing_variables
|
||||
phase_decreasing_variables = mv_decreasing_variables
|
||||
else:
|
||||
phase_increasing_variables = increasing_variables
|
||||
phase_decreasing_variables = decreasing_variables
|
||||
|
||||
for v in phase_increasing_variables:
|
||||
current_phase_values[v] = (
|
||||
current_phase_values[v] if current_phase_values[v] > previous_phase_values[v] else
|
||||
previous_phase_values[v]
|
||||
)
|
||||
for v in previous_phase_values:
|
||||
if v in decreasing_variables:
|
||||
if v in phase_decreasing_variables:
|
||||
current_phase_values[v] = (
|
||||
current_phase_values[v] if current_phase_values[v] < previous_phase_values[v] else
|
||||
previous_phase_values[v]
|
||||
|
|
@ -592,13 +602,19 @@ class Recommendations:
|
|||
"heat_demand": previous_phase_values["heat_demand"] - current_phase_values["heat_demand"],
|
||||
}
|
||||
|
||||
# Prevent from being negative
|
||||
# Prevent from being negative - apart from ventilation
|
||||
for metric in ["sap", "carbon", "heat_demand"]:
|
||||
property_phase_impact[metric] = (
|
||||
0 if property_phase_impact[metric] < 0 else property_phase_impact[metric]
|
||||
)
|
||||
if metric == "sap":
|
||||
property_phase_impact[metric] = round(property_phase_impact[metric], 2)
|
||||
if rec["type"] != "mechanical_ventilation":
|
||||
property_phase_impact[metric] = (
|
||||
0 if property_phase_impact[metric] < 0 else property_phase_impact[metric]
|
||||
)
|
||||
if metric == "sap":
|
||||
property_phase_impact[metric] = round(property_phase_impact[metric], 2)
|
||||
else:
|
||||
# We prevent these from being positive
|
||||
property_phase_impact[metric] = (
|
||||
0 if property_phase_impact[metric] > 0 else property_phase_impact[metric]
|
||||
)
|
||||
|
||||
# For the moment, we cap the number of SAP points that can be achieved by LEDs at 2
|
||||
if rec["type"] == "low_energy_lighting":
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class VentilationRecommendations(Definitions):
|
|||
def identify_ventilation(self):
|
||||
self.has_ventilaion = self.property.data["mechanical-ventilation"] in self.VENTILATION_DESCRIPTIONS
|
||||
|
||||
def recommend(self):
|
||||
def recommend(self, phase):
|
||||
"""
|
||||
If there is no ventilation, we recommend installing ventilation
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ class VentilationRecommendations(Definitions):
|
|||
# We recommend installing two mechanical ventilation systems
|
||||
self.recommendation = [
|
||||
{
|
||||
"phase": None,
|
||||
"phase": phase,
|
||||
"parts": part,
|
||||
"type": part[0]["type"],
|
||||
"measure_type": "mechanical_ventilation",
|
||||
|
|
@ -79,7 +79,13 @@ class VentilationRecommendations(Definitions):
|
|||
"total": estimated_cost,
|
||||
# We use a very simple and rough estimate of 4 hours per unit
|
||||
"labour_hours": labour_hours,
|
||||
"labour_days": labour_days # Assume 8 hour day
|
||||
"labour_days": labour_days, # Assume 8 hour day
|
||||
"simulation_config": {
|
||||
"mechanical_ventilation_ending": "mechanical, extract only",
|
||||
},
|
||||
"description_simulation": {
|
||||
"mechanical-ventilation": "mechanical, extract only"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,10 @@ county_to_region_map = {
|
|||
'Merthyr Tydfil': 'Wales', 'Monmouthshire': 'Wales', 'Mountain Ash': 'Wales', 'Neath Port Talbot': 'Wales',
|
||||
'Newport': 'Wales', 'Pembrokeshire': 'Wales', 'Penarth': 'Wales', 'Pentre': 'Wales', 'Pontyclun': 'Wales',
|
||||
'Pontypridd': 'Wales', 'Porth': 'Wales', 'Porthcawl': 'Wales', 'Powys': 'Wales', 'Rhondda Cynon Taff': 'Wales',
|
||||
'Rhoose': 'Wales', 'Sully': 'Wales', 'Swansea': 'Wales', 'The Vale of Glamorgan': 'Wales', 'Tonypandy': 'Wales',
|
||||
'Rhoose': 'Wales', 'Sully': 'Wales', 'Swansea': 'Wales',
|
||||
'The Vale of Glamorgan': 'Wales',
|
||||
'Vale of Glamorgan': 'Wales',
|
||||
'Tonypandy': 'Wales',
|
||||
'Torfaen': 'Wales', 'Treharris': 'Wales', 'Treorchy': 'Wales', 'Wrexham': 'Wales', 'Birmingham': 'West Midlands',
|
||||
'Bromsgrove': 'West Midlands', 'Cannock Chase': 'West Midlands', 'Coventry': 'West Midlands',
|
||||
'Dudley': 'West Midlands', 'East Staffordshire': 'West Midlands', 'Herefordshire': 'West Midlands',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue