mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Adding in costing framework wip
This commit is contained in:
parent
85989548f9
commit
e8d31d56a6
4 changed files with 34 additions and 12 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import enum
|
||||
|
||||
from sqlalchemy import Column, Integer, String, Float, Enum, TIMESTAMP
|
||||
from sqlalchemy import Column, Integer, String, Float, Enum, TIMESTAMP, Boolean
|
||||
from sqlalchemy.orm import declarative_base
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ class Material(Base):
|
|||
description = Column(String, nullable=False)
|
||||
depths = Column(String) # You may want to use a specific JSON type depending on the database
|
||||
depth_unit = Column(Enum(DepthUnit, values_callable=lambda x: [e.value for e in x]), nullable=False)
|
||||
cost = Column(Float)
|
||||
cost = Column(String)
|
||||
cost_unit = Column(Enum(CostUnit, values_callable=lambda x: [e.value for e in x]), nullable=False)
|
||||
r_value_per_mm = Column(Float)
|
||||
r_value_unit = Column(Enum(RValueUnit, values_callable=lambda x: [e.value for e in x]), nullable=False)
|
||||
|
|
@ -49,3 +49,4 @@ class Material(Base):
|
|||
)
|
||||
link = Column(String)
|
||||
created_at = Column(TIMESTAMP, nullable=False, server_default=func.now())
|
||||
is_active = Column(Boolean, nullable=False, default=True)
|
||||
|
|
|
|||
|
|
@ -200,8 +200,10 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
|
||||
# Floor recommendations
|
||||
floor_recommender = FloorRecommendations(
|
||||
property_instance=p, uvalue_estimates=floors_u_value_estimate,
|
||||
total_floor_area_group_decile=total_floor_area_group_decile
|
||||
property_instance=p,
|
||||
uvalue_estimates=floors_u_value_estimate,
|
||||
total_floor_area_group_decile=total_floor_area_group_decile,
|
||||
materials=materials_by_type["suspended_floor_insulation"] + materials_by_type["solid_floor_insulation"],
|
||||
)
|
||||
floor_recommender.recommend()
|
||||
|
||||
|
|
@ -256,8 +258,9 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
# TODO: We start off by optimising the recommendations
|
||||
|
||||
recommendations_to_upload = recommendations[p.id]
|
||||
if not recommendations:
|
||||
if not recommendations_to_upload:
|
||||
continue
|
||||
|
||||
# Create a plan
|
||||
new_plan_id = create_plan(
|
||||
{
|
||||
|
|
|
|||
|
|
@ -116,6 +116,13 @@ class FloorRecommendations(BaseUtility):
|
|||
else:
|
||||
self.materials = parts
|
||||
|
||||
self.suspended_floor_insulation_parts = [
|
||||
part for part in self.materials if part["type"] == "suspended_floor_insulation"
|
||||
]
|
||||
self.solid_floor_insulation_parts = [
|
||||
part for part in self.materials if part["type"] == "solid_floor_insulation"
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
def _estimate_perimeter(floor_area, num_rooms):
|
||||
# Compute average room size based on total floor area and number of rooms
|
||||
|
|
@ -266,11 +273,11 @@ class FloorRecommendations(BaseUtility):
|
|||
|
||||
if is_suspended:
|
||||
# Given the U-value, we recommend underfloor insulation
|
||||
self.recommend_floor_insulation(u_value=u_value, parts=suspended_floor_insulation_parts)
|
||||
self.recommend_floor_insulation(u_value=u_value, parts=self.suspended_floor_insulation_parts)
|
||||
|
||||
if is_solid:
|
||||
# Given the U-value, we recommend solid floor insulation options which are usually solid foam
|
||||
self.recommend_floor_insulation(u_value=u_value, parts=solid_floor_insulation_parts)
|
||||
self.recommend_floor_insulation(u_value=u_value, parts=self.solid_floor_insulation_parts)
|
||||
|
||||
@staticmethod
|
||||
def _make_floor_description(part, depth):
|
||||
|
|
@ -284,7 +291,8 @@ class FloorRecommendations(BaseUtility):
|
|||
|
||||
lowest_selected_u_value = None
|
||||
for part in parts:
|
||||
for depth in part["depths"]:
|
||||
for depth, cost_per_unit in zip(part["depths"], part["cost"]):
|
||||
|
||||
part_u_value = r_value_per_mm_to_u_value(depth, part["r_value_per_mm"])
|
||||
_, new_u_value = calculate_u_value_uplift(u_value, part_u_value)
|
||||
new_u_value = math.ceil(new_u_value * 100.0) / 100.0
|
||||
|
|
@ -306,7 +314,8 @@ class FloorRecommendations(BaseUtility):
|
|||
"description": self._make_floor_description(part, depth),
|
||||
"starting_u_value": u_value,
|
||||
"new_u_value": new_u_value,
|
||||
"sap_points": estimate_sap_points()
|
||||
"sap_points": estimate_sap_points(),
|
||||
"cost": cost_per_unit * self.property.floor_area,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -310,7 +310,8 @@ class WallRecommendations(BaseUtility):
|
|||
recommendations = []
|
||||
for part in parts:
|
||||
|
||||
for depth in part["depths"]:
|
||||
for depth, cost_per_unit in zip(part["depths"], part["cost"]):
|
||||
|
||||
part_u_value = r_value_per_mm_to_u_value(depth, part["r_value_per_mm"])
|
||||
|
||||
_, new_u_value = calculate_u_value_uplift(u_value, part_u_value)
|
||||
|
|
@ -339,6 +340,7 @@ class WallRecommendations(BaseUtility):
|
|||
"starting_u_value": u_value,
|
||||
"new_u_value": new_u_value,
|
||||
"sap_points": estimate_sap_points(),
|
||||
"cost": cost_per_unit * self.property.insulation_wall_area,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -371,7 +373,10 @@ class WallRecommendations(BaseUtility):
|
|||
# By looping through ewi first, if there is nothing there, that ensures not combinations are tested
|
||||
for ewi_part in ewi_parts:
|
||||
for iwi_part in iwi_parts:
|
||||
for ewi_depth, iwi_depth in itertools.product(ewi_part["depths"], iwi_part["depths"]):
|
||||
for (ewi_depth, ewi_cost_per_unit), (iwi_depth, iwi_cost_per_unit) in itertools.product(
|
||||
zip(ewi_part["depths"], ewi_part["cost"]),
|
||||
zip(iwi_part["depths"], iwi_part["cost"])
|
||||
):
|
||||
ewi_part_u_value = r_value_per_mm_to_u_value(ewi_depth, ewi_part["r_value_per_mm"])
|
||||
iwi_part_u_value = r_value_per_mm_to_u_value(iwi_depth, iwi_part["r_value_per_mm"])
|
||||
|
||||
|
|
@ -401,7 +406,11 @@ class WallRecommendations(BaseUtility):
|
|||
),
|
||||
"starting_u_value": u_value,
|
||||
"new_u_value": combined_new_u_value,
|
||||
"sap_points": estimate_sap_points()
|
||||
"sap_points": estimate_sap_points(),
|
||||
"cost": (
|
||||
ewi_cost_per_unit * self.property.insulation_wall_area + iwi_cost_per_unit *
|
||||
self.property.insulation_wall_area
|
||||
),
|
||||
}
|
||||
self.recommendations.append(recommendation)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue