final_energy_system_model #60

Merged
g_gutierrez merged 113 commits from final_energy_system_model into main 2024-03-14 09:13:21 -04:00
5 changed files with 0 additions and 782 deletions
Showing only changes of commit 11d493ba0e - Show all commits

View File

@ -1,461 +0,0 @@
"""
North america energy system catalog
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import xmltodict
from pathlib import Path
from hub.catalog_factories.catalog import Catalog
from hub.catalog_factories.data_models.energy_systems.system import System
from hub.catalog_factories.data_models.energy_systems.content import Content
from hub.catalog_factories.data_models.energy_systems.non_pv_generation_system import NonPvGenerationSystem
from hub.catalog_factories.data_models.energy_systems.pv_generation_system import PvGenerationSystem
from hub.catalog_factories.data_models.energy_systems.thermal_storage_system import ThermalStorageSystem
from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves
from hub.catalog_factories.data_models.energy_systems.archetype import Archetype
from hub.catalog_factories.data_models.construction.material import Material
from hub.catalog_factories.data_models.construction.layer import Layer
class NorthAmericaEnergySystemCatalog(Catalog):
"""
North america energy system catalog class
"""
def __init__(self, path):
path = str(path / 'north_america_systems.xml')
with open(path, 'r', encoding='utf-8') as xml:
self._archetypes = xmltodict.parse(xml.read(),
force_list=['photovoltaicModules', 'templateStorages', 'demand'])
self._storage_components = self._load_storage_components()
self._generation_components = self._load_generation_components()
self._systems = self._load_systems()
self._system_archetypes = self._load_archetypes()
self._content = Content(self._system_archetypes,
self._systems,
generations=self._generation_components)
def _load_generation_components(self):
generation_components = []
boilers = self._archetypes['EnergySystemCatalog']['energy_generation_components']['boilers']
heat_pumps = self._archetypes['EnergySystemCatalog']['energy_generation_components']['heatPumps']
photovoltaics = self._archetypes['EnergySystemCatalog']['energy_generation_components']['photovoltaicModules']
templates = self._archetypes['EnergySystemCatalog']['energy_generation_components']['templateGenerationEquipments']
for boiler in boilers:
boiler_id = boiler['@generation_id']
name = boiler['@name']
system_type = 'boiler'
boiler_model_name = boiler['@modelName']
boiler_manufacturer = boiler['@manufacturer']
boiler_fuel_type = boiler['@fuel']
boiler_nominal_thermal_output = float(boiler['@installedThermalPower'])
boiler_maximum_heat_output = float(boiler['@maximumHeatOutput'])
boiler_minimum_heat_output = float(boiler['@minimumHeatOutput'])
boiler_heat_efficiency = float(boiler['@nominalEfficiency'])
dual_supply = False
if '@dual_supply' in boiler.keys() and boiler['@dual_supply'] == 'True':
dual_supply = True
boiler_component = NonPvGenerationSystem(boiler_id,
name=name,
system_type=system_type,
model_name=boiler_model_name,
manufacturer=boiler_manufacturer,
fuel_type=boiler_fuel_type,
nominal_heat_output=boiler_nominal_thermal_output,
maximum_heat_output=boiler_maximum_heat_output,
minimum_heat_output=boiler_minimum_heat_output,
heat_efficiency=boiler_heat_efficiency,
dual_supply_capability=dual_supply)
generation_components.append(boiler_component)
for heat_pump in heat_pumps:
heat_pump_id = heat_pump['@generation_id']
name = heat_pump['@name']
system_type = 'heat pump'
heat_pump_model_name = heat_pump['@modelName']
heat_pump_manufacturer = heat_pump['@manufacturer']
heat_pump_fuel_type = heat_pump['@fuel']
heat_pump_nominal_thermal_output = float(heat_pump['@installedThermalPower'])
heat_pump_maximum_heat_output = float(heat_pump['@maximumHeatOutput'])
heat_pump_minimum_heat_output = float(heat_pump['@minimumHeatOutput'])
heat_pump_source_medium = heat_pump['@heatSource']
heat_pump_supply_medium = heat_pump['@supply_medium']
heat_pump_nominal_cop = float(heat_pump['@nominalCOP'])
heat_pump_maximum_heat_supply_temperature = float(heat_pump['@maxHeatingSupTemperature'])
heat_pump_minimum_heat_supply_temperature = float(heat_pump['@minHeatingSupTemperature'])
heat_pump_maximum_cooling_supply_temperature = float(heat_pump['@maxCoolingSupTemperature'])
heat_pump_minimum_cooling_supply_temperature = float(heat_pump['@minCoolingSupTemperature'])
cop_curve_type = heat_pump['performance_curve']['@curve_type']
dependant_variable = heat_pump['performance_curve']['dependant_variable']
parameters = heat_pump['performance_curve']['parameters']
coefficients = list(heat_pump['performance_curve']['coefficients'].values())
cop_curve = PerformanceCurves(cop_curve_type, dependant_variable, parameters, coefficients)
dual_supply = False
if '@dual_supply' in heat_pump.keys() and heat_pump['@dual_supply'] == 'True':
dual_supply = True
heat_pump_component = NonPvGenerationSystem(heat_pump_id,
name=name,
system_type=system_type,
model_name=heat_pump_model_name,
manufacturer=heat_pump_manufacturer,
fuel_type=heat_pump_fuel_type,
nominal_heat_output=heat_pump_nominal_thermal_output,
maximum_heat_output=heat_pump_maximum_heat_output,
minimum_heat_output=heat_pump_minimum_heat_output,
source_medium=heat_pump_source_medium,
supply_medium=heat_pump_supply_medium,
heat_efficiency=heat_pump_nominal_cop,
maximum_heat_supply_temperature=heat_pump_maximum_heat_supply_temperature,
minimum_heat_supply_temperature=heat_pump_minimum_heat_supply_temperature,
maximum_cooling_supply_temperature=heat_pump_maximum_cooling_supply_temperature,
minimum_cooling_supply_temperature=heat_pump_minimum_cooling_supply_temperature,
heat_efficiency_curve=cop_curve,
dual_supply_capability=dual_supply)
generation_components.append(heat_pump_component)
for pv in photovoltaics:
pv_id = pv['@generation_id']
name = pv['@name']
pv_model_name = pv['@modelName']
pv_manufacturer = pv['@manufacturer']
pv_electricity_efficiency = pv['@nominalEfficiency']
pv_nominal_electricity_output = pv['@nominalPower']
nominal_ambient_temperature = float(pv['@nominalAmbientTemperature'])
nominal_cell_temperature = float(pv['@nominalCellTemperature'])
nominal_radiation = float(pv['@nominalRadiation'])
standard_test_condition_cell_temperature = float(pv['@STCCellTemperature'])
standard_test_condition_maximum_power = float(pv['@STCMaxPower'])
cell_temperature_coefficient = float(pv['@CellTemperatureCoefficient'])
width = float(pv['@width'])
height = float(pv['@height'])
pv_component = PvGenerationSystem(pv_id,
name=name,
model_name=pv_model_name,
manufacturer=pv_manufacturer,
electricity_efficiency=pv_electricity_efficiency,
nominal_electricity_output=pv_nominal_electricity_output,
nominal_ambient_temperature=nominal_ambient_temperature,
nominal_cell_temperature=nominal_cell_temperature,
nominal_radiation=nominal_radiation,
standard_test_condition_cell_temperature=standard_test_condition_cell_temperature,
standard_test_condition_maximum_power=standard_test_condition_maximum_power,
cell_temperature_coefficient=cell_temperature_coefficient,
width=width,
height=height)
generation_components.append(pv_component)
for template in templates:
system_id = template['@generation_id']
system_name = template['@name']
if '@dual_supply' in template.keys() and template['@dual_supply'] == 'True':
dual_supply = True
if 'storage_id' in template.keys():
storage_component = template['storage_id']
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component)
energy_storage_system = storage_systems
else:
energy_storage_system = None
if "Boiler" in system_name:
system_type = 'boiler'
fuel_type = template['@fuel']
heat_efficiency = float(template['@nominalEfficiency'])
boiler_template = NonPvGenerationSystem(system_id=system_id,
name=system_name,
system_type=system_type,
fuel_type=fuel_type,
heat_efficiency=heat_efficiency,
energy_storage_systems=energy_storage_system,
dual_supply_capability=dual_supply)
generation_components.append(boiler_template)
elif "Heat Pump" in system_name:
system_type = 'heat pump'
fuel_type = template['@fuel']
heat_efficiency = template['@nominalCOP']
source_medium = template['@heatSource']
supply_medium = template['@supply_medium']
heat_pump_template = NonPvGenerationSystem(system_id=system_id,
name=system_name,
system_type=system_type,
source_medium=source_medium,
supply_medium=supply_medium,
fuel_type=fuel_type,
heat_efficiency=heat_efficiency,
energy_storage_systems=energy_storage_system,
dual_supply_capability=dual_supply)
generation_components.append(heat_pump_template)
else:
electricity_efficiency = float(template['@nominalEfficiency'])
height = float(template['@height'])
width = float(template['@width'])
pv_template = PvGenerationSystem(system_id=system_id,
name=system_name,
electricity_efficiency=electricity_efficiency,
width=width,
height=height)
generation_components.append(pv_template)
return generation_components
def _load_storage_components(self):
storage_components = []
thermal_storages = self._archetypes['EnergySystemCatalog']['energy_storage_components']['thermalStorages']
template_storages = self._archetypes['EnergySystemCatalog']['energy_storage_components']['templateStorages']
for tes in thermal_storages:
storage_id = tes['@storage_id']
model_name = tes['@modelName']
manufacturer = tes['@manufacturer']
storage_type = 'sensible'
volume = tes['physical_characteristics']['@volume']
height = tes['physical_characteristics']['@height']
maximum_operating_temperature = tes['@maxTemp']
materials = self._load_materials()
insulation_material_id = tes['insulation']['@material_id']
insulation_material = self._search_material(materials, insulation_material_id)
material_id = tes['physical_characteristics']['@material_id']
tank_material = self._search_material(materials, material_id)
thickness = float(tes['insulation']['@insulationThickness']) / 100 # from cm to m
insulation_layer = Layer(None, 'insulation', insulation_material, thickness)
thickness = float(tes['physical_characteristics']['@tankThickness']) / 100 # from cm to m
tank_layer = Layer(None, 'tank', tank_material, thickness)
media = self._load_media()
media_id = tes['medium']['@medium_id']
medium = self._search_media(media, media_id)
# the convention is from outside to inside
layers = [insulation_layer, tank_layer]
storage_component = ThermalStorageSystem(storage_id,
model_name,
manufacturer,
storage_type,
None,
None,
volume,
height,
layers,
maximum_operating_temperature,
medium)
storage_components.append(storage_component)
for template in template_storages:
storage_id = template['@storage_id']
storage_type = 'sensible'
maximum_temperature = template['@maxTemp']
height = template['physical_characteristics']['@height']
materials = self._load_materials()
insulation_material_id = template['insulation']['@material_id']
insulation_material = self._search_material(materials, insulation_material_id)
material_id = template['physical_characteristics']['@material_id']
tank_material = self._search_material(materials, material_id)
thickness = float(template['insulation']['@insulationThickness']) / 100 # from cm to m
insulation_layer = Layer(None, 'insulation', insulation_material, thickness)
thickness = float(template['physical_characteristics']['@tankThickness']) / 100 # from cm to m
tank_layer = Layer(None, 'tank', tank_material, thickness)
# the convention is from outside to inside
layers = [insulation_layer, tank_layer]
media = self._load_media()
media_id = template['medium']['@medium_id']
medium = self._search_media(media, media_id)
storage_component = ThermalStorageSystem(storage_id,
None,
None,
storage_type,
None,
None,
None,
height,
layers,
maximum_temperature,
medium)
storage_components.append(storage_component)
return storage_components
def _load_systems(self):
base_path = Path(Path(__file__).parent.parent.parent / 'data/energy_systems')
_catalog_systems = []
systems = self._archetypes['EnergySystemCatalog']['systems']['system']
for system in systems:
system_id = system['@id']
name = system['name']
demands = system['demands']['demand']
generation_components = system['components']['generation_id']
generation_systems = self._search_generation_equipment(self._load_generation_components(), generation_components)
configuration_schema = Path(base_path / system['schema'])
energy_system = System(system_id=system_id,
name=name,
demand_types=demands,
generation_systems=generation_systems,
distribution_systems=None,
configuration_schema=configuration_schema)
_catalog_systems.append(energy_system)
return _catalog_systems
def _load_archetypes(self):
_system_archetypes = []
system_clusters = self._archetypes['EnergySystemCatalog']['system_archetypes']['system_archetype']
for system_cluster in system_clusters:
name = system_cluster['name']
systems = system_cluster['systems']['system_id']
integer_system_ids = [int(item) for item in systems]
_systems = []
for system_archetype in self._systems:
if int(system_archetype.id) in integer_system_ids:
_systems.append(system_archetype)
_system_archetypes.append(Archetype(name=name, systems=_systems))
return _system_archetypes
def _load_materials(self):
materials = []
_materials = self._archetypes['EnergySystemCatalog']['materials']['material']
for _material in _materials:
material_id = _material['@material_id']
name = _material['@name']
thermal_conductivity = _material['@thermalConductivity']
material = Material(material_id,
name,
None,
None,
None,
False,
None,
thermal_conductivity,
None,
None)
materials.append(material)
return materials
@staticmethod
def _search_material(materials, material_id):
_material = None
for material in materials:
if int(material.id) == int(material_id):
_material = material
break
if _material is None:
raise ValueError(f'Material with the id = [{material_id}] not found in catalog ')
return _material
def _load_media(self):
media = []
_media = [self._archetypes['EnergySystemCatalog']['media']['medium']]
for _medium in _media:
medium_id = _medium['@medium_id']
name = _medium['@medium_name']
density = _medium['@density']
thermal_conductivity = _medium['@thermalConductivity']
specific_heat = _medium['@heatCapacity']
medium = Material(medium_id,
name,
None,
None,
None,
False,
None,
thermal_conductivity,
density,
specific_heat)
media.append(medium)
return media
@staticmethod
def _search_media(media, medium_id):
_medium = None
for medium in media:
if int(medium.id) == int(medium_id):
_medium = medium
break
if _medium is None:
raise ValueError(f'media with the id = [{medium_id}] not found in catalog ')
return _medium
@staticmethod
def _search_generation_equipment(generation_systems, generation_id):
_generation_systems = []
if isinstance(generation_id, list):
integer_ids = [int(item) for item in generation_id]
for generation in generation_systems:
if int(generation.id) in integer_ids:
_generation_systems.append(generation)
else:
integer_id = int(generation_id)
for generation in generation_systems:
if int(generation.id) == integer_id:
_generation_systems.append(generation)
if len(_generation_systems) == 0:
_generation_systems = None
raise ValueError(f'The system with the following id is not found in catalog [{generation_id}]')
return _generation_systems
@staticmethod
def _search_storage_equipment(storage_systems, storage_id):
_storage_systems = []
for storage in storage_systems:
if storage.id in storage_id:
_storage_systems.append(storage)
if len(_storage_systems) == 0:
_storage_systems_systems = None
raise ValueError(f'The system with the following id is not found in catalog [{storage_id}]')
return _storage_systems
def names(self, category=None):
"""
Get the catalog elements names
:parm: optional category filter
"""
if category is None:
_names = {'archetypes': [], 'systems': [], 'generation_equipments': [], 'storage_equipments': []}
for archetype in self._content.archetypes:
_names['archetypes'].append(archetype.name)
for system in self._content.systems:
_names['systems'].append(system.name)
for equipment in self._content.generation_equipments:
_names['generation_equipments'].append(equipment.name)
else:
_names = {category: []}
if category.lower() == 'archetypes':
for archetype in self._content.archetypes:
_names[category].append(archetype.name)
elif category.lower() == 'systems':
for system in self._content.systems:
_names[category].append(system.name)
elif category.lower() == 'generation_equipments':
for system in self._content.generation_equipments:
_names[category].append(system.name)
else:
raise ValueError(f'Unknown category [{category}]')
return _names
def entries(self, category=None):
"""
Get the catalog elements
:parm: optional category filter
"""
if category is None:
return self._content
if category.lower() == 'archetypes':
return self._content.archetypes
if category.lower() == 'systems':
return self._content.systems
if category.lower() == 'generation_equipments':
return self._content.generation_equipments
raise ValueError(f'Unknown category [{category}]')
def get_entry(self, name):
"""
Get one catalog element by names
:parm: entry name
"""
for entry in self._content.archetypes:
if entry.name.lower() == name.lower():
return entry
for entry in self._content.systems:
if entry.name.lower() == name.lower():
return entry
for entry in self._content.generation_equipments:
if entry.name.lower() == name.lower():
return entry
raise IndexError(f"{name} doesn't exists in the catalog")

View File

@ -9,7 +9,6 @@ from pathlib import Path
from typing import TypeVar from typing import TypeVar
from hub.catalog_factories.energy_systems.montreal_custom_catalog import MontrealCustomCatalog from hub.catalog_factories.energy_systems.montreal_custom_catalog import MontrealCustomCatalog
from hub.catalog_factories.energy_systems.north_america_energy_system_catalog import NorthAmericaEnergySystemCatalog
from hub.catalog_factories.energy_systems.montreal_future_system_catalogue import MontrealFutureSystemCatalogue from hub.catalog_factories.energy_systems.montreal_future_system_catalogue import MontrealFutureSystemCatalogue
from hub.helpers.utils import validate_import_export_type from hub.helpers.utils import validate_import_export_type
@ -34,13 +33,6 @@ class EnergySystemsCatalogFactory:
""" """
return MontrealCustomCatalog(self._path) return MontrealCustomCatalog(self._path)
@property
def _north_america(self):
"""
Retrieve North American catalog
"""
return NorthAmericaEnergySystemCatalog(self._path)
@property @property
def _montreal_future(self): def _montreal_future(self):
""" """

View File

@ -1,243 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<EnergySystemCatalog>
<schemas_path>./schemas/</schemas_path>
<media>
<medium medium_id="1" medium_name="Water" density="981.0" heatCapacity="4180.0" thermalConductivity="0.6" evaporationTemperature="100.0"/>
</media>
<energy_generation_components>
<boilers generation_id="1" name="Natural-Gas Boiler" modelName="ALP080B" manufacturer="Alpine" installedThermalPower="21.0" minimumHeatOutput="4.7" maximumHeatOutput="23.5" modulationRange="0.88" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="2" name="Natural-Gas Boiler" modelName="ALP105B" manufacturer="Alpine" installedThermalPower="28.0" minimumHeatOutput="6.15" maximumHeatOutput="30.8" modulationRange="0.88" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="3" name="Natural-Gas Boiler" modelName="ALP150B" manufacturer="Alpine" installedThermalPower="40.0" minimumHeatOutput="8.8" maximumHeatOutput="44" modulationRange="0.88" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="4" name="Natural-Gas Boiler" modelName="ALP210B" manufacturer="Alpine" installedThermalPower="57.0" minimumHeatOutput="12.3" maximumHeatOutput="61.5" modulationRange="0.87" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="5" name="Natural-Gas Boiler" modelName="ALTAC-136" manufacturer="Alta" installedThermalPower="33.0" minimumHeatOutput="4.0" maximumHeatOutput="35.2" modulationRange="0.95" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="6" name="Natural-Gas Boiler" modelName="ALTA-120" manufacturer="Alta" installedThermalPower="33.0" minimumHeatOutput="4.0" maximumHeatOutput="35.2" modulationRange="0.95" nominalEfficiency="0.95" combi="false" fuel="natural gas"/>
<boilers generation_id="7" name="Natural-Gas Boiler" modelName="ASPN-085" manufacturer="Aspen" installedThermalPower="23.15" minimumHeatOutput="2.5" maximumHeatOutput="25.0" modulationRange="0.97" nominalEfficiency="0.96" fuel="natural gas"/>
<boilers generation_id="8" name="Natural-Gas Boiler" modelName="ASPN-110" manufacturer="Aspen" installedThermalPower="30.19" minimumHeatOutput="3.2" maximumHeatOutput="32.0" modulationRange="0.96" nominalEfficiency="0.96" fuel="natural gas"/>
<boilers generation_id="9" name="Natural-Gas Boiler" modelName="ASPNC-155" manufacturer="Aspen" installedThermalPower="42.5" minimumHeatOutput="4.5" maximumHeatOutput="45.0" modulationRange="0.96" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="10" name="Natural-Gas Boiler" modelName="K2WTC-135B" manufacturer="K2" installedThermalPower="32.8" minimumHeatOutput="3.5" maximumHeatOutput="35.0" modulationRange="0.96" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="11" name="Natural-Gas Boiler" modelName="K2WTC-180B" manufacturer="K2" installedThermalPower="49.5" minimumHeatOutput="5.3" maximumHeatOutput="53.0" modulationRange="0.96" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<photovoltaicModules generation_id="12" name="Photovoltaic Module" modelName="445MS" manufacturer="Canadian Solar" nominalPower="334.0" nominalEfficiency="0.201" nominalRadiation="800.0" STCRadiation="1000.0" nominalCellTemperature="41.0" STCCellTemperature="26.0" nominalAmbientTemperature="20.0" STCMaxPower="445.0" CellTemperatureCoefficient="-0.0034" height="1.048" width="2.01"/>
<heatPumps generation_id="13" name="Air-to-Water Heat Pump" modelName="CMAA 012" description="A second degree equation is used in form of A*T_source^2 + B*T_source + C*T_source*T_sup + D*T_sup + E*T_sup^2 + F" manufacturer="TRANE" installedThermalPower="51.7" minimumHeatOutput="0" maximumHeatOutput="51.7" modulationRange="0.0" fuel="Electricity" heatSource="Air" nominalCOP="3.32" maxHeatingSupTemperature="55.0" minHeatingSupTemperature="6.0" maxCoolingSupTemperature="30.0" minCoolingSupTemperature="11.0" supply_medium="water" dual_supply="False">
<performance_curve curve_type="second degree multivariable function">
<dependant_variable>COP</dependant_variable>
<parameters>source_temperature</parameters>
<parameters>supply_temperature</parameters>
<coefficients a="9.5E-4" b="0.177" c="-0.00242" d="-0.155" e="9.3E-4" f="8.044"/>
</performance_curve>
</heatPumps>
<heatPumps generation_id="14" name="Air-to-Water Heat Pump" modelName="CMAA 70" description="A second degree equation is used in form of A*T_source^2 + B*T_source + C*T_source*T_sup + D*T_sup + E*T_sup^2 + F" manufacturer="TRANE" installedThermalPower="279.3" minimumHeatOutput="0" maximumHeatOutput="279.3" modulationRange="0.0" fuel="Electricity" heatSource="Air" nominalCOP="3.07" maxHeatingSupTemperature="55.0" minHeatingSupTemperature="6.0" maxCoolingSupTemperature="30.0" minCoolingSupTemperature="11.0" supply_medium="water" dual_supply="False">
<performance_curve curve_type="second degree multivariable function">
<dependant_variable>COP</dependant_variable>
<parameters>source_temperature</parameters>
<parameters>supply_temperature</parameters>
<coefficients a="0.0011" b="0.207" c="-0.00292" d="-0.187" e="0.00121" f="8.95"/>
</performance_curve>
</heatPumps>
<heatPumps generation_id="15" name="Air-to-Water Heat Pump" modelName="CMAA 140" description="A second degree equation is used in form of A*T_source^2 + B*T_source + C*T_source*T_sup + D*T_sup + E*T_sup^2 + F" manufacturer="TRANE" installedThermalPower="557" minimumHeatOutput="0" maximumHeatOutput="557" modulationRange="0.0" fuel="Electricity" heatSource="Air" nominalCOP="3.46" maxHeatingSupTemperature="55.0" minHeatingSupTemperature="6.0" maxCoolingSupTemperature="30.0" minCoolingSupTemperature="11.0" supply_medium="water" dual_supply="False">
<performance_curve curve_type="second degree multivariable function">
<dependant_variable>COP</dependant_variable>
<parameters>source_temperature</parameters>
<parameters>supply_temperature</parameters>
<coefficients a="0.00109" b="0.209" c="-0.00291" d="-0.172" e="0.00102" f="8.95"/>
</performance_curve>
</heatPumps>
<templateGenerationEquipments generation_id="16" name="template Natural-Gas Boiler" nominalEfficiency="0.90" fuel="natural gas">
<storage_id>6</storage_id>
</templateGenerationEquipments>
<templateGenerationEquipments generation_id="17" name="template Electric Boiler" nominalEfficiency="0.95" fuel="electricity">
<storage_id>6</storage_id>
</templateGenerationEquipments>
<templateGenerationEquipments generation_id="18" name="template Air-to-Water Heat Pump" fuel="electricity" heatSource="Air" nominalCOP="3" supply_medium="water" dual_supply="True">
<storage_id>6</storage_id>
</templateGenerationEquipments>
<templateGenerationEquipments generation_id="19" name="template Groundwater-to-Water Heat Pump" fuel="electricity" heatSource="Ground" nominalCOP="3.5" supply_medium="water" dual_supply="True">
<storage_id>6</storage_id>
</templateGenerationEquipments>
<templateGenerationEquipments generation_id="20" name="template Water-to-Water Heat Pump" fuel="electricity" heatSource="Water" nominalCOP="3.5" supply_medium="water" dual_supply="True">
<storage_id>6</storage_id>
</templateGenerationEquipments>
<templateGenerationEquipments generation_id="21" name="template Natural-Gas Boiler" nominalEfficiency="0.90" fuel="natural gas"/>
<templateGenerationEquipments generation_id="22" name="template Electric Boiler" nominalEfficiency="0.95" fuel="electricity"/>
<templateGenerationEquipments generation_id="23" name="template Air-to-Water Heat Pump" fuel="electricity" heatSource="Air" nominalCOP="3" supply_medium="water" dual_supply="True"/>
<templateGenerationEquipments generation_id="24" name="template Groundwater-to-Water Heat Pump" fuel="electricity" heatSource="Ground" nominalCOP="3.5" supply_medium="water" dual_supply="True"/>
<templateGenerationEquipments generation_id="25" name="template Water-to-Water Heat Pump" fuel="electricity" heatSource="Water" nominalCOP="3.5" supply_medium="water" dual_supply="True"/>
<templateGenerationEquipments generation_id="26" name="template Photovoltaic Module" nominalEfficiency="0.2" width="1.0" height="1.0"/>
<manufacturers manufacturer_id="1" name="Alpine" country="USA" product="Natural Gas Boiler"/>
<manufacturers manufacturer_id="2" name="Alta" country="USA" product="Natural Gas Boiler"/>
<manufacturers manufacturer_id="3" name="Aspen" country="USA" product="Natural Gas Boiler"/>
<manufacturers manufacturer_id="4" name="K2" country="USA" product="Natural Gas Boiler"/>
<manufacturers manufacturer_id="5" name="TRANE" product="Air-to-Water Heat Pump"/>
<manufacturers manufacturer_id="6" name="Canadian Solar" country="Canada" product="Photovoltaic Module"/>
</energy_generation_components>
<energy_storage_components>
<thermalStorages storage_id="1" name="Hot Water Storage Tank" modelName="HF 200" manufacturer="reflex" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel" volume="0.5"/>
<medium medium_id="1" usesMedium="Water"/>
</thermalStorages>
<thermalStorages storage_id="2" name="Hot Water Storage Tank" modelName="HF 300" manufacturer="reflex" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel" volume="0.6"/>
<medium medium_id="1" usesMedium="Water"/>
</thermalStorages>
<thermalStorages storage_id="3" name="Hot Water Storage Tank" modelName="HF 500" manufacturer="reflex" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel" volume="0.5"/>
<medium medium_id="1" usesMedium="Water"/>
</thermalStorages>
<thermalStorages storage_id="4" name="Hot Water Storage Tank" modelName="HF 200" manufacturer="reflex" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel" volume="0.5"/>
<medium medium_id="1" usesMedium="Water"/>
</thermalStorages>
<thermalStorages storage_id="5" name="Hot Water Storage Tank" modelName="HF 200" manufacturer="reflex" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel" volume="0.5"/>
<medium medium_id="1" usesMedium="Water"/>
</thermalStorages>
<templateStorages storage_id="6" name="template Hot Water Storage Tank" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel"/>
<medium medium_id="1" usesMedium="Water"/>
</templateStorages>
<manufacturers manufacturer_id="1" name="reflex" product="Storage Tank"/>
</energy_storage_components>
<materials>
<material material_id="1" name="Polyurethane" thermalConductivity="0.028"/>
<material material_id="2" name="Steel" thermalConductivity="18.0"/>
</materials>
<systems>
<system id="1">
<name>Air Source Heat Pump with Natural Gas Boiler and thermal storage</name>
<schema>schemas/ASHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>21</generation_id>
<generation_id>18</generation_id>
</components>
</system>
<system id="2">
<name>Air Source Heat Pump with Electrical Boiler and thermal storage</name>
<schema>schemas/ASHP+TES+ElectricBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>22</generation_id>
<generation_id>18</generation_id>
</components>
</system>
<system id="3">
<name>Ground Source Heat Pump with Natural Gas Boiler and thermal storage</name>
<schema>schemas/GSHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>21</generation_id>
<generation_id>19</generation_id>
</components>
</system>
<system id="4">
<name>Ground Source Heat Pump with Electrical Boiler and thermal storage</name>
<schema>schemas/GSHP+TES+ElectricBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>22</generation_id>
<generation_id>19</generation_id>
</components>
</system>
<system id="5">
<name>Water Source Heat Pump with Natural Gas Boiler and thermal storage</name>
<schema>schemas/WSHP+TES+GasBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>21</generation_id>
<generation_id>20</generation_id>
</components>
</system>
<system id="6">
<name>Water Source Heat Pump with Electrical Boiler and thermal storage</name>
<schema>schemas/WSHP+TES+ElectricBoiler.jpg</schema>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>22</generation_id>
<generation_id>20</generation_id>
</components>
</system>
<system id="7">
<name>Photovoltaic System</name>
<schema>schemas/PV.jpg</schema>
<demands>
<demand>electricity</demand>
</demands>
<components>
<generation_id>26</generation_id>
</components>
</system>
</systems>
<system_archetypes>
<system_archetype id="1">
<name>PV+ASHP+GasBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>1</system_id>
</systems>
</system_archetype>
<system_archetype id="2">
<name>PV+ASHP+ElectricBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>2</system_id>
</systems>
</system_archetype>
<system_archetype id="3">
<name>PV+GSHP+GasBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>3</system_id>
</systems>
</system_archetype>
<system_archetype id="4">
<name>PV+GSHP+ElectricBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>4</system_id>
</systems>
</system_archetype>
<system_archetype id="5">
<name>PV+WSHP+GasBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>5</system_id>
</systems>
</system_archetype>
<system_archetype id="6">
<name>PV+WSHP+ElectricBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>6</system_id>
</systems>
</system_archetype>
</system_archetypes>
<energy_demands>
<demand demand_id="1" name="heating"/>
<demand demand_id="2" name="domesticHotWater"/>
<demand demand_id="3" name="electricity"/>
<demand demand_id="4" name="cooling"/>
</energy_demands>
</EnergySystemCatalog>

View File

@ -34,28 +34,6 @@ class TestSystemsCatalog(TestCase):
with self.assertRaises(IndexError): with self.assertRaises(IndexError):
catalog.get_entry('unknown') catalog.get_entry('unknown')
def test_north_america_systems_catalog(self):
catalog = EnergySystemsCatalogFactory('north_america').catalog
catalog_categories = catalog.names()
archetypes = catalog.names('archetypes')
self.assertEqual(6, len(archetypes['archetypes']))
systems = catalog.names('systems')
self.assertEqual(7, len(systems['systems']))
generation_equipments = catalog.names('generation_equipments')
self.assertEqual(26, len(generation_equipments['generation_equipments']))
with self.assertRaises(ValueError):
catalog.names('unknown')
# retrieving all the entries should not raise any exceptions
for category in catalog_categories:
for value in catalog_categories[category]:
catalog.get_entry(value)
with self.assertRaises(IndexError):
catalog.get_entry('unknown')
print(catalog.entries())
def test_montreal_future_catalog(self): def test_montreal_future_catalog(self):
catalog = EnergySystemsCatalogFactory('montreal_future').catalog catalog = EnergySystemsCatalogFactory('montreal_future').catalog

View File

@ -96,54 +96,6 @@ class TestSystemsFactory(TestCase):
self.assertLess(0, building.domestic_hot_water_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]) self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0])
def test_north_america_custom_system_factory(self):
"""
Enrich the city with the construction information and verify it
"""
for building in self._city.buildings:
building.energy_systems_archetype_name = 'PV+ASHP+GasBoiler+TES'
EnergySystemsFactory('north_america', self._city).enrich()
self.assertEqual(1, len(self._city.generic_energy_systems))
def test_north_america_custom_system_results(self):
"""
Enrich the city with the construction information and verify it
"""
ConstructionFactory('nrcan', self._city).enrich()
UsageFactory('nrcan', self._city).enrich()
WeatherFactory('epw', self._city).enrich()
ExportsFactory('sra', self._city, self._output_path).export()
sra_path = (self._output_path / f'{self._city.name}_sra.xml').resolve()
subprocess.run(['sra', str(sra_path)])
ResultFactory('sra', self._city, self._output_path).enrich()
EnergyBuildingsExportsFactory('insel_monthly_energy_balance', self._city, self._output_path).export()
for building in self._city.buildings:
insel_path = (self._output_path / f'{building.name}.insel')
subprocess.run(['insel', str(insel_path)])
ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich()
for building in self._city.buildings:
building.energy_systems_archetype_name = 'PV+ASHP+GasBoiler+TES'
EnergySystemsFactory('north_america', self._city).enrich()
# Need to assign energy systems to buildings:
for building in self._city.buildings:
_building_energy_systems = []
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]
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]
for building in self._city.buildings:
self.assertLess(0, building.heating_consumption[cte.YEAR][0])
self.assertEqual(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])
print('test')
def test_montreal_future_system_results(self): def test_montreal_future_system_results(self):
""" """
Enrich the city with the construction information and verify it Enrich the city with the construction information and verify it