final_energy_system_model #60
|
@ -10,12 +10,13 @@ class Content:
|
|||
"""
|
||||
Content class
|
||||
"""
|
||||
def __init__(self, archetypes, systems, generations, distributions, emissions):
|
||||
def __init__(self, archetypes, systems, generations, distributions, emissions, storages):
|
||||
self._archetypes = archetypes
|
||||
self._systems = systems
|
||||
self._generations = generations
|
||||
self._distributions = distributions
|
||||
self._emissions = emissions
|
||||
self._storages = storages
|
||||
|
||||
@property
|
||||
def archetypes(self):
|
||||
|
@ -52,6 +53,13 @@ class Content:
|
|||
"""
|
||||
return self._emissions
|
||||
|
||||
@property
|
||||
def storage_equipments(self):
|
||||
"""
|
||||
All storage equipments in the catalog
|
||||
"""
|
||||
return self._storages
|
||||
|
||||
def to_dictionary(self):
|
||||
"""Class content to dictionary"""
|
||||
_archetypes = []
|
||||
|
|
|
@ -1,251 +0,0 @@
|
|||
"""
|
||||
Energy system catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
|
||||
"""
|
||||
|
||||
from ast import literal_eval
|
||||
import xmltodict
|
||||
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.generation_system import GenerationSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.energy_emission_system import EnergyEmissionSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves
|
||||
from hub.catalog_factories.data_models.energy_systems.archetype import Archetype
|
||||
|
||||
|
||||
class EnergySystem(Catalog):
|
||||
"""
|
||||
Montreal custom energy systems catalog class
|
||||
"""
|
||||
def __init__(self, path):
|
||||
path = str(path / 'montreal_custom_systems.xml')
|
||||
with open(path, 'r', encoding='utf-8') as xml:
|
||||
self._archetypes = xmltodict.parse(xml.read(), force_list=('system', 'system_cluster', 'equipment',
|
||||
'demand', 'system_id'))
|
||||
|
||||
self._lod = float(self._archetypes['catalog']['@lod'])
|
||||
|
||||
self._catalog_generation_equipments = self._load_generation_equipments()
|
||||
self._catalog_distribution_equipments = self._load_distribution_equipments()
|
||||
self._catalog_emission_equipments = self._load_emission_equipments()
|
||||
self._catalog_systems = self._load_systems()
|
||||
self._catalog_archetypes = self._load_archetypes()
|
||||
|
||||
# store the full catalog data model in self._content
|
||||
self._content = Content(self._catalog_archetypes,
|
||||
self._catalog_systems,
|
||||
self._catalog_generation_equipments,
|
||||
self._catalog_distribution_equipments,
|
||||
self._catalog_emission_equipments)
|
||||
|
||||
def _load_generation_equipments(self):
|
||||
_equipments = []
|
||||
equipments = self._archetypes['catalog']['generation_equipments']['equipment']
|
||||
for equipment in equipments:
|
||||
equipment_id = float(equipment['@id'])
|
||||
equipment_type = equipment['@type']
|
||||
fuel_type = equipment['@fuel_type']
|
||||
name = equipment['name']
|
||||
heating_efficiency = None
|
||||
if 'heating_efficiency' in equipment:
|
||||
heating_efficiency = float(equipment['heating_efficiency'])
|
||||
cooling_efficiency = None
|
||||
if 'cooling_efficiency' in equipment:
|
||||
cooling_efficiency = float(equipment['cooling_efficiency'])
|
||||
electricity_efficiency = None
|
||||
if 'electrical_efficiency' in equipment:
|
||||
electricity_efficiency = float(equipment['electrical_efficiency'])
|
||||
storage = literal_eval(equipment['storage'].capitalize())
|
||||
generation_system = GenerationSystem(equipment_id,
|
||||
name,
|
||||
equipment_type,
|
||||
fuel_type,
|
||||
None,
|
||||
heating_efficiency,
|
||||
cooling_efficiency,
|
||||
electricity_efficiency,
|
||||
None,
|
||||
None,
|
||||
storage,
|
||||
None)
|
||||
|
||||
_equipments.append(generation_system)
|
||||
return _equipments
|
||||
|
||||
def _load_distribution_equipments(self):
|
||||
_equipments = []
|
||||
equipments = self._archetypes['catalog']['distribution_equipments']['equipment']
|
||||
for equipment in equipments:
|
||||
equipment_id = float(equipment['@id'])
|
||||
equipment_type = equipment['@type']
|
||||
name = equipment['name']
|
||||
distribution_heat_losses = None
|
||||
if 'distribution_heat_losses' in equipment:
|
||||
distribution_heat_losses = float(equipment['distribution_heat_losses']['#text']) / 100
|
||||
distribution_consumption_fix_flow = None
|
||||
if 'distribution_consumption_fix_flow' in equipment:
|
||||
distribution_consumption_fix_flow = float(equipment['distribution_consumption_fix_flow']['#text']) / 100
|
||||
distribution_consumption_variable_flow = None
|
||||
if 'distribution_consumption_variable_flow' in equipment:
|
||||
distribution_consumption_variable_flow = float(equipment['distribution_consumption_variable_flow']['#text']) / 100
|
||||
|
||||
distribution_system = DistributionSystem(equipment_id,
|
||||
name,
|
||||
equipment_type,
|
||||
None,
|
||||
distribution_consumption_fix_flow,
|
||||
distribution_consumption_variable_flow,
|
||||
distribution_heat_losses)
|
||||
|
||||
_equipments.append(distribution_system)
|
||||
return _equipments
|
||||
|
||||
def _load_emission_equipments(self):
|
||||
_equipments = []
|
||||
equipments = self._archetypes['catalog']['dissipation_equipments']['equipment']
|
||||
for equipment in equipments:
|
||||
equipment_id = float(equipment['@id'])
|
||||
equipment_type = equipment['@type']
|
||||
name = equipment['name']
|
||||
parasitic_consumption = None
|
||||
if 'parasitic_consumption' in equipment:
|
||||
parasitic_consumption = float(equipment['parasitic_consumption']['#text']) / 100
|
||||
|
||||
emission_system = EnergyEmissionSystem(equipment_id,
|
||||
name,
|
||||
equipment_type,
|
||||
parasitic_consumption)
|
||||
|
||||
_equipments.append(emission_system)
|
||||
return _equipments
|
||||
|
||||
def _load_systems(self):
|
||||
_catalog_systems = []
|
||||
systems = self._archetypes['catalog']['systems']['system']
|
||||
for system in systems:
|
||||
system_id = float(system['@id'])
|
||||
name = system['name']
|
||||
demands = system['demands']['demand']
|
||||
generation_equipment = system['equipments']['generation_id']
|
||||
_generation_equipment = None
|
||||
for equipment_archetype in self._catalog_generation_equipments:
|
||||
if int(equipment_archetype.id) == int(generation_equipment):
|
||||
_generation_equipment = equipment_archetype
|
||||
distribution_equipment = system['equipments']['distribution_id']
|
||||
_distribution_equipment = None
|
||||
for equipment_archetype in self._catalog_distribution_equipments:
|
||||
if int(equipment_archetype.id) == int(distribution_equipment):
|
||||
_distribution_equipment = equipment_archetype
|
||||
emission_equipment = system['equipments']['dissipation_id']
|
||||
_emission_equipment = None
|
||||
for equipment_archetype in self._catalog_emission_equipments:
|
||||
if int(equipment_archetype.id) == int(emission_equipment):
|
||||
_emission_equipment = equipment_archetype
|
||||
|
||||
_catalog_systems.append(System(self._lod,
|
||||
system_id,
|
||||
name,
|
||||
demands,
|
||||
_generation_equipment,
|
||||
_distribution_equipment,
|
||||
_emission_equipment))
|
||||
return _catalog_systems
|
||||
|
||||
def _load_archetypes(self):
|
||||
_catalog_archetypes = []
|
||||
system_clusters = self._archetypes['catalog']['system_clusters']['system_cluster']
|
||||
for system_cluster in system_clusters:
|
||||
name = system_cluster['@name']
|
||||
systems = system_cluster['systems']['system_id']
|
||||
_systems = []
|
||||
for system in systems:
|
||||
for system_archetype in self._catalog_systems:
|
||||
if int(system_archetype.id) == int(system):
|
||||
_systems.append(system_archetype)
|
||||
_catalog_archetypes.append(Archetype(self._lod, name, _systems))
|
||||
return _catalog_archetypes
|
||||
|
||||
def names(self, category=None):
|
||||
"""
|
||||
Get the catalog elements names
|
||||
:parm: optional category filter
|
||||
"""
|
||||
if category is None:
|
||||
_names = {'archetypes': [], 'systems': [], 'generation_equipments': [], 'distribution_equipments': [],
|
||||
'emission_equipments':[]}
|
||||
for archetype in self._content.archetypes:
|
||||
_names['archetypes'].append(archetype.manufacturer)
|
||||
for system in self._content.systems:
|
||||
_names['systems'].append(system.manufacturer)
|
||||
for equipment in self._content.generation_equipments:
|
||||
_names['generation_equipments'].append(equipment.manufacturer)
|
||||
for equipment in self._content.distribution_equipments:
|
||||
_names['distribution_equipments'].append(equipment.manufacturer)
|
||||
for equipment in self._content.emission_equipments:
|
||||
_names['emission_equipments'].append(equipment.manufacturer)
|
||||
else:
|
||||
_names = {category: []}
|
||||
if category.lower() == 'archetypes':
|
||||
for archetype in self._content.archetypes:
|
||||
_names[category].append(archetype.manufacturer)
|
||||
elif category.lower() == 'systems':
|
||||
for system in self._content.systems:
|
||||
_names[category].append(system.manufacturer)
|
||||
elif category.lower() == 'generation_equipments':
|
||||
for system in self._content.generation_equipments:
|
||||
_names[category].append(system.manufacturer)
|
||||
elif category.lower() == 'distribution_equipments':
|
||||
for system in self._content.distribution_equipments:
|
||||
_names[category].append(system.manufacturer)
|
||||
elif category.lower() == 'emission_equipments':
|
||||
for system in self._content.emission_equipments:
|
||||
_names[category].append(system.manufacturer)
|
||||
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
|
||||
if category.lower() == 'distribution_equipments':
|
||||
return self._content.distribution_equipments
|
||||
if category.lower() == 'emission_equipments':
|
||||
return self._content.emission_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.manufacturer.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.systems:
|
||||
if entry.manufacturer.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.generation_equipments:
|
||||
if entry.manufacturer.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.distribution_equipments:
|
||||
if entry.manufacturer.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.emission_equipments:
|
||||
if entry.manufacturer.lower() == name.lower():
|
||||
return entry
|
||||
raise IndexError(f"{name} doesn't exists in the catalog")
|
|
@ -0,0 +1,109 @@
|
|||
"""
|
||||
North america energy system catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
|
||||
"""
|
||||
|
||||
from ast import literal_eval
|
||||
import xmltodict
|
||||
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.generation_system import GenerationSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.energy_emission_system import EnergyEmissionSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem
|
||||
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 / 'Tools4CitiesESMF.xml')
|
||||
with open(path, 'r', encoding='utf-8') as xml:
|
||||
self._archetypes = xmltodict.parse(xml.read())
|
||||
# self._systems = self._load_systems()
|
||||
# self._generation_components = self._load_generation_components()
|
||||
self._storage_components = self._load_storage_components()
|
||||
print(self._storage_components)
|
||||
# self._system_archetypes = self._load_system_archetypes()
|
||||
|
||||
# store the full catalog data model in self._content
|
||||
# self._content = Content(self._system_archetypes,
|
||||
# self._systems,
|
||||
# self._generation_components,
|
||||
# None,
|
||||
# None,
|
||||
# self._storage_components)
|
||||
|
||||
def _load_storage_components(self):
|
||||
storage_components = []
|
||||
components = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['thermalStorages']
|
||||
for component in components:
|
||||
model_name = component['@modelName']
|
||||
manufacturer = component['@manufacturer']
|
||||
volume = component['@volume']
|
||||
height = component['@height']
|
||||
maximum_operating_temperature = component['@maxTemp']
|
||||
materials = self._load_materials()
|
||||
material_name = component['@insulationMaterial']
|
||||
insulation_material = self._search_material(materials, material_name)
|
||||
material_name = component['@tankMaterial']
|
||||
tank_material = self._search_material(materials, material_name)
|
||||
thickness = float(component['@insulationThickness']) / 100 # from cm to m
|
||||
insulation_layer = Layer(None, 'insulation', insulation_material, thickness)
|
||||
thickness = float(component['@tankThickness']) / 100 # from cm to m
|
||||
tank_layer = Layer(None, 'insulation', tank_material, thickness)
|
||||
# the convention is from outside to inside
|
||||
layers = [insulation_layer, tank_layer]
|
||||
storage_component = EnergyStorageSystem(model_name,
|
||||
manufacturer,
|
||||
'thermal',
|
||||
volume,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
height,
|
||||
layers,
|
||||
maximum_operating_temperature)
|
||||
storage_components.append(storage_component)
|
||||
return storage_components
|
||||
|
||||
def _load_materials(self):
|
||||
materials = []
|
||||
_materials = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['materials']
|
||||
for _material in _materials:
|
||||
name = _material['@name']
|
||||
thermal_conductivity = _material['@thermalConductivity']
|
||||
material = Material(None,
|
||||
name,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
None,
|
||||
thermal_conductivity,
|
||||
None,
|
||||
None)
|
||||
materials.append(material)
|
||||
return materials
|
||||
|
||||
@staticmethod
|
||||
def _search_material(materials, material_name):
|
||||
_material = None
|
||||
for material in materials:
|
||||
if material.name == material_name:
|
||||
_material = material
|
||||
return _material
|
||||
|
||||
if _material is None:
|
||||
raise ValueError(f'Material not found in catalog [{material_name}]')
|
|
@ -9,6 +9,7 @@ from pathlib import Path
|
|||
from typing import TypeVar
|
||||
|
||||
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.helpers.utils import validate_import_export_type
|
||||
|
||||
Catalog = TypeVar('Catalog')
|
||||
|
@ -32,6 +33,13 @@ class EnergySystemsCatalogFactory:
|
|||
"""
|
||||
return MontrealCustomCatalog(self._path)
|
||||
|
||||
@property
|
||||
def _north_america(self):
|
||||
"""
|
||||
Retrieve North American catalog
|
||||
"""
|
||||
return NorthAmericaEnergySystemCatalog(self._path)
|
||||
|
||||
@property
|
||||
def catalog(self) -> Catalog:
|
||||
"""
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
<heatPumps 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="279.3" 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">
|
||||
<coefficientOfPerformance xsi:type="encomp:SecondDegreePolynomialFunction" parameter="COP" parameterA="0.00109" parameterB="0.209" parameterC="-0.00291" parameterD="-0.172" parameterE="0.00102" parameterF="8.95"/>
|
||||
</heatPumps>
|
||||
<thermalStorages modelName="HF 200" manufacturer="//@energycomponent.0/@manufacturers.5" volume="0.5" maxTemp="95.0" insulationThickness="90.0" usesMedium="Water" insulationMaterial="Polyurethane" height="1.5" tankMaterial="//@energycomponent.0/@materials.1"/>
|
||||
<thermalStorages modelName="HF 300" manufacturer="//@energycomponent.0/@manufacturers.5" volume="0.6" maxTemp="95.0" insulationThickness="90.0" usesMedium="Water" insulationMaterial="Polyurethane" height="1.3" tankMaterial="//@energycomponent.0/@materials.1"/>
|
||||
<thermalStorages modelName="HF 500" manufacturer="//@energycomponent.0/@manufacturers.5" volume="0.5" maxTemp="95.0" insulationThickness="90.0" usesMedium="Water" insulationMaterial="Polyurethane" height="1.5" tankMaterial="//@energycomponent.0/@materials.1"/>
|
||||
<thermalStorages modelName="HF 200" manufacturer="//@energycomponent.0/@manufacturers.5" volume="0.5" maxTemp="95.0" insulationThickness="90.0" usesMedium="Water" insulationMaterial="Polyurethane" height="1.5" tankMaterial="//@energycomponent.0/@materials.1"/>
|
||||
<thermalStorages modelName="HF 200" manufacturer="//@energycomponent.0/@manufacturers.5" volume="0.5" maxTemp="95.0" insulationThickness="90.0" usesMedium="Water" insulationMaterial="Polyurethane" height="1.5" tankMaterial="//@energycomponent.0/@materials.1"/>
|
||||
<thermalStorages modelName="HF 200" manufacturer="//@energycomponent.0/@manufacturers.5" volume="0.5" maxTemp="95.0" insulationThickness="90.0" tankThickness="0" usesMedium="Water" insulationMaterial="Polyurethane" height="1.5" tankMaterial="Steel"/>
|
||||
<thermalStorages modelName="HF 300" manufacturer="//@energycomponent.0/@manufacturers.5" volume="0.6" maxTemp="95.0" insulationThickness="90.0" tankThickness="0" usesMedium="Water" insulationMaterial="Polyurethane" height="1.3" tankMaterial="Steel"/>
|
||||
<thermalStorages modelName="HF 500" manufacturer="//@energycomponent.0/@manufacturers.5" volume="0.5" maxTemp="95.0" insulationThickness="90.0" tankThickness="0" usesMedium="Water" insulationMaterial="Polyurethane" height="1.5" tankMaterial="Steel"/>
|
||||
<thermalStorages modelName="HF 200" manufacturer="//@energycomponent.0/@manufacturers.5" volume="0.5" maxTemp="95.0" insulationThickness="90.0" tankThickness="0" usesMedium="Water" insulationMaterial="Polyurethane" height="1.5" tankMaterial="Steel"/>
|
||||
<thermalStorages modelName="HF 200" manufacturer="//@energycomponent.0/@manufacturers.5" volume="0.5" maxTemp="95.0" insulationThickness="90.0" tankThickness="0" usesMedium="Water" insulationMaterial="Polyurethane" height="1.5" tankMaterial="Steel"/>
|
||||
<powerStorages/>
|
||||
<manufacturers name="Alpine" country="USA"/>
|
||||
<manufacturers name="Alta" country="USA"/>
|
||||
|
@ -37,7 +37,7 @@
|
|||
<manufacturers name="reflex"/>
|
||||
<manufacturers name="Canadian Solar" country="Canada"/>
|
||||
<materials name="Polyurethane" thermalConductivity="0.028"/>
|
||||
<materials name="Polyurethane" thermalConductivity="18.0"/>
|
||||
<materials name="Steel" thermalConductivity="18.0"/>
|
||||
</energycomponent>
|
||||
<energysystemconfiguration configurationName="PvHpBoiler"/>
|
||||
<energysystemconfiguration configurationName="hpTesBoiler"/>
|
|
@ -35,3 +35,5 @@ class TestSystemsCatalog(TestCase):
|
|||
with self.assertRaises(IndexError):
|
||||
catalog.get_entry('unknown')
|
||||
|
||||
def test_north_america_systems_catalog(self):
|
||||
catalog = EnergySystemsCatalogFactory('north_america').catalog
|
||||
|
|
Loading…
Reference in New Issue
Block a user