fix: pv modelling workflow updated, montreal custom systems added to future catalogue

This commit is contained in:
Saeed Ranjbar 2024-11-19 13:25:54 +01:00
parent b633dca635
commit e4c761850b
18 changed files with 634 additions and 677 deletions

View File

@ -6,8 +6,6 @@ from energy_system_modelling_package.energy_system_modelling_factories.hvac_dhw_
HeatPumpCooling
from energy_system_modelling_package.energy_system_modelling_factories.hvac_dhw_systems_simulation_models.domestic_hot_water_heat_pump_with_tes import \
DomesticHotWaterHeatPumpTes
from energy_system_modelling_package.energy_system_modelling_factories.pv_assessment.pv_model import PVModel
from energy_system_modelling_package.energy_system_modelling_factories.pv_assessment.electricity_demand_calculator import HourlyElectricityDemand
import hub.helpers.constants as cte
from hub.helpers.monthly_values import MonthlyValues
@ -21,10 +19,6 @@ class ArchetypeCluster1:
self.heating_results, self.building_heating_hourly_consumption = self.heating_system_simulation()
self.cooling_results, self.total_cooling_consumption_hourly = self.cooling_system_simulation()
self.dhw_results, self.total_dhw_consumption_hourly = self.dhw_system_simulation()
if 'PV' in self.building.energy_systems_archetype_name:
self.pv_results = self.pv_system_simulation()
else:
self.pv_results = None
def heating_system_simulation(self):
building_heating_hourly_consumption = []
@ -55,7 +49,7 @@ class ArchetypeCluster1:
return results, building_heating_hourly_consumption
def cooling_system_simulation(self):
hp = self.building.energy_systems[1].generation_systems[1]
hp = self.building.energy_systems[2].generation_systems[0]
cooling_demand_joules = self.building.cooling_demand[cte.HOUR]
cooling_peak_load = self.building.cooling_peak_load[cte.YEAR][0]
cutoff_temperature = 13
@ -71,8 +65,8 @@ class ArchetypeCluster1:
def dhw_system_simulation(self):
building_dhw_hourly_consumption = []
hp = self.building.energy_systems[2].generation_systems[0]
tes = self.building.energy_systems[2].generation_systems[0].energy_storage_systems[0]
hp = self.building.energy_systems[-1].generation_systems[0]
tes = self.building.energy_systems[-1].generation_systems[0].energy_storage_systems[0]
dhw_demand_joules = self.building.domestic_hot_water_heat_demand[cte.HOUR]
upper_limit_tes = 65
outdoor_temperature = self.building.external_temperature[cte.HOUR]
@ -93,18 +87,6 @@ class ArchetypeCluster1:
dhw_consumption = 0
return results, building_dhw_hourly_consumption
def pv_system_simulation(self):
results = None
pv = self.building.energy_systems[0].generation_systems[0]
hourly_electricity_demand = HourlyElectricityDemand(self.building).calculate()
model_type = 'fixed_efficiency'
if model_type == 'fixed_efficiency':
results = PVModel(pv=pv,
hourly_electricity_demand_joules=hourly_electricity_demand,
solar_radiation=self.building.roofs[0].global_irradiance_tilted[cte.HOUR],
installed_pv_area=self.building.roofs[0].installed_solar_collector_area,
model_type='fixed_efficiency').fixed_efficiency()
return results
def enrich_building(self):
results = self.heating_results | self.cooling_results | self.dhw_results
@ -121,19 +103,6 @@ class ArchetypeCluster1:
MonthlyValues.get_total_month(self.building.domestic_hot_water_consumption[cte.HOUR]))
self.building.domestic_hot_water_consumption[cte.YEAR] = [
sum(self.building.domestic_hot_water_consumption[cte.MONTH])]
if self.pv_results is not None:
self.building.onsite_electrical_production[cte.HOUR] = [x * cte.WATTS_HOUR_TO_JULES for x in
self.pv_results['PV Output (W)']]
self.building.onsite_electrical_production[cte.MONTH] = MonthlyValues.get_total_month(self.building.onsite_electrical_production[cte.HOUR])
self.building.onsite_electrical_production[cte.YEAR] = [sum(self.building.onsite_electrical_production[cte.MONTH])]
if self.csv_output:
file_name = f'pv_system_simulation_results_{self.building.name}.csv'
with open(self.output_path / file_name, 'w', newline='') as csvfile:
output_file = csv.writer(csvfile)
# Write header
output_file.writerow(self.pv_results.keys())
# Write data
output_file.writerows(zip(*self.pv_results.values()))
if self.csv_output:
file_name = f'energy_system_simulation_results_{self.building.name}.csv'
with open(self.output_path / file_name, 'w', newline='') as csvfile:

View File

@ -9,7 +9,6 @@ from energy_system_modelling_package.energy_system_modelling_factories.system_si
PeakLoadSizing
from energy_system_modelling_package.energy_system_modelling_factories.system_sizing_methods.heuristic_sizing import \
HeuristicSizing
from energy_system_modelling_package.energy_system_modelling_factories.pv_assessment.pv_sizing import PVSizing
class EnergySystemsSizingFactory:
@ -39,33 +38,6 @@ class EnergySystemsSizingFactory:
for building in self._city.buildings:
building.level_of_detail.energy_systems = 1
def _pv_sizing(self):
"""
Size rooftop, facade or mixture of them for buildings
"""
system_type = 'rooftop'
results = {}
if system_type == 'rooftop':
surface_azimuth = 180
maintenance_factor = 0.1
mechanical_equipment_factor = 0.3
orientation_factor = 0.1
tilt_angle = self._city.latitude
pv_sizing = PVSizing(self._city,
tilt_angle=tilt_angle,
surface_azimuth=surface_azimuth,
mechanical_equipment_factor=mechanical_equipment_factor,
maintenance_factor=maintenance_factor,
orientation_factor=orientation_factor,
system_type=system_type)
results = pv_sizing.rooftop_sizing()
pv_sizing.rooftop_tilted_radiation()
self._city.level_of_detail.energy_systems = 1
for building in self._city.buildings:
building.level_of_detail.energy_systems = 1
return results
def _district_heating_cooling_sizing(self):
"""
Size District Heating and Cooling Network

View File

@ -1,37 +0,0 @@
from pathlib import Path
import subprocess
from hub.imports.geometry_factory import GeometryFactory
from building_modelling.geojson_creator import process_geojson
from hub.helpers.dictionaries import Dictionaries
from hub.imports.weather_factory import WeatherFactory
from hub.imports.results_factory import ResultFactory
from hub.exports.exports_factory import ExportsFactory
def pv_feasibility(current_x, current_y, current_diff, selected_buildings):
input_files_path = (Path(__file__).parent.parent.parent.parent / 'input_files')
output_path = (Path(__file__).parent.parent.parent.parent / 'out_files').resolve()
sra_output_path = output_path / 'sra_outputs' / 'extended_city_sra_outputs'
sra_output_path.mkdir(parents=True, exist_ok=True)
new_diff = current_diff * 5
geojson_file = process_geojson(x=current_x, y=current_y, diff=new_diff, expansion=True)
file_path = input_files_path / 'output_buildings.geojson'
city = GeometryFactory('geojson',
path=file_path,
height_field='height',
year_of_construction_field='year_of_construction',
function_field='function',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
WeatherFactory('epw', city).enrich()
ExportsFactory('sra', city, sra_output_path).export()
sra_path = (sra_output_path / f'{city.name}_sra.xml').resolve()
subprocess.run(['sra', str(sra_path)])
ResultFactory('sra', city, sra_output_path).enrich()
for selected_building in selected_buildings:
for building in city.buildings:
if selected_building.name == building.name:
selected_building.roofs[0].global_irradiance = building.roofs[0].global_irradiance

View File

@ -1,42 +0,0 @@
import math
import hub.helpers.constants as cte
from hub.helpers.monthly_values import MonthlyValues
class PVModel:
def __init__(self, pv, hourly_electricity_demand_joules, solar_radiation, installed_pv_area, model_type, ns=None,
np=None):
self.pv = pv
self.hourly_electricity_demand = [demand / cte.WATTS_HOUR_TO_JULES for demand in hourly_electricity_demand_joules]
self.solar_radiation = solar_radiation
self.installed_pv_area = installed_pv_area
self._model_type = '_' + model_type.lower()
self.ns = ns
self.np = np
self.results = {}
def fixed_efficiency(self):
module_efficiency = float(self.pv.electricity_efficiency)
variable_names = ["pv_output", "import", "export", "self_sufficiency_ratio"]
variables = {name: [0] * len(self.hourly_electricity_demand) for name in variable_names}
(pv_out, grid_import, grid_export, self_sufficiency_ratio) = [variables[name] for name in variable_names]
for i in range(len(self.hourly_electricity_demand)):
pv_out[i] = module_efficiency * self.installed_pv_area * self.solar_radiation[i] / cte.WATTS_HOUR_TO_JULES
if pv_out[i] < self.hourly_electricity_demand[i]:
grid_import[i] = self.hourly_electricity_demand[i] - pv_out[i]
else:
grid_export[i] = pv_out[i] - self.hourly_electricity_demand[i]
self_sufficiency_ratio[i] = pv_out[i] / self.hourly_electricity_demand[i]
self.results['Electricity Demand (W)'] = self.hourly_electricity_demand
self.results['PV Output (W)'] = pv_out
self.results['Imported from Grid (W)'] = grid_import
self.results['Exported to Grid (W)'] = grid_export
self.results['Self Sufficiency Ratio'] = self_sufficiency_ratio
return self.results
def enrich(self):
"""
Enrich the city given to the class using the class given handler
:return: None
"""
return getattr(self, self._model_type, lambda: None)()

View File

@ -1,70 +0,0 @@
import math
import hub.helpers.constants as cte
from energy_system_modelling_package.energy_system_modelling_factories.pv_assessment.solar_angles import CitySolarAngles
from energy_system_modelling_package.energy_system_modelling_factories.pv_assessment.radiation_tilted import RadiationTilted
class PVSizing(CitySolarAngles):
def __init__(self, city, tilt_angle, surface_azimuth=180, maintenance_factor=0.1, mechanical_equipment_factor=0.3,
orientation_factor=0.1, system_type='rooftop'):
super().__init__(location_latitude=city.latitude,
location_longitude=city.longitude,
tilt_angle=tilt_angle,
surface_azimuth_angle=surface_azimuth)
self.city = city
self.maintenance_factor = maintenance_factor
self.mechanical_equipment_factor = mechanical_equipment_factor
self.orientation_factor = orientation_factor
self.angles = self.calculate
self.system_type = system_type
def rooftop_sizing(self):
results = {}
# Available Roof Area
for building in self.city.buildings:
for energy_system in building.energy_systems:
for generation_system in energy_system.generation_systems:
if generation_system.system_type == cte.PHOTOVOLTAIC:
module_width = float(generation_system.width)
module_height = float(generation_system.height)
roof_area = 0
for roof in building.roofs:
roof_area += roof.perimeter_area
pv_module_area = module_width * module_height
available_roof = ((self.maintenance_factor + self.orientation_factor + self.mechanical_equipment_factor) *
roof_area)
# Inter-Row Spacing
winter_solstice = self.angles[(self.angles['AST'].dt.month == 12) &
(self.angles['AST'].dt.day == 21) &
(self.angles['AST'].dt.hour == 12)]
solar_altitude = winter_solstice['solar altitude'].values[0]
solar_azimuth = winter_solstice['solar azimuth'].values[0]
distance = ((module_height * abs(math.cos(math.radians(solar_azimuth)))) /
math.tan(math.radians(solar_altitude)))
distance = float(format(distance, '.1f'))
# Calculation of the number of panels
space_dimension = math.sqrt(available_roof)
space_dimension = float(format(space_dimension, '.2f'))
panels_per_row = math.ceil(space_dimension / module_width)
number_of_rows = math.ceil(space_dimension / distance)
total_number_of_panels = panels_per_row * number_of_rows
total_pv_area = panels_per_row * number_of_rows * pv_module_area
building.roofs[0].installed_solar_collector_area = total_pv_area
results[f'Building {building.name}'] = {'total_roof_area': roof_area,
'PV dedicated area': available_roof,
'total_pv_area': total_pv_area,
'total_number_of_panels': total_number_of_panels,
'number_of_rows': number_of_rows,
'panels_per_row': panels_per_row}
return results
def rooftop_tilted_radiation(self):
for building in self.city.buildings:
RadiationTilted(building=building,
solar_angles=self.angles,
tilt_angle=self.tilt_angle,
ghi=building.roofs[0].global_irradiance[cte.HOUR],
).enrich()
def facade_sizing(self):
pass

View File

@ -1,59 +0,0 @@
import math
from energy_system_modelling_package.energy_system_modelling_factories.pv_assessment.radiation_tilted import RadiationTilted
import hub.helpers.constants as cte
from hub.helpers.monthly_values import MonthlyValues
class PVSizingSimulation(RadiationTilted):
def __init__(self, building, solar_angles, tilt_angle, module_height, module_width, ghi):
super().__init__(building, solar_angles, tilt_angle, ghi)
self.module_height = module_height
self.module_width = module_width
self.total_number_of_panels = 0
self.enrich()
def available_space(self):
roof_area = self.building.roofs[0].perimeter_area
maintenance_factor = 0.1
orientation_factor = 0.2
if self.building.function == cte.RESIDENTIAL:
mechanical_equipment_factor = 0.2
else:
mechanical_equipment_factor = 0.3
available_roof = (maintenance_factor + orientation_factor + mechanical_equipment_factor) * roof_area
return available_roof
def inter_row_spacing(self):
winter_solstice = self.df[(self.df['AST'].dt.month == 12) &
(self.df['AST'].dt.day == 21) &
(self.df['AST'].dt.hour == 12)]
solar_altitude = winter_solstice['solar altitude'].values[0]
solar_azimuth = winter_solstice['solar azimuth'].values[0]
distance = ((self.module_height * abs(math.cos(math.radians(solar_azimuth)))) /
math.tan(math.radians(solar_altitude)))
distance = float(format(distance, '.1f'))
return distance
def number_of_panels(self, available_roof, inter_row_distance):
space_dimension = math.sqrt(available_roof)
space_dimension = float(format(space_dimension, '.2f'))
panels_per_row = math.ceil(space_dimension / self.module_width)
number_of_rows = math.ceil(space_dimension / inter_row_distance)
self.total_number_of_panels = panels_per_row * number_of_rows
return panels_per_row, number_of_rows
def pv_output_constant_efficiency(self):
radiation = self.total_radiation_tilted
pv_module_area = self.module_width * self.module_height
available_roof = self.available_space()
inter_row_spacing = self.inter_row_spacing()
self.number_of_panels(available_roof, inter_row_spacing)
self.building.roofs[0].installed_solar_collector_area = pv_module_area * self.total_number_of_panels
system_efficiency = 0.2
pv_hourly_production = [x * system_efficiency * self.total_number_of_panels * pv_module_area *
cte.WATTS_HOUR_TO_JULES for x in radiation]
self.building.onsite_electrical_production[cte.HOUR] = pv_hourly_production
self.building.onsite_electrical_production[cte.MONTH] = (
MonthlyValues.get_total_month(self.building.onsite_electrical_production[cte.HOUR]))
self.building.onsite_electrical_production[cte.YEAR] = [sum(self.building.onsite_electrical_production[cte.MONTH])]

View File

@ -8,15 +8,14 @@ from hub.helpers.monthly_values import MonthlyValues
class PvSystemAssessment:
def __init__(self, building=None, pv_system=None, battery=None, tilt_angle=None, solar_angles=None,
system_type=None, pv_installation_type=None, simulation_model_type=None, module_model_name=None,
def __init__(self, building=None, pv_system=None, battery=None, electricity_demand=None, tilt_angle=None,
solar_angles=None, pv_installation_type=None, simulation_model_type=None, module_model_name=None,
inverter_efficiency=None, system_catalogue_handler=None, roof_percentage_coverage=None,
facade_coverage_percentage=None, csv_output=False, output_path=None):
"""
:param building:
:param tilt_angle:
:param solar_angles:
:param system_type:
:param simulation_model_type:
:param module_model_name:
:param inverter_efficiency:
@ -25,9 +24,9 @@ class PvSystemAssessment:
:param facade_coverage_percentage:
"""
self.building = building
self.electricity_demand = electricity_demand
self.tilt_angle = tilt_angle
self.solar_angles = solar_angles
self.system_type = system_type
self.pv_installation_type = pv_installation_type
self.simulation_model_type = simulation_model_type
self.module_model_name = module_model_name
@ -58,19 +57,16 @@ class PvSystemAssessment:
self.battery = storage_system
@staticmethod
def explicit_model(standard_test_condition_maximum_power, standard_test_condition_radiation,
cell_temperature_coefficient, standard_test_condition_cell_temperature, nominal_radiation,
nominal_cell_temperature, nominal_ambient_temperature, inverter_efficiency, number_of_panels,
irradiance, outdoor_temperature):
def explicit_model(pv_system, inverter_efficiency, number_of_panels, irradiance, outdoor_temperature):
inverter_efficiency = inverter_efficiency
stc_power = float(standard_test_condition_maximum_power)
stc_irradiance = float(standard_test_condition_radiation)
cell_temperature_coefficient = float(cell_temperature_coefficient) / 100 if (
cell_temperature_coefficient is not None) else None
stc_t_cell = float(standard_test_condition_cell_temperature)
nominal_condition_irradiance = float(nominal_radiation)
nominal_condition_cell_temperature = float(nominal_cell_temperature)
nominal_t_out = float(nominal_ambient_temperature)
stc_power = float(pv_system.standard_test_condition_maximum_power)
stc_irradiance = float(pv_system.standard_test_condition_radiation)
cell_temperature_coefficient = float(pv_system.cell_temperature_coefficient) / 100 if (
pv_system.cell_temperature_coefficient is not None) else None
stc_t_cell = float(pv_system.standard_test_condition_cell_temperature)
nominal_condition_irradiance = float(pv_system.nominal_radiation)
nominal_condition_cell_temperature = float(pv_system.nominal_cell_temperature)
nominal_t_out = float(pv_system.nominal_ambient_temperature)
g_i = irradiance
t_out = outdoor_temperature
t_cell = []
@ -101,7 +97,8 @@ class PvSystemAssessment:
(self.solar_angles['AST'].dt.hour == 12)]
solar_altitude = winter_solstice['solar altitude'].values[0]
solar_azimuth = winter_solstice['solar azimuth'].values[0]
distance = ((module_height * math.sin(math.radians(self.tilt_angle)) * abs(math.cos(math.radians(solar_azimuth)))) / math.tan(math.radians(solar_altitude)))
distance = ((module_height * math.sin(math.radians(self.tilt_angle)) * abs(
math.cos(math.radians(solar_azimuth)))) / math.tan(math.radians(solar_altitude)))
distance = float(format(distance, '.2f'))
# Calculation of the number of panels
space_dimension = math.sqrt(available_roof)
@ -128,17 +125,20 @@ class PvSystemAssessment:
for idx, generation_system in enumerate(energy_system.generation_systems):
if generation_system.system_type == cte.PHOTOVOLTAIC:
new_system = selected_pv_module
# Preserve attributes that exist in the original but not in the new system
# Preserve attributes that exist in the original but not in the new system
for attr in dir(generation_system):
# Skip private attributes and methods
if not attr.startswith('__') and not callable(getattr(generation_system, attr)):
if not hasattr(new_system, attr):
setattr(new_system, attr, getattr(generation_system, attr))
# Replace the old generation system with the new one
# Replace the old generation system with the new one
energy_system.generation_systems[idx] = new_system
def grid_tied_system(self):
building_hourly_electricity_demand = [demand / cte.WATTS_HOUR_TO_JULES for demand in
if self.electricity_demand is not None:
electricity_demand = self.electricity_demand
else:
electricity_demand = [demand / cte.WATTS_HOUR_TO_JULES for demand in
HourlyElectricityDemand(self.building).calculate()]
rooftop_pv_output = [0] * 8760
facade_pv_output = [0] * 8760
@ -147,19 +147,7 @@ class PvSystemAssessment:
np, ns = self.rooftop_sizing()
if self.simulation_model_type == 'explicit':
rooftop_number_of_panels = np * ns
rooftop_pv_output = self.explicit_model(standard_test_condition_maximum_power=
float(self.pv_system.standard_test_condition_maximum_power),
standard_test_condition_radiation=
float(self.pv_system.standard_test_condition_radiation),
cell_temperature_coefficient=
float(self.pv_system.cell_temperature_coefficient) / 100,
standard_test_condition_cell_temperature=
float(self.pv_system.standard_test_condition_cell_temperature),
nominal_radiation=float(self.pv_system.nominal_radiation),
nominal_cell_temperature=float(
self.pv_system.nominal_cell_temperature),
nominal_ambient_temperature=
float(self.pv_system.nominal_ambient_temperature),
rooftop_pv_output = self.explicit_model(pv_system=self.pv_system,
inverter_efficiency=self.inverter_efficiency,
number_of_panels=rooftop_number_of_panels,
irradiance=self.building.roofs[0].global_irradiance_tilted[
@ -170,8 +158,8 @@ class PvSystemAssessment:
total_hourly_pv_output = [rooftop_pv_output[i] + facade_pv_output[i] for i in range(8760)]
imported_electricity = [0] * 8760
exported_electricity = [0] * 8760
for i in range(8760):
transfer = total_hourly_pv_output[i] - building_hourly_electricity_demand[i]
for i in range(len(electricity_demand)):
transfer = total_hourly_pv_output[i] - electricity_demand[i]
if transfer > 0:
exported_electricity[i] = transfer
else:
@ -185,17 +173,20 @@ class PvSystemAssessment:
f'yearly_rooftop_tilted_radiation_{self.tilt_angle}_degree_kW/m2':
self.building.roofs[0].global_irradiance_tilted[cte.YEAR][0] / 1000,
'yearly_rooftop_pv_production_kWh': sum(rooftop_pv_output) / 1000,
'yearly_total_pv_production_kWh': sum(total_hourly_pv_output) / 1000,
'specific_pv_production_kWh/kWp': sum(rooftop_pv_output) / (
float(self.pv_system.standard_test_condition_maximum_power) * rooftop_number_of_panels),
'hourly_rooftop_poa_irradiance_W/m2': self.building.roofs[0].global_irradiance_tilted[cte.HOUR],
'hourly_rooftop_pv_output_W': rooftop_pv_output, 'T_out': self.building.external_temperature[cte.HOUR],
'building_electricity_demand_W': building_hourly_electricity_demand,
'building_electricity_demand_W': electricity_demand,
'total_hourly_pv_system_output_W': total_hourly_pv_output, 'import_from_grid_W': imported_electricity,
'export_to_grid_W': exported_electricity}
return results
def enrich(self):
if self.system_type.lower() == 'grid_tied':
system_archetype_name = self.building.energy_systems_archetype_name
archetype_name = '_'.join(system_archetype_name.lower().split())
if 'grid_tied' in archetype_name:
self.results = self.grid_tied_system()
hourly_pv_output = self.results['total_hourly_pv_system_output_W']
self.building.onsite_electrical_production[cte.HOUR] = hourly_pv_output
@ -221,15 +212,14 @@ class PvSystemAssessment:
# Open the CSV file for writing
with open(output_path / filename, mode='w', newline='') as csv_file:
writer = csv.writer(csv_file)
# Write single-value data as a header section
# Write single-value data as a header section
for key in single_value_keys:
writer.writerow([key, data[key]])
# Write an empty row for separation
# Write an empty row for separation
writer.writerow([])
# Write the header for the list values
# Write the header for the list values
writer.writerow(list_value_keys)
# Write each row for the lists
# Write each row for the lists
for i in range(num_rows):
row = [data[key][i] for key in list_value_keys]
writer.writerow(row)

View File

@ -1,112 +0,0 @@
import pandas as pd
import math
import hub.helpers.constants as cte
from hub.helpers.monthly_values import MonthlyValues
class RadiationTilted:
def __init__(self, building, solar_angles, tilt_angle, solar_constant=1366.1, maximum_clearness_index=1,
min_cos_zenith=0.065, maximum_zenith_angle=87):
self.building = building
self.tilt_angle = tilt_angle
self.zeniths = solar_angles['zenith'].tolist()
self.incidents = solar_angles['incident angle'].tolist()
self.date_time = solar_angles['DateTime'].tolist()
self.ast = solar_angles['AST'].tolist()
self.solar_azimuth = solar_angles['solar azimuth'].tolist()
self.solar_altitude = solar_angles['solar altitude'].tolist()
data = {'DateTime': self.date_time, 'AST': self.ast, 'solar altitude': self.solar_altitude, 'zenith': self.zeniths,
'solar azimuth': self.solar_azimuth, 'incident angle': self.incidents}
self.df = pd.DataFrame(data)
self.df['DateTime'] = pd.to_datetime(self.df['DateTime'])
self.df['AST'] = pd.to_datetime(self.df['AST'])
self.df.set_index('DateTime', inplace=True)
self.solar_constant = solar_constant
self.maximum_clearness_index = maximum_clearness_index
self.min_cos_zenith = min_cos_zenith
self.maximum_zenith_angle = maximum_zenith_angle
self.i_on = []
self.i_oh = []
self.k_t = []
self.fraction_diffuse = []
self.diffuse_hor = []
self.dni = []
self.tilted_diffuse = []
self.tilted_beam = []
self.total_tilted = []
def dni_extra(self):
for i in range(len(self.df)):
self.i_on.append(self.solar_constant * (1 + 0.033 *
math.cos(math.radians(360 * self.df.index.dayofyear[i] / 365))))
self.i_oh.append(self.i_on[i] * max(math.cos(math.radians(self.zeniths[i])), self.min_cos_zenith))
self.df['extraterrestrial normal radiation (Wh/m2)'] = self.i_on
self.df['extraterrestrial radiation on horizontal (Wh/m2)'] = self.i_oh
def clearness_index(self, ghi, i_oh):
k_t = ghi / i_oh
k_t = max(0, k_t)
k_t = min(self.maximum_clearness_index, k_t)
return k_t
def diffuse_fraction(self, k_t, zenith):
if k_t <= 0.22:
fraction_diffuse = 1 - 0.09 * k_t
elif k_t <= 0.8:
fraction_diffuse = (0.9511 - 0.1604 * k_t + 4.388 * k_t ** 2 - 16.638 * k_t ** 3 + 12.336 * k_t ** 4)
else:
fraction_diffuse = 0.165
if zenith > self.maximum_zenith_angle:
fraction_diffuse = 1
return fraction_diffuse
def radiation_components_horizontal(self, ghi, fraction_diffuse, zenith):
diffuse_horizontal = ghi * fraction_diffuse
dni = (ghi - diffuse_horizontal) / math.cos(math.radians(zenith))
if zenith > self.maximum_zenith_angle or dni < 0:
dni = 0
return diffuse_horizontal, dni
def radiation_components_tilted(self, diffuse_horizontal, dni, incident_angle):
beam_tilted = dni * math.cos(math.radians(incident_angle))
beam_tilted = max(beam_tilted, 0)
self.tilted_beam.append(beam_tilted)
diffuse_tilted = diffuse_horizontal * ((1 + math.cos(math.radians(self.tilt_angle))) / 2)
self.tilted_diffuse.append(diffuse_tilted)
total_radiation_tilted = beam_tilted + diffuse_tilted
return total_radiation_tilted
def enrich(self):
self.dni_extra()
ghi = self.building.roofs[0].global_irradiance[cte.HOUR]
hourly_tilted_radiation = []
for i in range(len(ghi)):
k_t = self.clearness_index(ghi=ghi[i], i_oh=self.i_oh[i])
self.k_t.append(k_t)
fraction_diffuse = self.diffuse_fraction(k_t, self.zeniths[i])
self.fraction_diffuse.append(fraction_diffuse)
diffuse_horizontal, dni = self.radiation_components_horizontal(ghi=ghi[i],
fraction_diffuse=fraction_diffuse,
zenith=self.zeniths[i])
self.diffuse_hor.append(diffuse_horizontal)
self.dni.append(dni)
hourly_tilted_radiation.append(int(self.radiation_components_tilted(diffuse_horizontal=diffuse_horizontal,
dni=dni,
incident_angle=self.incidents[i])))
self.total_tilted.append(hourly_tilted_radiation[i])
self.building.roofs[0].global_irradiance_tilted[cte.HOUR] = hourly_tilted_radiation
self.building.roofs[0].global_irradiance_tilted[cte.MONTH] = (
MonthlyValues.get_total_month(self.building.roofs[0].global_irradiance_tilted[cte.HOUR]))
self.building.roofs[0].global_irradiance_tilted[cte.YEAR] = \
[sum(self.building.roofs[0].global_irradiance_tilted[cte.MONTH])]
self.df['k_t'] = self.k_t
self.df['diffuse_frac'] = self.fraction_diffuse
self.df['diff_hor'] = self.diffuse_hor
self.df['dni'] = self.dni
self.df['diff_tilted'] = self.tilted_diffuse
self.df['diff_beam'] = self.tilted_beam
self.df['total_tilted'] = self.total_tilted
self.df['ghi'] = ghi
self.df.to_csv(f'{self.building.name}_old_radiation.csv')

View File

@ -1,145 +0,0 @@
import math
import pandas as pd
from datetime import datetime
class CitySolarAngles:
def __init__(self, location_latitude, location_longitude, tilt_angle, surface_azimuth_angle,
standard_meridian=-75):
self.location_latitude = location_latitude
self.location_longitude = location_longitude
self.location_latitude_rad = math.radians(location_latitude)
self.surface_azimuth_angle = surface_azimuth_angle
self.surface_azimuth_rad = math.radians(surface_azimuth_angle)
self.tilt_angle = tilt_angle
self.tilt_angle_rad = math.radians(tilt_angle)
self.standard_meridian = standard_meridian
self.longitude_correction = (location_longitude - standard_meridian) * 4
self.timezone = 'Etc/GMT+5'
self.eot = []
self.ast = []
self.hour_angles = []
self.declinations = []
self.solar_altitudes = []
self.solar_azimuths = []
self.zeniths = []
self.incidents = []
self.beam_tilted = []
self.factor = []
self.times = pd.date_range(start='2023-01-01', end='2023-12-31 23:00', freq='h', tz=self.timezone)
self.df = pd.DataFrame(index=self.times)
self.day_of_year = self.df.index.dayofyear
def solar_time(self, datetime_val, day_of_year):
b = (day_of_year - 81) * 2 * math.pi / 364
eot = 9.87 * math.sin(2 * b) - 7.53 * math.cos(b) - 1.5 * math.sin(b)
self.eot.append(eot)
# Calculate Local Solar Time (LST)
lst_hour = datetime_val.hour
lst_minute = datetime_val.minute
lst_second = datetime_val.second
lst = lst_hour + lst_minute / 60 + lst_second / 3600
# Calculate Apparent Solar Time (AST) in decimal hours
ast_decimal = lst + eot / 60 + self.longitude_correction / 60
ast_hours = int(ast_decimal) % 24 # Adjust hours to fit within 023 range
ast_minutes = round((ast_decimal - ast_hours) * 60)
# Ensure ast_minutes is within valid range
if ast_minutes == 60:
ast_hours += 1
ast_minutes = 0
elif ast_minutes < 0:
ast_minutes = 0
ast_time = datetime(year=datetime_val.year, month=datetime_val.month, day=datetime_val.day,
hour=ast_hours, minute=ast_minutes)
self.ast.append(ast_time)
return ast_time
def declination_angle(self, day_of_year):
declination = 23.45 * math.sin(math.radians(360 / 365 * (284 + day_of_year)))
declination_radian = math.radians(declination)
self.declinations.append(declination)
return declination_radian
def hour_angle(self, ast_time):
hour_angle = ((ast_time.hour * 60 + ast_time.minute) - 720) / 4
hour_angle_radian = math.radians(hour_angle)
self.hour_angles.append(hour_angle)
return hour_angle_radian
def solar_altitude(self, declination_radian, hour_angle_radian):
solar_altitude_radians = math.asin(math.cos(self.location_latitude_rad) * math.cos(declination_radian) *
math.cos(hour_angle_radian) + math.sin(self.location_latitude_rad) *
math.sin(declination_radian))
solar_altitude = math.degrees(solar_altitude_radians)
self.solar_altitudes.append(solar_altitude)
return solar_altitude_radians
def zenith(self, solar_altitude_radians):
solar_altitude = math.degrees(solar_altitude_radians)
zenith_degree = 90 - solar_altitude
zenith_radian = math.radians(zenith_degree)
self.zeniths.append(zenith_degree)
return zenith_radian
def solar_azimuth_analytical(self, hourangle, declination, zenith):
numer = (math.cos(zenith) * math.sin(self.location_latitude_rad) - math.sin(declination))
denom = (math.sin(zenith) * math.cos(self.location_latitude_rad))
if math.isclose(denom, 0.0, abs_tol=1e-8):
cos_azi = 1.0
else:
cos_azi = numer / denom
cos_azi = max(-1.0, min(1.0, cos_azi))
sign_ha = math.copysign(1, hourangle)
solar_azimuth_radians = sign_ha * math.acos(cos_azi) + math.pi
solar_azimuth_degrees = math.degrees(solar_azimuth_radians)
self.solar_azimuths.append(solar_azimuth_degrees)
return solar_azimuth_radians
def incident_angle(self, solar_altitude_radians, solar_azimuth_radians):
incident_radian = math.acos(math.cos(solar_altitude_radians) *
math.cos(abs(solar_azimuth_radians - self.surface_azimuth_rad)) *
math.sin(self.tilt_angle_rad) + math.sin(solar_altitude_radians) *
math.cos(self.tilt_angle_rad))
incident_angle_degrees = math.degrees(incident_radian)
self.incidents.append(incident_angle_degrees)
return incident_radian
@property
def calculate(self) -> pd.DataFrame:
for i in range(len(self.times)):
datetime_val = self.times[i]
day_of_year = self.day_of_year[i]
declination_radians = self.declination_angle(day_of_year)
ast_time = self.solar_time(datetime_val, day_of_year)
hour_angle_radians = self.hour_angle(ast_time)
solar_altitude_radians = self.solar_altitude(declination_radians, hour_angle_radians)
zenith_radians = self.zenith(solar_altitude_radians)
solar_azimuth_radians = self.solar_azimuth_analytical(hour_angle_radians, declination_radians, zenith_radians)
incident_angle_radian = self.incident_angle(solar_altitude_radians, solar_azimuth_radians)
self.df['DateTime'] = self.times
self.df['AST'] = self.ast
self.df['hour angle'] = self.hour_angles
self.df['eot'] = self.eot
self.df['declination angle'] = self.declinations
self.df['solar altitude'] = self.solar_altitudes
self.df['zenith'] = self.zeniths
self.df['solar azimuth'] = self.solar_azimuths
self.df['incident angle'] = self.incidents
return self.df

View File

@ -29,21 +29,41 @@ residential_systems_percentage = {'system 1 gas': 15,
'system 8 electricity': 35}
residential_new_systems_percentage = {
'Central Hydronic Air and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and PV': 50,
'Central Hydronic Air and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW and PV': 0,
'Central Hydronic Ground and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and PV': 0,
'Central Hydronic Ground and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW '
'and PV': 0,
'Central Hydronic Water and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and PV': 0,
'Central Hydronic Water and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW '
'and PV': 0,
'Central Hydronic Air and Gas Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Central Hydronic Air and Electricity Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Central Hydronic Ground and Gas Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Central Hydronic Ground and Electricity Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Central Hydronic Water and Gas Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Central Hydronic Water and Electricity Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Grid-Tied PV System': 50
'Central Hydronic Air and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and Grid Tied PV': 100,
'Central Hydronic Air and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW and Grid Tied PV': 0,
'Central Hydronic Ground and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and Grid Tied PV': 0,
'Central Hydronic Ground and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW '
'and Grid Tied PV': 0,
'Central Hydronic Water and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and Grid Tied PV': 0,
'Central Hydronic Water and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW '
'and Grid Tied PV': 0,
'Central Hydronic Air and Gas Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Central Hydronic Air and Electricity Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Central Hydronic Ground and Gas Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Central Hydronic Ground and Electricity Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Central Hydronic Water and Gas Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Central Hydronic Water and Electricity Source Heating System with Unitary Split and Air Source HP DHW': 0,
'Grid Tied PV System': 0,
'system 1 gas': 0,
'system 1 gas grid tied pv': 0,
'system 1 electricity': 0,
'system 1 electricity grid tied pv': 0,
'system 2 gas': 0,
'system 2 gas grid tied pv': 0,
'system 2 electricity': 0,
'system 2 electricity grid tied pv': 0,
'system 3 and 4 gas': 0,
'system 3 and 4 gas grid tied pv': 0,
'system 3 and 4 electricity': 0,
'system 3 and 4 electricity grid tied pv': 0,
'system 6 gas': 0,
'system 6 gas grid tied pv': 0,
'system 6 electricity': 0,
'system 6 electricity grid tied pv': 0,
'system 8 gas': 0,
'system 8 gas grid tied pv': 0,
'system 8 electricity': 0,
'system 8 electricity grid tied pv': 0,
}
non_residential_systems_percentage = {'system 1 gas': 0,
@ -120,4 +140,3 @@ def call_random(_buildings: [Building], _systems_percentage):
_buildings[_selected_buildings[_position]].energy_systems_archetype_name = case['system']
_position += 1
return _buildings

View File

@ -3,8 +3,10 @@ import subprocess
from building_modelling.ep_run_enrich import energy_plus_workflow
from energy_system_modelling_package.energy_system_modelling_factories.montreal_energy_system_archetype_modelling_factory import \
MontrealEnergySystemArchetypesSimulationFactory
from energy_system_modelling_package.energy_system_modelling_factories.pv_assessment.pv_feasibility import \
pv_feasibility
from energy_system_modelling_package.energy_system_modelling_factories.pv_assessment.pv_system_assessment import \
PvSystemAssessment
from energy_system_modelling_package.energy_system_modelling_factories.pv_assessment.solar_calculator import \
SolarCalculator
from hub.imports.geometry_factory import GeometryFactory
from hub.helpers.dictionaries import Dictionaries
from hub.imports.construction_factory import ConstructionFactory
@ -22,9 +24,10 @@ from costing_package.constants import SYSTEM_RETROFIT_AND_PV, CURRENT_STATUS
from hub.exports.exports_factory import ExportsFactory
# Specify the GeoJSON file path
main_path = Path(__file__).parent.resolve()
input_files_path = (Path(__file__).parent / 'input_files')
input_files_path.mkdir(parents=True, exist_ok=True)
geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001)
geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.00006, path=main_path)
geojson_file_path = input_files_path / 'output_buildings.geojson'
output_path = (Path(__file__).parent / 'out_files').resolve()
output_path.mkdir(parents=True, exist_ok=True)
@ -34,6 +37,8 @@ simulation_results_path = (Path(__file__).parent / 'out_files' / 'simulation_res
simulation_results_path.mkdir(parents=True, exist_ok=True)
sra_output_path = output_path / 'sra_outputs'
sra_output_path.mkdir(parents=True, exist_ok=True)
pv_assessment_path = output_path / 'pv_outputs'
pv_assessment_path.mkdir(parents=True, exist_ok=True)
cost_analysis_output_path = output_path / 'cost_analysis'
cost_analysis_output_path.mkdir(parents=True, exist_ok=True)
city = GeometryFactory(file_type='geojson',
@ -49,7 +54,6 @@ ExportsFactory('sra', city, sra_output_path).export()
sra_path = (sra_output_path / f'{city.name}_sra.xml').resolve()
subprocess.run(['sra', str(sra_path)])
ResultFactory('sra', city, sra_output_path).enrich()
pv_feasibility(-73.5681295982132, 45.49218262677643, 0.0001, selected_buildings=city.buildings)
energy_plus_workflow(city, energy_plus_output_path)
random_assignation.call_random(city.buildings, random_assignation.residential_systems_percentage)
EnergySystemsFactory('montreal_custom', city).enrich()
@ -65,12 +69,35 @@ for building in city.buildings:
current_status_life_cycle_cost[f'{building.name}'] = cost_data(building, lcc_dataframe, cost_retrofit_scenario)
random_assignation.call_random(city.buildings, random_assignation.residential_new_systems_percentage)
EnergySystemsFactory('montreal_future', city).enrich()
EnergySystemsSizingFactory('pv_sizing', city).enrich()
EnergySystemsSizingFactory('peak_load_sizing', city).enrich()
# # Initialize solar calculation parameters (e.g., azimuth, altitude) and compute irradiance and solar angles
tilt_angle = 37
solar_parameters = SolarCalculator(city=city,
surface_azimuth_angle=180,
tilt_angle=tilt_angle,
standard_meridian=-75)
solar_angles = solar_parameters.solar_angles # Obtain solar angles for further analysis
solar_parameters.tilted_irradiance_calculator() # Calculate the solar radiation on a tilted surface
for building in city.buildings:
MontrealEnergySystemArchetypesSimulationFactory(f'archetype_cluster_{building.energy_systems_archetype_cluster_id}',
building,
simulation_results_path).enrich()
if 'PV' in building.energy_systems_archetype_name:
PvSystemAssessment(building=building,
pv_system=None,
battery=None,
electricity_demand=None,
tilt_angle=tilt_angle,
solar_angles=solar_angles,
pv_installation_type='rooftop',
simulation_model_type='explicit',
module_model_name=None,
inverter_efficiency=0.95,
system_catalogue_handler=None,
roof_percentage_coverage=0.75,
facade_coverage_percentage=0,
csv_output=False,
output_path=pv_assessment_path).enrich()
retrofitted_energy_consumption = consumption_data(city)
retrofitted_life_cycle_cost = {}
for building in city.buildings:

View File

@ -15,7 +15,7 @@ from hub.imports.weather_factory import WeatherFactory
from hub.imports.results_factory import ResultFactory
from building_modelling.geojson_creator import process_geojson
from hub.exports.exports_factory import ExportsFactory
import hub.helpers.constants as cte
# Define paths for input and output directories, ensuring directories are created if they do not exist
main_path = Path(__file__).parent.parent.resolve()
input_files_path = (Path(__file__).parent.parent / 'input_files')
@ -44,7 +44,7 @@ ConstructionFactory('nrcan', city).enrich()
UsageFactory('nrcan', city).enrich()
WeatherFactory('epw', city).enrich()
# Execute the EnergyPlus workflow to simulate building energy performance and generate output
energy_plus_workflow(city, energy_plus_output_path)
# energy_plus_workflow(city, energy_plus_output_path)
# Export the city data in SRA-compatible format to facilitate solar radiation assessment
ExportsFactory('sra', city, sra_output_path).export()
# Run SRA simulation using an external command, passing the generated SRA XML file path as input
@ -60,9 +60,10 @@ EnergySystemsFactory('montreal_future', city).enrich()
tilt_angle = 37
solar_parameters = SolarCalculator(city=city,
surface_azimuth_angle=180,
tilt_angle=tilt_angle)
tilt_angle=tilt_angle,
standard_meridian=-75)
solar_angles = solar_parameters.solar_angles # Obtain solar angles for further analysis
solar_parameters.tilted_irradiance_calculator()
solar_parameters.tilted_irradiance_calculator() # Calculate the solar radiation on a tilted surface
# # PV modelling building by building
#List of available PV modules ['RE400CAA Pure 2', 'RE410CAA Pure 2', 'RE420CAA Pure 2', 'RE430CAA Pure 2',
# 'REC600AA Pro M', 'REC610AA Pro M', 'REC620AA Pro M', 'REC630AA Pro M', 'REC640AA Pro M']
@ -72,10 +73,9 @@ for building in city.buildings:
battery=None,
tilt_angle=tilt_angle,
solar_angles=solar_angles,
system_type='grid_tied',
pv_installation_type='rooftop',
simulation_model_type='explicit',
module_model_name=None,
module_model_name='REC640AA Pro M',
inverter_efficiency=0.95,
system_catalogue_handler='montreal_future',
roof_percentage_coverage=0.75,
@ -83,6 +83,4 @@ for building in city.buildings:
csv_output=False,
output_path=pv_assessment_path).enrich()
print('test')

View File

@ -119,7 +119,7 @@ class ThermalStorageSystem(EnergyStorageSystem):
'height [m]': self.height,
'layers': _layers,
'maximum operating temperature [Celsius]': self.maximum_operating_temperature,
'storage_medium': self.storage_medium.to_dictionary(),
'storage_medium': _medias,
'heating coil capacity [W]': self.heating_coil_capacity
}
}

View File

@ -30,7 +30,8 @@ class MontrealFutureSystemCatalogue(Catalog):
path = str(path / 'montreal_future_systems.xml')
with open(path, 'r', encoding='utf-8') as xml:
self._archetypes = xmltodict.parse(xml.read(),
force_list=['pv_generation_component', 'templateStorages', 'demand'])
force_list=['pv_generation_component', 'templateStorages', 'demand',
'system', 'system_id'])
self._storage_components = self._load_storage_components()
self._generation_components = self._load_generation_components()
@ -49,7 +50,7 @@ class MontrealFutureSystemCatalogue(Catalog):
'non_pv_generation_component']
if non_pv_generation_components is not None:
for non_pv in non_pv_generation_components:
system_id = non_pv['system_id']
system_id = non_pv['generation_system_id']
name = non_pv['name']
system_type = non_pv['system_type']
model_name = non_pv['model_name']
@ -181,7 +182,7 @@ class MontrealFutureSystemCatalogue(Catalog):
'pv_generation_component']
if pv_generation_components is not None:
for pv in pv_generation_components:
system_id = pv['system_id']
system_id = pv['generation_system_id']
name = pv['name']
system_type = pv['system_type']
model_name = pv['model_name']

View File

@ -17,7 +17,7 @@
</media>
<energy_generation_components>
<non_pv_generation_component>
<system_id>1</system_id>
<generation_system_id>1</generation_system_id>
<name>Natural-Gas Boiler</name>
<system_type>boiler</system_type>
<model_name>ALP080B</model_name>
@ -56,7 +56,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>2</system_id>
<generation_system_id>2</generation_system_id>
<name>Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name>ALP105B</model_name>
@ -95,7 +95,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>3</system_id>
<generation_system_id>3</generation_system_id>
<name>Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name>ALP150B</model_name>
@ -134,7 +134,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>4</system_id>
<generation_system_id>4</generation_system_id>
<name>Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name>ALP210B</model_name>
@ -173,7 +173,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>5</system_id>
<generation_system_id>5</generation_system_id>
<name>Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name>ALTAC-136</model_name>
@ -212,7 +212,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>6</system_id>
<generation_system_id>6</generation_system_id>
<name>Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name>ALTA-120</model_name>
@ -251,7 +251,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>7</system_id>
<generation_system_id>7</generation_system_id>
<name>Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name>ASPN-085</model_name>
@ -290,7 +290,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>8</system_id>
<generation_system_id>8</generation_system_id>
<name>Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name>ASPN-110</model_name>
@ -329,7 +329,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>9</system_id>
<generation_system_id>9</generation_system_id>
<name>Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name>ASPNC-155</model_name>
@ -368,7 +368,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>10</system_id>
<generation_system_id>10</generation_system_id>
<name>Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name>K2WTC-135B</model_name>
@ -407,7 +407,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>11</system_id>
<generation_system_id>11</generation_system_id>
<name>Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name>K2WTC-180B</model_name>
@ -446,27 +446,27 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<pv_generation_component>
<system_id>12</system_id>
<generation_system_id>12</generation_system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>445MS</model_name>
<manufacturer>Canadian Solar</manufacturer>
<nominal_electricity_output/>
<electricity_efficiency/>
<nominal_ambient_temperature/>
<nominal_cell_temperature/>
<nominal_radiation/>
<standard_test_condition_cell_temperature/>
<standard_test_condition_radiation/>
<standard_test_condition_maximum_power/>
<cell_temperature_coefficient/>
<nominal_electricity_output>332</nominal_electricity_output>
<electricity_efficiency>0.201</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>40</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>445</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.35</cell_temperature_coefficient>
<width>2.01</width>
<height>1.048</height>
<distribution_systems/>
<energy_storage_systems/>
</pv_generation_component>
<non_pv_generation_component>
<system_id>13</system_id>
<generation_system_id>13</generation_system_id>
<name>Air-to-Water heat pump</name>
<system_type>heat pump</system_type>
<model_name>CMAA 012</model_name>
@ -511,7 +511,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>14</system_id>
<generation_system_id>14</generation_system_id>
<name>Air-to-Water heat pump</name>
<system_type>heat pump</system_type>
<model_name>CMAA 70</model_name>
@ -556,7 +556,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>15</system_id>
<generation_system_id>15</generation_system_id>
<name>Air-to-Water heat pump</name>
<system_type>heat pump</system_type>
<model_name>CMAA 140</model_name>
@ -601,7 +601,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>16</system_id>
<generation_system_id>16</generation_system_id>
<name>template Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name/>
@ -642,7 +642,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>17</system_id>
<generation_system_id>17</generation_system_id>
<name>template Electric boiler</name>
<system_type>boiler</system_type>
<model_name/>
@ -683,7 +683,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>18</system_id>
<generation_system_id>18</generation_system_id>
<name>template reversible 4-pipe air-to-water heat pump with storage</name>
<system_type>heat pump</system_type>
<model_name/>
@ -736,7 +736,7 @@
<simultaneous_heat_cold>True</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>19</system_id>
<generation_system_id>19</generation_system_id>
<name>template reversible 4-pipe groundwater-to-water heat pump with storage</name>
<system_type>heat pump</system_type>
<model_name/>
@ -777,7 +777,7 @@
<simultaneous_heat_cold>True</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>20</system_id>
<generation_system_id>20</generation_system_id>
<name>template reversible 4-pipe water-to-water heat pump with storage</name>
<system_type>heat pump</system_type>
<model_name/>
@ -818,7 +818,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>21</system_id>
<generation_system_id>21</generation_system_id>
<name>template Natural-Gas boiler</name>
<system_type>boiler</system_type>
<model_name/>
@ -857,7 +857,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>22</system_id>
<generation_system_id>22</generation_system_id>
<name>template Electric boiler</name>
<system_type>boiler</system_type>
<model_name/>
@ -896,7 +896,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>23</system_id>
<generation_system_id>23</generation_system_id>
<name>template reversible 4-pipe air-to-water heat pump</name>
<system_type>heat pump</system_type>
<model_name/>
@ -947,7 +947,7 @@
<simultaneous_heat_cold>True</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>24</system_id>
<generation_system_id>24</generation_system_id>
<name>template reversible 4-pipe groundwater-to-water heat pump</name>
<system_type>heat pump</system_type>
<model_name/>
@ -986,7 +986,7 @@
<simultaneous_heat_cold>True</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>25</system_id>
<generation_system_id>25</generation_system_id>
<name>template reversible 4-pipe water-to-water heat pump</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1025,7 +1025,7 @@
<simultaneous_heat_cold>True</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>26</system_id>
<generation_system_id>26</generation_system_id>
<name>template reversible 2-pipe air-to-water heat pump with storage</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1078,7 +1078,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>27</system_id>
<generation_system_id>27</generation_system_id>
<name>template reversible 2-pipe groundwater-to-water heat pump with storage</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1119,7 +1119,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>28</system_id>
<generation_system_id>28</generation_system_id>
<name>template reversible 2-pipe water-to-water heat pump with storage</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1160,7 +1160,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>29</system_id>
<generation_system_id>29</generation_system_id>
<name>template reversible 2-pipe air-to-water heat pump</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1211,7 +1211,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>30</system_id>
<generation_system_id>30</generation_system_id>
<name>template reversible 2-pipe groundwater-to-water heat pump</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1250,7 +1250,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>31</system_id>
<generation_system_id>31</generation_system_id>
<name>template reversible 2-pipe water-to-water heat pump</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1289,7 +1289,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>32</system_id>
<generation_system_id>32</generation_system_id>
<name>template air-to-water heating heat pump</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1334,7 +1334,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>33</system_id>
<generation_system_id>33</generation_system_id>
<name>template groundwater-to-water heating heat pump</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1373,7 +1373,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>34</system_id>
<generation_system_id>34</generation_system_id>
<name>template water-to-water heating heat pump</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1412,7 +1412,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>35</system_id>
<generation_system_id>35</generation_system_id>
<name>template unitary split system</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1457,7 +1457,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>36</system_id>
<generation_system_id>36</generation_system_id>
<name>template domestic hot water heat pump</name>
<system_type>heat pump</system_type>
<model_name/>
@ -1503,8 +1503,125 @@
<cooling_supply_temperature/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<generation_system_id>37</generation_system_id>
<name>template gas furnace</name>
<system_type>furnace</system_type>
<model_name/>
<manufacturer/>
<nominal_heat_output/>
<minimum_heat_output/>
<maximum_heat_output/>
<heat_efficiency>0.85</heat_efficiency>
<reversible/>
<fuel_type>natural gas</fuel_type>
<source_medium/>
<supply_medium/>
<nominal_cooling_output/>
<minimum_cooling_output/>
<maximum_cooling_output/>
<cooling_efficiency/>
<electricity_efficiency/>
<source_temperature/>
<source_mass_flow/>
<nominal_electricity_output/>
<maximum_heat_supply_temperature/>
<minimum_heat_supply_temperature/>
<maximum_cooling_supply_temperature/>
<minimum_cooling_supply_temperature/>
<heat_output_curve/>
<heat_fuel_consumption_curve/>
<heat_efficiency_curve/>
<cooling_output_curve/>
<cooling_fuel_consumption_curve/>
<cooling_efficiency_curve/>
<distribution_systems/>
<energy_storage_systems/>
<domestic_hot_water/>
<heat_supply_temperature/>
<cooling_supply_temperature/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<generation_system_id>38</generation_system_id>
<name>template electrical furnace</name>
<system_type>furnace</system_type>
<model_name/>
<manufacturer/>
<nominal_heat_output/>
<minimum_heat_output/>
<maximum_heat_output/>
<heat_efficiency>0.85</heat_efficiency>
<reversible/>
<fuel_type>electricity</fuel_type>
<source_medium/>
<supply_medium/>
<nominal_cooling_output/>
<minimum_cooling_output/>
<maximum_cooling_output/>
<cooling_efficiency/>
<electricity_efficiency/>
<source_temperature/>
<source_mass_flow/>
<nominal_electricity_output/>
<maximum_heat_supply_temperature/>
<minimum_heat_supply_temperature/>
<maximum_cooling_supply_temperature/>
<minimum_cooling_supply_temperature/>
<heat_output_curve/>
<heat_fuel_consumption_curve/>
<heat_efficiency_curve/>
<cooling_output_curve/>
<cooling_fuel_consumption_curve/>
<cooling_efficiency_curve/>
<distribution_systems/>
<energy_storage_systems/>
<domestic_hot_water/>
<heat_supply_temperature/>
<cooling_supply_temperature/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<generation_system_id>39</generation_system_id>
<name>template air cooled DX with external condenser</name>
<system_type>cooler</system_type>
<model_name/>
<manufacturer/>
<nominal_heat_output/>
<minimum_heat_output/>
<maximum_heat_output/>
<heat_efficiency/>
<reversible/>
<fuel_type>electricity</fuel_type>
<source_medium/>
<supply_medium/>
<nominal_cooling_output/>
<minimum_cooling_output/>
<maximum_cooling_output/>
<cooling_efficiency>3.23</cooling_efficiency>
<electricity_efficiency/>
<source_temperature/>
<source_mass_flow/>
<nominal_electricity_output/>
<maximum_heat_supply_temperature/>
<minimum_heat_supply_temperature/>
<maximum_cooling_supply_temperature/>
<minimum_cooling_supply_temperature/>
<heat_output_curve/>
<heat_fuel_consumption_curve/>
<heat_efficiency_curve/>
<cooling_output_curve/>
<cooling_fuel_consumption_curve/>
<cooling_efficiency_curve/>
<distribution_systems/>
<energy_storage_systems/>
<domestic_hot_water/>
<heat_supply_temperature/>
<cooling_supply_temperature/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<pv_generation_component>
<system_id>37</system_id>
<generation_system_id>40</generation_system_id>
<name>template Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name/>
@ -1525,7 +1642,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>38</system_id>
<generation_system_id>41</generation_system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>RE400CAA Pure 2</model_name>
@ -1546,7 +1663,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>39</system_id>
<generation_system_id>42</generation_system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>RE410CAA Pure 2</model_name>
@ -1567,7 +1684,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>40</system_id>
<generation_system_id>43</generation_system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>RE420CAA Pure 2</model_name>
@ -1588,7 +1705,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>41</system_id>
<generation_system_id>44</generation_system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>RE430CAA Pure 2</model_name>
@ -1609,7 +1726,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>42</system_id>
<generation_system_id>45</generation_system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>REC600AA Pro M</model_name>
@ -1630,7 +1747,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>43</system_id>
<generation_system_id>46</generation_system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>REC610AA Pro M</model_name>
@ -1651,7 +1768,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>44</system_id>
<generation_system_id>47</generation_system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>REC620AA Pro M</model_name>
@ -1672,7 +1789,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>45</system_id>
<generation_system_id>48</generation_system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>REC630AA Pro M</model_name>
@ -1693,7 +1810,7 @@
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>46</system_id>
<generation_system_id>49</generation_system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>REC640AA Pro M</model_name>
@ -1939,7 +2056,7 @@
<demand>electricity</demand>
</demands>
<components>
<generation_id>37</generation_id>
<generation_id>40</generation_id>
</components>
</system>
<system>
@ -2223,11 +2340,186 @@
<generation_id>36</generation_id>
</components>
</system>
<system>
<id>25</id>
<name>Unitary air conditioner with baseboard heater fuel fired boiler</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>21</generation_id>
</components>
</system>
<system>
<id>26</id>
<name>Unitary air conditioner with baseboard heater electrical boiler</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>22</generation_id>
</components>
</system>
<system>
<id>27</id>
<name>4 pipe fan coils with fuel fired boiler</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>21</generation_id>
</components>
</system>
<system>
<id>28</id>
<name>4 pipe fan coils with electrical resistance water boiler</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>21</generation_id>
</components>
</system>
<system>
<id>29</id>
<name>Single zone packaged rooftop unit with fuel-fired furnace and baseboards and fuel boiler for acs</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>37</generation_id>
</components>
</system>
<system>
<id>30</id>
<name>Single zone packaged rooftop unit with electrical resistance furnace and baseboards and fuel boiler for acs</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>38</generation_id>
</components>
</system>
<system>
<id>31</id>
<name>Single zone make-up air unit with baseboard heating with fuel fired boiler</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>21</generation_id>
</components>
</system>
<system>
<id>32</id>
<name>Single zone make-up air unit with electrical baseboard heating and DHW with resistance</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>22</generation_id>
</components>
</system>
<system>
<id>33</id>
<name>Multi-zone built-up system with baseboard heater hydronic with fuel fired boiler</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>21</generation_id>
</components>
</system>
<system>
<id>34</id>
<name>Multi-zone built-up system with electrical baseboard heater and electrical hot water</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>22</generation_id>
</components>
</system>
<system>
<id>35</id>
<name>Unitary air conditioner air cooled DX with external condenser</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>cooling</demand>
</demands>
<components>
<generation_id>39</generation_id>
</components>
</system>
<system>
<id>36</id>
<name>4 pipe fan coils with water cooled, water chiller</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>cooling</demand>
</demands>
<components>
<generation_id>39</generation_id>
</components>
</system>
<system>
<id>37</id>
<name>Single zone packaged rooftop unit with air cooled DX</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>cooling</demand>
</demands>
<components>
<generation_id>39</generation_id>
</components>
</system>
<system>
<id>38</id>
<name>Single zone make-up air unit with air cooled DX</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>cooling</demand>
</demands>
<components>
<generation_id>39</generation_id>
</components>
</system>
<system>
<id>39</id>
<name>Multi-zone built-up system with water cooled, water chiller</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>cooling</demand>
</demands>
<components>
<generation_id>39</generation_id>
</components>
</system>
</systems>
<system_archetypes>
<system_archetype cluster_id="1">
<name>Central Hydronic Air and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and PV</name>
<name>Central Hydronic Air and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and Grid Tied PV</name>
<systems>
<system_id>1</system_id>
<system_id>11</system_id>
@ -2236,16 +2528,16 @@
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>Central Hydronic Air and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW and PV</name>
<name>Central Hydronic Air and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW and Grid Tied PV</name>
<systems>
<system_id>1</system_id>
<system_id>12</system_id>
<system_id>23</system_id>
<system_id>8</system_id>
<system_id>24</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>Central Hydronic Ground and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and PV</name>
<name>Central Hydronic Ground and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and Grid Tied PV</name>
<systems>
<system_id>1</system_id>
<system_id>13</system_id>
@ -2254,7 +2546,7 @@
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>Central Hydronic Ground and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW and PV</name>
<name>Central Hydronic Ground and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW and Grid Tied PV</name>
<systems>
<system_id>1</system_id>
<system_id>14</system_id>
@ -2263,7 +2555,7 @@
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>Central Hydronic Water and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and PV</name>
<name>Central Hydronic Water and Gas Source Heating System with Unitary Split Cooling and Air Source HP DHW and Grid Tied PV</name>
<systems>
<system_id>1</system_id>
<system_id>15</system_id>
@ -2272,7 +2564,7 @@
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>Central Hydronic Water and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW and PV</name>
<name>Central Hydronic Water and Electricity Source Heating System with Unitary Split Cooling and Air Source HP DHW and Grid Tied PV</name>
<systems>
<system_id>1</system_id>
<system_id>16</system_id>
@ -2329,11 +2621,165 @@
</systems>
</system_archetype>
<system_archetype cluster_id="2">
<name>Grid-Tied PV System</name>
<name>Grid Tied PV System</name>
<systems>
<system_id>1</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 1 gas</name>
<systems>
<system_id>25</system_id>
<system_id>35</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 1 gas grid tied pv</name>
<systems>
<system_id>1</system_id>
<system_id>25</system_id>
<system_id>35</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 1 electricity</name>
<systems>
<system_id>26</system_id>
<system_id>35</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 1 electricity grid tied pv</name>
<systems>
<system_id>26</system_id>
<system_id>1</system_id>
<system_id>35</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 2 gas</name>
<systems>
<system_id>27</system_id>
<system_id>36</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 2 gas grid tied pv</name>
<systems>
<system_id>1</system_id>
<system_id>27</system_id>
<system_id>36</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 2 electricity</name>
<systems>
<system_id>28</system_id>
<system_id>36</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 2 electricity grid tied pv</name>
<systems>
<system_id>1</system_id>
<system_id>28</system_id>
<system_id>36</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 3 and 4 gas</name>
<systems>
<system_id>29</system_id>
<system_id>37</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 3 and 4 gas grid tied pv</name>
<systems>
<system_id>1</system_id>
<system_id>29</system_id>
<system_id>37</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 3 and 4 electricity</name>
<systems>
<system_id>30</system_id>
<system_id>37</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 3 and 4 electricity grid tied pv</name>
<systems>
<system_id>30</system_id>
<system_id>37</system_id>
<system_id>1</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 6 gas</name>
<systems>
<system_id>33</system_id>
<system_id>39</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 6 gas grid tied pv</name>
<systems>
<system_id>33</system_id>
<system_id>39</system_id>
<system_id>1</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 6 electricity</name>
<systems>
<system_id>34</system_id>
<system_id>39</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 6 electricity grid tied pv</name>
<systems>
<system_id>34</system_id>
<system_id>39</system_id>
<system_id>1</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 7 electricity grid tied pv</name>
<systems>
<system_id>1</system_id>
<system_id>8</system_id>
<system_id>24</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 8 gas</name>
<systems>
<system_id>25</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 8 gas grid tied pv</name>
<systems>
<system_id>25</system_id>
<system_id>1</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 8 electricity</name>
<systems>
<system_id>26</system_id>
</systems>
</system_archetype>
<system_archetype cluster_id="1">
<name>system 8 electricity grid tied pv</name>
<systems>
<system_id>26</system_id>
<system_id>1</system_id>
</systems>
</system_archetype>
</system_archetypes>
</EnergySystemCatalog>

View File

@ -303,6 +303,7 @@ GRID = 'Grid'
ONSITE_ELECTRICITY = 'Onsite Electricity'
PHOTOVOLTAIC = 'Photovoltaic'
BOILER = 'Boiler'
FURNACE = 'Furnace'
HEAT_PUMP = 'Heat Pump'
BASEBOARD = 'Baseboard'
ELECTRICITY_GENERATOR = 'Electricity generator'

View File

@ -39,11 +39,11 @@ class TestSystemsCatalog(TestCase):
catalog_categories = catalog.names()
archetypes = catalog.names()
self.assertEqual(13, len(archetypes['archetypes']))
self.assertEqual(34, len(archetypes['archetypes']))
systems = catalog.names('systems')
self.assertEqual(24, len(systems['systems']))
self.assertEqual(39, len(systems['systems']))
generation_equipments = catalog.names('generation_equipments')
self.assertEqual(46, len(generation_equipments['generation_equipments']))
self.assertEqual(49, len(generation_equipments['generation_equipments']))
with self.assertRaises(ValueError):
catalog.names('unknown')
@ -54,6 +54,4 @@ class TestSystemsCatalog(TestCase):
with self.assertRaises(IndexError):
catalog.get_entry('unknown')
catalog_pv_generation_equipments = [component for component in
catalog.entries('generation_equipments') if
component.system_type == cte.PHOTOVOLTAIC]

View File

@ -114,8 +114,8 @@ class TestSystemsFactory(TestCase):
ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich()
for building in self._city.buildings:
building.energy_systems_archetype_name = ('Central 4 Pipes Air to Water Heat Pump and Gas Boiler with '
'Independent Water Heating and PV')
building.energy_systems_archetype_name = ('Central Hydronic Air and Gas Source Heating System with Unitary Split '
'Cooling and Air Source HP DHW and Grid Tied PV')
EnergySystemsFactory('montreal_future', self._city).enrich()
# Need to assign energy systems to buildings:
for building in self._city.buildings:
@ -123,13 +123,14 @@ class TestSystemsFactory(TestCase):
for energy_system in building.energy_systems:
if cte.HEATING in energy_system.demand_types:
_generation_system = cast(NonPvGenerationSystem, energy_system.generation_systems[0])
_generation_system.heat_power = building.heating_peak_load[cte.YEAR][0]
_generation_system.nominal_heat_output = building.heating_peak_load[cte.YEAR][0]
if cte.COOLING in energy_system.demand_types:
_generation_system = cast(NonPvGenerationSystem, energy_system.generation_systems[0])
_generation_system.cooling_power = building.cooling_peak_load[cte.YEAR][0]
_generation_system.nominal_cooling_output = building.cooling_peak_load[cte.YEAR][0]
for building in self._city.buildings:
self.assertLess(0, building.heating_consumption[cte.YEAR][0])
self.assertLess(0, building.cooling_consumption[cte.YEAR][0])
self.assertLess(0, building.domestic_hot_water_consumption[cte.YEAR][0])
self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0])
if 'PV' in building.energy_systems_archetype_name:
self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0])