2024-04-10 10:27:10 -04:00
|
|
|
"""
|
|
|
|
Cost module
|
|
|
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|
|
|
Copyright © 2023 Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
|
|
|
Code contributor Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|
|
|
Code contributor Oriol Gavalda Torrellas oriol.gavalda@concordia.ca
|
|
|
|
"""
|
|
|
|
import datetime
|
|
|
|
|
|
|
|
import pandas as pd
|
|
|
|
import numpy_financial as npf
|
|
|
|
from hub.city_model_structure.building import Building
|
|
|
|
from hub.helpers.dictionaries import Dictionaries
|
2024-04-10 10:27:10 -04:00
|
|
|
from scripts.costs.configuration import Configuration
|
|
|
|
from scripts.costs.capital_costs import CapitalCosts
|
|
|
|
from scripts.costs.end_of_life_costs import EndOfLifeCosts
|
|
|
|
from scripts.costs.total_maintenance_costs import TotalMaintenanceCosts
|
|
|
|
from scripts.costs.total_operational_costs import TotalOperationalCosts
|
|
|
|
from scripts.costs.total_operational_incomes import TotalOperationalIncomes
|
|
|
|
from scripts.costs.constants import CURRENT_STATUS, SKIN_RETROFIT, SYSTEM_RETROFIT_AND_PV, SKIN_RETROFIT_AND_SYSTEM_RETROFIT_AND_PV
|
|
|
|
import hub.helpers.constants as cte
|
2024-04-10 10:27:10 -04:00
|
|
|
|
|
|
|
|
|
|
|
class Cost:
|
|
|
|
"""
|
|
|
|
Cost class
|
|
|
|
"""
|
|
|
|
|
|
|
|
def __init__(self,
|
|
|
|
building: Building,
|
|
|
|
number_of_years=31,
|
|
|
|
percentage_credit=0,
|
|
|
|
interest_rate=0.04,
|
|
|
|
credit_years=15,
|
|
|
|
consumer_price_index=0.04,
|
|
|
|
electricity_peak_index=0.05,
|
|
|
|
electricity_price_index=0.05,
|
2024-04-10 10:27:10 -04:00
|
|
|
fuel_price_index=0.05,
|
2024-04-10 10:27:10 -04:00
|
|
|
discount_rate=0.03,
|
|
|
|
retrofitting_year_construction=2020,
|
2024-04-10 10:27:10 -04:00
|
|
|
factories_handler='montreal_new',
|
2024-04-10 10:27:10 -04:00
|
|
|
retrofit_scenario=CURRENT_STATUS,
|
|
|
|
dictionary=None):
|
|
|
|
if dictionary is None:
|
|
|
|
dictionary = Dictionaries().hub_function_to_montreal_custom_costs_function
|
|
|
|
self._building = building
|
2024-04-10 10:27:10 -04:00
|
|
|
fuel_type = self._building.energy_consumption_breakdown.keys()
|
2024-04-10 10:27:10 -04:00
|
|
|
self._configuration = Configuration(number_of_years,
|
|
|
|
percentage_credit,
|
|
|
|
interest_rate, credit_years,
|
|
|
|
consumer_price_index,
|
|
|
|
electricity_peak_index,
|
|
|
|
electricity_price_index,
|
2024-04-10 10:27:10 -04:00
|
|
|
fuel_price_index,
|
2024-04-10 10:27:10 -04:00
|
|
|
discount_rate,
|
|
|
|
retrofitting_year_construction,
|
|
|
|
factories_handler,
|
|
|
|
retrofit_scenario,
|
|
|
|
fuel_type,
|
|
|
|
dictionary)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def building(self) -> Building:
|
|
|
|
"""
|
|
|
|
Get current building.
|
|
|
|
"""
|
|
|
|
return self._building
|
|
|
|
|
|
|
|
def _npv_from_list(self, list_cashflow):
|
|
|
|
return npf.npv(self._configuration.discount_rate, list_cashflow)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def life_cycle(self) -> pd.DataFrame:
|
|
|
|
"""
|
|
|
|
Get complete life cycle costs
|
|
|
|
:return: DataFrame
|
|
|
|
"""
|
|
|
|
results = pd.DataFrame()
|
|
|
|
global_capital_costs, global_capital_incomes = CapitalCosts(self._building, self._configuration).calculate()
|
|
|
|
global_end_of_life_costs = EndOfLifeCosts(self._building, self._configuration).calculate()
|
|
|
|
global_operational_costs = TotalOperationalCosts(self._building, self._configuration).calculate()
|
|
|
|
global_maintenance_costs = TotalMaintenanceCosts(self._building, self._configuration).calculate()
|
|
|
|
global_operational_incomes = TotalOperationalIncomes(self._building, self._configuration).calculate()
|
2024-04-10 10:27:10 -04:00
|
|
|
|
2024-04-10 10:27:10 -04:00
|
|
|
df_capital_costs_skin = (
|
|
|
|
global_capital_costs['B2010_opaque_walls'] +
|
|
|
|
global_capital_costs['B2020_transparent'] +
|
|
|
|
global_capital_costs['B3010_opaque_roof'] +
|
2024-04-10 10:27:10 -04:00
|
|
|
global_capital_costs['B1010_superstructure']
|
2024-04-10 10:27:10 -04:00
|
|
|
)
|
|
|
|
df_capital_costs_systems = (
|
2024-04-10 10:27:10 -04:00
|
|
|
global_capital_costs['D3020_heat_and_cooling_generating_systems'] +
|
|
|
|
global_capital_costs['D3040_distribution_systems'] +
|
|
|
|
global_capital_costs['D3050_other_hvac_ahu'] +
|
|
|
|
global_capital_costs['D3060_storage_systems'] +
|
|
|
|
global_capital_costs['D40_dhw'] +
|
2024-04-10 10:27:10 -04:00
|
|
|
global_capital_costs['D5020_lighting_and_branch_wiring'] +
|
2024-04-10 10:27:10 -04:00
|
|
|
global_capital_costs['D2010_photovoltaic_system']
|
2024-04-10 10:27:10 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
df_end_of_life_costs = global_end_of_life_costs['End_of_life_costs']
|
2024-04-10 10:27:10 -04:00
|
|
|
operational_costs_list = [
|
|
|
|
global_operational_costs['Fixed Costs Electricity Peak'],
|
|
|
|
global_operational_costs['Fixed Costs Electricity Monthly'],
|
|
|
|
global_operational_costs['Variable Costs Electricity']
|
|
|
|
]
|
|
|
|
additional_costs = [
|
|
|
|
global_operational_costs[f'Fixed Costs {fuel}'] for fuel in
|
2024-04-10 10:27:10 -04:00
|
|
|
self._building.energy_consumption_breakdown.keys() if fuel != cte.ELECTRICITY
|
2024-04-10 10:27:10 -04:00
|
|
|
] + [
|
|
|
|
global_operational_costs[f'Variable Costs {fuel}'] for fuel in
|
2024-04-10 10:27:10 -04:00
|
|
|
self._building.energy_consumption_breakdown.keys() if fuel != cte.ELECTRICITY
|
2024-04-10 10:27:10 -04:00
|
|
|
]
|
|
|
|
df_operational_costs = sum(operational_costs_list + additional_costs)
|
2024-04-10 10:27:10 -04:00
|
|
|
df_maintenance_costs = (
|
|
|
|
global_maintenance_costs['Heating_maintenance'] +
|
|
|
|
global_maintenance_costs['Cooling_maintenance'] +
|
|
|
|
global_maintenance_costs['PV_maintenance']
|
|
|
|
)
|
|
|
|
df_operational_incomes = global_operational_incomes['Incomes electricity']
|
|
|
|
df_capital_incomes = (
|
|
|
|
global_capital_incomes['Subsidies construction'] +
|
|
|
|
global_capital_incomes['Subsidies HVAC'] +
|
|
|
|
global_capital_incomes['Subsidies PV']
|
|
|
|
)
|
|
|
|
|
|
|
|
life_cycle_costs_capital_skin = self._npv_from_list(df_capital_costs_skin.values.tolist())
|
|
|
|
life_cycle_costs_capital_systems = self._npv_from_list(df_capital_costs_systems.values.tolist())
|
|
|
|
life_cycle_costs_end_of_life_costs = self._npv_from_list(df_end_of_life_costs.values.tolist())
|
2024-04-10 10:27:10 -04:00
|
|
|
life_cycle_operational_costs = self._npv_from_list(df_operational_costs)
|
2024-04-10 10:27:10 -04:00
|
|
|
life_cycle_maintenance_costs = self._npv_from_list(df_maintenance_costs.values.tolist())
|
|
|
|
life_cycle_operational_incomes = self._npv_from_list(df_operational_incomes.values.tolist())
|
|
|
|
life_cycle_capital_incomes = self._npv_from_list(df_capital_incomes.values.tolist())
|
|
|
|
|
|
|
|
results[f'Scenario {self._configuration.retrofit_scenario}'] = [
|
|
|
|
life_cycle_costs_capital_skin,
|
|
|
|
life_cycle_costs_capital_systems,
|
|
|
|
life_cycle_costs_end_of_life_costs,
|
|
|
|
life_cycle_operational_costs,
|
|
|
|
life_cycle_maintenance_costs,
|
|
|
|
life_cycle_operational_incomes,
|
|
|
|
life_cycle_capital_incomes,
|
|
|
|
global_capital_costs,
|
|
|
|
global_capital_incomes,
|
|
|
|
global_end_of_life_costs,
|
|
|
|
global_operational_costs,
|
|
|
|
global_maintenance_costs,
|
|
|
|
global_operational_incomes
|
|
|
|
]
|
|
|
|
|
|
|
|
results.index = [
|
|
|
|
'total_capital_costs_skin',
|
|
|
|
'total_capital_costs_systems',
|
|
|
|
'end_of_life_costs',
|
|
|
|
'total_operational_costs',
|
|
|
|
'total_maintenance_costs',
|
|
|
|
'operational_incomes',
|
|
|
|
'capital_incomes',
|
|
|
|
'global_capital_costs',
|
|
|
|
'global_capital_incomes',
|
|
|
|
'global_end_of_life_costs',
|
|
|
|
'global_operational_costs',
|
|
|
|
'global_maintenance_costs',
|
|
|
|
'global_operational_incomes'
|
|
|
|
]
|
|
|
|
return results
|