mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
ammended system change costs for first time central heating
This commit is contained in:
parent
1ee115fa7e
commit
14a1f35fb1
2 changed files with 77 additions and 4 deletions
|
|
@ -83,6 +83,14 @@ CONVENTIONAL_BOILER_COSTS = {
|
||||||
ROOM_HEATER_REMOVAL_COST = 120
|
ROOM_HEATER_REMOVAL_COST = 120
|
||||||
ROOM_HEATER_REMOVAL_LABOUR_HOURS = 3
|
ROOM_HEATER_REMOVAL_LABOUR_HOURS = 3
|
||||||
|
|
||||||
|
# This is a cost quoted by Jim for a system flush - existig system will run more efficiently
|
||||||
|
SYSTEM_FLUSH_COST = 250
|
||||||
|
|
||||||
|
SINGLE_RADIATOR_COST = 150
|
||||||
|
DOUBLE_RADIATOR_COST = 300
|
||||||
|
FLUE_COST = 600
|
||||||
|
PIPEWORK_COST = 750 # Min cost is £500
|
||||||
|
|
||||||
|
|
||||||
class Costs:
|
class Costs:
|
||||||
"""
|
"""
|
||||||
|
|
@ -1126,9 +1134,45 @@ class Costs:
|
||||||
"labour_days": np.ceil(removal_labour_hours / 8),
|
"labour_days": np.ceil(removal_labour_hours / 8),
|
||||||
}
|
}
|
||||||
|
|
||||||
def boiler(self, is_combi, size, exising_room_heaters, n_heated_rooms):
|
@staticmethod
|
||||||
|
def _estimate_n_radiators(number_habitable_rooms, total_floor_area, property_type, built_form):
|
||||||
|
# Base number of radiators: one per habitable room
|
||||||
|
base_radiators = number_habitable_rooms
|
||||||
|
|
||||||
|
# Additional radiators for non-habitable essential areas (e.g., kitchens, hallways)
|
||||||
|
additional_radiators = 3 # Initial assumption
|
||||||
|
|
||||||
|
# Adjust additional radiators based on property type
|
||||||
|
if property_type == 'Flat':
|
||||||
|
additional_radiators -= 1 # Flats may need fewer radiators due to less exposure
|
||||||
|
elif property_type in ['House', 'Bungalow', 'Maisonette']:
|
||||||
|
# Multiple floors in Maisonette may require additional heating points
|
||||||
|
additional_radiators += 2 # Houses and bungalows might need more due to greater exposure
|
||||||
|
else:
|
||||||
|
raise Exception("Invalid property type")
|
||||||
|
|
||||||
|
# Adjust total radiator needs based on built form
|
||||||
|
form_factor = {
|
||||||
|
'Mid-Terrace': 0.95,
|
||||||
|
'Semi-Detached': 1.05,
|
||||||
|
'Detached': 1.25,
|
||||||
|
'End-Terrace': 1.05
|
||||||
|
}
|
||||||
|
|
||||||
|
# Calculate total heating power needed and number of radiators based on standard output
|
||||||
|
total_heating_power_required = total_floor_area * 80 # Watts per square meter
|
||||||
|
radiator_output = 1000 # Average wattage per radiator
|
||||||
|
total_radiators_based_on_power = (total_heating_power_required / radiator_output) * form_factor[built_form]
|
||||||
|
|
||||||
|
# Final estimation taking the higher of calculated needs or base room count
|
||||||
|
estimated_radiators = max(total_radiators_based_on_power, base_radiators + additional_radiators)
|
||||||
|
return round(estimated_radiators)
|
||||||
|
|
||||||
|
def boiler(self, is_combi, size, exising_room_heaters, system_change, n_heated_rooms, n_rooms):
|
||||||
"""
|
"""
|
||||||
Based on a basic estimate of median value £2600 to install a low carbon combi boiler
|
Based on a basic estimate of median value £2600 to install a low carbon combi boiler
|
||||||
|
First time central heating vosts can als be found here:
|
||||||
|
https://www.checkatrade.com/blog/cost-guides/central-heating-installation-cost/
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -1137,11 +1181,11 @@ class Costs:
|
||||||
# We now need to estimate the cost of the works
|
# We now need to estimate the cost of the works
|
||||||
labour_days = 2
|
labour_days = 2
|
||||||
labour_hours = labour_days * 8
|
labour_hours = labour_days * 8
|
||||||
labour_rate = 500
|
labour_rate = 300
|
||||||
|
|
||||||
# Average cost of installation is 1 (maybe 2days) at £300 per day
|
# Average cost of installation is 1 (maybe 2days) at £300 per day
|
||||||
# https://www.checkatrade.com/blog/cost-guides/new-boiler-cost/
|
# https://www.checkatrade.com/blog/cost-guides/new-boiler-cost/
|
||||||
# To be pessimistic, assume 2 days work and £500 day rate
|
# To be pessimistic, assume 2 days work
|
||||||
labour_cost = labour_rate * self.labour_adjustment_factor * labour_days
|
labour_cost = labour_rate * self.labour_adjustment_factor * labour_days
|
||||||
# Add contingency and preliminaries
|
# Add contingency and preliminaries
|
||||||
labour_cost = labour_cost * (1 + self.CONTINGENCY + self.PRELIMINARIES)
|
labour_cost = labour_cost * (1 + self.CONTINGENCY + self.PRELIMINARIES)
|
||||||
|
|
@ -1161,6 +1205,28 @@ class Costs:
|
||||||
subtotal_before_vat += removal_costing["subtotal"]
|
subtotal_before_vat += removal_costing["subtotal"]
|
||||||
labour_hours += removal_costing["labour_hours"]
|
labour_hours += removal_costing["labour_hours"]
|
||||||
labour_days += removal_costing["labour_days"]
|
labour_days += removal_costing["labour_days"]
|
||||||
|
vat += removal_costing["vat"]
|
||||||
|
|
||||||
|
if system_change:
|
||||||
|
# We need the cost of radiators
|
||||||
|
n_radiators = self._estimate_n_radiators(
|
||||||
|
number_habitable_rooms=n_rooms,
|
||||||
|
total_floor_area=self.property.floor_area,
|
||||||
|
property_type=self.property.data["property-type"],
|
||||||
|
built_form=self.property.data["built-form"]
|
||||||
|
)
|
||||||
|
|
||||||
|
additionals_labour_cost = labour_rate * self.labour_adjustment_factor
|
||||||
|
radiator_cost = DOUBLE_RADIATOR_COST * n_radiators
|
||||||
|
system_change_cost = radiator_cost + FLUE_COST + PIPEWORK_COST + additionals_labour_cost
|
||||||
|
system_change_cost_before_vat = system_change_cost / (1 + self.VAT_RATE)
|
||||||
|
system_change_vat = system_change_cost - system_change_cost_before_vat
|
||||||
|
# We add an extra labour day for the system change
|
||||||
|
labour_days += 1
|
||||||
|
labour_hours += 8
|
||||||
|
total_cost += system_change_cost
|
||||||
|
subtotal_before_vat += system_change_cost_before_vat
|
||||||
|
vat += system_change_vat
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"total": total_cost,
|
"total": total_cost,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,11 @@ class HeatingRecommender:
|
||||||
self.recommendations = []
|
self.recommendations = []
|
||||||
|
|
||||||
def recommend(self, phase=0):
|
def recommend(self, phase=0):
|
||||||
|
|
||||||
|
# TODO: We could have a system flush recommendation for an existing boiler, where there is no need to replace
|
||||||
|
# the boiler, but instead flushing the system will make it run more efficiently. There is a cost for this
|
||||||
|
# in the Costs class, stored as SYSTEM_FLUSH_COST
|
||||||
|
|
||||||
self.recommendations = []
|
self.recommendations = []
|
||||||
# This first iteration of the recommender will provide very basic recommendation
|
# This first iteration of the recommender will provide very basic recommendation
|
||||||
# We recommend heating controls based on the main heating system
|
# We recommend heating controls based on the main heating system
|
||||||
|
|
@ -361,7 +366,9 @@ class HeatingRecommender:
|
||||||
is_combi=is_combi,
|
is_combi=is_combi,
|
||||||
size=f"{boiler_size}kw",
|
size=f"{boiler_size}kw",
|
||||||
exising_room_heaters=exising_room_heaters,
|
exising_room_heaters=exising_room_heaters,
|
||||||
n_heated_rooms=self.property.data["number-heated-rooms"]
|
system_change=system_change,
|
||||||
|
n_heated_rooms=self.property.data["number-heated-rooms"],
|
||||||
|
n_rooms=self.property.number_of_rooms
|
||||||
)
|
)
|
||||||
|
|
||||||
is_override = "heating" in self.property.override
|
is_override = "heating" in self.property.override
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue