working on costing for led installation

This commit is contained in:
Khalim Conn-Kowlessar 2023-11-28 16:54:14 +00:00
parent e441e5f018
commit 96b49aa680
6 changed files with 92 additions and 2 deletions

View file

@ -83,6 +83,7 @@ class Property(Definitions):
self.floor_area = None
self.pitched_roof_area = None
self.insulation_floor_area = None
self.number_lighting_outlets = None
if epc_client:
self.epc_client = epc_client
@ -703,7 +704,6 @@ class Property(Definitions):
'PROPERTY_TYPE',
'UPRN',
'NUMBER_OPEN_FIREPLACES',
'FIXED_LIGHTING_OUTLETS_COUNT',
'MULTI_GLAZE_PROPORTION',
'MECHANICAL_VENTILATION',
'PHOTO_SUPPLY',
@ -752,9 +752,21 @@ class Property(Definitions):
"FLOOR_HEIGHT": self.floor_height,
"NUMBER_HABITABLE_ROOMS": self.number_of_rooms,
"TOTAL_FLOOR_AREA": self.floor_area,
"FIXED_LIGHTING_OUTLETS_COUNT": self.number_lighting_outlets,
**epc_raw_data,
"BUILT_FORM": built_form,
"POSTCODE": self.data["postcode"],
}
return property_data
def set_number_lighting_outlets(self, cleaned_property_data):
"""
Extracts and cleans the estimated number of lighting outlets
:return:
"""
if self.data["fixed-lighting-outlets-count"] == "":
self.number_lighting_outlets = round(cleaned_property_data["FIXED_LIGHTING_OUTLETS_COUNT"].values[0])
else:
self.number_lighting_outlets = float(self.data["fixed-lighting-outlets-count"])

View file

@ -32,6 +32,7 @@ class MaterialType(enum.Enum):
ewi_wall_demolition = "ewi_wall_demolition"
ewi_wall_preparation = "ewi_wall_preparation"
ewi_wall_redecoration = "ewi_wall_redecoration"
low_energy_lighting_installation = "low_energy_lighting_installation"
class DepthUnit(enum.Enum):

View file

@ -124,6 +124,14 @@ async def trigger_plan(body: PlanTriggerRequest):
# Property recommendations
p.get_components(cleaned)
# This is temp - this should happen after scoring
cleaned_property_data = DataProcessor.apply_averages_cleaning(
data_to_clean=pd.DataFrame([dict(**p.get_model_data(), LOCAL_AUTHORITY=p.data["local-authority"])]),
cleaning_data=cleaning_data,
cols_to_merge_on=['PROPERTY_TYPE', 'BUILT_FORM', 'CONSTRUCTION_AGE_BAND', 'LOCAL_AUTHORITY'],
)
p.set_number_lighting_outlets(cleaned_property_data)
recommender = Recommendations(property_instance=p, materials=materials)
property_recommendations = recommender.recommend()

View file

@ -595,3 +595,33 @@ class Costs:
contingency = self.HIGH_RISK_CONTINGENCY
else:
contingency = self.CONTINGENCY
material_cost = material["material_cost"] * number_of_lights
labour_cost = material["labour_cost"] * number_of_lights * self.labour_adjustment_factor
subtotal_before_profit = material_cost + labour_cost
contingency_cost = subtotal_before_profit * contingency
preliminaries_cost = subtotal_before_profit * self.PRELIMINARIES
profit_cost = subtotal_before_profit * self.PROFIT_MARGIN
subtotal_before_vat = subtotal_before_profit + contingency_cost + preliminaries_cost + profit_cost
vat_cost = subtotal_before_vat * self.VAT_RATE
total_cost = subtotal_before_vat + vat_cost
labour_hours = material["labour_hours_per_unit"] * number_of_lights
# Assume a single electrician installing
labour_days = (labour_hours / 8)
return {
"total": total_cost,
"subtotal": subtotal_before_vat,
"vat": vat_cost,
"contingency": contingency_cost,
"preliminaries": preliminaries_cost,
"material": material_cost,
"profit": profit_cost,
"labour_hours": labour_hours,
"labour_days": labour_days,
"labour_cost": labour_cost
}

View file

@ -1,5 +1,6 @@
from backend.Property import Property
from typing import List
from recommendations.Costs import Costs
class LightingRecommendations:
@ -11,7 +12,16 @@ class LightingRecommendations:
"""
self.property = property_instance
self.materials = materials
self.costs = Costs(self.property)
material = [
material for material in materials if material["type"] == "low_energy_lighting_installation"
]
if len(material) != 1:
raise ValueError("Incorrect number of low energy lighting materials specified")
self.material = material[0]
self.recommendation = []
def recommend(self):
"""
@ -32,3 +42,25 @@ class LightingRecommendations:
)
number_non_lel_outlets = round(number_non_lel_outlets)
if number_non_lel_outlets == 0:
return
# Get the cost of the fittings
cost_result = self.costs.low_energy_lighting(
number_of_lights=number_non_lel_outlets,
number_current_lel_lights=number_lighting_outlets - number_non_lel_outlets,
material=self.material
)
self.recommendation = [
{
"parts": [],
"type": "sealing_open_fireplace",
"description": "Install low energy lighting in %s outlets" % str(number_non_lel_outlets),
"starting_u_value": None,
"new_u_value": None,
"sap_points": None,
**cost_result
}
]

View file

@ -5,6 +5,7 @@ from recommendations.WallRecommendations import WallRecommendations
from recommendations.RoofRecommendations import RoofRecommendations
from recommendations.VentilationRecommendations import VentilationRecommendations
from recommendations.FireplaceRecommendations import FireplaceRecommendations
from recommendations.LightingRecommendations import LightingRecommendations
from backend.ml_models.AnnualBillSavings import AnnualBillSavings
@ -34,6 +35,7 @@ class Recommendations:
materials=[part for part in materials if part["type"] == "mechanical_ventilation"]
)
self.fireplace_recommender = FireplaceRecommendations(property_instance=property_instance)
self.lighting_recommender = LightingRecommendations(property_instance=property_instance, materials=materials)
def recommend(self):
@ -69,6 +71,11 @@ class Recommendations:
if self.fireplace_recommender.recommendation:
property_recommendations.append(self.fireplace_recommender.recommendation)
# Lighting recommendations
self.lighting_recommender.recommend()
if self.lighting_recommender.recommendation:
property_recommendations.append(self.lighting_recommender.recommendation)
# We insert temporary ids into the recommendations which is important for the optimiser later
property_recommendations = self.insert_temp_recommendation_id(property_recommendations)