diff --git a/hub/catalog_factories/data_models/energy_systems/energy_storage_system.py b/hub/catalog_factories/data_models/energy_systems/energy_storage_system.py index f898af34..be1c4413 100644 --- a/hub/catalog_factories/data_models/energy_systems/energy_storage_system.py +++ b/hub/catalog_factories/data_models/energy_systems/energy_storage_system.py @@ -34,7 +34,7 @@ class EnergyStorageSystem: self._maximum_operating_temperature = maximum_operating_temperature @property - def stroage_id(self): + def id(self): """ Get storage id :return: string @@ -151,7 +151,7 @@ class EnergyStorageSystem: for _layer in self.layers: _layers.append(_layer.to_dictionary()) content = {'Storage component': { - 'storage id': self.stroage_id, + 'storage id': self.id, 'name': self.name, 'model name': self.model_name, 'manufacturer': self.manufacturer, diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index dc1337ca..96d8a08c 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -115,14 +115,14 @@ class System: _storage_system = [_storage.to_dictionary() for _storage in self.energy_storage_system] if self.energy_storage_system is not None else None - content = {'Layer': {'id': self.id, - 'name': self.name, - 'level of detail': self.lod, - 'demand types': self.demand_types, - 'Generation system(s)': _generation_systems, - 'distribution system': _distribution_system, - 'emission system': _emission_system, - 'energy storage system': _storage_system, - } + content = {'system': {'id': self.id, + 'name': self.name, + 'level of detail': self.lod, + 'demand types': self.demand_types, + 'Generation system(s)': _generation_systems, + 'distribution system': _distribution_system, + 'emission system': _emission_system, + 'energy storage system': _storage_system, + } } return content diff --git a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py index 0336c940..d8c7630c 100644 --- a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py +++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py @@ -40,7 +40,8 @@ class MontrealCustomCatalog(Catalog): self._catalog_systems, self._catalog_generation_equipments, self._catalog_distribution_equipments, - self._catalog_emission_equipments) + self._catalog_emission_equipments, + storages=None) def _load_generation_equipments(self): _equipments = [] @@ -62,14 +63,34 @@ class MontrealCustomCatalog(Catalog): storage = literal_eval(equipment['storage'].capitalize()) generation_system = GenerationSystem(equipment_id, name, + None, + None, equipment_type, fuel_type, None, + None, + None, + None, + None, heating_efficiency, + None, + None, + None, cooling_efficiency, electricity_efficiency, None, None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, storage, None) @@ -153,7 +174,8 @@ class MontrealCustomCatalog(Catalog): demands, _generation_equipment, _distribution_equipment, - _emission_equipment)) + _emission_equipment, + energy_storage_systems=None)) return _catalog_systems def _load_archetypes(self): diff --git a/hub/catalog_factories/energy_systems/north_america_energy_system_catalog.py b/hub/catalog_factories/energy_systems/north_america_energy_system_catalog.py index e0f7a3de..b4783f71 100644 --- a/hub/catalog_factories/energy_systems/north_america_energy_system_catalog.py +++ b/hub/catalog_factories/energy_systems/north_america_energy_system_catalog.py @@ -6,21 +6,18 @@ 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.pv_generation_system import PvGenerationSystem -from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem -from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem 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 -import hub.helpers.constants as cte class NorthAmericaEnergySystemCatalog(Catalog): @@ -33,12 +30,16 @@ class NorthAmericaEnergySystemCatalog(Catalog): with open(path, 'r', encoding='utf-8') as xml: self._archetypes = xmltodict.parse(xml.read(), force_list=['photovoltaicModules', 'templateStorages']) self._generation_components = self._load_generation_components() - print(self._generation_components) - print(len(self._generation_components)) self._storage_components = self._load_storage_components() - print(self._storage_components) - # self._systems = self._load_systems() - # print(self._load_systems()) + self._systems = self._load_systems() + self._system_archetypes = self._load_archetypes() + print(self._system_archetypes) + self._content = Content(self._system_archetypes, + self._systems, + self._generation_components, + None, + None, + self._storage_components) def _load_generation_components(self): generation_components = [] @@ -299,7 +300,7 @@ class NorthAmericaEnergySystemCatalog(Catalog): insulation_layer = Layer(None, 'insulation', insulation_material, thickness) thickness = float(tes['@tankThickness']) / 100 # from cm to m tank_layer = Layer(None, 'insulation', tank_material, thickness) - # the convention is from outside to inside + # the convention is from outside to inside layers = [insulation_layer, tank_layer] storage_component = EnergyStorageSystem(storage_id, name, @@ -330,7 +331,7 @@ class NorthAmericaEnergySystemCatalog(Catalog): insulation_layer = Layer(None, 'insulation', insulation_material, thickness) thickness = float(template['@tankThickness']) / 100 # from cm to m tank_layer = Layer(None, 'insulation', tank_material, thickness) - # the convention is from outside to inside + # the convention is from outside to inside layers = [insulation_layer, tank_layer] storage_component = EnergyStorageSystem(storage_id, name, @@ -349,24 +350,44 @@ class NorthAmericaEnergySystemCatalog(Catalog): storage_components.append(storage_component) return storage_components - # def _load_systems(self): - # _catalog_systems = [] - # systems = self._archetypes['EnergySystemCatalog']['systems']['system'] - # for system in systems: - # system_id = system['@id'] - # name = system['@name'] - # generation_components = - # - # energy_system = System(None, - # system_id, - # None, - # None, - # None, - # None, - # None, - # None) - # _catalog_systems.append(energy_system) - # return _catalog_systems + def _load_systems(self): + _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) + if 'storage_id' in system['components'].keys(): + storage_components = system['components']['storage_id'] + storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_components) + else: + storage_systems = None + energy_system = System(None, + system_id, + name, + demands, + generation_systems, + None, + None, + storage_systems) + _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'] + _systems = [] + for system in systems: + for system_archetype in self._systems: + if int(system_archetype.id) == int(system): + _systems.append(system_archetype) + _system_archetypes.append(Archetype(None, name, _systems)) + return _system_archetypes def _load_materials(self): materials = [] @@ -398,12 +419,93 @@ class NorthAmericaEnergySystemCatalog(Catalog): if _material is None: raise ValueError(f'Material not found in catalog [{material_name}]') - def _load_demands(self): - demands = [] - _demands = self._archetypes['encomp:EnergySystemCatalog']['energydemand'] - for _demand in _demands: - demand_type = _demand['@name'] - demands.append(demand_type) - return demands + @staticmethod + def _search_generation_equipment(generation_systems, generation_id): + _generation_systems = [] + for generation in generation_systems: + if generation.id in generation_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 - # def _search_demands(self, config_name): + @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) + for equipment in self._content.storage_equipments: + _names['storage_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) + elif category.lower() == 'storage_equipments': + for system in self._content.storage_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 + if category.lower() == 'storage_equipments': + return self._content.storage_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 + for entry in self._content.storage_equipments: + if entry.name.lower() == name.lower(): + return entry + raise IndexError(f"{name} doesn't exists in the catalog") diff --git a/hub/data/energy_systems/north_america_systems.xml b/hub/data/energy_systems/north_america_systems.xml index 0f8f8728..4584ac16 100644 --- a/hub/data/energy_systems/north_america_systems.xml +++ b/hub/data/energy_systems/north_america_systems.xml @@ -71,8 +71,8 @@ Air Source Heat Pump with Natural Gas Boiler and thermal storage - 1 - 2 + heating + domestic_hot_water 16 @@ -83,8 +83,8 @@ Air Source Heat Pump with Electrical Boiler and thermal storage - 1 - 2 + heating + domestic_hot_water 17 @@ -95,8 +95,8 @@ Ground Source Heat Pump with Natural Gas Boiler and thermal storage - 1 - 2 + heating + domestic_hot_water 16 @@ -107,8 +107,8 @@ Ground Source Heat Pump with Electrical Boiler and thermal storage - 1 - 2 + heating + domestic_hot_water 17 @@ -119,8 +119,8 @@ Water Source Heat Pump with Natural Gas Boiler and thermal storage - 1 - 2 + heating + domestic_hot_water 16 @@ -131,8 +131,8 @@ Water Source Heat Pump with Electrical Boiler and thermal storage - 1 - 2 + heating + domestic_hot_water 17 @@ -143,7 +143,7 @@ Photovoltaic System - 3 + electricity 21 diff --git a/tests/test_systems_catalog.py b/tests/test_systems_catalog.py index 48446d50..8747acb4 100644 --- a/tests/test_systems_catalog.py +++ b/tests/test_systems_catalog.py @@ -37,3 +37,6 @@ class TestSystemsCatalog(TestCase): def test_north_america_systems_catalog(self): catalog = EnergySystemsCatalogFactory('north_america').catalog + + def test_montreal_catalog(self): + catalog = EnergySystemsCatalogFactory('montreal_custom').catalog