mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Wrote ventilation recommendations, still needs unit tests
This commit is contained in:
parent
b938285009
commit
ada2101a73
7 changed files with 92 additions and 8 deletions
2
.idea/Model.iml
generated
2
.idea/Model.iml
generated
|
|
@ -7,7 +7,7 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/open_uprn" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/recommendations" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.10 (model_data)" jdkType="Python SDK" />
|
||||
<orderEntry type="jdk" jdkName="Python 3.10 (backend)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyNamespacePackagesService">
|
||||
|
|
|
|||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (model_data)" project-jdk-type="Python SDK" />
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (backend)" project-jdk-type="Python SDK" />
|
||||
<component name="PythonCompatibilityInspectionAdvertiser">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ class MaterialType(enum.Enum):
|
|||
external_wall_insulation = "external_wall_insulation"
|
||||
internal_wall_insulation = "internal_wall_insulation"
|
||||
cavity_wall_insulation = "cavity_wall_insulation"
|
||||
mechanical_ventilation = "mechanical_ventilation"
|
||||
|
||||
|
||||
class DepthUnit(enum.Enum):
|
||||
|
|
@ -21,6 +22,7 @@ class DepthUnit(enum.Enum):
|
|||
|
||||
class CostUnit(enum.Enum):
|
||||
gbp_sq_meter = "gbp_sq_meter"
|
||||
gbp_per_unit = "gbp_per_unit"
|
||||
|
||||
|
||||
class RValueUnit(enum.Enum):
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ from backend.Property import Property
|
|||
from etl.epc.DataProcessor import DataProcessor
|
||||
from etl.epc.settings import COLUMNS_TO_MERGE_ON
|
||||
from recommendations.FloorRecommendations import FloorRecommendations
|
||||
from recommendations.VentilationRecommendations import VentilationRecommendations
|
||||
from recommendations.optimiser.CostOptimiser import CostOptimiser
|
||||
from recommendations.optimiser.GainOptimiser import GainOptimiser
|
||||
from recommendations.optimiser.optimiser_functions import prepare_input_measures
|
||||
|
|
@ -125,9 +126,6 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
#
|
||||
# with open("cleaned.pickle", "rb") as f:
|
||||
# cleaned = pickle.load(f)
|
||||
#
|
||||
# with open("materials_by_type.pickle", "wb") as f:
|
||||
# materials_by_type = pickle.load(f)
|
||||
|
||||
recommendations = {}
|
||||
recommendations_scoring_data = []
|
||||
|
|
@ -160,6 +158,16 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
if wall_recomender.recommendations:
|
||||
property_recommendations.append(wall_recomender.recommendations)
|
||||
|
||||
# Ventilation recommendations
|
||||
ventilation_recomender = VentilationRecommendations(
|
||||
property_instance=p,
|
||||
materials=materials_by_type["ventilation"]
|
||||
)
|
||||
ventilation_recomender.recommend()
|
||||
|
||||
if ventilation_recomender.recommendation:
|
||||
property_recommendations.append(ventilation_recomender.recommendation)
|
||||
|
||||
# We insert temporary ids into the recommendations which is important for the optimiser later
|
||||
property_recommendations = insert_temp_recommendation_id(property_recommendations)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ def filter_materials(materials):
|
|||
|
||||
mapping = {
|
||||
"walls": ["internal_wall_insulation", "external_wall_insulation", "cavity_wall_insulation"],
|
||||
"floor": ["suspended_floor_insulation", "solid_floor_insulation"]
|
||||
"floor": ["suspended_floor_insulation", "solid_floor_insulation"],
|
||||
"ventilation": ["mechanical_ventilation"],
|
||||
}
|
||||
|
||||
materials = [row2dict(material) for material in materials]
|
||||
|
|
@ -164,9 +165,13 @@ def create_recommendation_scoring_data(
|
|||
if scoring_dict["floor_insulation_thickness_ENDING"] is None:
|
||||
scoring_dict["floor_insulation_thickness_ENDING"] = "none"
|
||||
|
||||
if recommendation["type"] not in ["wall_insulation", "floor_insulation"]:
|
||||
if recommendation["type"] == "mechanical_ventilation":
|
||||
scoring_dict["MECHANICAL_VENTILATION_ENDING"] = 'mechanical, extract only'
|
||||
|
||||
if recommendation["type"] not in ["wall_insulation", "floor_insulation", "mechanical_ventilation"]:
|
||||
raise NotImplementedError("Implement me")
|
||||
|
||||
# Fill missing roof u-values - this fill is not based on recommended upgrades
|
||||
if scoring_dict["roof_thermal_transmittance_ENDING"] is None:
|
||||
scoring_dict["roof_thermal_transmittance_ENDING"] = get_roof_u_value(
|
||||
insulation_thickness=property.roof["insulation_thickness"],
|
||||
|
|
|
|||
70
recommendations/VentilationRecommendations.py
Normal file
70
recommendations/VentilationRecommendations.py
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
import pandas as pd
|
||||
from BaseUtility import Definitions
|
||||
from backend.Property import Property
|
||||
|
||||
|
||||
class VentilationRecommendations(Definitions):
|
||||
"""
|
||||
For properties that do not have ventilation, we recommend installing ventilaion
|
||||
This is particularly important for properties that have insulated walls and is also
|
||||
crucial for prevent overheating risks in warmer months
|
||||
"""
|
||||
|
||||
VENTILATION_DESCRIPTIONS = [
|
||||
'mechanical, extract only',
|
||||
'mechanical, supply and extract'
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
property_instance: Property,
|
||||
materials
|
||||
):
|
||||
self.property = property_instance
|
||||
|
||||
self.has_ventilaion = None
|
||||
self.recommendation = None
|
||||
self.materials = materials
|
||||
|
||||
def identify_ventilation(self):
|
||||
self.has_ventilaion = self.property.data["mechanical-ventilation"] in self.VENTILATION_DESCRIPTIONS
|
||||
|
||||
def recommend(self):
|
||||
"""
|
||||
If there is no ventilation, we recommend installing ventilation
|
||||
|
||||
Generally, best practice is to install controlled ventilation for insulated walls so we still recommend
|
||||
ventilation if there is natural ventilation
|
||||
:return:
|
||||
"""
|
||||
|
||||
self.identify_ventilation()
|
||||
if self.has_ventilaion:
|
||||
return
|
||||
|
||||
if len(self.materials) != 1:
|
||||
raise NotImplementedError("Only handled the case of having one venilation option")
|
||||
|
||||
# We recommend installing 2 units
|
||||
n_units = 2
|
||||
|
||||
part = self.materials.copy()
|
||||
|
||||
estimated_cost = n_units * part[0]["cost"]
|
||||
|
||||
part[0]["estimated_cost"] = estimated_cost
|
||||
part[0]["quantity"] = n_units
|
||||
part[0]["quantity_unit"] = None
|
||||
|
||||
# We recommend installing two mechanical ventilation systems
|
||||
self.recommendation = [
|
||||
{
|
||||
"parts": part,
|
||||
"type": part[0]["type"],
|
||||
"description": "Install %s" % part[0]["description"],
|
||||
"starting_u_value": None,
|
||||
"new_u_value": None,
|
||||
"sap_points": None,
|
||||
"cost": estimated_cost,
|
||||
}
|
||||
]
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
import itertools
|
||||
import math
|
||||
from typing import List
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue