Wrote ventilation recommendations, still needs unit tests

This commit is contained in:
Khalim Conn-Kowlessar 2023-10-18 17:25:50 +11:00
parent b938285009
commit ada2101a73
7 changed files with 92 additions and 8 deletions

2
.idea/Model.iml generated
View file

@ -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
View file

@ -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>

View file

@ -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):

View file

@ -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)

View file

@ -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"],

View 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,
}
]

View file

@ -1,4 +1,3 @@
import itertools
import math
from typing import List