From 7f5cde81759d4873f1c7ce81cc49acfe003bd4eb Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Wed, 9 Aug 2023 11:25:56 -0400 Subject: [PATCH 01/38] starting updates in system catalog --- hub/catalog_factories/data_models/energy_systems/archetype.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hub/catalog_factories/data_models/energy_systems/archetype.py b/hub/catalog_factories/data_models/energy_systems/archetype.py index 86bfb68d..b490ebb9 100644 --- a/hub/catalog_factories/data_models/energy_systems/archetype.py +++ b/hub/catalog_factories/data_models/energy_systems/archetype.py @@ -3,6 +3,7 @@ Energy System catalog archetype SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2023 Concordia CERC group Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca """ from typing import List From 2b95173dfc2ba216a7966da673f4ccc63699295b Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Wed, 9 Aug 2023 12:02:16 -0400 Subject: [PATCH 02/38] starting updates in system catalog --- .idea/.gitignore | 3 +++ .idea/codeStyles/codeStyleConfig.xml | 5 +++++ .idea/hub.iml | 12 ++++++++++++ .idea/inspectionProfiles/Project_Default.xml | 12 ++++++++++++ .idea/inspectionProfiles/profiles_settings.xml | 6 ++++++ .idea/misc.xml | 4 ++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ tests/test_systems_catalog.py | 1 + 9 files changed, 57 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/hub.iml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..26d33521 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000..a55e7a17 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/hub.iml b/.idea/hub.iml new file mode 100644 index 00000000..8b8c3954 --- /dev/null +++ b/.idea/hub.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..92775997 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 00000000..105ce2da --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..ef318927 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..8d1428ff --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/test_systems_catalog.py b/tests/test_systems_catalog.py index 48af728c..f17038cb 100644 --- a/tests/test_systems_catalog.py +++ b/tests/test_systems_catalog.py @@ -34,3 +34,4 @@ class TestSystemsCatalog(TestCase): with self.assertRaises(IndexError): catalog.get_entry('unknown') + From 9034c3375e9125028f7b23e23a1717093592b27f Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Wed, 9 Aug 2023 19:31:26 -0400 Subject: [PATCH 03/38] The generation_system.py is renamed to heat_generation_system.py and the attributes and decorators are modified to encapsulate all the needed attributes for boilers and heat pumps. Another class named electricity_generation_system.py is created to add the attributes and decorators of PV, inverter, and maybe wind turbines in future. The system.py is also modified accordingly --- .idea/misc.xml | 3 + .../electricity_generation_system.py | 159 ++++++++++++++++++ .../energy_systems/generation_system.py | 147 ---------------- .../energy_systems/heat_generation_system.py | 146 ++++++++++++++++ .../data_models/energy_systems/system.py | 28 ++- .../energy_systems/montreal_custom_catalog.py | 2 +- 6 files changed, 329 insertions(+), 156 deletions(-) create mode 100644 hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py delete mode 100644 hub/catalog_factories/data_models/energy_systems/generation_system.py create mode 100644 hub/catalog_factories/data_models/energy_systems/heat_generation_system.py diff --git a/.idea/misc.xml b/.idea/misc.xml index ef318927..0e4465aa 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,7 @@ + + \ No newline at end of file diff --git a/hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py b/hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py new file mode 100644 index 00000000..762615a3 --- /dev/null +++ b/hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py @@ -0,0 +1,159 @@ +""" +Energy System catalog heat generation system +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca +""" + +from __future__ import annotations +from typing import Union + + +class ElectricityGenerationSystem: + """ + Heat Generation system class + """ + + def __init__(self, model_name, manufacturer, system_type, nominal_power_output, nominal_efficiency, + nominal_ambient_temperature, nominal_cell_temperature, nominal_radiation, + standard_test_condition_cell_temperature, standard_test_condition_maximum_power, width, height, + control_strategy): + self._model_name = model_name + self._name = manufacturer + self._type = system_type + self._nominal_power_output = nominal_power_output + self._nominal_efficiency = nominal_efficiency + self._nominal_ambient_temperature = nominal_ambient_temperature + self._nominal_cell_temperature = nominal_cell_temperature + self._nominal_radiation = nominal_radiation + self._standard_test_condition_cell_temperature = standard_test_condition_cell_temperature + self._standard_test_condition_maximum_power = standard_test_condition_maximum_power + self._width = width + self._height = height + self._control_strategy = control_strategy + + @property + def id(self): + """ + Get system id + :return: float + """ + return self._model_name + + @property + def name(self): + """ + Get name + :return: string + """ + return self._name + + @property + def type(self): + """ + Get type + :return: string + """ + return self._type + + @property + def nominal_power_output(self): + """ + Get nominal_power_output of electricity generation devices or inverters in kW + :return: float + """ + return self._nominal_power_output + + @property + def nominal_efficiency(self): + """ + Get nominal_efficiency of electricity generation devices or inverters + :return: float + """ + return self._nominal_efficiency + + @property + def nominal_ambient_temperature(self): + """ + Get nominal ambient temperature of PV panels in degree Celsius + :return: float + """ + return self._nominal_ambient_temperature + + @property + def nominal_cell_temperature(self): + """ + Get nominal cell temperature of PV panels in degree Celsius + :return: float + """ + return self._nominal_cell_temperature + + @property + def nominal_radiation(self): + """ + Get nominal radiation of PV panels + :return: float + """ + return self._nominal_radiation + + @property + def standard_test_condition_cell_temperature(self): + """ + Get standard test condition cell temperature of PV panels in degree Celsius + :return: float + """ + return self._standard_test_condition_cell_temperature + + @property + def standard_test_condition_maximum_power(self): + """ + Get standard test condition maximum power of PV panels in kW + :return: float + """ + return self._standard_test_condition_maximum_power + + @property + def width(self): + """ + Get PV module width in m + :return: float + """ + return self._width + + @property + def height(self): + """ + Get PV module height in m + :return: float + """ + return self._height + + @property + def control_strategy(self): + """" + Get control_strategy of Inverter from [MPPT, grid_tied, power_factor_control] + :return: string + """ + return self._control_strategy + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Generation component': {'id': self.id, + 'name': self.name, + 'type': self.type, + 'nominal power output [kW]': self.nominal_power_output, + 'nominal efficiency': self.nominal_efficiency, + 'nominal ambient temperature [Celsius]': self.nominal_ambient_temperature, + 'nominal cell temperature [Celsius]': self.nominal_cell_temperature, + 'nominal radiation [W/m2]': self.nominal_radiation, + 'standard test condition cell temperature [Celsius]': + self.standard_test_condition_cell_temperature, + 'standard test condition maximum power [kW]': + self.standard_test_condition_maximum_power, + 'width': self.width, + 'height': self.height, + 'control strategy': self.control_strategy + } + } + return content diff --git a/hub/catalog_factories/data_models/energy_systems/generation_system.py b/hub/catalog_factories/data_models/energy_systems/generation_system.py deleted file mode 100644 index 1728540f..00000000 --- a/hub/catalog_factories/data_models/energy_systems/generation_system.py +++ /dev/null @@ -1,147 +0,0 @@ -""" -Energy System catalog generation system -SPDX - License - Identifier: LGPL - 3.0 - or -later -Copyright © 2023 Concordia CERC group -Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca -""" - -from __future__ import annotations -from typing import Union - - -class GenerationSystem: - """ - Generation system class - """ - def __init__(self, system_id, name, system_type, fuel_type, source_types, heat_efficiency, cooling_efficiency, - electricity_efficiency, source_temperature, source_mass_flow, storage, auxiliary_equipment): - - self._system_id = system_id - self._name = name - self._type = system_type - self._fuel_type = fuel_type - self._source_types = source_types - self._heat_efficiency = heat_efficiency - self._cooling_efficiency = cooling_efficiency - self._electricity_efficiency = electricity_efficiency - self._source_temperature = source_temperature - self._source_mass_flow = source_mass_flow - self._storage = storage - self._auxiliary_equipment = auxiliary_equipment - - @property - def id(self): - """ - Get system id - :return: float - """ - return self._system_id - - @property - def name(self): - """ - Get name - :return: string - """ - return self._name - - @property - def type(self): - """ - Get type - :return: string - """ - return self._type - - @property - def fuel_type(self): - """ - Get fuel_type from [renewable, gas, diesel, electricity, wood, coal] - :return: string - """ - return self._fuel_type - - @property - def source_types(self): - """ - Get source_type from [air, water, geothermal, district_heating, grid, on_site_electricity] - :return: [string] - """ - return self._source_types - - @property - def heat_efficiency(self): - """ - Get heat_efficiency - :return: float - """ - return self._heat_efficiency - - @property - def cooling_efficiency(self): - """ - Get cooling_efficiency - :return: float - """ - return self._cooling_efficiency - - @property - def electricity_efficiency(self): - """ - Get electricity_efficiency - :return: float - """ - return self._electricity_efficiency - - @property - def source_temperature(self): - """ - Get source_temperature in degree Celsius - :return: float - """ - return self._source_temperature - - @property - def source_mass_flow(self): - """ - Get source_mass_flow in kg/s - :return: float - """ - return self._source_mass_flow - - @property - def storage(self): - """ - Get boolean storage exists - :return: bool - """ - return self._storage - - @property - def auxiliary_equipment(self) -> Union[None, GenerationSystem]: - """ - Get auxiliary_equipment - :return: GenerationSystem - """ - return self._auxiliary_equipment - - def to_dictionary(self): - """Class content to dictionary""" - _auxiliary_equipment = [] - if self.auxiliary_equipment is not None: - _auxiliary_equipment = self.auxiliary_equipment.to_dictionary() - content = {'Layer': {'id': self.id, - 'name': self.name, - 'type': self.type, - 'fuel type': self.fuel_type, - 'source types': self.source_types, - 'source temperature [Celsius]': self.source_temperature, - 'source mass flow [kg/s]': self.source_mass_flow, - 'heat efficiency': self.heat_efficiency, - 'cooling efficiency': self.cooling_efficiency, - 'electricity efficiency': self.electricity_efficiency, - 'it has storage': self.storage, - 'auxiliary equipment': _auxiliary_equipment - } - } - return content diff --git a/hub/catalog_factories/data_models/energy_systems/heat_generation_system.py b/hub/catalog_factories/data_models/energy_systems/heat_generation_system.py new file mode 100644 index 00000000..002d12a9 --- /dev/null +++ b/hub/catalog_factories/data_models/energy_systems/heat_generation_system.py @@ -0,0 +1,146 @@ +""" +Energy System catalog heat generation system +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca +""" + +from __future__ import annotations +from typing import Union + + +class HeatGenerationSystem: + """ + Heat Generation system class + """ + + def __init__(self, model_name, manufacturer, system_type, fuel_type, nominal_thermal_output, modulation_range, + source_types, heat_efficiency, cooling_efficiency, electricity_efficiency, source_temperature, + source_mass_flow): + self._model_name = model_name + self._manufacturer = manufacturer + self._system_type = system_type + self._fuel_type = fuel_type + self._nominal_thermal_output = nominal_thermal_output + self._modulation_range = modulation_range + self._source_types = source_types + self._heat_efficiency = heat_efficiency + self._cooling_efficiency = cooling_efficiency + self._electricity_efficiency = electricity_efficiency + self._source_temperature = source_temperature + self._source_mass_flow = source_mass_flow + + @property + def model_name(self): + """ + Get system id + :return: float + """ + return self._model_name + + @property + def manufacturer(self): + """ + Get name + :return: string + """ + return self._manufacturer + + @property + def system_type(self): + """ + Get type + :return: string + """ + return self._system_type + + @property + def fuel_type(self): + """ + Get fuel_type from [renewable, gas, diesel, electricity, wood, coal, biogas] + :return: string + """ + return self._fuel_type + + @property + def nominal_thermal_output(self): + """ + Get nominal_thermal_output of heat generation devices in kW + :return: float + """ + return self._nominal_thermal_output + + @property + def modulation_range(self): + """ + Get modulation range of heat generation devices + :return: float + """ + return self._modulation_range + + @property + def source_types(self): + """ + Get source_type from [air, water, ground, district_heating, grid, on_site_electricity] + :return: [string] + """ + return self._source_types + + @property + def heat_efficiency(self): + """ + Get heat_efficiency + :return: float + """ + return self._heat_efficiency + + @property + def cooling_efficiency(self): + """ + Get cooling_efficiency + :return: float + """ + return self._cooling_efficiency + + @property + def electricity_efficiency(self): + """ + Get electricity_efficiency + :return: float + """ + return self._electricity_efficiency + + @property + def source_temperature(self): + """ + Get source_temperature in degree Celsius + :return: float + """ + return self._source_temperature + + @property + def source_mass_flow(self): + """ + Get source_mass_flow in kg/s + :return: float + """ + return self._source_mass_flow + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Generation component': {'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'type': self.system_type, + 'fuel type': self.fuel_type, + 'nominal thermal output': self.nominal_thermal_output, + 'modulation_range': self.modulation_range, + 'source types': self.source_types, + 'source temperature [Celsius]': self.source_temperature, + 'source mass flow [kg/s]': self.source_mass_flow, + 'heat efficiency': self.heat_efficiency, + 'cooling efficiency': self.cooling_efficiency, + 'electricity efficiency': self.electricity_efficiency, + } + } + return content diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index 6059bec7..743c5b56 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -7,7 +7,8 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca from typing import Union -from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem +from hub.catalog_factories.data_models.energy_systems.heat_generation_system import HeatGenerationSystem +from hub.catalog_factories.data_models.energy_systems.electricity_generation_system import ElectricityGenerationSystem from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem @@ -21,7 +22,8 @@ class System: system_id, name, demand_types, - generation_system, + heat_generation_system, + electricity_generation_system, distribution_system, emission_system): @@ -29,7 +31,8 @@ class System: self._system_id = system_id self._name = name self._demand_types = demand_types - self._generation_system = generation_system + self._heat_generation_system = heat_generation_system + self._electricity_generation_system = electricity_generation_system self._distribution_system = distribution_system self._emission_system = emission_system @@ -66,12 +69,20 @@ class System: return self._demand_types @property - def generation_system(self) -> GenerationSystem: + def heat_generation_system(self) -> HeatGenerationSystem: """ - Get generation system - :return: GenerationSystem + Get heat generation system + :return: HeatGenerationSystem """ - return self._generation_system + return self._heat_generation_system + + @property + def electricity_generation_system(self) -> ElectricityGenerationSystem: + """ + Get electricity generation system + :return: ElectricityGenerationSystem + """ + return self._electricity_generation_system @property def distribution_system(self) -> Union[None, DistributionSystem]: @@ -101,7 +112,8 @@ class System: 'name': self.name, 'level of detail': self.lod, 'demand types': self.demand_types, - 'generation system': self.generation_system.to_dictionary(), + 'heat generation system': self.heat_generation_system.to_dictionary(), + 'electricity generation system': self.electricity_generation_system.to_dictionary(), 'distribution system': _distribution_system, 'emission system': _emission_system } diff --git a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py index 91c8d4e4..e190e49a 100644 --- a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py +++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py @@ -10,7 +10,7 @@ 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.heat_generation_system import GenerationSystem 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.archetype import Archetype From fde6f0f7513e5ea87c60a32e03ecdd517d429248 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Thu, 10 Aug 2023 20:55:35 -0400 Subject: [PATCH 04/38] Few modifications were mafe to heat_generation_system.py and electricity_generation_system.py classes. A new class named energy_storage_system.py is created to represent different possible energy storage systems in energy systems. --- .../electricity_generation_system.py | 66 ++++-- .../energy_systems/energy_storage_system.py | 217 ++++++++++++++++++ .../energy_systems/heat_generation_system.py | 26 +-- 3 files changed, 272 insertions(+), 37 deletions(-) create mode 100644 hub/catalog_factories/data_models/energy_systems/energy_storage_system.py diff --git a/hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py b/hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py index 762615a3..bc1bdb81 100644 --- a/hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py @@ -12,16 +12,17 @@ from typing import Union class ElectricityGenerationSystem: """ - Heat Generation system class + Electricity Generation system class """ - def __init__(self, model_name, manufacturer, system_type, nominal_power_output, nominal_efficiency, + def __init__(self, model_name, manufacturer, system_type, energy_source, nominal_power_output, nominal_efficiency, nominal_ambient_temperature, nominal_cell_temperature, nominal_radiation, standard_test_condition_cell_temperature, standard_test_condition_maximum_power, width, height, - control_strategy): + cogeneration_ratio, control_strategy): self._model_name = model_name self._name = manufacturer self._type = system_type + self._energy_source = energy_source self._nominal_power_output = nominal_power_output self._nominal_efficiency = nominal_efficiency self._nominal_ambient_temperature = nominal_ambient_temperature @@ -32,31 +33,39 @@ class ElectricityGenerationSystem: self._width = width self._height = height self._control_strategy = control_strategy + self._cogeneration_ratio = cogeneration_ratio @property - def id(self): + def model_name(self): """ - Get system id + Get system model :return: float """ return self._model_name @property - def name(self): + def manufacturer(self): """ - Get name + Get name of manufacturer :return: string """ return self._name @property - def type(self): + def system_type(self): """ Get type :return: string """ return self._type + @property + def energy_source(self): + """ + Get the energy source of the electricity generation system from [sun, wind, natural gas, biogas, diesel, biomass] + :return: string + """ + @property def nominal_power_output(self): """ @@ -129,6 +138,13 @@ class ElectricityGenerationSystem: """ return self._height + @property + def cogeneration_ratio(self): + """ + Get the ratio between the heat output and electricity output of CHP units + :return: float + """ + @property def control_strategy(self): """" @@ -139,21 +155,23 @@ class ElectricityGenerationSystem: def to_dictionary(self): """Class content to dictionary""" - content = {'Generation component': {'id': self.id, - 'name': self.name, - 'type': self.type, - 'nominal power output [kW]': self.nominal_power_output, - 'nominal efficiency': self.nominal_efficiency, - 'nominal ambient temperature [Celsius]': self.nominal_ambient_temperature, - 'nominal cell temperature [Celsius]': self.nominal_cell_temperature, - 'nominal radiation [W/m2]': self.nominal_radiation, - 'standard test condition cell temperature [Celsius]': - self.standard_test_condition_cell_temperature, - 'standard test condition maximum power [kW]': - self.standard_test_condition_maximum_power, - 'width': self.width, - 'height': self.height, - 'control strategy': self.control_strategy - } + content = {'Electricity Generation component': {'id': self.model_name, + 'name': self.manufacturer, + 'type': self.system_type, + 'energy source': self.energy_source, + 'nominal power output [kW]': self.nominal_power_output, + 'nominal efficiency': self.nominal_efficiency, + 'nominal ambient temperature [Celsius]': self.nominal_ambient_temperature, + 'nominal cell temperature [Celsius]': self.nominal_cell_temperature, + 'nominal radiation [W/m2]': self.nominal_radiation, + 'standard test condition cell temperature [Celsius]': + self.standard_test_condition_cell_temperature, + 'standard test condition maximum power [kW]': + self.standard_test_condition_maximum_power, + 'width': self.width, + 'height': self.height, + 'cogeneration ratio': self.cogeneration_ratio, + 'control strategy': self.control_strategy + } } return content 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 new file mode 100644 index 00000000..e76c0b65 --- /dev/null +++ b/hub/catalog_factories/data_models/energy_systems/energy_storage_system.py @@ -0,0 +1,217 @@ +""" +Energy System catalog heat generation system +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca +""" + +from __future__ import annotations +from typing import Union + + +class EnergyStorageSystem: + """" + Energy Storage System Class + """ + + def __init__(self, model_name, manufacturer, storage_type, storage_subtype, physical_volume, rated_output_power, + nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, diameter, height, + storage_material, storage_thickness, material_conductivity, insulation_material, insulation_thickness, + insulation_conductivity, maximum_operating_temperature): + self._model_name = model_name + self._manufacturer = manufacturer + self._storage_type = storage_type + self._storage_subtype = storage_subtype + self._physical_volume = physical_volume + self._rated_output_power = rated_output_power + self._nominal_efficiency = nominal_efficiency + self._battery_voltage = battery_voltage + self._depth_of_discharge = depth_of_discharge + self._self_discharge_rate = self_discharge_rate + self._diameter = diameter + self._height = height + self._storage_material = storage_material + self._storage_thickness = storage_thickness + self._material_conductivity = material_conductivity + self._insulation_material = insulation_material + self._insulation_thickness = insulation_thickness + self._insulation_conductivity = insulation_conductivity + self._maximum_operating_temperature = maximum_operating_temperature + + @property + def model_name(self): + """ + Get system model + :return: float + """ + return self._model_name + + @property + def manufacturer(self): + """ + Get name of manufacturer + :return: string + """ + return self._manufacturer + + @property + def storage_type(self): + """ + Get storage type from [electrical, electrochemical, mechanical, thermal], chemical] + :return: string + """ + return self._storage_type + + @property + def storage_subtype(self): + """ + Get storage subtype from [lithium ion, lead acid, niMH, caes, flywheel, sensible heat storage, latent heat storage] + :return: string + """ + return self._storage_subtype + + @property + def physical_volume(self): + """ + Get the physical volume of the storage system in cubic meters + :return: float + """ + return self._physical_volume + + @property + def rated_output_power(self): + """ + Get the rated output power of storage system in kW + :return: float + """ + return self._rated_output_power + + @property + def nominal_efficiency(self): + """ + Get the nominal efficiency of the storage system + :return: float + """ + return self._nominal_efficiency + + @property + def battery_voltage(self): + """ + Get the battery voltage in Volt + :return: float + """ + return self._battery_voltage + + @property + def depth_of_discharge(self): + """ + Get the depth of discharge as a percentage + :return: float + """ + return self._depth_of_discharge + + @property + def self_discharge_rate(self): + """ + Get the self discharge rate of battery as a percentage + :return: float + """ + return self._self_discharge_rate + + @property + def diameter(self): + """ + Get the diameter of the storage system in meters + :return: float + """ + return self._diameter + + @property + def height(self): + """ + Get the height of the storage system in meters + :return: float + """ + return self._height + + @property + def storage_material(self): + """ + Get the name of the storage system material + :return: string + """ + return self._storage_material + + @property + def storage_thickness(self): + """ + Get the thickness of the storage system in meters + :return: float + """ + return self._storage_thickness + + @property + def material_conductivity(self): + """ + Get the thermal conductivity of the storage system material in W/(m.K) + :return: float + """ + return self._material_conductivity + + @property + def insulation_material(self): + """ + Get the name of the material used as insulation + :return: string + """ + return self._insulation_material + + @property + def insulation_thickness(self): + """ + Get the thickness of the insulation used for the storage system in meters + :return: float + """ + return self._storage_thickness + + @property + def insulation_conductivity(self): + """ + Get the thickness of the insulation used for the storage system in W/(m.K) + :return: float + """ + return self._insulation_conductivity + + @property + def maximum_operating_temperature(self): + """ + Get maximum operating temperature of the storage system in degree Celsius + :return: float + """ + return self._maximum_operating_temperature + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Storage component': {'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'storage type': self.storage_type, + 'storage subtype': self.storage_subtype, + 'physical volume [m3]': self.physical_volume, + 'rated power [kW]': self.rated_output_power, + 'nominal efficiency': self.nominal_efficiency, + 'battery voltage [V]': self.battery_voltage, + 'depth of discharge': self.depth_of_discharge, + 'self discharge rate': self.self_discharge_rate, + 'diameter [m]': self.diameter, + 'height [m]': self.height, + 'storage material': self.storage_material, + 'storage thickness [m]': self.storage_thickness, + 'storage material thermal conductivity [W/m.K]': self.material_conductivity, + 'insulation material': self.insulation_material, + 'insulation thickness[m]': self.insulation_thickness, + 'insulation thermal conductivity [W/m.K]': self.insulation_conductivity, + 'maximum operating temperature [Celsius]': self.maximum_operating_temperature + } + } + return content \ No newline at end of file diff --git a/hub/catalog_factories/data_models/energy_systems/heat_generation_system.py b/hub/catalog_factories/data_models/energy_systems/heat_generation_system.py index 002d12a9..4b290d15 100644 --- a/hub/catalog_factories/data_models/energy_systems/heat_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/heat_generation_system.py @@ -129,18 +129,18 @@ class HeatGenerationSystem: def to_dictionary(self): """Class content to dictionary""" - content = {'Generation component': {'model name': self.model_name, - 'manufacturer': self.manufacturer, - 'type': self.system_type, - 'fuel type': self.fuel_type, - 'nominal thermal output': self.nominal_thermal_output, - 'modulation_range': self.modulation_range, - 'source types': self.source_types, - 'source temperature [Celsius]': self.source_temperature, - 'source mass flow [kg/s]': self.source_mass_flow, - 'heat efficiency': self.heat_efficiency, - 'cooling efficiency': self.cooling_efficiency, - 'electricity efficiency': self.electricity_efficiency, - } + content = {'Heat Generation component': {'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'type': self.system_type, + 'fuel type': self.fuel_type, + 'nominal thermal output': self.nominal_thermal_output, + 'modulation_range': self.modulation_range, + 'source types': self.source_types, + 'source temperature [Celsius]': self.source_temperature, + 'source mass flow [kg/s]': self.source_mass_flow, + 'heat efficiency': self.heat_efficiency, + 'cooling efficiency': self.cooling_efficiency, + 'electricity efficiency': self.electricity_efficiency, + } } return content From 1b3a128f334b9cd048d882a44c042b143c2224a1 Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Fri, 11 Aug 2023 10:18:33 -0400 Subject: [PATCH 05/38] added .gitignore to always ignore .idea --- .gitignore | 1 + .idea/.gitignore | 3 --- .idea/codeStyles/codeStyleConfig.xml | 5 ----- .idea/hub.iml | 12 ------------ .idea/inspectionProfiles/Project_Default.xml | 12 ------------ .idea/inspectionProfiles/profiles_settings.xml | 6 ------ .idea/misc.xml | 7 ------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 9 files changed, 1 insertion(+), 59 deletions(-) create mode 100644 .gitignore delete mode 100644 .idea/.gitignore delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/hub.iml delete mode 100644 .idea/inspectionProfiles/Project_Default.xml delete mode 100644 .idea/inspectionProfiles/profiles_settings.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..723ef36f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d33521..00000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index a55e7a17..00000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/hub.iml b/.idea/hub.iml deleted file mode 100644 index 8b8c3954..00000000 --- a/.idea/hub.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 92775997..00000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2da..00000000 --- a/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 0e4465aa..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 8d1428ff..00000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 94a25f7f..00000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 61d4c012dcca65665af9891c25ee719d24950eac Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Sun, 13 Aug 2023 10:26:36 -0400 Subject: [PATCH 06/38] Renamed the electricity_generation_system.py to pv_generation_system.py and modified the heating_generation_system to generation_system.py to account for all the generation systems. --- .../energy_systems/energy_storage_system.py | 30 ++----- ...eration_system.py => generation_system.py} | 24 ++++- ...tion_system.py => pv_generation_system.py} | 87 +------------------ .../data_models/energy_systems/system.py | 8 +- .../energy_systems/montreal_custom_catalog.py | 2 +- 5 files changed, 37 insertions(+), 114 deletions(-) rename hub/catalog_factories/data_models/energy_systems/{heat_generation_system.py => generation_system.py} (83%) rename hub/catalog_factories/data_models/energy_systems/{electricity_generation_system.py => pv_generation_system.py} (54%) 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 e76c0b65..7ac5d7d0 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 @@ -8,6 +8,8 @@ Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca from __future__ import annotations from typing import Union +from hub.catalog_factories.data_models.construction.material import Material +from hub.catalog_factories.data_models.construction.layer import Layer class EnergyStorageSystem: @@ -15,22 +17,20 @@ class EnergyStorageSystem: Energy Storage System Class """ - def __init__(self, model_name, manufacturer, storage_type, storage_subtype, physical_volume, rated_output_power, - nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, diameter, height, + def __init__(self, model_name, manufacturer, storage_type, volume, rated_output_power, + nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, diameter, storage_material, storage_thickness, material_conductivity, insulation_material, insulation_thickness, insulation_conductivity, maximum_operating_temperature): self._model_name = model_name self._manufacturer = manufacturer self._storage_type = storage_type - self._storage_subtype = storage_subtype - self._physical_volume = physical_volume + self._physical_volume = volume self._rated_output_power = rated_output_power self._nominal_efficiency = nominal_efficiency self._battery_voltage = battery_voltage self._depth_of_discharge = depth_of_discharge self._self_discharge_rate = self_discharge_rate self._diameter = diameter - self._height = height self._storage_material = storage_material self._storage_thickness = storage_thickness self._material_conductivity = material_conductivity @@ -58,19 +58,11 @@ class EnergyStorageSystem: @property def storage_type(self): """ - Get storage type from [electrical, electrochemical, mechanical, thermal], chemical] + Get storage type from ['lithium_ion', 'sensible', 'latent'] :return: string """ return self._storage_type - @property - def storage_subtype(self): - """ - Get storage subtype from [lithium ion, lead acid, niMH, caes, flywheel, sensible heat storage, latent heat storage] - :return: string - """ - return self._storage_subtype - @property def physical_volume(self): """ @@ -127,14 +119,6 @@ class EnergyStorageSystem: """ return self._diameter - @property - def height(self): - """ - Get the height of the storage system in meters - :return: float - """ - return self._height - @property def storage_material(self): """ @@ -196,7 +180,6 @@ class EnergyStorageSystem: content = {'Storage component': {'model name': self.model_name, 'manufacturer': self.manufacturer, 'storage type': self.storage_type, - 'storage subtype': self.storage_subtype, 'physical volume [m3]': self.physical_volume, 'rated power [kW]': self.rated_output_power, 'nominal efficiency': self.nominal_efficiency, @@ -204,7 +187,6 @@ class EnergyStorageSystem: 'depth of discharge': self.depth_of_discharge, 'self discharge rate': self.self_discharge_rate, 'diameter [m]': self.diameter, - 'height [m]': self.height, 'storage material': self.storage_material, 'storage thickness [m]': self.storage_thickness, 'storage material thermal conductivity [W/m.K]': self.material_conductivity, diff --git a/hub/catalog_factories/data_models/energy_systems/heat_generation_system.py b/hub/catalog_factories/data_models/energy_systems/generation_system.py similarity index 83% rename from hub/catalog_factories/data_models/energy_systems/heat_generation_system.py rename to hub/catalog_factories/data_models/energy_systems/generation_system.py index 4b290d15..5179eb8d 100644 --- a/hub/catalog_factories/data_models/energy_systems/heat_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/generation_system.py @@ -10,14 +10,14 @@ from __future__ import annotations from typing import Union -class HeatGenerationSystem: +class GenerationSystem: """ Heat Generation system class """ def __init__(self, model_name, manufacturer, system_type, fuel_type, nominal_thermal_output, modulation_range, source_types, heat_efficiency, cooling_efficiency, electricity_efficiency, source_temperature, - source_mass_flow): + source_mass_flow, nominal_electricity_output, cogeneration_ratio): self._model_name = model_name self._manufacturer = manufacturer self._system_type = system_type @@ -30,6 +30,8 @@ class HeatGenerationSystem: self._electricity_efficiency = electricity_efficiency self._source_temperature = source_temperature self._source_mass_flow = source_mass_flow + self._nominal_electricity_output = nominal_electricity_output + self._cogeneration_ratio = cogeneration_ratio @property def model_name(self): @@ -127,6 +129,22 @@ class HeatGenerationSystem: """ return self._source_mass_flow + @property + def nominal_electricity_output(self): + """ + Get nominal_power_output of electricity generation devices or inverters in kW + :return: float + """ + return self._nominal_electricity_output + + @property + def cogeneration_ratio(self): + """ + Get the ratio between the heat output and electricity output of CHP units + :return: float + """ + return self._cogeneration_ratio + def to_dictionary(self): """Class content to dictionary""" content = {'Heat Generation component': {'model name': self.model_name, @@ -141,6 +159,8 @@ class HeatGenerationSystem: 'heat efficiency': self.heat_efficiency, 'cooling efficiency': self.cooling_efficiency, 'electricity efficiency': self.electricity_efficiency, + 'nominal power output [kW]': self.nominal_electricity_output, + 'cogeneration ratio': self.cogeneration_ratio, } } return content diff --git a/hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py similarity index 54% rename from hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py rename to hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index bc1bdb81..78bd2bd6 100644 --- a/hub/catalog_factories/data_models/energy_systems/electricity_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -10,21 +10,13 @@ from __future__ import annotations from typing import Union -class ElectricityGenerationSystem: +class PvGenerationSystem: """ Electricity Generation system class """ - def __init__(self, model_name, manufacturer, system_type, energy_source, nominal_power_output, nominal_efficiency, - nominal_ambient_temperature, nominal_cell_temperature, nominal_radiation, - standard_test_condition_cell_temperature, standard_test_condition_maximum_power, width, height, - cogeneration_ratio, control_strategy): - self._model_name = model_name - self._name = manufacturer - self._type = system_type - self._energy_source = energy_source - self._nominal_power_output = nominal_power_output - self._nominal_efficiency = nominal_efficiency + def __init__(self, nominal_ambient_temperature, nominal_cell_temperature, nominal_radiation, + standard_test_condition_cell_temperature, standard_test_condition_maximum_power, width, height): self._nominal_ambient_temperature = nominal_ambient_temperature self._nominal_cell_temperature = nominal_cell_temperature self._nominal_radiation = nominal_radiation @@ -32,55 +24,6 @@ class ElectricityGenerationSystem: self._standard_test_condition_maximum_power = standard_test_condition_maximum_power self._width = width self._height = height - self._control_strategy = control_strategy - self._cogeneration_ratio = cogeneration_ratio - - @property - def model_name(self): - """ - Get system model - :return: float - """ - return self._model_name - - @property - def manufacturer(self): - """ - Get name of manufacturer - :return: string - """ - return self._name - - @property - def system_type(self): - """ - Get type - :return: string - """ - return self._type - - @property - def energy_source(self): - """ - Get the energy source of the electricity generation system from [sun, wind, natural gas, biogas, diesel, biomass] - :return: string - """ - - @property - def nominal_power_output(self): - """ - Get nominal_power_output of electricity generation devices or inverters in kW - :return: float - """ - return self._nominal_power_output - - @property - def nominal_efficiency(self): - """ - Get nominal_efficiency of electricity generation devices or inverters - :return: float - """ - return self._nominal_efficiency @property def nominal_ambient_temperature(self): @@ -138,29 +81,9 @@ class ElectricityGenerationSystem: """ return self._height - @property - def cogeneration_ratio(self): - """ - Get the ratio between the heat output and electricity output of CHP units - :return: float - """ - - @property - def control_strategy(self): - """" - Get control_strategy of Inverter from [MPPT, grid_tied, power_factor_control] - :return: string - """ - return self._control_strategy - def to_dictionary(self): """Class content to dictionary""" - content = {'Electricity Generation component': {'id': self.model_name, - 'name': self.manufacturer, - 'type': self.system_type, - 'energy source': self.energy_source, - 'nominal power output [kW]': self.nominal_power_output, - 'nominal efficiency': self.nominal_efficiency, + content = {'Electricity Generation component': { 'nominal ambient temperature [Celsius]': self.nominal_ambient_temperature, 'nominal cell temperature [Celsius]': self.nominal_cell_temperature, 'nominal radiation [W/m2]': self.nominal_radiation, @@ -170,8 +93,6 @@ class ElectricityGenerationSystem: self.standard_test_condition_maximum_power, 'width': self.width, 'height': self.height, - 'cogeneration ratio': self.cogeneration_ratio, - 'control strategy': self.control_strategy } } return content diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index 743c5b56..f8b47905 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -7,8 +7,8 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca from typing import Union -from hub.catalog_factories.data_models.energy_systems.heat_generation_system import HeatGenerationSystem -from hub.catalog_factories.data_models.energy_systems.electricity_generation_system import ElectricityGenerationSystem +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 @@ -69,7 +69,7 @@ class System: return self._demand_types @property - def heat_generation_system(self) -> HeatGenerationSystem: + def heat_generation_system(self) -> GenerationSystem: """ Get heat generation system :return: HeatGenerationSystem @@ -77,7 +77,7 @@ class System: return self._heat_generation_system @property - def electricity_generation_system(self) -> ElectricityGenerationSystem: + def electricity_generation_system(self) -> PvGenerationSystem: """ Get electricity generation system :return: ElectricityGenerationSystem diff --git a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py index e190e49a..91c8d4e4 100644 --- a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py +++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py @@ -10,7 +10,7 @@ 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.heat_generation_system import GenerationSystem +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.emission_system import EmissionSystem from hub.catalog_factories.data_models.energy_systems.archetype import Archetype From 231e4a17f2be08476195adce37da6d0b15efff66 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Sun, 13 Aug 2023 20:43:05 -0400 Subject: [PATCH 07/38] All the attributes related to the material and insulation of the tank are substituted with one attribute called "layers" --- .../energy_systems/energy_storage_system.py | 70 +++---------------- 1 file changed, 11 insertions(+), 59 deletions(-) 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 7ac5d7d0..c84e6706 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 @@ -18,9 +18,8 @@ class EnergyStorageSystem: """ def __init__(self, model_name, manufacturer, storage_type, volume, rated_output_power, - nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, diameter, - storage_material, storage_thickness, material_conductivity, insulation_material, insulation_thickness, - insulation_conductivity, maximum_operating_temperature): + nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, diameter, layers + , maximum_operating_temperature): self._model_name = model_name self._manufacturer = manufacturer self._storage_type = storage_type @@ -31,12 +30,7 @@ class EnergyStorageSystem: self._depth_of_discharge = depth_of_discharge self._self_discharge_rate = self_discharge_rate self._diameter = diameter - self._storage_material = storage_material - self._storage_thickness = storage_thickness - self._material_conductivity = material_conductivity - self._insulation_material = insulation_material - self._insulation_thickness = insulation_thickness - self._insulation_conductivity = insulation_conductivity + self._layers = layers self._maximum_operating_temperature = maximum_operating_temperature @property @@ -120,52 +114,12 @@ class EnergyStorageSystem: return self._diameter @property - def storage_material(self): + def layers(self) -> [Layer]: """ - Get the name of the storage system material - :return: string + Get construction layers + :return: [layer] """ - return self._storage_material - - @property - def storage_thickness(self): - """ - Get the thickness of the storage system in meters - :return: float - """ - return self._storage_thickness - - @property - def material_conductivity(self): - """ - Get the thermal conductivity of the storage system material in W/(m.K) - :return: float - """ - return self._material_conductivity - - @property - def insulation_material(self): - """ - Get the name of the material used as insulation - :return: string - """ - return self._insulation_material - - @property - def insulation_thickness(self): - """ - Get the thickness of the insulation used for the storage system in meters - :return: float - """ - return self._storage_thickness - - @property - def insulation_conductivity(self): - """ - Get the thickness of the insulation used for the storage system in W/(m.K) - :return: float - """ - return self._insulation_conductivity + return self._layers @property def maximum_operating_temperature(self): @@ -177,6 +131,9 @@ class EnergyStorageSystem: def to_dictionary(self): """Class content to dictionary""" + _layers = [] + for _layer in self.layers: + _layers.append(_layer.to_dictionary()) content = {'Storage component': {'model name': self.model_name, 'manufacturer': self.manufacturer, 'storage type': self.storage_type, @@ -187,12 +144,7 @@ class EnergyStorageSystem: 'depth of discharge': self.depth_of_discharge, 'self discharge rate': self.self_discharge_rate, 'diameter [m]': self.diameter, - 'storage material': self.storage_material, - 'storage thickness [m]': self.storage_thickness, - 'storage material thermal conductivity [W/m.K]': self.material_conductivity, - 'insulation material': self.insulation_material, - 'insulation thickness[m]': self.insulation_thickness, - 'insulation thermal conductivity [W/m.K]': self.insulation_conductivity, + 'layers': _layers, 'maximum operating temperature [Celsius]': self.maximum_operating_temperature } } From d6ee3d6e6ba5f89d2c076288f9f4cc9f80168436 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Sun, 13 Aug 2023 20:44:14 -0400 Subject: [PATCH 08/38] All the attributes related to the material and insulation of the tank are substituted with one attribute called "layers" --- .../data_models/energy_systems/energy_storage_system.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 c84e6706..9be2d17d 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 @@ -18,8 +18,8 @@ class EnergyStorageSystem: """ def __init__(self, model_name, manufacturer, storage_type, volume, rated_output_power, - nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, diameter, layers - , maximum_operating_temperature): + nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, diameter, layers, + maximum_operating_temperature): self._model_name = model_name self._manufacturer = manufacturer self._storage_type = storage_type From 6ce82c52de487c9f1d51c305cdc04afaa50d28e3 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Sun, 13 Aug 2023 21:17:03 -0400 Subject: [PATCH 09/38] Class parameter_function.py is created --- .../energy_systems/parameter_function.py | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 hub/catalog_factories/data_models/energy_systems/parameter_function.py diff --git a/hub/catalog_factories/data_models/energy_systems/parameter_function.py b/hub/catalog_factories/data_models/energy_systems/parameter_function.py new file mode 100644 index 00000000..089812b5 --- /dev/null +++ b/hub/catalog_factories/data_models/energy_systems/parameter_function.py @@ -0,0 +1,53 @@ +""" +Energy System catalog heat generation system +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca +""" + +from __future__ import annotations +from typing import Union + + +class ParameterFunction: + """ + Parameter function class + """ + + def __init__(self, type, coefficients): + self._type = type + self._coefficients = coefficients + + @property + def type(self): + """ + The type of the fit function from the following + Linear =>>> y = a*x + b + Exponential =>>> y = a*(b**x) + Polynomial =>>> y = a*(x**2) + b*x + c + Power =>>> y = a*(x**b) + Second degree multivariable =>>> y = a*(x**2) + b*x + c*x*y + d*y + e*(y**2) + f + + Get the type of function from ['linear', 'exponential', 'polynomial', 'power', 'second degree multivariable'] + :return: string + """ + return self._type + + @property + def coefficients(self): + """ + Get the coefficients of the functions as list + :return: [coefficients] + """ + return self._coefficients + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Parameter Function': { + 'type': self.type, + 'coefficients': self.coefficients, + } + } + return content + From acd7ad22666b22839ff5f073430e080ec530caa8 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Sun, 13 Aug 2023 22:53:43 -0400 Subject: [PATCH 10/38] distribution_system.py is modified --- .../energy_systems/distribution_system.py | 50 +++++++++++++------ .../data_models/energy_systems/system.py | 1 + 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/distribution_system.py b/hub/catalog_factories/data_models/energy_systems/distribution_system.py index e24ba64c..8c1146fd 100644 --- a/hub/catalog_factories/data_models/energy_systems/distribution_system.py +++ b/hub/catalog_factories/data_models/energy_systems/distribution_system.py @@ -5,42 +5,46 @@ Copyright © 2023 Concordia CERC group Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ +from hub.catalog_factories.data_models.construction.material import Material + class DistributionSystem: """ Distribution system class """ - def __init__(self, system_id, name, system_type, supply_temperature, distribution_consumption_fix_flow, - distribution_consumption_variable_flow, heat_losses): - self._system_id = system_id - self._name = name + def __init__(self, model, manufacturer, system_type, supply_temperature, distribution_consumption_fix_flow, + distribution_consumption_variable_flow, heat_losses, nominal_heat_output, medium): + self._model = model + self._manufacturer = manufacturer self._type = system_type self._supply_temperature = supply_temperature self._distribution_consumption_fix_flow = distribution_consumption_fix_flow self._distribution_consumption_variable_flow = distribution_consumption_variable_flow self._heat_losses = heat_losses + self._nominal_heat_output = nominal_heat_output + self._medium = medium @property - def id(self): + def model(self): """ - Get system id - :return: float + Get system model + :return: string """ - return self._system_id + return self._model @property - def name(self): + def manufacturer(self): """ Get name :return: string """ - return self._name + return self._manufacturer @property def type(self): """ - Get type from [air, water, refrigerant] + Get type from ['radiator', 'forced air convection', 'radiant floor heating'] :return: string """ return self._type @@ -78,17 +82,35 @@ class DistributionSystem: """ return self._heat_losses + @property + def nominal_heat_output(self): + """ + Get the nominal heat output of the heat distribution system in kW + :return: float + """ + return self._nominal_heat_output + + @property + def medium(self) -> Material: + """ + Get the heat transfer medium characteristics + :return: Material + """ + return self._medium + def to_dictionary(self): """Class content to dictionary""" content = { 'Layer': { - 'id': self.id, - 'name': self.name, + 'model': self.model, + 'manufacturer': self.manufacturer, 'type': self.type, 'supply temperature [Celsius]': self.supply_temperature, 'distribution consumption if fix flow over peak power [W/W]': self.distribution_consumption_fix_flow, 'distribution consumption if variable flow over peak power [J/J]': self.distribution_consumption_variable_flow, - 'heat losses per energy produced [J/J]': self.heat_losses + 'heat losses per energy produced [J/J]': self.heat_losses, + 'nominal_heat_output': self.nominal_heat_output, + 'heat transfer medium': self.medium } } return content diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index f8b47905..5dc59ddb 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -9,6 +9,7 @@ from typing import Union 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.energy_storage_system import EnergyStorageSystem 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 3feecac15d49f5dd940473b4fc0d2af9124e5139 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Mon, 14 Aug 2023 20:00:17 -0400 Subject: [PATCH 11/38] cogeneration ratio was removed from generation_system.py pv_generation_system.py is completed by adding an inheritance from the GenerationSystem class parameter_function.py is renamed to performance_curves.py and an attribute to get the list of target parameters is added to it system.py is modified by adding energy storage, performance curves, pv to it --- .../energy_systems/distribution_system.py | 48 +++------- .../energy_systems/emission_system.py | 60 ------------ .../energy_systems/energy_emission_system.py | 94 +++++++++++++++++++ .../energy_systems/generation_system.py | 40 +++----- .../energy_systems/pv_generation_system.py | 39 +++++--- .../data_models/energy_systems/system.py | 90 ++++++++++++------ .../energy_systems/montreal_custom_catalog.py | 40 ++++---- 7 files changed, 231 insertions(+), 180 deletions(-) delete mode 100644 hub/catalog_factories/data_models/energy_systems/emission_system.py create mode 100644 hub/catalog_factories/data_models/energy_systems/energy_emission_system.py diff --git a/hub/catalog_factories/data_models/energy_systems/distribution_system.py b/hub/catalog_factories/data_models/energy_systems/distribution_system.py index 8c1146fd..defdad4f 100644 --- a/hub/catalog_factories/data_models/energy_systems/distribution_system.py +++ b/hub/catalog_factories/data_models/energy_systems/distribution_system.py @@ -13,38 +13,36 @@ class DistributionSystem: Distribution system class """ - def __init__(self, model, manufacturer, system_type, supply_temperature, distribution_consumption_fix_flow, - distribution_consumption_variable_flow, heat_losses, nominal_heat_output, medium): - self._model = model - self._manufacturer = manufacturer + def __init__(self, system_id, name, system_type, supply_temperature, distribution_consumption_fix_flow, + distribution_consumption_variable_flow, heat_losses): + self._system_id = system_id + self._name = name self._type = system_type self._supply_temperature = supply_temperature self._distribution_consumption_fix_flow = distribution_consumption_fix_flow self._distribution_consumption_variable_flow = distribution_consumption_variable_flow self._heat_losses = heat_losses - self._nominal_heat_output = nominal_heat_output - self._medium = medium @property - def model(self): + def id(self): """ - Get system model - :return: string + Get system id + :return: float """ - return self._model + return self._system_id @property - def manufacturer(self): + def name(self): """ Get name :return: string """ - return self._manufacturer + return self._name @property def type(self): """ - Get type from ['radiator', 'forced air convection', 'radiant floor heating'] + Get type from [air, water, refrigerant] :return: string """ return self._type @@ -82,35 +80,17 @@ class DistributionSystem: """ return self._heat_losses - @property - def nominal_heat_output(self): - """ - Get the nominal heat output of the heat distribution system in kW - :return: float - """ - return self._nominal_heat_output - - @property - def medium(self) -> Material: - """ - Get the heat transfer medium characteristics - :return: Material - """ - return self._medium - def to_dictionary(self): """Class content to dictionary""" content = { 'Layer': { - 'model': self.model, - 'manufacturer': self.manufacturer, + 'id': self.id, + 'name': self.name, 'type': self.type, 'supply temperature [Celsius]': self.supply_temperature, 'distribution consumption if fix flow over peak power [W/W]': self.distribution_consumption_fix_flow, 'distribution consumption if variable flow over peak power [J/J]': self.distribution_consumption_variable_flow, - 'heat losses per energy produced [J/J]': self.heat_losses, - 'nominal_heat_output': self.nominal_heat_output, - 'heat transfer medium': self.medium + 'heat losses per energy produced [J/J]': self.heat_losses } } return content diff --git a/hub/catalog_factories/data_models/energy_systems/emission_system.py b/hub/catalog_factories/data_models/energy_systems/emission_system.py deleted file mode 100644 index 5e9d2865..00000000 --- a/hub/catalog_factories/data_models/energy_systems/emission_system.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -Energy System catalog emission system -SPDX - License - Identifier: LGPL - 3.0 - or -later -Copyright © 2023 Concordia CERC group -Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca -""" - - -class EmissionSystem: - """ - Emission system class - """ - def __init__(self, system_id, name, system_type, parasitic_energy_consumption): - - self._system_id = system_id - self._name = name - self._type = system_type - self._parasitic_energy_consumption = parasitic_energy_consumption - - @property - def id(self): - """ - Get system id - :return: float - """ - return self._system_id - - @property - def name(self): - """ - Get name - :return: string - """ - return self._name - - @property - def type(self): - """ - Get type - :return: string - """ - return self._type - - @property - def parasitic_energy_consumption(self): - """ - Get parasitic_energy_consumption in ratio (J/J) - :return: float - """ - return self._parasitic_energy_consumption - - def to_dictionary(self): - """Class content to dictionary""" - content = {'Layer': {'id': self.id, - 'name': self.name, - 'type': self.type, - 'parasitic energy consumption per energy produced [J/J]': self.parasitic_energy_consumption - } - } - return content diff --git a/hub/catalog_factories/data_models/energy_systems/energy_emission_system.py b/hub/catalog_factories/data_models/energy_systems/energy_emission_system.py new file mode 100644 index 00000000..171a8fda --- /dev/null +++ b/hub/catalog_factories/data_models/energy_systems/energy_emission_system.py @@ -0,0 +1,94 @@ +""" +Energy System catalog emission system +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca +""" + +from hub.catalog_factories.data_models.construction.material import Material + + +class EnergyEmissionSystem: + """ + Emission system class + """ + def __init__(self, model_name, manufacturer, system_type, parasitic_energy_consumption, nominal_heat_output, + nominal_efficiency, medium): + + self._system_id = model_name + self._name = manufacturer + self._type = system_type + self._parasitic_energy_consumption = parasitic_energy_consumption + self._nominal_heat_output = nominal_heat_output + self._nominal_efficiency = nominal_efficiency + self._medium = medium + + @property + def model_name(self): + """ + Get system id + :return: float + """ + return self._system_id + + @property + def manufacturer(self): + """ + Get name + :return: string + """ + return self._name + + @property + def type(self): + """ + Get type + :return: string + """ + return self._type + + @property + def parasitic_energy_consumption(self): + """ + Get parasitic_energy_consumption in ratio (J/J) + :return: float + """ + return self._parasitic_energy_consumption + + @property + def nominal_heat_output(self): + """ + Get the nominal heat output of the emission system in kW + :return: float + """ + return self._nominal_heat_output + + @property + def nominal_efficiency(self): + """ + Get the nominal efficiency of the emission system + :return: float + """ + return self._nominal_efficiency + + @property + def medium(self) -> Material: + """ + Get the heat transfer characteristics of the heat transfer medium + :return: Material + """ + return self._medium + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Layer': {'id': self.model_name, + 'name': self.manufacturer, + 'type': self.type, + 'parasitic energy consumption per energy produced [J/J]': self.parasitic_energy_consumption, + 'nominal heat output [kW]': self.nominal_heat_output, + 'nominal efficiency': self.nominal_efficiency, + 'heat transfer medium': self.medium + } + } + return content diff --git a/hub/catalog_factories/data_models/energy_systems/generation_system.py b/hub/catalog_factories/data_models/energy_systems/generation_system.py index 5179eb8d..f0ce35ab 100644 --- a/hub/catalog_factories/data_models/energy_systems/generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/generation_system.py @@ -17,7 +17,7 @@ class GenerationSystem: def __init__(self, model_name, manufacturer, system_type, fuel_type, nominal_thermal_output, modulation_range, source_types, heat_efficiency, cooling_efficiency, electricity_efficiency, source_temperature, - source_mass_flow, nominal_electricity_output, cogeneration_ratio): + source_mass_flow, nominal_electricity_output): self._model_name = model_name self._manufacturer = manufacturer self._system_type = system_type @@ -31,7 +31,6 @@ class GenerationSystem: self._source_temperature = source_temperature self._source_mass_flow = source_mass_flow self._nominal_electricity_output = nominal_electricity_output - self._cogeneration_ratio = cogeneration_ratio @property def model_name(self): @@ -137,30 +136,21 @@ class GenerationSystem: """ return self._nominal_electricity_output - @property - def cogeneration_ratio(self): - """ - Get the ratio between the heat output and electricity output of CHP units - :return: float - """ - return self._cogeneration_ratio - def to_dictionary(self): """Class content to dictionary""" - content = {'Heat Generation component': {'model name': self.model_name, - 'manufacturer': self.manufacturer, - 'type': self.system_type, - 'fuel type': self.fuel_type, - 'nominal thermal output': self.nominal_thermal_output, - 'modulation_range': self.modulation_range, - 'source types': self.source_types, - 'source temperature [Celsius]': self.source_temperature, - 'source mass flow [kg/s]': self.source_mass_flow, - 'heat efficiency': self.heat_efficiency, - 'cooling efficiency': self.cooling_efficiency, - 'electricity efficiency': self.electricity_efficiency, - 'nominal power output [kW]': self.nominal_electricity_output, - 'cogeneration ratio': self.cogeneration_ratio, - } + content = {'Energy Generation component': {'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'type': self.system_type, + 'fuel type': self.fuel_type, + 'nominal thermal output': self.nominal_thermal_output, + 'modulation_range': self.modulation_range, + 'source types': self.source_types, + 'source temperature [Celsius]': self.source_temperature, + 'source mass flow [kg/s]': self.source_mass_flow, + 'heat efficiency': self.heat_efficiency, + 'cooling efficiency': self.cooling_efficiency, + 'electricity efficiency': self.electricity_efficiency, + 'nominal power output [kW]': self.nominal_electricity_output, + } } return content diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index 78bd2bd6..a258b4b9 100644 --- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -8,15 +8,22 @@ Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca from __future__ import annotations from typing import Union +from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem -class PvGenerationSystem: +class PvGenerationSystem(GenerationSystem): """ Electricity Generation system class """ def __init__(self, nominal_ambient_temperature, nominal_cell_temperature, nominal_radiation, - standard_test_condition_cell_temperature, standard_test_condition_maximum_power, width, height): + standard_test_condition_cell_temperature, standard_test_condition_maximum_power, width, height, + model_name, manufacturer, electricity_efficiency, nominal_electricity_output): + super(GenerationSystem, self).__init__(model_name=model_name, manufacturer=manufacturer, system_type='pv', + fuel_type='renewable', nominal_thermal_output=None, modulation_range=None, + source_types=None, heat_efficiency=None, cooling_efficiency=None, + electricity_efficiency=electricity_efficiency, source_temperature=None, + source_mass_flow=None, nominal_electricity_output=nominal_electricity_output) self._nominal_ambient_temperature = nominal_ambient_temperature self._nominal_cell_temperature = nominal_cell_temperature self._nominal_radiation = nominal_radiation @@ -83,16 +90,20 @@ class PvGenerationSystem: def to_dictionary(self): """Class content to dictionary""" - content = {'Electricity Generation component': { - 'nominal ambient temperature [Celsius]': self.nominal_ambient_temperature, - 'nominal cell temperature [Celsius]': self.nominal_cell_temperature, - 'nominal radiation [W/m2]': self.nominal_radiation, - 'standard test condition cell temperature [Celsius]': - self.standard_test_condition_cell_temperature, - 'standard test condition maximum power [kW]': - self.standard_test_condition_maximum_power, - 'width': self.width, - 'height': self.height, - } - } + content = {'Photovoltaic Module': { + 'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'type': self.system_type, + 'fuel type': self.fuel_type, + 'electricity efficiency': self.electricity_efficiency, + 'nominal power output [kW]': self.nominal_electricity_output, + 'nominal ambient temperature [Celsius]': self.nominal_ambient_temperature, + 'nominal cell temperature [Celsius]': self.nominal_cell_temperature, + 'nominal radiation [W/m2]': self.nominal_radiation, + 'standard test condition cell temperature [Celsius]': self.standard_test_condition_cell_temperature, + 'standard test condition maximum power [kW]': self.standard_test_condition_maximum_power, + 'width': self.width, + 'height': self.height, + } + } return content diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index 5dc59ddb..b22251f8 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -1,41 +1,47 @@ """ -Energy System catalog equipment +Energy System catalog heat generation system SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2023 Concordia CERC group Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca """ -from typing import Union +from typing import Union, List 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.energy_storage_system import EnergyStorageSystem 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.performance_curves import PerformanceCurves +from hub.catalog_factories.data_models.energy_systems.energy_emission_system import EnergyEmissionSystem class System: """ System class """ + def __init__(self, lod, system_id, - name, + system_configuration, demand_types, - heat_generation_system, - electricity_generation_system, + generation_systems, + pv_generation_system, distribution_system, - emission_system): - + emission_system, + energy_storage_systems, + performance_curves): self._lod = lod self._system_id = system_id - self._name = name + self._system_configuration = system_configuration self._demand_types = demand_types - self._heat_generation_system = heat_generation_system - self._electricity_generation_system = electricity_generation_system self._distribution_system = distribution_system self._emission_system = emission_system + self._generation_systems = generation_systems + self._pv_generation_system = pv_generation_system + self._energy_storage_systems = energy_storage_systems + self._performance_curves = performance_curves @property def lod(self): @@ -54,36 +60,37 @@ class System: return self._system_id @property - def name(self): + def system_configuration(self): """ - Get name + Get the system configuration from ['hp_tes', 'hp_boiler_tes', 'pv_hp', 'pv_battery', 'pv', 'pv_hp_tes', + 'pv_hp_battery_tes'] :return: string """ - return self._name + return self._system_configuration @property def demand_types(self): """ - Get demand able to cover from [heating, cooling, domestic_hot_water, electricity] + Get demand able to cover from ['heating', 'cooling', 'domestic_hot_water', 'electricity'] :return: [string] """ return self._demand_types @property - def heat_generation_system(self) -> GenerationSystem: + def generation_systems(self) -> List[GenerationSystem]: """ - Get heat generation system - :return: HeatGenerationSystem + Get generation system + :return: GenerationSystem """ - return self._heat_generation_system + return self._generation_systems @property - def electricity_generation_system(self) -> PvGenerationSystem: + def pv_generation_system(self) -> Union[None, PvGenerationSystem]: """ - Get electricity generation system + Get pv generation system :return: ElectricityGenerationSystem """ - return self._electricity_generation_system + return self._pv_generation_system @property def distribution_system(self) -> Union[None, DistributionSystem]: @@ -94,29 +101,58 @@ class System: return self._distribution_system @property - def emission_system(self) -> Union[None, EmissionSystem]: + def emission_system(self) -> Union[None, EnergyEmissionSystem]: """ Get emission system :return: EmissionSystem """ return self._emission_system + @property + def energy_storage_system(self) -> Union[None, List[EnergyStorageSystem]]: + """ + Get energy storage system + :return: EnergyStorageSystem + """ + return self._energy_storage_systems + + @property + def performance_curves(self) -> Union[None, List[PerformanceCurves]]: + """ + Get the list of all performance curves associated with components + :return: PerformanceCurves + """ + return self._performance_curves + def to_dictionary(self): """Class content to dictionary""" + _generation_systems = [] + for _generation in self.generation_systems: + _generation_systems.append(_generation.to_dictionary()) + _pv_system = None + if self.pv_generation_system is not None: + _pv_system = self.pv_generation_system.to_dictionary() _distribution_system = None if self.distribution_system is not None: _distribution_system = self.distribution_system.to_dictionary() _emission_system = None if self.emission_system is not None: _emission_system = self.emission_system.to_dictionary() + _storage_system = [_storage.to_dictionary() for _storage in + self.energy_storage_system] if self.energy_storage_system is not None else None + _performance_curves = [_curve.to_dictionary() for _curve in + self.performance_curves] if self.performance_curves is not None else None + content = {'Layer': {'id': self.id, - 'name': self.name, + 'name': self.system_configuration, 'level of detail': self.lod, 'demand types': self.demand_types, - 'heat generation system': self.heat_generation_system.to_dictionary(), - 'electricity generation system': self.electricity_generation_system.to_dictionary(), + 'Generation system(s)': _generation_systems, + 'electricity generation system': _pv_system, 'distribution system': _distribution_system, - 'emission system': _emission_system + 'emission system': _emission_system, + 'energy storage system': _storage_system, + 'performance curves': _performance_curves } } 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 91c8d4e4..bea78b0d 100644 --- a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py +++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py @@ -12,7 +12,7 @@ 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.emission_system import EmissionSystem +from hub.catalog_factories.data_models.energy_systems.energy_emission_system import EnergyEmissionSystem from hub.catalog_factories.data_models.energy_systems.archetype import Archetype @@ -114,10 +114,10 @@ class MontrealCustomCatalog(Catalog): if 'parasitic_consumption' in equipment: parasitic_consumption = float(equipment['parasitic_consumption']['#text']) / 100 - emission_system = EmissionSystem(equipment_id, - name, - equipment_type, - parasitic_consumption) + emission_system = EnergyEmissionSystem(equipment_id, + name, + equipment_type, + parasitic_consumption) _equipments.append(emission_system) return _equipments @@ -177,32 +177,32 @@ class MontrealCustomCatalog(Catalog): _names = {'archetypes': [], 'systems': [], 'generation_equipments': [], 'distribution_equipments': [], 'emission_equipments':[]} for archetype in self._content.archetypes: - _names['archetypes'].append(archetype.name) + _names['archetypes'].append(archetype.manufacturer) for system in self._content.systems: - _names['systems'].append(system.name) + _names['systems'].append(system.manufacturer) for equipment in self._content.generation_equipments: - _names['generation_equipments'].append(equipment.name) + _names['generation_equipments'].append(equipment.manufacturer) for equipment in self._content.distribution_equipments: - _names['distribution_equipments'].append(equipment.name) + _names['distribution_equipments'].append(equipment.manufacturer) for equipment in self._content.emission_equipments: - _names['emission_equipments'].append(equipment.name) + _names['emission_equipments'].append(equipment.manufacturer) else: _names = {category: []} if category.lower() == 'archetypes': for archetype in self._content.archetypes: - _names[category].append(archetype.name) + _names[category].append(archetype.manufacturer) elif category.lower() == 'systems': for system in self._content.systems: - _names[category].append(system.name) + _names[category].append(system.manufacturer) elif category.lower() == 'generation_equipments': for system in self._content.generation_equipments: - _names[category].append(system.name) + _names[category].append(system.manufacturer) elif category.lower() == 'distribution_equipments': for system in self._content.distribution_equipments: - _names[category].append(system.name) + _names[category].append(system.manufacturer) elif category.lower() == 'emission_equipments': for system in self._content.emission_equipments: - _names[category].append(system.name) + _names[category].append(system.manufacturer) else: raise ValueError(f'Unknown category [{category}]') return _names @@ -232,18 +232,18 @@ class MontrealCustomCatalog(Catalog): :parm: entry name """ for entry in self._content.archetypes: - if entry.name.lower() == name.lower(): + if entry.manufacturer.lower() == name.lower(): return entry for entry in self._content.systems: - if entry.name.lower() == name.lower(): + if entry.manufacturer.lower() == name.lower(): return entry for entry in self._content.generation_equipments: - if entry.name.lower() == name.lower(): + if entry.manufacturer.lower() == name.lower(): return entry for entry in self._content.distribution_equipments: - if entry.name.lower() == name.lower(): + if entry.manufacturer.lower() == name.lower(): return entry for entry in self._content.emission_equipments: - if entry.name.lower() == name.lower(): + if entry.manufacturer.lower() == name.lower(): return entry raise IndexError(f"{name} doesn't exists in the catalog") From ccdc7a454d00271bb3599343d12a0069efef715c Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Mon, 14 Aug 2023 20:26:37 -0400 Subject: [PATCH 12/38] small changes to performance_curves.py and distribution_system.py created the montreal_custom_catalog_new.py uploaded my xml file --- .../energy_systems/distribution_system.py | 1 + ...eter_function.py => performance_curves.py} | 23 +- .../montreal_custom_catalog_new.py | 251 ++++++++++++++++++ .../energy_systems/Tools4CitiesESMF.encomp | 43 +++ 4 files changed, 311 insertions(+), 7 deletions(-) rename hub/catalog_factories/data_models/energy_systems/{parameter_function.py => performance_curves.py} (74%) create mode 100644 hub/catalog_factories/energy_systems/montreal_custom_catalog_new.py create mode 100644 hub/data/energy_systems/Tools4CitiesESMF.encomp diff --git a/hub/catalog_factories/data_models/energy_systems/distribution_system.py b/hub/catalog_factories/data_models/energy_systems/distribution_system.py index defdad4f..1e4aa96f 100644 --- a/hub/catalog_factories/data_models/energy_systems/distribution_system.py +++ b/hub/catalog_factories/data_models/energy_systems/distribution_system.py @@ -3,6 +3,7 @@ Energy System catalog distribution system SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2023 Concordia CERC group Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca """ from hub.catalog_factories.data_models.construction.material import Material diff --git a/hub/catalog_factories/data_models/energy_systems/parameter_function.py b/hub/catalog_factories/data_models/energy_systems/performance_curves.py similarity index 74% rename from hub/catalog_factories/data_models/energy_systems/parameter_function.py rename to hub/catalog_factories/data_models/energy_systems/performance_curves.py index 089812b5..44301bec 100644 --- a/hub/catalog_factories/data_models/energy_systems/parameter_function.py +++ b/hub/catalog_factories/data_models/energy_systems/performance_curves.py @@ -10,13 +10,14 @@ from __future__ import annotations from typing import Union -class ParameterFunction: +class PerformanceCurves: """ Parameter function class """ - def __init__(self, type, coefficients): + def __init__(self, type, parameters, coefficients): self._type = type + self._parameters = parameters self._coefficients = coefficients @property @@ -34,6 +35,14 @@ class ParameterFunction: """ return self._type + @property + def parameters(self): + """ + Get the list of parameters involved in fitting process as ['y', 'x', 'z'] + :return: string + """ + return self._parameters + @property def coefficients(self): """ @@ -45,9 +54,9 @@ class ParameterFunction: def to_dictionary(self): """Class content to dictionary""" content = {'Parameter Function': { - 'type': self.type, - 'coefficients': self.coefficients, - } - } + 'type': self.type, + 'parameters': self.parameters, + 'coefficients': self.coefficients, + } + } return content - diff --git a/hub/catalog_factories/energy_systems/montreal_custom_catalog_new.py b/hub/catalog_factories/energy_systems/montreal_custom_catalog_new.py new file mode 100644 index 00000000..e24dde48 --- /dev/null +++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog_new.py @@ -0,0 +1,251 @@ +""" +Montreal custom energy systems catalog module +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 MontrealCustomCatalog(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") diff --git a/hub/data/energy_systems/Tools4CitiesESMF.encomp b/hub/data/energy_systems/Tools4CitiesESMF.encomp new file mode 100644 index 00000000..26344db0 --- /dev/null +++ b/hub/data/energy_systems/Tools4CitiesESMF.encomp @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 21ca1e1e28f35d6bfd8823c8c2a8e5dc6d794efd Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Tue, 15 Aug 2023 14:49:17 -0400 Subject: [PATCH 13/38] modified energy_storage_system.py and energy_system_catalog.py generation_system.py The xml data is modified --- .../energy_systems/energy_storage_system.py | 10 +-- .../energy_systems/generation_system.py | 87 +++++++++++++++---- ...atalog_new.py => energy_system_catalog.py} | 4 +- .../energy_systems/Tools4CitiesESMF.encomp | 46 +++++----- 4 files changed, 101 insertions(+), 46 deletions(-) rename hub/catalog_factories/energy_systems/{montreal_custom_catalog_new.py => energy_system_catalog.py} (99%) 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 9be2d17d..52812ca1 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 @@ -18,7 +18,7 @@ class EnergyStorageSystem: """ def __init__(self, model_name, manufacturer, storage_type, volume, rated_output_power, - nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, diameter, layers, + nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, height, layers, maximum_operating_temperature): self._model_name = model_name self._manufacturer = manufacturer @@ -29,7 +29,7 @@ class EnergyStorageSystem: self._battery_voltage = battery_voltage self._depth_of_discharge = depth_of_discharge self._self_discharge_rate = self_discharge_rate - self._diameter = diameter + self._height = height self._layers = layers self._maximum_operating_temperature = maximum_operating_temperature @@ -106,12 +106,12 @@ class EnergyStorageSystem: return self._self_discharge_rate @property - def diameter(self): + def height(self): """ Get the diameter of the storage system in meters :return: float """ - return self._diameter + return self._height @property def layers(self) -> [Layer]: @@ -143,7 +143,7 @@ class EnergyStorageSystem: 'battery voltage [V]': self.battery_voltage, 'depth of discharge': self.depth_of_discharge, 'self discharge rate': self.self_discharge_rate, - 'diameter [m]': self.diameter, + 'height [m]': self.height, 'layers': _layers, 'maximum operating temperature [Celsius]': self.maximum_operating_temperature } diff --git a/hub/catalog_factories/data_models/energy_systems/generation_system.py b/hub/catalog_factories/data_models/energy_systems/generation_system.py index f0ce35ab..11560500 100644 --- a/hub/catalog_factories/data_models/energy_systems/generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/generation_system.py @@ -16,8 +16,10 @@ class GenerationSystem: """ def __init__(self, model_name, manufacturer, system_type, fuel_type, nominal_thermal_output, modulation_range, - source_types, heat_efficiency, cooling_efficiency, electricity_efficiency, source_temperature, - source_mass_flow, nominal_electricity_output): + source_types, supply_medium, heat_efficiency, cooling_efficiency, electricity_efficiency, + source_temperature, source_mass_flow, nominal_electricity_output, maximum_heating_supply_temperature, + minimum_heating_supply_temperature, maximum_cooling_supply_temperature, + minimum_cooling_supply_temperature): self._model_name = model_name self._manufacturer = manufacturer self._system_type = system_type @@ -25,12 +27,17 @@ class GenerationSystem: self._nominal_thermal_output = nominal_thermal_output self._modulation_range = modulation_range self._source_types = source_types + self._supply_medium = supply_medium self._heat_efficiency = heat_efficiency self._cooling_efficiency = cooling_efficiency self._electricity_efficiency = electricity_efficiency self._source_temperature = source_temperature self._source_mass_flow = source_mass_flow self._nominal_electricity_output = nominal_electricity_output + self._maximum_heating_supply_temperature = maximum_heating_supply_temperature + self._minimum_heating_supply_temperature = minimum_heating_supply_temperature + self._maximum_cooling_supply_temperature = maximum_cooling_supply_temperature + self._minimum_cooling_supply_temperature = minimum_cooling_supply_temperature @property def model_name(self): @@ -88,6 +95,14 @@ class GenerationSystem: """ return self._source_types + @property + def supply_medium(self): + """ + Get the supply medium from ['air', 'water'] + :return: string + """ + return self._supply_medium + @property def heat_efficiency(self): """ @@ -136,21 +151,59 @@ class GenerationSystem: """ return self._nominal_electricity_output + @property + def maximum_heating_supply_temperature(self): + """ + Get the maximum heating supply temperature in degree Celsius + :return: float + """ + return self._minimum_heating_supply_temperature + + @property + def minimum_heating_supply_temperature(self): + """ + Get the minimum heating supply temperature in degree Celsius + :return: float + """ + return self._minimum_heating_supply_temperature + + @property + def maximum_cooling_supply_temperature(self): + """ + Get the maximum cooling supply temperature in degree Celsius + :return: float + """ + return self._maximum_cooling_supply_temperature + + @property + def minimum_cooling_supply_temperature(self): + """ + Get the minimum cooling supply temperature in degree Celsius + :return: float + """ + return self._minimum_cooling_supply_temperature + def to_dictionary(self): """Class content to dictionary""" - content = {'Energy Generation component': {'model name': self.model_name, - 'manufacturer': self.manufacturer, - 'type': self.system_type, - 'fuel type': self.fuel_type, - 'nominal thermal output': self.nominal_thermal_output, - 'modulation_range': self.modulation_range, - 'source types': self.source_types, - 'source temperature [Celsius]': self.source_temperature, - 'source mass flow [kg/s]': self.source_mass_flow, - 'heat efficiency': self.heat_efficiency, - 'cooling efficiency': self.cooling_efficiency, - 'electricity efficiency': self.electricity_efficiency, - 'nominal power output [kW]': self.nominal_electricity_output, - } - } + content = {'Energy Generation component': { + 'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'type': self.system_type, + 'fuel type': self.fuel_type, + 'nominal thermal output': self.nominal_thermal_output, + 'modulation_range': self.modulation_range, + 'source types': self.source_types, + 'supply medium': self.supply_medium, + 'source temperature [Celsius]': self.source_temperature, + 'source mass flow [kg/s]': self.source_mass_flow, + 'heat efficiency': self.heat_efficiency, + 'cooling efficiency': self.cooling_efficiency, + 'electricity efficiency': self.electricity_efficiency, + 'nominal power output [kW]': self.nominal_electricity_output, + 'maximum heating supply temperature [Celsius]': self.maximum_heating_supply_temperature, + 'minimum heating supply temperature [Celsius]': self.minimum_heating_supply_temperature, + 'maximum cooling supply temperature [Celsius]': self.maximum_cooling_supply_temperature, + 'minimum cooling supply temperature [Celsius]': self.minimum_cooling_supply_temperature + } + } return content diff --git a/hub/catalog_factories/energy_systems/montreal_custom_catalog_new.py b/hub/catalog_factories/energy_systems/energy_system_catalog.py similarity index 99% rename from hub/catalog_factories/energy_systems/montreal_custom_catalog_new.py rename to hub/catalog_factories/energy_systems/energy_system_catalog.py index e24dde48..564b5d40 100644 --- a/hub/catalog_factories/energy_systems/montreal_custom_catalog_new.py +++ b/hub/catalog_factories/energy_systems/energy_system_catalog.py @@ -1,5 +1,5 @@ """ -Montreal custom energy systems catalog module +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 @@ -18,7 +18,7 @@ from hub.catalog_factories.data_models.energy_systems.performance_curves import from hub.catalog_factories.data_models.energy_systems.archetype import Archetype -class MontrealCustomCatalog(Catalog): +class EnergySystem(Catalog): """ Montreal custom energy systems catalog class """ diff --git a/hub/data/energy_systems/Tools4CitiesESMF.encomp b/hub/data/energy_systems/Tools4CitiesESMF.encomp index 26344db0..06c9e622 100644 --- a/hub/data/energy_systems/Tools4CitiesESMF.encomp +++ b/hub/data/energy_systems/Tools4CitiesESMF.encomp @@ -2,42 +2,44 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + - + - + - - - - - + + + + + + + - + - + From 16618fb54a86ed0973384f8cd8fcec4f31f1608a Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 15 Aug 2023 16:27:05 -0400 Subject: [PATCH 14/38] started north america energy system catalog importer. NOT WORKING --- .../data_models/energy_systems/content.py | 10 +- .../energy_systems/energy_system_catalog.py | 251 ------------------ .../north_america_energy_system_catalog.py | 109 ++++++++ .../energy_systems_catalog_factory.py | 8 + ...CitiesESMF.encomp => Tools4CitiesESMF.xml} | 12 +- tests/test_systems_catalog.py | 2 + 6 files changed, 134 insertions(+), 258 deletions(-) delete mode 100644 hub/catalog_factories/energy_systems/energy_system_catalog.py create mode 100644 hub/catalog_factories/energy_systems/north_america_energy_system_catalog.py rename hub/data/energy_systems/{Tools4CitiesESMF.encomp => Tools4CitiesESMF.xml} (88%) diff --git a/hub/catalog_factories/data_models/energy_systems/content.py b/hub/catalog_factories/data_models/energy_systems/content.py index 8042a73d..d3fd9068 100644 --- a/hub/catalog_factories/data_models/energy_systems/content.py +++ b/hub/catalog_factories/data_models/energy_systems/content.py @@ -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 = [] diff --git a/hub/catalog_factories/energy_systems/energy_system_catalog.py b/hub/catalog_factories/energy_systems/energy_system_catalog.py deleted file mode 100644 index 564b5d40..00000000 --- a/hub/catalog_factories/energy_systems/energy_system_catalog.py +++ /dev/null @@ -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") 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 new file mode 100644 index 00000000..86d8f215 --- /dev/null +++ b/hub/catalog_factories/energy_systems/north_america_energy_system_catalog.py @@ -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}]') diff --git a/hub/catalog_factories/energy_systems_catalog_factory.py b/hub/catalog_factories/energy_systems_catalog_factory.py index 4b59eeda..6e102bc3 100644 --- a/hub/catalog_factories/energy_systems_catalog_factory.py +++ b/hub/catalog_factories/energy_systems_catalog_factory.py @@ -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: """ diff --git a/hub/data/energy_systems/Tools4CitiesESMF.encomp b/hub/data/energy_systems/Tools4CitiesESMF.xml similarity index 88% rename from hub/data/energy_systems/Tools4CitiesESMF.encomp rename to hub/data/energy_systems/Tools4CitiesESMF.xml index 06c9e622..6ee58c84 100644 --- a/hub/data/energy_systems/Tools4CitiesESMF.encomp +++ b/hub/data/energy_systems/Tools4CitiesESMF.xml @@ -23,11 +23,11 @@ - - - - - + + + + + @@ -37,7 +37,7 @@ - + diff --git a/tests/test_systems_catalog.py b/tests/test_systems_catalog.py index f17038cb..48446d50 100644 --- a/tests/test_systems_catalog.py +++ b/tests/test_systems_catalog.py @@ -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 From e91e61741edf834d363931e5933daf1ce0048962 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Wed, 16 Aug 2023 15:58:49 -0400 Subject: [PATCH 15/38] add generation and config --- .../energy_systems/pv_generation_system.py | 15 ++- .../north_america_energy_system_catalog.py | 127 ++++++++++++++++-- hub/data/energy_systems/Tools4CitiesESMF.xml | 24 ++-- 3 files changed, 142 insertions(+), 24 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index a258b4b9..47a2507f 100644 --- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -17,8 +17,9 @@ class PvGenerationSystem(GenerationSystem): """ def __init__(self, nominal_ambient_temperature, nominal_cell_temperature, nominal_radiation, - standard_test_condition_cell_temperature, standard_test_condition_maximum_power, width, height, - model_name, manufacturer, electricity_efficiency, nominal_electricity_output): + standard_test_condition_cell_temperature, standard_test_condition_maximum_power, + cell_temperature_coefficient, width, height, model_name, manufacturer, electricity_efficiency, + nominal_electricity_output): super(GenerationSystem, self).__init__(model_name=model_name, manufacturer=manufacturer, system_type='pv', fuel_type='renewable', nominal_thermal_output=None, modulation_range=None, source_types=None, heat_efficiency=None, cooling_efficiency=None, @@ -29,6 +30,7 @@ class PvGenerationSystem(GenerationSystem): self._nominal_radiation = nominal_radiation self._standard_test_condition_cell_temperature = standard_test_condition_cell_temperature self._standard_test_condition_maximum_power = standard_test_condition_maximum_power + self._cell_temperature_coefficient = cell_temperature_coefficient self._width = width self._height = height @@ -72,6 +74,14 @@ class PvGenerationSystem(GenerationSystem): """ return self._standard_test_condition_maximum_power + @property + def cell_temperature_coefficient(self): + """ + Get cell temperature coefficient of PV module + :return: float + """ + return self._cell_temperature_coefficient + @property def width(self): """ @@ -102,6 +112,7 @@ class PvGenerationSystem(GenerationSystem): 'nominal radiation [W/m2]': self.nominal_radiation, 'standard test condition cell temperature [Celsius]': self.standard_test_condition_cell_temperature, 'standard test condition maximum power [kW]': self.standard_test_condition_maximum_power, + 'cell temperature coefficient':self.cell_temperature_coefficient, 'width': self.width, 'height': self.height, } 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 86d8f215..b703945e 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 @@ -12,6 +12,7 @@ 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.energy_emission_system import EnergyEmissionSystem from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem @@ -25,23 +26,129 @@ 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._systems = self._load_systems() + print(self._load_systems()) + self._generation_components = self._load_generation_components() + print(self._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) + # 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_systems(self): + system_configurations = [] + configurations = self._archetypes['encomp:EnergySystemCatalog']['energysystemconfiguration'] + for configuration in configurations: + system_configurations.append(configuration['@configurationName']) + return system_configurations + + def _load_generation_components(self): + generation_components = [] + boilers = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['boilers'] + heat_pumps = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['heatPumps'] + photovoltaics = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['photovoltaicModules'] + print(photovoltaics.keys()) + for boiler in boilers: + boiler_model_name = boiler['@modelName'] + boiler_manufacturer = boiler['@manufacturer'] + system_type = 'boiler' + boiler_fuel_type = boiler['@fuel'] + boiler_nominal_thermal_output = float(boiler['@installedThermalPower']) + boiler_modulation_range = float(boiler['@modulationRange']) + boiler_heat_efficiency = float(boiler['@nominalEfficiency']) + + boiler_component = GenerationSystem(boiler_model_name, + boiler_manufacturer, + system_type, + boiler_fuel_type, + boiler_nominal_thermal_output, + boiler_modulation_range, + None, + None, + boiler_heat_efficiency, + None, + None, + None, + None, + None, + None, + None, + None, + None) + generation_components.append(boiler_component) + for heat_pump in heat_pumps: + heat_pump_model_name = heat_pump['@modelName'] + heat_pump_manufacturer = heat_pump['@manufacturer'] + system_type = 'heat pump' + heat_pump_fuel_type = heat_pump['@fuel'] + heat_pump_nominal_thermal_output = float(heat_pump['@installedThermalPower']) + heat_pump_modulation_range = float(heat_pump['@modulationRange']) + heat_pump_source_type = heat_pump['@heatSource'] + heat_pump_supply_medium = heat_pump['@supply_medium'] + heat_pump_nominal_cop = float(heat_pump['@nominalCOP']) + heat_pump_maximum_heating_temperature = float(heat_pump['@maxHeatingSupTemperature']) + heat_pump_minimum_heating_temperature = float(heat_pump['@minHeatingSupTemperature']) + heat_pump_maximum_cooling_temperature = float(heat_pump['@maxCoolingSupTemperature']) + heat_pump_minimum_cooling_temperature = float(heat_pump['@minCoolingSupTemperature']) + + heat_pump_component = GenerationSystem(heat_pump_model_name, + heat_pump_manufacturer, + system_type, + heat_pump_fuel_type, + heat_pump_nominal_thermal_output, + heat_pump_modulation_range, + heat_pump_source_type, + heat_pump_supply_medium, + heat_pump_nominal_cop, + None, + None, + None, + None, + None, + heat_pump_maximum_heating_temperature, + heat_pump_minimum_heating_temperature, + heat_pump_maximum_cooling_temperature, + heat_pump_minimum_cooling_temperature) + generation_components.append(heat_pump_component) + for pv in photovoltaics: + 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_model_name = pv['@modelName'] + pv_manufacturer = pv['@manufacturer'] + pv_electricity_efficiency = pv['@nominalEfficiency'] + pv_nominal_electricity_output = pv['@nominalPower'] + pv_component = PvGenerationSystem(nominal_ambient_temperature, + nominal_cell_temperature, + nominal_radiation, + standard_test_condition_cell_temperature, + standard_test_condition_maximum_power, + cell_temperature_coefficient, + width, + height, + pv_model_name, + pv_manufacturer, + pv_electricity_efficiency, + pv_nominal_electricity_output) + generation_components.append(pv_component) + return generation_components def _load_storage_components(self): storage_components = [] diff --git a/hub/data/energy_systems/Tools4CitiesESMF.xml b/hub/data/energy_systems/Tools4CitiesESMF.xml index 6ee58c84..d1a18651 100644 --- a/hub/data/energy_systems/Tools4CitiesESMF.xml +++ b/hub/data/energy_systems/Tools4CitiesESMF.xml @@ -2,18 +2,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + From 32a40f17a6552c65a923fd436d0ae7504b889993 Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Wed, 16 Aug 2023 16:28:20 -0400 Subject: [PATCH 16/38] fixing pv problem --- .../north_america_energy_system_catalog.py | 29 ++++++++++++------- hub/data/energy_systems/Tools4CitiesESMF.xml | 10 ++++++- hub/imports/geometry_factory.py | 4 +-- 3 files changed, 29 insertions(+), 14 deletions(-) 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 b703945e..150df075 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 @@ -20,6 +20,7 @@ from hub.catalog_factories.data_models.energy_systems.performance_curves import 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): @@ -30,13 +31,13 @@ class NorthAmericaEnergySystemCatalog(Catalog): 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() - print(self._load_systems()) + self._archetypes = xmltodict.parse(xml.read(), force_list=['boilers', 'photovoltaicModules']) self._generation_components = self._load_generation_components() print(self._generation_components) self._storage_components = self._load_storage_components() print(self._storage_components) + self._systems = self._load_systems() + print(self._load_systems()) # self._system_archetypes = self._load_system_archetypes() @@ -47,19 +48,27 @@ class NorthAmericaEnergySystemCatalog(Catalog): # None, # None, # self._storage_components) - def _load_systems(self): - system_configurations = [] - configurations = self._archetypes['encomp:EnergySystemCatalog']['energysystemconfiguration'] - for configuration in configurations: - system_configurations.append(configuration['@configurationName']) - return system_configurations +# def _load_systems(self): +# systems = [] +# catalog_systems = self._archetypes['encomp:EnergySystemCatalog']['energysystemconfiguration'] +# for catalog_system in catalog_systems: + # look for the demands and add it to demands[] + # look for the components in self._generation_systems and add them to generation_systems[] + # same with emission and distribution and storage +# System(None, +# None, +# catalog_system['@configurationName'], +# demands, +# generation_systems,... +# ) + +# return system_configurations def _load_generation_components(self): generation_components = [] boilers = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['boilers'] heat_pumps = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['heatPumps'] photovoltaics = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['photovoltaicModules'] - print(photovoltaics.keys()) for boiler in boilers: boiler_model_name = boiler['@modelName'] boiler_manufacturer = boiler['@manufacturer'] diff --git a/hub/data/energy_systems/Tools4CitiesESMF.xml b/hub/data/energy_systems/Tools4CitiesESMF.xml index d1a18651..0f79b6e2 100644 --- a/hub/data/energy_systems/Tools4CitiesESMF.xml +++ b/hub/data/energy_systems/Tools4CitiesESMF.xml @@ -39,7 +39,15 @@ - + + + + + + + + + diff --git a/hub/imports/geometry_factory.py b/hub/imports/geometry_factory.py index 3e6ca0b3..7adf8197 100644 --- a/hub/imports/geometry_factory.py +++ b/hub/imports/geometry_factory.py @@ -17,8 +17,7 @@ class GeometryFactory: GeometryFactory class """ def __init__(self, file_type, - path=None, - data_frame=None, + path, aliases_field=None, height_field=None, year_of_construction_field=None, @@ -27,7 +26,6 @@ class GeometryFactory: self._file_type = '_' + file_type.lower() validate_import_export_type(GeometryFactory, file_type) self._path = path - self._data_frame = data_frame self._aliases_field = aliases_field self._height_field = height_field self._year_of_construction_field = year_of_construction_field From 923b1fe2671b280cd7beae5f0115ffd0f3135bab Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Wed, 16 Aug 2023 19:33:18 -0400 Subject: [PATCH 17/38] generation components are all added to north_america_energy_system_catalog.py pv_generation_system.py is modified Tools4CitiesESMF.xml is modified --- .../energy_systems/pv_generation_system.py | 17 ++++++---- .../north_america_energy_system_catalog.py | 2 +- hub/data/energy_systems/Tools4CitiesESMF.xml | 32 +++++++++++-------- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index 47a2507f..650694d2 100644 --- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -20,11 +20,16 @@ class PvGenerationSystem(GenerationSystem): standard_test_condition_cell_temperature, standard_test_condition_maximum_power, cell_temperature_coefficient, width, height, model_name, manufacturer, electricity_efficiency, nominal_electricity_output): - super(GenerationSystem, self).__init__(model_name=model_name, manufacturer=manufacturer, system_type='pv', - fuel_type='renewable', nominal_thermal_output=None, modulation_range=None, - source_types=None, heat_efficiency=None, cooling_efficiency=None, - electricity_efficiency=electricity_efficiency, source_temperature=None, - source_mass_flow=None, nominal_electricity_output=nominal_electricity_output) + super(PvGenerationSystem, self).__init__(model_name=model_name, manufacturer=manufacturer, system_type='pv', + fuel_type='renewable', nominal_thermal_output=None, modulation_range=None, + source_types=None,supply_medium=None, heat_efficiency=None, + cooling_efficiency=None, electricity_efficiency=electricity_efficiency, + source_temperature=None, source_mass_flow=None, + nominal_electricity_output=nominal_electricity_output, + maximum_heating_supply_temperature=None, + minimum_heating_supply_temperature=None, + maximum_cooling_supply_temperature=None, + minimum_cooling_supply_temperature=None) self._nominal_ambient_temperature = nominal_ambient_temperature self._nominal_cell_temperature = nominal_cell_temperature self._nominal_radiation = nominal_radiation @@ -112,7 +117,7 @@ class PvGenerationSystem(GenerationSystem): 'nominal radiation [W/m2]': self.nominal_radiation, 'standard test condition cell temperature [Celsius]': self.standard_test_condition_cell_temperature, 'standard test condition maximum power [kW]': self.standard_test_condition_maximum_power, - 'cell temperature coefficient':self.cell_temperature_coefficient, + 'cell temperature coefficient': self.cell_temperature_coefficient, 'width': self.width, 'height': self.height, } 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 150df075..f6b37cff 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 @@ -31,7 +31,7 @@ class NorthAmericaEnergySystemCatalog(Catalog): def __init__(self, path): path = str(path / 'Tools4CitiesESMF.xml') with open(path, 'r', encoding='utf-8') as xml: - self._archetypes = xmltodict.parse(xml.read(), force_list=['boilers', 'photovoltaicModules']) + self._archetypes = xmltodict.parse(xml.read(), force_list=['photovoltaicModules']) self._generation_components = self._load_generation_components() print(self._generation_components) self._storage_components = self._load_storage_components() diff --git a/hub/data/energy_systems/Tools4CitiesESMF.xml b/hub/data/energy_systems/Tools4CitiesESMF.xml index 0f79b6e2..f7e45e35 100644 --- a/hub/data/energy_systems/Tools4CitiesESMF.xml +++ b/hub/data/energy_systems/Tools4CitiesESMF.xml @@ -23,11 +23,11 @@ - - - - - + + + + + @@ -40,14 +40,20 @@ - - - - - - + + + + + + + + - - + + + + + + From 0528aa0718cca7694d6a1bf76cbb09b891e26bd3 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Wed, 16 Aug 2023 20:07:24 -0400 Subject: [PATCH 18/38] started to work on systems --- .../north_america_energy_system_catalog.py | 18 ++++++++++++++++++ hub/data/energy_systems/Tools4CitiesESMF.xml | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) 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 f6b37cff..e3a54197 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 @@ -194,6 +194,24 @@ class NorthAmericaEnergySystemCatalog(Catalog): storage_components.append(storage_component) return storage_components + def _load_systems(self): + systems = [] + catalog_systems = self._archetypes['encomp:EnergySystemCatalog']['energysystemconfiguration'] + for catalog_system in catalog_systems: + system_configuration = catalog_system['@configurationName'] + energy_system = System(None, + None, + system_configuration, + None, + None, + None, + None, + None, + None, + None) + systems.append(energy_system) + return systems + def _load_materials(self): materials = [] _materials = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['materials'] diff --git a/hub/data/energy_systems/Tools4CitiesESMF.xml b/hub/data/energy_systems/Tools4CitiesESMF.xml index f7e45e35..ef96db92 100644 --- a/hub/data/energy_systems/Tools4CitiesESMF.xml +++ b/hub/data/energy_systems/Tools4CitiesESMF.xml @@ -50,7 +50,7 @@ - + From e20a700deba4d68be5a4f040601c168cf846d8a3 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Thu, 17 Aug 2023 18:48:48 -0400 Subject: [PATCH 19/38] emission_system.py is rolled back to original performance_curves.py is imported in generation_system.py The order of arguments in pv_generation_system.py is fixed Modulation range is replaced with maximum and minimum heat output in generation_system.py maximum,minimum, and nominal cooling output are also added to generation_system.py --- .../energy_systems/emission_system.py | 60 ++++++ .../energy_systems/energy_emission_system.py | 94 --------- .../energy_systems/energy_storage_system.py | 55 ++++-- .../energy_systems/generation_system.py | 182 ++++++++++++++++-- .../energy_systems/performance_curves.py | 14 +- .../energy_systems/pv_generation_system.py | 23 ++- .../data_models/energy_systems/system.py | 4 +- .../energy_systems/montreal_custom_catalog.py | 16 +- .../north_america_energy_system_catalog.py | 19 +- hub/data/energy_systems/Tools4CitiesESMF.xml | 73 ++++--- ...ontreal_custom_energy_system_parameters.py | 2 +- 11 files changed, 353 insertions(+), 189 deletions(-) create mode 100644 hub/catalog_factories/data_models/energy_systems/emission_system.py delete mode 100644 hub/catalog_factories/data_models/energy_systems/energy_emission_system.py diff --git a/hub/catalog_factories/data_models/energy_systems/emission_system.py b/hub/catalog_factories/data_models/energy_systems/emission_system.py new file mode 100644 index 00000000..5e9d2865 --- /dev/null +++ b/hub/catalog_factories/data_models/energy_systems/emission_system.py @@ -0,0 +1,60 @@ +""" +Energy System catalog emission system +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" + + +class EmissionSystem: + """ + Emission system class + """ + def __init__(self, system_id, name, system_type, parasitic_energy_consumption): + + self._system_id = system_id + self._name = name + self._type = system_type + self._parasitic_energy_consumption = parasitic_energy_consumption + + @property + def id(self): + """ + Get system id + :return: float + """ + return self._system_id + + @property + def name(self): + """ + Get name + :return: string + """ + return self._name + + @property + def type(self): + """ + Get type + :return: string + """ + return self._type + + @property + def parasitic_energy_consumption(self): + """ + Get parasitic_energy_consumption in ratio (J/J) + :return: float + """ + return self._parasitic_energy_consumption + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Layer': {'id': self.id, + 'name': self.name, + 'type': self.type, + 'parasitic energy consumption per energy produced [J/J]': self.parasitic_energy_consumption + } + } + return content diff --git a/hub/catalog_factories/data_models/energy_systems/energy_emission_system.py b/hub/catalog_factories/data_models/energy_systems/energy_emission_system.py deleted file mode 100644 index 171a8fda..00000000 --- a/hub/catalog_factories/data_models/energy_systems/energy_emission_system.py +++ /dev/null @@ -1,94 +0,0 @@ -""" -Energy System catalog emission system -SPDX - License - Identifier: LGPL - 3.0 - or -later -Copyright © 2023 Concordia CERC group -Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca -Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca -""" - -from hub.catalog_factories.data_models.construction.material import Material - - -class EnergyEmissionSystem: - """ - Emission system class - """ - def __init__(self, model_name, manufacturer, system_type, parasitic_energy_consumption, nominal_heat_output, - nominal_efficiency, medium): - - self._system_id = model_name - self._name = manufacturer - self._type = system_type - self._parasitic_energy_consumption = parasitic_energy_consumption - self._nominal_heat_output = nominal_heat_output - self._nominal_efficiency = nominal_efficiency - self._medium = medium - - @property - def model_name(self): - """ - Get system id - :return: float - """ - return self._system_id - - @property - def manufacturer(self): - """ - Get name - :return: string - """ - return self._name - - @property - def type(self): - """ - Get type - :return: string - """ - return self._type - - @property - def parasitic_energy_consumption(self): - """ - Get parasitic_energy_consumption in ratio (J/J) - :return: float - """ - return self._parasitic_energy_consumption - - @property - def nominal_heat_output(self): - """ - Get the nominal heat output of the emission system in kW - :return: float - """ - return self._nominal_heat_output - - @property - def nominal_efficiency(self): - """ - Get the nominal efficiency of the emission system - :return: float - """ - return self._nominal_efficiency - - @property - def medium(self) -> Material: - """ - Get the heat transfer characteristics of the heat transfer medium - :return: Material - """ - return self._medium - - def to_dictionary(self): - """Class content to dictionary""" - content = {'Layer': {'id': self.model_name, - 'name': self.manufacturer, - 'type': self.type, - 'parasitic energy consumption per energy produced [J/J]': self.parasitic_energy_consumption, - 'nominal heat output [kW]': self.nominal_heat_output, - 'nominal efficiency': self.nominal_efficiency, - 'heat transfer medium': self.medium - } - } - return content 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 52812ca1..f898af34 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 @@ -7,8 +7,6 @@ Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca """ from __future__ import annotations -from typing import Union -from hub.catalog_factories.data_models.construction.material import Material from hub.catalog_factories.data_models.construction.layer import Layer @@ -17,9 +15,11 @@ class EnergyStorageSystem: Energy Storage System Class """ - def __init__(self, model_name, manufacturer, storage_type, volume, rated_output_power, + def __init__(self, storage_id, name, model_name, manufacturer, storage_type, volume, rated_output_power, nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, height, layers, maximum_operating_temperature): + self._storage_id = storage_id + self._name = name self._model_name = model_name self._manufacturer = manufacturer self._storage_type = storage_type @@ -33,6 +33,22 @@ class EnergyStorageSystem: self._layers = layers self._maximum_operating_temperature = maximum_operating_temperature + @property + def stroage_id(self): + """ + Get storage id + :return: string + """ + return self._storage_id + + @property + def name(self): + """ + Get storage name + :return: string + """ + return self._name + @property def model_name(self): """ @@ -134,18 +150,21 @@ class EnergyStorageSystem: _layers = [] for _layer in self.layers: _layers.append(_layer.to_dictionary()) - content = {'Storage component': {'model name': self.model_name, - 'manufacturer': self.manufacturer, - 'storage type': self.storage_type, - 'physical volume [m3]': self.physical_volume, - 'rated power [kW]': self.rated_output_power, - 'nominal efficiency': self.nominal_efficiency, - 'battery voltage [V]': self.battery_voltage, - 'depth of discharge': self.depth_of_discharge, - 'self discharge rate': self.self_discharge_rate, - 'height [m]': self.height, - 'layers': _layers, - 'maximum operating temperature [Celsius]': self.maximum_operating_temperature - } - } - return content \ No newline at end of file + content = {'Storage component': { + 'storage id': self.stroage_id, + 'name': self.name, + 'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'storage type': self.storage_type, + 'physical volume [m3]': self.physical_volume, + 'rated power [kW]': self.rated_output_power, + 'nominal efficiency': self.nominal_efficiency, + 'battery voltage [V]': self.battery_voltage, + 'depth of discharge': self.depth_of_discharge, + 'self discharge rate': self.self_discharge_rate, + 'height [m]': self.height, + 'layers': _layers, + 'maximum operating temperature [Celsius]': self.maximum_operating_temperature + } + } + return content diff --git a/hub/catalog_factories/data_models/energy_systems/generation_system.py b/hub/catalog_factories/data_models/energy_systems/generation_system.py index 11560500..7fdc3130 100644 --- a/hub/catalog_factories/data_models/energy_systems/generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/generation_system.py @@ -8,6 +8,7 @@ Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca from __future__ import annotations from typing import Union +from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves class GenerationSystem: @@ -15,20 +16,29 @@ class GenerationSystem: Heat Generation system class """ - def __init__(self, model_name, manufacturer, system_type, fuel_type, nominal_thermal_output, modulation_range, - source_types, supply_medium, heat_efficiency, cooling_efficiency, electricity_efficiency, - source_temperature, source_mass_flow, nominal_electricity_output, maximum_heating_supply_temperature, - minimum_heating_supply_temperature, maximum_cooling_supply_temperature, - minimum_cooling_supply_temperature): + def __init__(self, system_id, name, model_name, manufacturer, system_type, fuel_type, nominal_thermal_output, + maximum_heat_output, minimum_heat_output, source_medium, supply_medium, heat_efficiency, + nominal_cooling_output, maximum_cooling_output, minimum_cooling_output, cooling_efficiency, + electricity_efficiency, source_temperature, source_mass_flow, nominal_electricity_output, + maximum_heating_supply_temperature, minimum_heating_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, storage, auxiliary_equipment): + self._system_id = system_id + self._name = name self._model_name = model_name self._manufacturer = manufacturer self._system_type = system_type self._fuel_type = fuel_type self._nominal_thermal_output = nominal_thermal_output - self._modulation_range = modulation_range - self._source_types = source_types + self._maximum_heat_output = maximum_heat_output + self._minimum_heat_output = minimum_heat_output + self._source_medium = source_medium self._supply_medium = supply_medium self._heat_efficiency = heat_efficiency + self._nominal_cooling_output = nominal_cooling_output + self._maximum_cooling_output = maximum_cooling_output + self._minimum_cooling_output = minimum_cooling_output self._cooling_efficiency = cooling_efficiency self._electricity_efficiency = electricity_efficiency self._source_temperature = source_temperature @@ -38,6 +48,31 @@ class GenerationSystem: self._minimum_heating_supply_temperature = minimum_heating_supply_temperature self._maximum_cooling_supply_temperature = maximum_cooling_supply_temperature self._minimum_cooling_supply_temperature = minimum_cooling_supply_temperature + self._heat_output_curve = heat_output_curve + self._heat_fuel_consumption_curve = heat_fuel_consumption_curve + self._heat_efficiency_curve = heat_efficiency_curve + self._cooling_output_curve = cooling_output_curve + self._cooling_fuel_consumption_curve = cooling_fuel_consumption_curve + self._cooling_efficiency_curve = cooling_efficiency_curve + + self._storage = storage + self._auxiliary_equipment = auxiliary_equipment + + @property + def id(self): + """ + Get system id + :return: float + """ + return self._system_id + + @property + def name(self): + """ + Get name + :return: string + """ + return self._name @property def model_name(self): @@ -80,20 +115,28 @@ class GenerationSystem: return self._nominal_thermal_output @property - def modulation_range(self): + def maximum_heat_output(self): """ - Get modulation range of heat generation devices + Get maximum heat output of heat generation devices in W :return: float """ - return self._modulation_range + return self._maximum_heat_output @property - def source_types(self): + def minimum_heat_output(self): + """ + Get minimum heat output of heat generation devices in W + :return: float + """ + return self._minimum_heat_output + + @property + def source_medium(self): """ Get source_type from [air, water, ground, district_heating, grid, on_site_electricity] :return: [string] """ - return self._source_types + return self._source_medium @property def supply_medium(self): @@ -111,6 +154,30 @@ class GenerationSystem: """ return self._heat_efficiency + @property + def nominal_cooling_output(self): + """ + Get nominal_thermal_output of heat generation devices in kW + :return: float + """ + return self._nominal_cooling_output + + @property + def maximum_cooling_output(self): + """ + Get maximum heat output of heat generation devices in W + :return: float + """ + return self._maximum_cooling_output + + @property + def minimum_cooling_output(self): + """ + Get minimum heat output of heat generation devices in W + :return: float + """ + return self._minimum_cooling_output + @property def cooling_efficiency(self): """ @@ -183,27 +250,108 @@ class GenerationSystem: """ return self._minimum_cooling_supply_temperature + @property + def heat_output_curve(self) -> Union[None, PerformanceCurves]: + """ + Get the heat output curve of the heat generation device + :return: PerformanceCurve + """ + return self._heat_output_curve + + @property + def heat_fuel_consumption_curve(self) -> Union[None, PerformanceCurves]: + """ + Get the heating fuel consumption curve of the heat generation device + :return: PerformanceCurve + """ + return self._heat_fuel_consumption_curve + + @property + def heat_efficiency_curve(self) -> Union[None, PerformanceCurves]: + """ + Get the heating efficiency curve of the heat generation device + :return: PerformanceCurve + """ + return self._heat_efficiency_curve + + @property + def cooling_output_curve(self) -> Union[None, PerformanceCurves]: + """ + Get the heat output curve of the heat generation device + :return: PerformanceCurve + """ + return self._cooling_output_curve + + @property + def cooling_fuel_consumption_curve(self) -> Union[None, PerformanceCurves]: + """ + Get the heating fuel consumption curve of the heat generation device + :return: PerformanceCurve + """ + return self._cooling_fuel_consumption_curve + + @property + def cooling_efficiency_curve(self) -> Union[None, PerformanceCurves]: + """ + Get the heating efficiency curve of the heat generation device + :return: PerformanceCurve + """ + return self._cooling_efficiency_curve + + @property + def storage(self): + """ + Get boolean storage exists + :return: bool + """ + return self._storage + + @property + def auxiliary_equipment(self) -> Union[None, GenerationSystem]: + """ + Get auxiliary_equipment + :return: GenerationSystem + """ + return self._auxiliary_equipment + def to_dictionary(self): """Class content to dictionary""" + _auxiliary_equipment = [] + if self.auxiliary_equipment is not None: + _auxiliary_equipment = self.auxiliary_equipment.to_dictionary() content = {'Energy Generation component': { + 'id': self.id, + 'name': self.name, 'model name': self.model_name, 'manufacturer': self.manufacturer, 'type': self.system_type, 'fuel type': self.fuel_type, - 'nominal thermal output': self.nominal_thermal_output, - 'modulation_range': self.modulation_range, - 'source types': self.source_types, + 'nominal thermal output [W]': self.nominal_thermal_output, + 'maximum heat output [W]': self.maximum_heat_output, + 'minimum heat output [W]': self.minimum_heat_output, + 'source medium': self.source_medium, 'supply medium': self.supply_medium, 'source temperature [Celsius]': self.source_temperature, 'source mass flow [kg/s]': self.source_mass_flow, 'heat efficiency': self.heat_efficiency, + 'nominal cooling output [W]': self.nominal_cooling_output, + 'maximum cooling output [W]': self.maximum_cooling_output, + 'minimum cooling output [W]': self.minimum_cooling_output, 'cooling efficiency': self.cooling_efficiency, 'electricity efficiency': self.electricity_efficiency, - 'nominal power output [kW]': self.nominal_electricity_output, + 'nominal power output [W]': self.nominal_electricity_output, 'maximum heating supply temperature [Celsius]': self.maximum_heating_supply_temperature, 'minimum heating supply temperature [Celsius]': self.minimum_heating_supply_temperature, 'maximum cooling supply temperature [Celsius]': self.maximum_cooling_supply_temperature, - 'minimum cooling supply temperature [Celsius]': self.minimum_cooling_supply_temperature + 'minimum cooling supply temperature [Celsius]': self.minimum_cooling_supply_temperature, + 'heat output curve': self.heat_output_curve, + 'heat fuel consumption curve': self.heat_fuel_consumption_curve, + 'heat efficiency curve': self.heat_efficiency_curve, + 'cooling output curve': self.cooling_output_curve, + 'cooling fuel consumption curve': self.cooling_fuel_consumption_curve, + 'cooling efficiency curve': self.cooling_efficiency_curve, + 'it has storage': self.storage, + 'auxiliary equipment': _auxiliary_equipment } } return content diff --git a/hub/catalog_factories/data_models/energy_systems/performance_curves.py b/hub/catalog_factories/data_models/energy_systems/performance_curves.py index 44301bec..fb9b74ff 100644 --- a/hub/catalog_factories/data_models/energy_systems/performance_curves.py +++ b/hub/catalog_factories/data_models/energy_systems/performance_curves.py @@ -7,7 +7,7 @@ Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca """ from __future__ import annotations -from typing import Union + class PerformanceCurves: @@ -15,13 +15,13 @@ class PerformanceCurves: Parameter function class """ - def __init__(self, type, parameters, coefficients): - self._type = type + def __init__(self, curve_type, parameters, coefficients): + self._curve_type = curve_type self._parameters = parameters self._coefficients = coefficients @property - def type(self): + def curve_type(self): """ The type of the fit function from the following Linear =>>> y = a*x + b @@ -33,7 +33,7 @@ class PerformanceCurves: Get the type of function from ['linear', 'exponential', 'polynomial', 'power', 'second degree multivariable'] :return: string """ - return self._type + return self._curve_type @property def parameters(self): @@ -46,7 +46,7 @@ class PerformanceCurves: @property def coefficients(self): """ - Get the coefficients of the functions as list + Get the coefficients of the functions as list of ['a', 'b', 'c', 'd', 'e', 'f'] :return: [coefficients] """ return self._coefficients @@ -54,7 +54,7 @@ class PerformanceCurves: def to_dictionary(self): """Class content to dictionary""" content = {'Parameter Function': { - 'type': self.type, + 'curve type': self.curve_type, 'parameters': self.parameters, 'coefficients': self.coefficients, } diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index 650694d2..5c03c3f3 100644 --- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -7,7 +7,6 @@ Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca """ from __future__ import annotations -from typing import Union from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem @@ -16,20 +15,26 @@ class PvGenerationSystem(GenerationSystem): Electricity Generation system class """ - def __init__(self, nominal_ambient_temperature, nominal_cell_temperature, nominal_radiation, - standard_test_condition_cell_temperature, standard_test_condition_maximum_power, - cell_temperature_coefficient, width, height, model_name, manufacturer, electricity_efficiency, - nominal_electricity_output): - super(PvGenerationSystem, self).__init__(model_name=model_name, manufacturer=manufacturer, system_type='pv', - fuel_type='renewable', nominal_thermal_output=None, modulation_range=None, - source_types=None,supply_medium=None, heat_efficiency=None, + def __init__(self, system_id, name, model_name, manufacturer, electricity_efficiency, + nominal_electricity_output, nominal_ambient_temperature, nominal_cell_temperature, + nominal_radiation, standard_test_condition_cell_temperature, standard_test_condition_maximum_power, + cell_temperature_coefficient, width, height): + super(PvGenerationSystem, self).__init__(system_id=system_id, name=name, model_name=model_name, + manufacturer=manufacturer, system_type='pv', fuel_type='renewable', + nominal_thermal_output=None, maximum_heat_output=None, + minimum_heat_output=None, source_medium=None, + supply_medium=None, heat_efficiency=None, nominal_cooling_output=None, + maximum_cooling_output=None, minimum_cooling_output=None, cooling_efficiency=None, electricity_efficiency=electricity_efficiency, source_temperature=None, source_mass_flow=None, nominal_electricity_output=nominal_electricity_output, maximum_heating_supply_temperature=None, minimum_heating_supply_temperature=None, maximum_cooling_supply_temperature=None, - minimum_cooling_supply_temperature=None) + minimum_cooling_supply_temperature=None, heat_output_curve=None, + heat_fuel_consumption_curve=None, heat_efficiency_curve=None, + cooling_output_curve=None, cooling_fuel_consumption_curve=None, + cooling_efficiency_curve=None, storage=None, auxiliary_equipment=None) self._nominal_ambient_temperature = nominal_ambient_temperature self._nominal_cell_temperature = nominal_cell_temperature self._nominal_radiation = nominal_radiation diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index b22251f8..299b82c7 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -13,7 +13,7 @@ from hub.catalog_factories.data_models.energy_systems.pv_generation_system impor from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves -from hub.catalog_factories.data_models.energy_systems.energy_emission_system import EnergyEmissionSystem +from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem class System: @@ -101,7 +101,7 @@ class System: return self._distribution_system @property - def emission_system(self) -> Union[None, EnergyEmissionSystem]: + def emission_system(self) -> Union[None, EmissionSystem]: """ Get emission system :return: EmissionSystem diff --git a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py index bea78b0d..87b9d4ab 100644 --- a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py +++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py @@ -12,7 +12,7 @@ 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.emission_system import EmissionSystem from hub.catalog_factories.data_models.energy_systems.archetype import Archetype @@ -20,6 +20,7 @@ class MontrealCustomCatalog(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: @@ -90,7 +91,8 @@ class MontrealCustomCatalog(Catalog): 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_consumption_variable_flow = float( + equipment['distribution_consumption_variable_flow']['#text']) / 100 distribution_system = DistributionSystem(equipment_id, name, @@ -114,10 +116,10 @@ class MontrealCustomCatalog(Catalog): if 'parasitic_consumption' in equipment: parasitic_consumption = float(equipment['parasitic_consumption']['#text']) / 100 - emission_system = EnergyEmissionSystem(equipment_id, - name, - equipment_type, - parasitic_consumption) + emission_system = EmissionSystem(equipment_id, + name, + equipment_type, + parasitic_consumption) _equipments.append(emission_system) return _equipments @@ -175,7 +177,7 @@ class MontrealCustomCatalog(Catalog): """ if category is None: _names = {'archetypes': [], 'systems': [], 'generation_equipments': [], 'distribution_equipments': [], - 'emission_equipments':[]} + 'emission_equipments': []} for archetype in self._content.archetypes: _names['archetypes'].append(archetype.manufacturer) for system in self._content.systems: 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 e3a54197..cd84a6b3 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 @@ -14,7 +14,7 @@ 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.energy_emission_system import EnergyEmissionSystem +from hub.catalog_factories.data_models.energy_systems.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 @@ -199,10 +199,15 @@ class NorthAmericaEnergySystemCatalog(Catalog): catalog_systems = self._archetypes['encomp:EnergySystemCatalog']['energysystemconfiguration'] for catalog_system in catalog_systems: system_configuration = catalog_system['@configurationName'] + demands = catalog_system['demands'] + demand_types = [] + for demand in demands: + name = demand['@name'] + demand_types.append(name) energy_system = System(None, None, system_configuration, - None, + demand_types, None, None, None, @@ -241,3 +246,13 @@ 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 + + # def _search_demands(self, config_name): diff --git a/hub/data/energy_systems/Tools4CitiesESMF.xml b/hub/data/energy_systems/Tools4CitiesESMF.xml index ef96db92..0270f61c 100644 --- a/hub/data/energy_systems/Tools4CitiesESMF.xml +++ b/hub/data/energy_systems/Tools4CitiesESMF.xml @@ -1,43 +1,43 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - + - - - - - + + + + + - - - - - - - - - + + + + + + + + + @@ -49,11 +49,20 @@ - + + + + + + + + + + - + diff --git a/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py b/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py index 9b3f7a61..3982221b 100644 --- a/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py +++ b/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py @@ -92,7 +92,7 @@ class MontrealCustomEnergySystemParameters: _type] _fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_equipment.fuel_type] _generation_system.fuel_type = _fuel_type - _generation_system.source_types = archetype_generation_equipment.source_types + _generation_system.source_types = archetype_generation_equipment.source_medium _generation_system.heat_efficiency = archetype_generation_equipment.heat_efficiency _generation_system.cooling_efficiency = archetype_generation_equipment.cooling_efficiency _generation_system.electricity_efficiency = archetype_generation_equipment.electricity_efficiency From 72b5ff10409c15622d58c491d33f9d789ee89ab8 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Fri, 18 Aug 2023 18:22:10 -0400 Subject: [PATCH 20/38] north_america_components.xml is modified The montreal_custom_catalog.py is modified --- .../energy_systems/montreal_custom_catalog.py | 32 +++++----- .../north_america_energy_system_catalog.py | 2 +- ...sESMF.xml => north_america_components.xml} | 60 ++++++++++--------- .../energy_systems/north_america_systems.xml | 29 +++++++++ 4 files changed, 79 insertions(+), 44 deletions(-) rename hub/data/energy_systems/{Tools4CitiesESMF.xml => north_america_components.xml} (80%) create mode 100644 hub/data/energy_systems/north_america_systems.xml diff --git a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py index 87b9d4ab..0336c940 100644 --- a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py +++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py @@ -179,32 +179,32 @@ class MontrealCustomCatalog(Catalog): _names = {'archetypes': [], 'systems': [], 'generation_equipments': [], 'distribution_equipments': [], 'emission_equipments': []} for archetype in self._content.archetypes: - _names['archetypes'].append(archetype.manufacturer) + _names['archetypes'].append(archetype.name) for system in self._content.systems: - _names['systems'].append(system.manufacturer) + _names['systems'].append(system.name) for equipment in self._content.generation_equipments: - _names['generation_equipments'].append(equipment.manufacturer) + _names['generation_equipments'].append(equipment.name) for equipment in self._content.distribution_equipments: - _names['distribution_equipments'].append(equipment.manufacturer) + _names['distribution_equipments'].append(equipment.name) for equipment in self._content.emission_equipments: - _names['emission_equipments'].append(equipment.manufacturer) + _names['emission_equipments'].append(equipment.name) else: _names = {category: []} if category.lower() == 'archetypes': for archetype in self._content.archetypes: - _names[category].append(archetype.manufacturer) + _names[category].append(archetype.name) elif category.lower() == 'systems': for system in self._content.systems: - _names[category].append(system.manufacturer) + _names[category].append(system.name) elif category.lower() == 'generation_equipments': for system in self._content.generation_equipments: - _names[category].append(system.manufacturer) + _names[category].append(system.name) elif category.lower() == 'distribution_equipments': for system in self._content.distribution_equipments: - _names[category].append(system.manufacturer) + _names[category].append(system.name) elif category.lower() == 'emission_equipments': for system in self._content.emission_equipments: - _names[category].append(system.manufacturer) + _names[category].append(system.name) else: raise ValueError(f'Unknown category [{category}]') return _names @@ -234,18 +234,18 @@ class MontrealCustomCatalog(Catalog): :parm: entry name """ for entry in self._content.archetypes: - if entry.manufacturer.lower() == name.lower(): + if entry.name.lower() == name.lower(): return entry for entry in self._content.systems: - if entry.manufacturer.lower() == name.lower(): + if entry.name.lower() == name.lower(): return entry for entry in self._content.generation_equipments: - if entry.manufacturer.lower() == name.lower(): + if entry.name.lower() == name.lower(): return entry for entry in self._content.distribution_equipments: - if entry.manufacturer.lower() == name.lower(): + if entry.name.lower() == name.lower(): return entry for entry in self._content.emission_equipments: - if entry.manufacturer.lower() == name.lower(): + if entry.name.lower() == name.lower(): return entry - raise IndexError(f"{name} doesn't exists in the catalog") + raise IndexError(f"{name} doesn't exists in the catalog") \ No newline at end of file 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 cd84a6b3..543c2e43 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 @@ -29,7 +29,7 @@ class NorthAmericaEnergySystemCatalog(Catalog): """ def __init__(self, path): - path = str(path / 'Tools4CitiesESMF.xml') + path = str(path / 'north_america_components.xml') with open(path, 'r', encoding='utf-8') as xml: self._archetypes = xmltodict.parse(xml.read(), force_list=['photovoltaicModules']) self._generation_components = self._load_generation_components() diff --git a/hub/data/energy_systems/Tools4CitiesESMF.xml b/hub/data/energy_systems/north_america_components.xml similarity index 80% rename from hub/data/energy_systems/Tools4CitiesESMF.xml rename to hub/data/energy_systems/north_america_components.xml index 0270f61c..b4a9a71a 100644 --- a/hub/data/energy_systems/Tools4CitiesESMF.xml +++ b/hub/data/energy_systems/north_america_components.xml @@ -1,44 +1,50 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + - - - - - - - + + + - + @@ -64,5 +70,5 @@ - + diff --git a/hub/data/energy_systems/north_america_systems.xml b/hub/data/energy_systems/north_america_systems.xml new file mode 100644 index 00000000..0adcff00 --- /dev/null +++ b/hub/data/energy_systems/north_america_systems.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 072d2a6d9d1070d4463aa0ce64cded3150f487c0 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Mon, 21 Aug 2023 17:41:12 -0400 Subject: [PATCH 21/38] modifications done to the xml file and north_america_energy_system_catalog.py --- .../north_america_energy_system_catalog.py | 272 +++++++++--------- .../north_america_components.xml | 74 ----- .../energy_systems/north_america_systems.xml | 229 +++++++++++++-- 3 files changed, 340 insertions(+), 235 deletions(-) delete mode 100644 hub/data/energy_systems/north_america_components.xml 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 543c2e43..306da80a 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 @@ -14,7 +14,7 @@ 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 EnergyEmissionSystem +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 @@ -29,11 +29,11 @@ class NorthAmericaEnergySystemCatalog(Catalog): """ def __init__(self, path): - path = str(path / 'north_america_components.xml') + 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']) - self._generation_components = self._load_generation_components() - print(self._generation_components) + # self._generation_components = self._load_generation_components() + # print(self._generation_components) self._storage_components = self._load_storage_components() print(self._storage_components) self._systems = self._load_systems() @@ -64,122 +64,126 @@ class NorthAmericaEnergySystemCatalog(Catalog): # return system_configurations - def _load_generation_components(self): - generation_components = [] - boilers = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['boilers'] - heat_pumps = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['heatPumps'] - photovoltaics = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['photovoltaicModules'] - for boiler in boilers: - boiler_model_name = boiler['@modelName'] - boiler_manufacturer = boiler['@manufacturer'] - system_type = 'boiler' - boiler_fuel_type = boiler['@fuel'] - boiler_nominal_thermal_output = float(boiler['@installedThermalPower']) - boiler_modulation_range = float(boiler['@modulationRange']) - boiler_heat_efficiency = float(boiler['@nominalEfficiency']) - - boiler_component = GenerationSystem(boiler_model_name, - boiler_manufacturer, - system_type, - boiler_fuel_type, - boiler_nominal_thermal_output, - boiler_modulation_range, - None, - None, - boiler_heat_efficiency, - None, - None, - None, - None, - None, - None, - None, - None, - None) - generation_components.append(boiler_component) - for heat_pump in heat_pumps: - heat_pump_model_name = heat_pump['@modelName'] - heat_pump_manufacturer = heat_pump['@manufacturer'] - system_type = 'heat pump' - heat_pump_fuel_type = heat_pump['@fuel'] - heat_pump_nominal_thermal_output = float(heat_pump['@installedThermalPower']) - heat_pump_modulation_range = float(heat_pump['@modulationRange']) - heat_pump_source_type = heat_pump['@heatSource'] - heat_pump_supply_medium = heat_pump['@supply_medium'] - heat_pump_nominal_cop = float(heat_pump['@nominalCOP']) - heat_pump_maximum_heating_temperature = float(heat_pump['@maxHeatingSupTemperature']) - heat_pump_minimum_heating_temperature = float(heat_pump['@minHeatingSupTemperature']) - heat_pump_maximum_cooling_temperature = float(heat_pump['@maxCoolingSupTemperature']) - heat_pump_minimum_cooling_temperature = float(heat_pump['@minCoolingSupTemperature']) - - heat_pump_component = GenerationSystem(heat_pump_model_name, - heat_pump_manufacturer, - system_type, - heat_pump_fuel_type, - heat_pump_nominal_thermal_output, - heat_pump_modulation_range, - heat_pump_source_type, - heat_pump_supply_medium, - heat_pump_nominal_cop, - None, - None, - None, - None, - None, - heat_pump_maximum_heating_temperature, - heat_pump_minimum_heating_temperature, - heat_pump_maximum_cooling_temperature, - heat_pump_minimum_cooling_temperature) - generation_components.append(heat_pump_component) - for pv in photovoltaics: - 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_model_name = pv['@modelName'] - pv_manufacturer = pv['@manufacturer'] - pv_electricity_efficiency = pv['@nominalEfficiency'] - pv_nominal_electricity_output = pv['@nominalPower'] - pv_component = PvGenerationSystem(nominal_ambient_temperature, - nominal_cell_temperature, - nominal_radiation, - standard_test_condition_cell_temperature, - standard_test_condition_maximum_power, - cell_temperature_coefficient, - width, - height, - pv_model_name, - pv_manufacturer, - pv_electricity_efficiency, - pv_nominal_electricity_output) - generation_components.append(pv_component) - return generation_components + # def _load_generation_components(self): + # generation_components = [] + # boilers = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['boilers'] + # heat_pumps = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['heatPumps'] + # photovoltaics = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['photovoltaicModules'] + # for boiler in boilers: + # boiler_model_name = boiler['@modelName'] + # boiler_manufacturer = boiler['@manufacturer'] + # system_type = 'boiler' + # boiler_fuel_type = boiler['@fuel'] + # boiler_nominal_thermal_output = float(boiler['@installedThermalPower']) + # boiler_modulation_range = float(boiler['@modulationRange']) + # boiler_heat_efficiency = float(boiler['@nominalEfficiency']) + # + # boiler_component = GenerationSystem(boiler_model_name, + # boiler_manufacturer, + # system_type, + # boiler_fuel_type, + # boiler_nominal_thermal_output, + # boiler_modulation_range, + # None, + # None, + # boiler_heat_efficiency, + # None, + # None, + # None, + # None, + # None, + # None, + # None, + # None, + # None) + # generation_components.append(boiler_component) + # for heat_pump in heat_pumps: + # heat_pump_model_name = heat_pump['@modelName'] + # heat_pump_manufacturer = heat_pump['@manufacturer'] + # system_type = 'heat pump' + # heat_pump_fuel_type = heat_pump['@fuel'] + # heat_pump_nominal_thermal_output = float(heat_pump['@installedThermalPower']) + # heat_pump_modulation_range = float(heat_pump['@modulationRange']) + # heat_pump_source_type = heat_pump['@heatSource'] + # heat_pump_supply_medium = heat_pump['@supply_medium'] + # heat_pump_nominal_cop = float(heat_pump['@nominalCOP']) + # heat_pump_maximum_heating_temperature = float(heat_pump['@maxHeatingSupTemperature']) + # heat_pump_minimum_heating_temperature = float(heat_pump['@minHeatingSupTemperature']) + # heat_pump_maximum_cooling_temperature = float(heat_pump['@maxCoolingSupTemperature']) + # heat_pump_minimum_cooling_temperature = float(heat_pump['@minCoolingSupTemperature']) + # + # heat_pump_component = GenerationSystem(heat_pump_model_name, + # heat_pump_manufacturer, + # system_type, + # heat_pump_fuel_type, + # heat_pump_nominal_thermal_output, + # heat_pump_modulation_range, + # heat_pump_source_type, + # heat_pump_supply_medium, + # heat_pump_nominal_cop, + # None, + # None, + # None, + # None, + # None, + # heat_pump_maximum_heating_temperature, + # heat_pump_minimum_heating_temperature, + # heat_pump_maximum_cooling_temperature, + # heat_pump_minimum_cooling_temperature) + # generation_components.append(heat_pump_component) + # for pv in photovoltaics: + # 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_model_name = pv['@modelName'] + # pv_manufacturer = pv['@manufacturer'] + # pv_electricity_efficiency = pv['@nominalEfficiency'] + # pv_nominal_electricity_output = pv['@nominalPower'] + # pv_component = PvGenerationSystem(nominal_ambient_temperature, + # nominal_cell_temperature, + # nominal_radiation, + # standard_test_condition_cell_temperature, + # standard_test_condition_maximum_power, + # cell_temperature_coefficient, + # width, + # height, + # pv_model_name, + # pv_manufacturer, + # pv_electricity_efficiency, + # pv_nominal_electricity_output) + # generation_components.append(pv_component) + # return generation_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'] + thermal_storages = self._archetypes['EnergySystemCatalog']['energy_storage_components']['thermalStorages'] + for tes in thermal_storages: + storage_id = tes['@storage_id'] + name = tes['@name'] + model_name = tes['@modelName'] + manufacturer = tes['@manufacturer'] + volume = tes['@volume'] + height = tes['@height'] + maximum_operating_temperature = tes['@maxTemp'] materials = self._load_materials() - material_name = component['@insulationMaterial'] - insulation_material = self._search_material(materials, material_name) - material_name = component['@tankMaterial'] + insulation_material_name = tes['@insulationMaterial'] + insulation_material = self._search_material(materials, insulation_material_name) + material_name = tes['@tankMaterial'] tank_material = self._search_material(materials, material_name) - thickness = float(component['@insulationThickness']) / 100 # from cm to m + thickness = float(tes['@insulationThickness']) / 100 # from cm to m insulation_layer = Layer(None, 'insulation', insulation_material, thickness) - thickness = float(component['@tankThickness']) / 100 # from cm to m + thickness = float(tes['@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, + storage_component = EnergyStorageSystem(storage_id, + name, + model_name, manufacturer, 'thermal', volume, @@ -194,32 +198,32 @@ class NorthAmericaEnergySystemCatalog(Catalog): storage_components.append(storage_component) return storage_components - def _load_systems(self): - systems = [] - catalog_systems = self._archetypes['encomp:EnergySystemCatalog']['energysystemconfiguration'] - for catalog_system in catalog_systems: - system_configuration = catalog_system['@configurationName'] - demands = catalog_system['demands'] - demand_types = [] - for demand in demands: - name = demand['@name'] - demand_types.append(name) - energy_system = System(None, - None, - system_configuration, - demand_types, - None, - None, - None, - None, - None, - None) - systems.append(energy_system) - return systems + # def _load_systems(self): + # systems = [] + # catalog_systems = self._archetypes['encomp:EnergySystemCatalog']['energysystemconfiguration'] + # for catalog_system in catalog_systems: + # system_configuration = catalog_system['@configurationName'] + # demands = catalog_system['demands'] + # demand_types = [] + # for demand in demands: + # name = demand['@name'] + # demand_types.append(name) + # energy_system = System(None, + # None, + # system_configuration, + # demand_types, + # None, + # None, + # None, + # None, + # None, + # None) + # systems.append(energy_system) + # return systems def _load_materials(self): materials = [] - _materials = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['materials'] + _materials = self._archetypes['EnergySystemCatalog']['materials']['material'] for _material in _materials: name = _material['@name'] thermal_conductivity = _material['@thermalConductivity'] diff --git a/hub/data/energy_systems/north_america_components.xml b/hub/data/energy_systems/north_america_components.xml deleted file mode 100644 index b4a9a71a..00000000 --- a/hub/data/energy_systems/north_america_components.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/hub/data/energy_systems/north_america_systems.xml b/hub/data/energy_systems/north_america_systems.xml index 0adcff00..c9618448 100644 --- a/hub/data/energy_systems/north_america_systems.xml +++ b/hub/data/energy_systems/north_america_systems.xml @@ -1,29 +1,204 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + COP + source_temperature + supply_temperature + + + + + + COP + source_temperature + supply_temperature + + + + + + COP + source_temperature + supply_temperature + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Air Source Heat Pump with Natural Gas Boiler and thermal storage + + 1 + 2 + + + 16 + 18 + 6 + + + + Air Source Heat Pump with Electrical Boiler and thermal storage + + 1 + 2 + + + 17 + 18 + 6 + + + + Ground Source Heat Pump with Natural Gas Boiler and thermal storage + + 1 + 2 + + + 16 + 19 + 6 + + + + Ground Source Heat Pump with Electrical Boiler and thermal storage + + 1 + 2 + + + 17 + 19 + 6 + + + + Water Source Heat Pump with Natural Gas Boiler and thermal storage + + 1 + 2 + + + 16 + 20 + 6 + + + + Water Source Heat Pump with Electrical Boiler and thermal storage + + 1 + 2 + + + 17 + 20 + 6 + + + + Photovoltaic System + + 3 + + + 21 + + + + + + PV+ASHP+GasBoiler+TES + + 7 + 1 + + + + PV+ASHP+ElectricBoiler+TES + + 7 + 2 + + + + PV+GSHP+GasBoiler+TES + + 7 + 3 + + + + PV+GSHP+ElectricBoiler+TES + + 7 + 4 + + + + PV+WSHP+GasBoiler+TES + + 7 + 5 + + + + PV+WSHP+ElectricBoiler+TES + + 7 + 6 + + + + + + + + + + From 9b0bdf2b7e7ad883ca201bc843197fe9bdd2d969 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Tue, 22 Aug 2023 19:09:35 -0400 Subject: [PATCH 22/38] load_generation and load_storage in north_america_energy_system_catalog.py is completed --- .../energy_systems/generation_system.py | 1 - .../data_models/energy_systems/system.py | 44 +- .../north_america_energy_system_catalog.py | 417 ++++++++++++------ .../energy_systems/north_america_systems.xml | 14 +- 4 files changed, 296 insertions(+), 180 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/generation_system.py b/hub/catalog_factories/data_models/energy_systems/generation_system.py index 7fdc3130..7c382dee 100644 --- a/hub/catalog_factories/data_models/energy_systems/generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/generation_system.py @@ -54,7 +54,6 @@ class GenerationSystem: self._cooling_output_curve = cooling_output_curve self._cooling_fuel_consumption_curve = cooling_fuel_consumption_curve self._cooling_efficiency_curve = cooling_efficiency_curve - self._storage = storage self._auxiliary_equipment = auxiliary_equipment diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index 299b82c7..dc1337ca 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -9,10 +9,8 @@ Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca from typing import Union, List 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.energy_storage_system import EnergyStorageSystem from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem -from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem @@ -24,24 +22,20 @@ class System: def __init__(self, lod, system_id, - system_configuration, + name, demand_types, generation_systems, - pv_generation_system, distribution_system, emission_system, - energy_storage_systems, - performance_curves): + energy_storage_systems): self._lod = lod self._system_id = system_id - self._system_configuration = system_configuration + self._name = name self._demand_types = demand_types self._distribution_system = distribution_system self._emission_system = emission_system self._generation_systems = generation_systems - self._pv_generation_system = pv_generation_system self._energy_storage_systems = energy_storage_systems - self._performance_curves = performance_curves @property def lod(self): @@ -60,13 +54,12 @@ class System: return self._system_id @property - def system_configuration(self): + def name(self): """ - Get the system configuration from ['hp_tes', 'hp_boiler_tes', 'pv_hp', 'pv_battery', 'pv', 'pv_hp_tes', - 'pv_hp_battery_tes'] + Get the system name :return: string """ - return self._system_configuration + return self._name @property def demand_types(self): @@ -84,14 +77,6 @@ class System: """ return self._generation_systems - @property - def pv_generation_system(self) -> Union[None, PvGenerationSystem]: - """ - Get pv generation system - :return: ElectricityGenerationSystem - """ - return self._pv_generation_system - @property def distribution_system(self) -> Union[None, DistributionSystem]: """ @@ -116,22 +101,11 @@ class System: """ return self._energy_storage_systems - @property - def performance_curves(self) -> Union[None, List[PerformanceCurves]]: - """ - Get the list of all performance curves associated with components - :return: PerformanceCurves - """ - return self._performance_curves - def to_dictionary(self): """Class content to dictionary""" _generation_systems = [] for _generation in self.generation_systems: _generation_systems.append(_generation.to_dictionary()) - _pv_system = None - if self.pv_generation_system is not None: - _pv_system = self.pv_generation_system.to_dictionary() _distribution_system = None if self.distribution_system is not None: _distribution_system = self.distribution_system.to_dictionary() @@ -140,19 +114,15 @@ class System: _emission_system = self.emission_system.to_dictionary() _storage_system = [_storage.to_dictionary() for _storage in self.energy_storage_system] if self.energy_storage_system is not None else None - _performance_curves = [_curve.to_dictionary() for _curve in - self.performance_curves] if self.performance_curves is not None else None content = {'Layer': {'id': self.id, - 'name': self.system_configuration, + 'name': self.name, 'level of detail': self.lod, 'demand types': self.demand_types, 'Generation system(s)': _generation_systems, - 'electricity generation system': _pv_system, 'distribution system': _distribution_system, 'emission system': _emission_system, 'energy storage system': _storage_system, - 'performance curves': _performance_curves } } return content 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 306da80a..e0f7a3de 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 @@ -31,137 +31,257 @@ class NorthAmericaEnergySystemCatalog(Catalog): 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']) - # self._generation_components = self._load_generation_components() - # print(self._generation_components) + 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() + # print(self._load_systems()) - # self._system_archetypes = self._load_system_archetypes() + 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'] + boiler_name = boiler['@name'] + boiler_model_name = boiler['@modelName'] + boiler_manufacturer = boiler['@manufacturer'] + system_type = 'boiler' + boiler_fuel_type = boiler['@fuel'] + boiler_nominal_thermal_output = float(boiler['@installedThermalPower']) + boiler_maximum_heat_output = float(boiler['@modulationRange']) + boiler_heat_efficiency = float(boiler['@nominalEfficiency']) - # 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_systems(self): -# systems = [] -# catalog_systems = self._archetypes['encomp:EnergySystemCatalog']['energysystemconfiguration'] -# for catalog_system in catalog_systems: - # look for the demands and add it to demands[] - # look for the components in self._generation_systems and add them to generation_systems[] - # same with emission and distribution and storage -# System(None, -# None, -# catalog_system['@configurationName'], -# demands, -# generation_systems,... -# ) + boiler_component = GenerationSystem(boiler_id, + boiler_name, + boiler_model_name, + boiler_manufacturer, + system_type, + boiler_fuel_type, + boiler_nominal_thermal_output, + None, + None, + None, + None, + boiler_heat_efficiency, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None) + generation_components.append(boiler_component) + for heat_pump in heat_pumps: + heat_pump_id = heat_pump['@generation_id'] + heat_pump_name = heat_pump['@name'] + heat_pump_model_name = heat_pump['@modelName'] + heat_pump_manufacturer = heat_pump['@manufacturer'] + system_type = 'heat pump' + heat_pump_fuel_type = heat_pump['@fuel'] + heat_pump_nominal_thermal_output = float(heat_pump['@installedThermalPower']) + heat_pump_modulation_range = float(heat_pump['@modulationRange']) + heat_pump_source_type = heat_pump['@heatSource'] + heat_pump_supply_medium = heat_pump['@supply_medium'] + heat_pump_nominal_cop = float(heat_pump['@nominalCOP']) + heat_pump_maximum_heating_temperature = float(heat_pump['@maxHeatingSupTemperature']) + heat_pump_minimum_heating_temperature = float(heat_pump['@minHeatingSupTemperature']) + heat_pump_maximum_cooling_temperature = float(heat_pump['@maxCoolingSupTemperature']) + heat_pump_minimum_cooling_temperature = float(heat_pump['@minCoolingSupTemperature']) + cop_curve_type = heat_pump['performance_curve']['@curve_type'] + parameters = heat_pump['performance_curve']['parameters'] + coefficients = list(heat_pump['performance_curve']['coefficients'].values()) + cop_curve = PerformanceCurves(cop_curve_type, parameters, coefficients) -# return system_configurations + heat_pump_component = GenerationSystem(heat_pump_id, + heat_pump_name, + heat_pump_model_name, + heat_pump_manufacturer, + system_type, + heat_pump_fuel_type, + heat_pump_nominal_thermal_output, + None, + None, + heat_pump_source_type, + heat_pump_supply_medium, + heat_pump_nominal_cop, + None, + None, + None, + None, + None, + None, + None, + None, + heat_pump_maximum_heating_temperature, + heat_pump_minimum_heating_temperature, + heat_pump_maximum_cooling_temperature, + heat_pump_minimum_cooling_temperature, + None, + None, + cop_curve, + None, + None, + None, + None, + None) + generation_components.append(heat_pump_component) + for pv in photovoltaics: + pv_id = pv['@generation_id'] + pv_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']) - # def _load_generation_components(self): - # generation_components = [] - # boilers = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['boilers'] - # heat_pumps = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['heatPumps'] - # photovoltaics = self._archetypes['encomp:EnergySystemCatalog']['energycomponent']['photovoltaicModules'] - # for boiler in boilers: - # boiler_model_name = boiler['@modelName'] - # boiler_manufacturer = boiler['@manufacturer'] - # system_type = 'boiler' - # boiler_fuel_type = boiler['@fuel'] - # boiler_nominal_thermal_output = float(boiler['@installedThermalPower']) - # boiler_modulation_range = float(boiler['@modulationRange']) - # boiler_heat_efficiency = float(boiler['@nominalEfficiency']) - # - # boiler_component = GenerationSystem(boiler_model_name, - # boiler_manufacturer, - # system_type, - # boiler_fuel_type, - # boiler_nominal_thermal_output, - # boiler_modulation_range, - # None, - # None, - # boiler_heat_efficiency, - # None, - # None, - # None, - # None, - # None, - # None, - # None, - # None, - # None) - # generation_components.append(boiler_component) - # for heat_pump in heat_pumps: - # heat_pump_model_name = heat_pump['@modelName'] - # heat_pump_manufacturer = heat_pump['@manufacturer'] - # system_type = 'heat pump' - # heat_pump_fuel_type = heat_pump['@fuel'] - # heat_pump_nominal_thermal_output = float(heat_pump['@installedThermalPower']) - # heat_pump_modulation_range = float(heat_pump['@modulationRange']) - # heat_pump_source_type = heat_pump['@heatSource'] - # heat_pump_supply_medium = heat_pump['@supply_medium'] - # heat_pump_nominal_cop = float(heat_pump['@nominalCOP']) - # heat_pump_maximum_heating_temperature = float(heat_pump['@maxHeatingSupTemperature']) - # heat_pump_minimum_heating_temperature = float(heat_pump['@minHeatingSupTemperature']) - # heat_pump_maximum_cooling_temperature = float(heat_pump['@maxCoolingSupTemperature']) - # heat_pump_minimum_cooling_temperature = float(heat_pump['@minCoolingSupTemperature']) - # - # heat_pump_component = GenerationSystem(heat_pump_model_name, - # heat_pump_manufacturer, - # system_type, - # heat_pump_fuel_type, - # heat_pump_nominal_thermal_output, - # heat_pump_modulation_range, - # heat_pump_source_type, - # heat_pump_supply_medium, - # heat_pump_nominal_cop, - # None, - # None, - # None, - # None, - # None, - # heat_pump_maximum_heating_temperature, - # heat_pump_minimum_heating_temperature, - # heat_pump_maximum_cooling_temperature, - # heat_pump_minimum_cooling_temperature) - # generation_components.append(heat_pump_component) - # for pv in photovoltaics: - # 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_model_name = pv['@modelName'] - # pv_manufacturer = pv['@manufacturer'] - # pv_electricity_efficiency = pv['@nominalEfficiency'] - # pv_nominal_electricity_output = pv['@nominalPower'] - # pv_component = PvGenerationSystem(nominal_ambient_temperature, - # nominal_cell_temperature, - # nominal_radiation, - # standard_test_condition_cell_temperature, - # standard_test_condition_maximum_power, - # cell_temperature_coefficient, - # width, - # height, - # pv_model_name, - # pv_manufacturer, - # pv_electricity_efficiency, - # pv_nominal_electricity_output) - # generation_components.append(pv_component) - # return generation_components + pv_component = PvGenerationSystem(pv_id, + pv_name, + pv_model_name, + pv_manufacturer, + pv_electricity_efficiency, + pv_nominal_electricity_output, + nominal_ambient_temperature, + nominal_cell_temperature, + nominal_radiation, + standard_test_condition_cell_temperature, + standard_test_condition_maximum_power, + cell_temperature_coefficient, + width, + height) + generation_components.append(pv_component) + for template in templates: + system_id = template['@generation_id'] + system_name = template['@name'] + if "Boiler" in system_name: + system_type = 'boiler' + fuel_type = template['@fuel'] + heat_efficiency = float(template['@nominalEfficiency']) + source_medium = None + supply_medium = None + boiler_template = GenerationSystem(system_id, + system_name, + None, + None, + system_type, + fuel_type, + None, + None, + None, + source_medium, + supply_medium, + heat_efficiency, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None) + 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 = GenerationSystem(system_id, + system_name, + None, + None, + system_type, + fuel_type, + None, + None, + None, + source_medium, + supply_medium, + heat_efficiency, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None) + 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_name, + None, + None, + electricity_efficiency, + None, + None, + None, + None, + None, + None, + None, + width, + 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'] name = tes['@name'] @@ -196,30 +316,57 @@ class NorthAmericaEnergySystemCatalog(Catalog): layers, maximum_operating_temperature) storage_components.append(storage_component) + + for template in template_storages: + storage_id = template['@storage_id'] + name = template['@name'] + maximum_temperature = template['@maxTemp'] + materials = self._load_materials() + insulation_material_name = template['@insulationMaterial'] + insulation_material = self._search_material(materials, insulation_material_name) + material_name = template['@tankMaterial'] + tank_material = self._search_material(materials, material_name) + thickness = float(template['@insulationThickness']) / 100 # from cm to m + 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 + layers = [insulation_layer, tank_layer] + storage_component = EnergyStorageSystem(storage_id, + name, + None, + None, + 'thermal', + None, + None, + None, + None, + None, + None, + None, + layers, + maximum_temperature) + storage_components.append(storage_component) return storage_components # def _load_systems(self): - # systems = [] - # catalog_systems = self._archetypes['encomp:EnergySystemCatalog']['energysystemconfiguration'] - # for catalog_system in catalog_systems: - # system_configuration = catalog_system['@configurationName'] - # demands = catalog_system['demands'] - # demand_types = [] - # for demand in demands: - # name = demand['@name'] - # demand_types.append(name) + # _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, - # None, - # system_configuration, - # demand_types, + # system_id, # None, # None, # None, # None, # None, # None) - # systems.append(energy_system) - # return systems + # _catalog_systems.append(energy_system) + # return _catalog_systems def _load_materials(self): materials = [] diff --git a/hub/data/energy_systems/north_america_systems.xml b/hub/data/energy_systems/north_america_systems.xml index c9618448..0f8f8728 100644 --- a/hub/data/energy_systems/north_america_systems.xml +++ b/hub/data/energy_systems/north_america_systems.xml @@ -40,12 +40,12 @@ - - - - - - + + + + + + @@ -59,7 +59,7 @@ - + From 3deb63b14a4bb36a07554b5e9b4d2c8ae0917f39 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Wed, 23 Aug 2023 17:09:55 -0400 Subject: [PATCH 23/38] north_america_energy_system_catalog.py is completed montreal_custom_catalog.py is fixed --- .../energy_systems/energy_storage_system.py | 4 +- .../data_models/energy_systems/system.py | 18 +- .../energy_systems/montreal_custom_catalog.py | 26 ++- .../north_america_energy_system_catalog.py | 176 ++++++++++++++---- .../energy_systems/north_america_systems.xml | 26 +-- tests/test_systems_catalog.py | 3 + 6 files changed, 190 insertions(+), 63 deletions(-) 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 From fe0a2d3003682ae9abede4557bf638d02436e8a5 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Thu, 24 Aug 2023 15:09:17 -0400 Subject: [PATCH 24/38] north_america_energy_system_catalog.py is completed and all the bugs have been resolved. --- .../energy_systems/pv_generation_system.py | 4 +++- .../north_america_energy_system_catalog.py | 24 ++++++++++++------- tests/test_systems_catalog.py | 4 ++-- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index 5c03c3f3..9bc50823 100644 --- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -110,7 +110,9 @@ class PvGenerationSystem(GenerationSystem): def to_dictionary(self): """Class content to dictionary""" - content = {'Photovoltaic Module': { + content = {'Energy Generation component': { + 'id': self.id, + 'name': self.name, 'model name': self.model_name, 'manufacturer': self.manufacturer, 'type': self.system_type, 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 b4783f71..6a414703 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 @@ -33,13 +33,13 @@ class NorthAmericaEnergySystemCatalog(Catalog): self._storage_components = self._load_storage_components() 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) + print(self._content) def _load_generation_components(self): generation_components = [] @@ -381,11 +381,11 @@ class NorthAmericaEnergySystemCatalog(Catalog): 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 in systems: - for system_archetype in self._systems: - if int(system_archetype.id) == int(system): - _systems.append(system_archetype) + for system_archetype in self._systems: + if int(system_archetype.id) in integer_system_ids: + _systems.append(system_archetype) _system_archetypes.append(Archetype(None, name, _systems)) return _system_archetypes @@ -422,9 +422,17 @@ class NorthAmericaEnergySystemCatalog(Catalog): @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 type(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}]') diff --git a/tests/test_systems_catalog.py b/tests/test_systems_catalog.py index 8747acb4..2fb40758 100644 --- a/tests/test_systems_catalog.py +++ b/tests/test_systems_catalog.py @@ -38,5 +38,5 @@ 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 + # def test_montreal_catalog(self): + # catalog = EnergySystemsCatalogFactory('montreal_custom').catalog From 43e5bb7310767a71032a28fbf5aed750aa7f73cc Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Fri, 25 Aug 2023 10:22:46 -0400 Subject: [PATCH 25/38] nothing is changed --- .../energy_systems/montreal_custom_catalog.py | 1 - tests/test_systems_catalog.py | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py index d8c7630c..39707c0b 100644 --- a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py +++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py @@ -34,7 +34,6 @@ class MontrealCustomCatalog(Catalog): 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, diff --git a/tests/test_systems_catalog.py b/tests/test_systems_catalog.py index 2fb40758..0f9ee878 100644 --- a/tests/test_systems_catalog.py +++ b/tests/test_systems_catalog.py @@ -35,8 +35,8 @@ class TestSystemsCatalog(TestCase): with self.assertRaises(IndexError): catalog.get_entry('unknown') - def test_north_america_systems_catalog(self): - catalog = EnergySystemsCatalogFactory('north_america').catalog + # def test_north_america_systems_catalog(self): + # catalog = EnergySystemsCatalogFactory('north_america').catalog - # def test_montreal_catalog(self): - # catalog = EnergySystemsCatalogFactory('montreal_custom').catalog + def test_montreal_catalog(self): + catalog = EnergySystemsCatalogFactory('montreal_custom').catalog From 5d4813f2f609167b7d4c4793fc11a9b505a1a360 Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Mon, 28 Aug 2023 10:18:18 -0400 Subject: [PATCH 26/38] some changes in code to be reviewed by Saeed --- .../energy_systems/distribution_system.py | 2 -- .../energy_systems/energy_storage_system.py | 4 +-- .../energy_systems/generation_system.py | 28 +++++++++---------- .../energy_systems/performance_curves.py | 17 +++++++---- .../energy_systems/pv_generation_system.py | 8 +++--- .../data_models/energy_systems/system.py | 1 + .../north_america_energy_system_catalog.py | 4 +-- .../energy_systems/north_america_systems.xml | 6 ++-- tests/test_systems_catalog.py | 4 +-- 9 files changed, 40 insertions(+), 34 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/distribution_system.py b/hub/catalog_factories/data_models/energy_systems/distribution_system.py index 1e4aa96f..cac9b2b3 100644 --- a/hub/catalog_factories/data_models/energy_systems/distribution_system.py +++ b/hub/catalog_factories/data_models/energy_systems/distribution_system.py @@ -6,8 +6,6 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca """ -from hub.catalog_factories.data_models.construction.material import Material - class DistributionSystem: """ 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 be1c4413..98523ac2 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 @@ -2,8 +2,8 @@ Energy System catalog heat generation system SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2023 Concordia CERC group -Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca -Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca +Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca +Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ from __future__ import annotations diff --git a/hub/catalog_factories/data_models/energy_systems/generation_system.py b/hub/catalog_factories/data_models/energy_systems/generation_system.py index 7c382dee..afc7c5c4 100644 --- a/hub/catalog_factories/data_models/energy_systems/generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/generation_system.py @@ -20,7 +20,7 @@ class GenerationSystem: maximum_heat_output, minimum_heat_output, source_medium, supply_medium, heat_efficiency, nominal_cooling_output, maximum_cooling_output, minimum_cooling_output, cooling_efficiency, electricity_efficiency, source_temperature, source_mass_flow, nominal_electricity_output, - maximum_heating_supply_temperature, minimum_heating_supply_temperature, + 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, storage, auxiliary_equipment): @@ -33,19 +33,19 @@ class GenerationSystem: self._nominal_thermal_output = nominal_thermal_output self._maximum_heat_output = maximum_heat_output self._minimum_heat_output = minimum_heat_output - self._source_medium = source_medium - self._supply_medium = supply_medium self._heat_efficiency = heat_efficiency self._nominal_cooling_output = nominal_cooling_output self._maximum_cooling_output = maximum_cooling_output self._minimum_cooling_output = minimum_cooling_output self._cooling_efficiency = cooling_efficiency self._electricity_efficiency = electricity_efficiency + self._nominal_electricity_output = nominal_electricity_output + self._source_medium = source_medium self._source_temperature = source_temperature self._source_mass_flow = source_mass_flow - self._nominal_electricity_output = nominal_electricity_output - self._maximum_heating_supply_temperature = maximum_heating_supply_temperature - self._minimum_heating_supply_temperature = minimum_heating_supply_temperature + self._supply_medium = supply_medium + self._maximum_heat_supply_temperature = maximum_heat_supply_temperature + self._minimum_heat_supply_temperature = minimum_heat_supply_temperature self._maximum_cooling_supply_temperature = maximum_cooling_supply_temperature self._minimum_cooling_supply_temperature = minimum_cooling_supply_temperature self._heat_output_curve = heat_output_curve @@ -218,20 +218,20 @@ class GenerationSystem: return self._nominal_electricity_output @property - def maximum_heating_supply_temperature(self): + def maximum_heat_supply_temperature(self): """ - Get the maximum heating supply temperature in degree Celsius + Get the maximum heat supply temperature in degree Celsius :return: float """ - return self._minimum_heating_supply_temperature + return self._minimum_heat_supply_temperature @property - def minimum_heating_supply_temperature(self): + def minimum_heat_supply_temperature(self): """ - Get the minimum heating supply temperature in degree Celsius + Get the minimum heat supply temperature in degree Celsius :return: float """ - return self._minimum_heating_supply_temperature + return self._minimum_heat_supply_temperature @property def maximum_cooling_supply_temperature(self): @@ -339,8 +339,8 @@ class GenerationSystem: 'cooling efficiency': self.cooling_efficiency, 'electricity efficiency': self.electricity_efficiency, 'nominal power output [W]': self.nominal_electricity_output, - 'maximum heating supply temperature [Celsius]': self.maximum_heating_supply_temperature, - 'minimum heating supply temperature [Celsius]': self.minimum_heating_supply_temperature, + 'maximum heating supply temperature [Celsius]': self.maximum_heat_supply_temperature, + 'minimum heating supply temperature [Celsius]': self.minimum_heat_supply_temperature, 'maximum cooling supply temperature [Celsius]': self.maximum_cooling_supply_temperature, 'minimum cooling supply temperature [Celsius]': self.minimum_cooling_supply_temperature, 'heat output curve': self.heat_output_curve, diff --git a/hub/catalog_factories/data_models/energy_systems/performance_curves.py b/hub/catalog_factories/data_models/energy_systems/performance_curves.py index fb9b74ff..b713fd44 100644 --- a/hub/catalog_factories/data_models/energy_systems/performance_curves.py +++ b/hub/catalog_factories/data_models/energy_systems/performance_curves.py @@ -2,14 +2,13 @@ Energy System catalog heat generation system SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2023 Concordia CERC group -Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca -Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca +Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca +Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ from __future__ import annotations - class PerformanceCurves: """ Parameter function class @@ -28,17 +27,25 @@ class PerformanceCurves: Exponential =>>> y = a*(b**x) Polynomial =>>> y = a*(x**2) + b*x + c Power =>>> y = a*(x**b) - Second degree multivariable =>>> y = a*(x**2) + b*x + c*x*y + d*y + e*(y**2) + f + Second degree multivariable =>>> y = a*(x**2) + b*x + c*x*z + d*z + e*(z**2) + f Get the type of function from ['linear', 'exponential', 'polynomial', 'power', 'second degree multivariable'] :return: string """ return self._curve_type + @property + def function(self): + """ + y (e.g. COP in COP = a*source temperature**2... ) + """ + return self._function + @property def parameters(self): """ - Get the list of parameters involved in fitting process as ['y', 'x', 'z'] + Get the list of parameters involved in fitting process as ['x', 'z'] (e.g. [source temperature, supply temperature] + in COP=) :return: string """ return self._parameters diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index 9bc50823..1cbe69e5 100644 --- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -2,8 +2,8 @@ Energy System catalog heat generation system SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2023 Concordia CERC group -Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca -Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca +Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca +Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ from __future__ import annotations @@ -28,8 +28,8 @@ class PvGenerationSystem(GenerationSystem): cooling_efficiency=None, electricity_efficiency=electricity_efficiency, source_temperature=None, source_mass_flow=None, nominal_electricity_output=nominal_electricity_output, - maximum_heating_supply_temperature=None, - minimum_heating_supply_temperature=None, + maximum_heat_supply_temperature=None, + minimum_heat_supply_temperature=None, maximum_cooling_supply_temperature=None, minimum_cooling_supply_temperature=None, heat_output_curve=None, heat_fuel_consumption_curve=None, heat_efficiency_curve=None, diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index 96d8a08c..0d4667d3 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -36,6 +36,7 @@ class System: self._emission_system = emission_system self._generation_systems = generation_systems self._energy_storage_systems = energy_storage_systems + self._configuration = configuration @property def lod(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 6a414703..933ddc62 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 @@ -2,8 +2,8 @@ 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 +Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca +Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ diff --git a/hub/data/energy_systems/north_america_systems.xml b/hub/data/energy_systems/north_america_systems.xml index 4584ac16..6fe12090 100644 --- a/hub/data/energy_systems/north_america_systems.xml +++ b/hub/data/energy_systems/north_america_systems.xml @@ -1,5 +1,6 @@ + ./schemas/ @@ -129,7 +130,7 @@ - Water Source Heat Pump with Electrical Boiler and thermal storage + Water Source Heat Pump with Electrical Boiler and thermal storage\ heating domestic_hot_water @@ -197,8 +198,7 @@ - + - diff --git a/tests/test_systems_catalog.py b/tests/test_systems_catalog.py index 0f9ee878..8747acb4 100644 --- a/tests/test_systems_catalog.py +++ b/tests/test_systems_catalog.py @@ -35,8 +35,8 @@ class TestSystemsCatalog(TestCase): with self.assertRaises(IndexError): catalog.get_entry('unknown') - # def test_north_america_systems_catalog(self): - # catalog = EnergySystemsCatalogFactory('north_america').catalog + def test_north_america_systems_catalog(self): + catalog = EnergySystemsCatalogFactory('north_america').catalog def test_montreal_catalog(self): catalog = EnergySystemsCatalogFactory('montreal_custom').catalog From 24a670755ad44532f69797233322c642a35dd0f9 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Mon, 28 Aug 2023 18:37:55 -0400 Subject: [PATCH 27/38] performance_curves.py is fixed material_name is replaced with material_id in north_america_energy_system_catalog.py The unused variables are fixed. The code is modified to accommodate the reorganization Pilar did in generation_systems The system.py is modified to be able to accommodate more than one distribution or emission system --- .../energy_systems/performance_curves.py | 13 ++-- .../data_models/energy_systems/system.py | 24 +++--- .../north_america_energy_system_catalog.py | 78 ++++++++++--------- .../energy_systems/north_america_systems.xml | 71 +++++++++++------ 4 files changed, 107 insertions(+), 79 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/performance_curves.py b/hub/catalog_factories/data_models/energy_systems/performance_curves.py index b713fd44..65cc0878 100644 --- a/hub/catalog_factories/data_models/energy_systems/performance_curves.py +++ b/hub/catalog_factories/data_models/energy_systems/performance_curves.py @@ -14,8 +14,9 @@ class PerformanceCurves: Parameter function class """ - def __init__(self, curve_type, parameters, coefficients): + def __init__(self, curve_type, dependant_variable, parameters, coefficients): self._curve_type = curve_type + self._dependant_variable = dependant_variable self._parameters = parameters self._coefficients = coefficients @@ -35,11 +36,12 @@ class PerformanceCurves: return self._curve_type @property - def function(self): + def dependant_variable(self): """ - y (e.g. COP in COP = a*source temperature**2... ) + y (e.g. COP in COP = a*source temperature**2 + b*source temperature + c*source temperature*supply temperature + + d*supply temperature + e*supply temperature**2 + f) """ - return self._function + return self._dependant_variable @property def parameters(self): @@ -62,7 +64,8 @@ class PerformanceCurves: """Class content to dictionary""" content = {'Parameter Function': { 'curve type': self.curve_type, - 'parameters': self.parameters, + 'dependant variable': self.dependant_variable, + 'parameter(s)': self.parameters, 'coefficients': self.coefficients, } } diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index 0d4667d3..9dd0ab83 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -36,7 +36,7 @@ class System: self._emission_system = emission_system self._generation_systems = generation_systems self._energy_storage_systems = energy_storage_systems - self._configuration = configuration + # self._configuration = configuration @property def lod(self): @@ -79,7 +79,7 @@ class System: return self._generation_systems @property - def distribution_system(self) -> Union[None, DistributionSystem]: + def distribution_system(self) -> Union[None, List[DistributionSystem]]: """ Get distribution system :return: DistributionSystem @@ -87,7 +87,7 @@ class System: return self._distribution_system @property - def emission_system(self) -> Union[None, EmissionSystem]: + def emission_system(self) -> Union[None, List[EmissionSystem]]: """ Get emission system :return: EmissionSystem @@ -107,12 +107,10 @@ class System: _generation_systems = [] for _generation in self.generation_systems: _generation_systems.append(_generation.to_dictionary()) - _distribution_system = None - if self.distribution_system is not None: - _distribution_system = self.distribution_system.to_dictionary() - _emission_system = None - if self.emission_system is not None: - _emission_system = self.emission_system.to_dictionary() + _distribution_system = [_distribution.to_dictionary() for _distribution in + self.distribution_system] if self.distribution_system is not None else None + _emission_system = [_emission.to_dictionary() for _emission in + self.emission_system] if self.emission_system is not None else None _storage_system = [_storage.to_dictionary() for _storage in self.energy_storage_system] if self.energy_storage_system is not None else None @@ -120,10 +118,10 @@ class System: '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, + 'generation system(s)': _generation_systems, + 'distribution system(s)': _distribution_system, + 'emission system(s)': _emission_system, + 'energy storage system(s)': _storage_system, } } return content 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 933ddc62..ceaacfdd 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 @@ -55,7 +55,8 @@ class NorthAmericaEnergySystemCatalog(Catalog): system_type = 'boiler' boiler_fuel_type = boiler['@fuel'] boiler_nominal_thermal_output = float(boiler['@installedThermalPower']) - boiler_maximum_heat_output = float(boiler['@modulationRange']) + boiler_maximum_heat_output = float(boiler['@maximumHeatOutput']) + boiler_minimum_heat_output = float(boiler['@minimumHeatOutput']) boiler_heat_efficiency = float(boiler['@nominalEfficiency']) boiler_component = GenerationSystem(boiler_id, @@ -65,8 +66,8 @@ class NorthAmericaEnergySystemCatalog(Catalog): system_type, boiler_fuel_type, boiler_nominal_thermal_output, - None, - None, + boiler_maximum_heat_output, + boiler_minimum_heat_output, None, None, boiler_heat_efficiency, @@ -99,18 +100,20 @@ class NorthAmericaEnergySystemCatalog(Catalog): system_type = 'heat pump' heat_pump_fuel_type = heat_pump['@fuel'] heat_pump_nominal_thermal_output = float(heat_pump['@installedThermalPower']) - heat_pump_modulation_range = float(heat_pump['@modulationRange']) - heat_pump_source_type = heat_pump['@heatSource'] + 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_heating_temperature = float(heat_pump['@maxHeatingSupTemperature']) - heat_pump_minimum_heating_temperature = float(heat_pump['@minHeatingSupTemperature']) - heat_pump_maximum_cooling_temperature = float(heat_pump['@maxCoolingSupTemperature']) - heat_pump_minimum_cooling_temperature = float(heat_pump['@minCoolingSupTemperature']) + 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, parameters, coefficients) + cop_curve = PerformanceCurves(cop_curve_type, dependant_variable, parameters, coefficients) heat_pump_component = GenerationSystem(heat_pump_id, heat_pump_name, @@ -119,9 +122,9 @@ class NorthAmericaEnergySystemCatalog(Catalog): system_type, heat_pump_fuel_type, heat_pump_nominal_thermal_output, - None, - None, - heat_pump_source_type, + heat_pump_maximum_heat_output, + heat_pump_minimum_heat_output, + heat_pump_source_medium, heat_pump_supply_medium, heat_pump_nominal_cop, None, @@ -132,10 +135,10 @@ class NorthAmericaEnergySystemCatalog(Catalog): None, None, None, - heat_pump_maximum_heating_temperature, - heat_pump_minimum_heating_temperature, - heat_pump_maximum_cooling_temperature, - heat_pump_minimum_cooling_temperature, + heat_pump_minimum_heat_supply_temperature, + heat_pump_minimum_heat_supply_temperature, + heat_pump_maximum_cooling_supply_temperature, + heat_pump_minimum_cooling_supply_temperature, None, None, cop_curve, @@ -288,18 +291,18 @@ class NorthAmericaEnergySystemCatalog(Catalog): name = tes['@name'] model_name = tes['@modelName'] manufacturer = tes['@manufacturer'] - volume = tes['@volume'] - height = tes['@height'] + volume = tes['physical_characteristics']['@volume'] + height = tes['physical_characteristics']['@height'] maximum_operating_temperature = tes['@maxTemp'] materials = self._load_materials() - insulation_material_name = tes['@insulationMaterial'] - insulation_material = self._search_material(materials, insulation_material_name) - material_name = tes['@tankMaterial'] - tank_material = self._search_material(materials, material_name) - thickness = float(tes['@insulationThickness']) / 100 # from cm to m + 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['@tankThickness']) / 100 # from cm to m - tank_layer = Layer(None, 'insulation', tank_material, thickness) + thickness = float(tes['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] storage_component = EnergyStorageSystem(storage_id, @@ -323,14 +326,14 @@ class NorthAmericaEnergySystemCatalog(Catalog): name = template['@name'] maximum_temperature = template['@maxTemp'] materials = self._load_materials() - insulation_material_name = template['@insulationMaterial'] - insulation_material = self._search_material(materials, insulation_material_name) - material_name = template['@tankMaterial'] - tank_material = self._search_material(materials, material_name) - thickness = float(template['@insulationThickness']) / 100 # from cm to m + 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(template['@tankThickness']) / 100 # from cm to m - tank_layer = Layer(None, 'insulation', tank_material, thickness) + thickness = float(tes['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] storage_component = EnergyStorageSystem(storage_id, @@ -393,9 +396,10 @@ class NorthAmericaEnergySystemCatalog(Catalog): 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(None, + material = Material(material_id, name, None, None, @@ -409,15 +413,15 @@ class NorthAmericaEnergySystemCatalog(Catalog): return materials @staticmethod - def _search_material(materials, material_name): + def _search_material(materials, material_id): _material = None for material in materials: - if material.name == material_name: + if int(material.id) == int(material_id): _material = material return _material if _material is None: - raise ValueError(f'Material not found in catalog [{material_name}]') + raise ValueError(f'Material with the id = [{material_id}] not found in catalog ') @staticmethod def _search_generation_equipment(generation_systems, generation_id): diff --git a/hub/data/energy_systems/north_america_systems.xml b/hub/data/energy_systems/north_america_systems.xml index 6fe12090..285f9de7 100644 --- a/hub/data/energy_systems/north_america_systems.xml +++ b/hub/data/energy_systems/north_america_systems.xml @@ -5,37 +5,37 @@ - - - - - - - - - - - + + + + + + + + + + + - + - COP + COP source_temperature supply_temperature - + - COP + COP source_temperature supply_temperature - + - COP + COP source_temperature supply_temperature @@ -55,13 +55,36 @@ - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 644b1c9346b114dc408723563f4d2348bbfa9de3 Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Tue, 29 Aug 2023 11:45:02 -0400 Subject: [PATCH 28/38] energy_storage_system.py is modified and inherited by thermal_storage_system.py and electrical_storage_system.py --- .../data_models/energy_systems/archetype.py | 2 + .../data_models/energy_systems/content.py | 7 -- .../electrical_storage_system.py | 90 +++++++++++++++++ .../energy_systems/energy_storage_system.py | 96 +------------------ .../energy_systems/thermal_storage_system.py | 84 ++++++++++++++++ .../north_america_energy_system_catalog.py | 67 ++++++------- tests/test_systems_catalog.py | 6 +- 7 files changed, 211 insertions(+), 141 deletions(-) create mode 100644 hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py create mode 100644 hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py diff --git a/hub/catalog_factories/data_models/energy_systems/archetype.py b/hub/catalog_factories/data_models/energy_systems/archetype.py index b490ebb9..7f43c5dc 100644 --- a/hub/catalog_factories/data_models/energy_systems/archetype.py +++ b/hub/catalog_factories/data_models/energy_systems/archetype.py @@ -56,3 +56,5 @@ class Archetype: } } return content + + diff --git a/hub/catalog_factories/data_models/energy_systems/content.py b/hub/catalog_factories/data_models/energy_systems/content.py index d3fd9068..f6a03ea0 100644 --- a/hub/catalog_factories/data_models/energy_systems/content.py +++ b/hub/catalog_factories/data_models/energy_systems/content.py @@ -69,11 +69,4 @@ class Content: return content - def __str__(self): - """Print content""" - _archetypes = [] - for _archetype in self.archetypes: - _archetypes.append(_archetype.to_dictionary()) - content = {'Archetypes': _archetypes} - return str(content) diff --git a/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py b/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py new file mode 100644 index 00000000..a660c08c --- /dev/null +++ b/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py @@ -0,0 +1,90 @@ +""" +Energy System catalog heat generation system +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca +Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" +from __future__ import annotations +from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem + + +class ThermalStorageSystem(EnergyStorageSystem): + """ + Thermal Storage system class + """ + + def __init__(self, storage_id, name, model_name, manufacturer, storage_type, rated_output_power, + nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate): + super().__init__(storage_id=storage_id, name=name, model_name=model_name, + manufacturer=manufacturer) + self._storage_type = storage_type + self._rated_output_power = rated_output_power + self._nominal_efficiency = nominal_efficiency + self._battery_voltage = battery_voltage + self._depth_of_discharge = depth_of_discharge + self._self_discharge_rate = self_discharge_rate + + @property + def storage_type(self): + """ + Get storage type from ['lithium_ion', 'lead_acid', 'NiCd'] + :return: string + """ + return self._storage_type + + @property + def rated_output_power(self): + """ + Get the rated output power of storage system in kW + :return: float + """ + return self._rated_output_power + + @property + def nominal_efficiency(self): + """ + Get the nominal efficiency of the storage system + :return: float + """ + return self._nominal_efficiency + + @property + def battery_voltage(self): + """ + Get the battery voltage in Volt + :return: float + """ + return self._battery_voltage + + @property + def depth_of_discharge(self): + """ + Get the depth of discharge as a percentage + :return: float + """ + return self._depth_of_discharge + + @property + def self_discharge_rate(self): + """ + Get the self discharge rate of battery as a percentage + :return: float + """ + return self._self_discharge_rate + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Storage component': { + 'storage id': self.id, + 'name': self.name, + 'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'storage type': self.storage_type, + 'rated power [kW]': self.rated_output_power, + 'nominal efficiency': self.nominal_efficiency, + 'battery voltage [V]': self.battery_voltage, + 'depth of discharge': self.depth_of_discharge, + } + } + return content 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 98523ac2..2b183e55 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 @@ -15,23 +15,12 @@ class EnergyStorageSystem: Energy Storage System Class """ - def __init__(self, storage_id, name, model_name, manufacturer, storage_type, volume, rated_output_power, - nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, height, layers, - maximum_operating_temperature): + def __init__(self, storage_id, name, model_name, manufacturer, storage_type): self._storage_id = storage_id self._name = name self._model_name = model_name self._manufacturer = manufacturer self._storage_type = storage_type - self._physical_volume = volume - self._rated_output_power = rated_output_power - self._nominal_efficiency = nominal_efficiency - self._battery_voltage = battery_voltage - self._depth_of_discharge = depth_of_discharge - self._self_discharge_rate = self_discharge_rate - self._height = height - self._layers = layers - self._maximum_operating_temperature = maximum_operating_temperature @property def id(self): @@ -73,78 +62,6 @@ class EnergyStorageSystem: """ return self._storage_type - @property - def physical_volume(self): - """ - Get the physical volume of the storage system in cubic meters - :return: float - """ - return self._physical_volume - - @property - def rated_output_power(self): - """ - Get the rated output power of storage system in kW - :return: float - """ - return self._rated_output_power - - @property - def nominal_efficiency(self): - """ - Get the nominal efficiency of the storage system - :return: float - """ - return self._nominal_efficiency - - @property - def battery_voltage(self): - """ - Get the battery voltage in Volt - :return: float - """ - return self._battery_voltage - - @property - def depth_of_discharge(self): - """ - Get the depth of discharge as a percentage - :return: float - """ - return self._depth_of_discharge - - @property - def self_discharge_rate(self): - """ - Get the self discharge rate of battery as a percentage - :return: float - """ - return self._self_discharge_rate - - @property - def height(self): - """ - Get the diameter of the storage system in meters - :return: float - """ - return self._height - - @property - def layers(self) -> [Layer]: - """ - Get construction layers - :return: [layer] - """ - return self._layers - - @property - def maximum_operating_temperature(self): - """ - Get maximum operating temperature of the storage system in degree Celsius - :return: float - """ - return self._maximum_operating_temperature - def to_dictionary(self): """Class content to dictionary""" _layers = [] @@ -155,16 +72,7 @@ class EnergyStorageSystem: 'name': self.name, 'model name': self.model_name, 'manufacturer': self.manufacturer, - 'storage type': self.storage_type, - 'physical volume [m3]': self.physical_volume, - 'rated power [kW]': self.rated_output_power, - 'nominal efficiency': self.nominal_efficiency, - 'battery voltage [V]': self.battery_voltage, - 'depth of discharge': self.depth_of_discharge, - 'self discharge rate': self.self_discharge_rate, - 'height [m]': self.height, - 'layers': _layers, - 'maximum operating temperature [Celsius]': self.maximum_operating_temperature + 'storage type': self.storage_type } } return content diff --git a/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py b/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py new file mode 100644 index 00000000..ebf0d45b --- /dev/null +++ b/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py @@ -0,0 +1,84 @@ +""" +Energy System catalog heat generation system +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca +Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +""" +from __future__ import annotations +from hub.catalog_factories.data_models.construction.layer import Layer +from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem + + +class ThermalStorageSystem(EnergyStorageSystem): + """ + Thermal Storage system class + """ + + def __init__(self, storage_id, name, model_name, manufacturer, storage_type, volume, height, layers, + maximum_operating_temperature): + super().__init__(storage_id=storage_id, name=name, model_name=model_name, + manufacturer=manufacturer, storage_type=storage_type) + self._volume = volume + self._height = height + self._layers = layers + self._maximum_operating_temperature = maximum_operating_temperature + + @property + def storage_type(self): + """ + Get storage type from ['sensible', 'latent'] + :return: string + """ + return self._storage_type + + @property + def volume(self): + """ + Get the physical volume of the storage system in cubic meters + :return: float + """ + return self._volume + + @property + def height(self): + """ + Get the diameter of the storage system in meters + :return: float + """ + return self._height + + @property + def layers(self) -> [Layer]: + """ + Get construction layers + :return: [layer] + """ + return self._layers + + @property + def maximum_operating_temperature(self): + """ + Get maximum operating temperature of the storage system in degree Celsius + :return: float + """ + return self._maximum_operating_temperature + + def to_dictionary(self): + """Class content to dictionary""" + _layers = [] + for _layer in self.layers: + _layers.append(_layer.to_dictionary()) + content = {'Storage component': { + 'storage id': self.id, + 'name': self.name, + 'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'storage type': self.storage_type, + 'volume [m3]': self.physical_volume, + 'height [m]': self.height, + 'layers': _layers, + 'maximum operating temperature [Celsius]': self.maximum_operating_temperature + } + } + return content 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 ceaacfdd..a1e4798e 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,14 +6,13 @@ Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ - 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.energy_storage_system import EnergyStorageSystem +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 @@ -40,7 +39,6 @@ class NorthAmericaEnergySystemCatalog(Catalog): None, self._storage_components) print(self._content) - def _load_generation_components(self): generation_components = [] boilers = self._archetypes['EnergySystemCatalog']['energy_generation_components']['boilers'] @@ -135,7 +133,7 @@ class NorthAmericaEnergySystemCatalog(Catalog): None, None, None, - heat_pump_minimum_heat_supply_temperature, + heat_pump_maximum_heat_supply_temperature, heat_pump_minimum_heat_supply_temperature, heat_pump_maximum_cooling_supply_temperature, heat_pump_minimum_cooling_supply_temperature, @@ -291,6 +289,7 @@ class NorthAmericaEnergySystemCatalog(Catalog): name = tes['@name'] 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'] @@ -303,53 +302,45 @@ class NorthAmericaEnergySystemCatalog(Catalog): 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) - # 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, - model_name, - manufacturer, - 'thermal', - volume, - None, - None, - None, - None, - None, - height, - layers, - maximum_operating_temperature) + storage_component = ThermalStorageSystem(storage_id, + name, + model_name, + manufacturer, + storage_type, + volume, + height, + layers, + maximum_operating_temperature) storage_components.append(storage_component) for template in template_storages: storage_id = template['@storage_id'] name = template['@name'] + storage_type = 'sensible' maximum_temperature = template['@maxTemp'] + height = template['physical_characteristics']['@height'] materials = self._load_materials() - insulation_material_id = tes['insulation']['@material_id'] + insulation_material_id = template['insulation']['@material_id'] insulation_material = self._search_material(materials, insulation_material_id) - material_id = tes['physical_characteristics']['@material_id'] + material_id = template['physical_characteristics']['@material_id'] tank_material = self._search_material(materials, material_id) - thickness = float(tes['insulation']['@insulationThickness']) / 100 # from cm to m + thickness = float(template['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 + 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 +# the convention is from outside to inside layers = [insulation_layer, tank_layer] - storage_component = EnergyStorageSystem(storage_id, - name, - None, - None, - 'thermal', - None, - None, - None, - None, - None, - None, - None, - layers, - maximum_temperature) + storage_component = ThermalStorageSystem(storage_id, + name, + None, + None, + storage_type, + None, + height, + layers, + maximum_temperature) storage_components.append(storage_component) return storage_components diff --git a/tests/test_systems_catalog.py b/tests/test_systems_catalog.py index 8747acb4..a0720708 100644 --- a/tests/test_systems_catalog.py +++ b/tests/test_systems_catalog.py @@ -38,5 +38,7 @@ 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 + + + # def test_montreal_catalog(self): + # catalog = EnergySystemsCatalogFactory('montreal_custom').catalog From 6ac63adaaf7d9f2d57ef3a7715494576ff90b3ef Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 29 Aug 2023 12:22:06 -0400 Subject: [PATCH 29/38] separated storage class in three, one abstract --- .../electrical_storage_system.py | 84 +++++++++++++ .../energy_systems/energy_storage_system.py | 114 ++---------------- .../energy_systems/thermal_storage_system.py | 78 ++++++++++++ 3 files changed, 174 insertions(+), 102 deletions(-) create mode 100644 hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py create mode 100644 hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py diff --git a/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py b/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py new file mode 100644 index 00000000..face6903 --- /dev/null +++ b/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py @@ -0,0 +1,84 @@ +""" +Energy System catalog electrical storage system +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca +""" + +from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem + + +class ElectricalStorageSystem(EnergyStorageSystem): + """" + Energy Storage System Class + """ + + def __init__(self, storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio, + rated_output_power, nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate): + + super().__init__(storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio) + self._rated_output_power = rated_output_power + self._nominal_efficiency = nominal_efficiency + self._battery_voltage = battery_voltage + self._depth_of_discharge = depth_of_discharge + self._self_discharge_rate = self_discharge_rate + + @property + def rated_output_power(self): + """ + Get the rated output power of storage system in kW + :return: float + """ + return self._rated_output_power + + @property + def nominal_efficiency(self): + """ + Get the nominal efficiency of the storage system + :return: float + """ + return self._nominal_efficiency + + @property + def battery_voltage(self): + """ + Get the battery voltage in Volt + :return: float + """ + return self._battery_voltage + + @property + def depth_of_discharge(self): + """ + Get the depth of discharge as a percentage + :return: float + """ + return self._depth_of_discharge + + @property + def self_discharge_rate(self): + """ + Get the self discharge rate of battery as a percentage + :return: float + """ + return self._self_discharge_rate + + def to_dictionary(self): + """Class content to dictionary""" + content = {'Storage component': { + 'storage id': self.id, + 'name': self.name, + 'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'storage type': self.storage_type, + 'nominal capacity [J]': self.nominal_capacity, + 'losses-ratio [J/J]': self.losses_ratio, + 'rated power [kW]': self.rated_output_power, + 'nominal efficiency': self.nominal_efficiency, + 'battery voltage [V]': self.battery_voltage, + 'depth of discharge': self.depth_of_discharge, + 'self discharge rate': self.self_discharge_rate + } + } + return content 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 98523ac2..6e746f35 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 @@ -6,32 +6,22 @@ Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ -from __future__ import annotations -from hub.catalog_factories.data_models.construction.layer import Layer +from abc import ABC -class EnergyStorageSystem: +class EnergyStorageSystem(ABC): """" Energy Storage System Class """ - def __init__(self, storage_id, name, model_name, manufacturer, storage_type, volume, rated_output_power, - nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate, height, layers, - maximum_operating_temperature): + def __init__(self, storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio): self._storage_id = storage_id self._name = name self._model_name = model_name self._manufacturer = manufacturer self._storage_type = storage_type - self._physical_volume = volume - self._rated_output_power = rated_output_power - self._nominal_efficiency = nominal_efficiency - self._battery_voltage = battery_voltage - self._depth_of_discharge = depth_of_discharge - self._self_discharge_rate = self_discharge_rate - self._height = height - self._layers = layers - self._maximum_operating_temperature = maximum_operating_temperature + self._nominal_capacity = nominal_capacity + self._losses_ratio = losses_ratio @property def id(self): @@ -68,103 +58,23 @@ class EnergyStorageSystem: @property def storage_type(self): """ - Get storage type from ['lithium_ion', 'sensible', 'latent'] + Get storage type from ['electricity', 'thermal', 'chemical', 'lithium_ion', 'sensible', 'latent'] :return: string """ return self._storage_type @property - def physical_volume(self): + def nominal_capacity(self): """ - Get the physical volume of the storage system in cubic meters + Get the nominal capacity of the storage system in Jules :return: float """ - return self._physical_volume + return self._nominal_capacity @property - def rated_output_power(self): + def losses_ratio(self): """ - Get the rated output power of storage system in kW + Get the losses-ratio of storage system in Jules lost / Jules stored :return: float """ - return self._rated_output_power - - @property - def nominal_efficiency(self): - """ - Get the nominal efficiency of the storage system - :return: float - """ - return self._nominal_efficiency - - @property - def battery_voltage(self): - """ - Get the battery voltage in Volt - :return: float - """ - return self._battery_voltage - - @property - def depth_of_discharge(self): - """ - Get the depth of discharge as a percentage - :return: float - """ - return self._depth_of_discharge - - @property - def self_discharge_rate(self): - """ - Get the self discharge rate of battery as a percentage - :return: float - """ - return self._self_discharge_rate - - @property - def height(self): - """ - Get the diameter of the storage system in meters - :return: float - """ - return self._height - - @property - def layers(self) -> [Layer]: - """ - Get construction layers - :return: [layer] - """ - return self._layers - - @property - def maximum_operating_temperature(self): - """ - Get maximum operating temperature of the storage system in degree Celsius - :return: float - """ - return self._maximum_operating_temperature - - def to_dictionary(self): - """Class content to dictionary""" - _layers = [] - for _layer in self.layers: - _layers.append(_layer.to_dictionary()) - content = {'Storage component': { - 'storage id': self.id, - 'name': self.name, - 'model name': self.model_name, - 'manufacturer': self.manufacturer, - 'storage type': self.storage_type, - 'physical volume [m3]': self.physical_volume, - 'rated power [kW]': self.rated_output_power, - 'nominal efficiency': self.nominal_efficiency, - 'battery voltage [V]': self.battery_voltage, - 'depth of discharge': self.depth_of_discharge, - 'self discharge rate': self.self_discharge_rate, - 'height [m]': self.height, - 'layers': _layers, - 'maximum operating temperature [Celsius]': self.maximum_operating_temperature - } - } - return content + return self._losses_ratio diff --git a/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py b/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py new file mode 100644 index 00000000..ea565e49 --- /dev/null +++ b/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py @@ -0,0 +1,78 @@ +""" +Energy System catalog thermal storage system +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2023 Concordia CERC group +Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca +Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca +""" + +from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem +from hub.catalog_factories.data_models.construction.layer import Layer + + +class ThermalStorageSystem(EnergyStorageSystem): + """" + Energy Storage System Class + """ + + def __init__(self, storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio, + volume, height, layers, maximum_operating_temperature): + + super().__init__(storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio) + self._physical_volume = volume + self._height = height + self._layers = layers + self._maximum_operating_temperature = maximum_operating_temperature + + @property + def physical_volume(self): + """ + Get the physical volume of the storage system in cubic meters + :return: float + """ + return self._physical_volume + + @property + def height(self): + """ + Get the diameter of the storage system in meters + :return: float + """ + return self._height + + @property + def layers(self) -> [Layer]: + """ + Get construction layers + :return: [layer] + """ + return self._layers + + @property + def maximum_operating_temperature(self): + """ + Get maximum operating temperature of the storage system in degree Celsius + :return: float + """ + return self._maximum_operating_temperature + + def to_dictionary(self): + """Class content to dictionary""" + _layers = [] + for _layer in self.layers: + _layers.append(_layer.to_dictionary()) + content = {'Storage component': { + 'storage id': self.id, + 'name': self.name, + 'model name': self.model_name, + 'manufacturer': self.manufacturer, + 'storage type': self.storage_type, + 'nominal capacity [J]': self.nominal_capacity, + 'losses-ratio [J/J]': self.losses_ratio, + 'physical volume [m3]': self.physical_volume, + 'height [m]': self.height, + 'layers': _layers, + 'maximum operating temperature [Celsius]': self.maximum_operating_temperature + } + } + return content From c77b2254f10ad5439781d8ac9af7567a4b82b9b9 Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 29 Aug 2023 12:26:19 -0400 Subject: [PATCH 30/38] separated storage class in three, one abstract --- .../data_models/energy_systems/energy_storage_system.py | 3 ++- .../data_models/energy_systems/thermal_storage_system.py | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) 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 6e746f35..e23d176c 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 @@ -58,7 +58,8 @@ class EnergyStorageSystem(ABC): @property def storage_type(self): """ - Get storage type from ['electricity', 'thermal', 'chemical', 'lithium_ion', 'sensible', 'latent'] + Get storage type from ['electricity', 'thermal', 'chemical', + 'lithium_ion', 'lead_acid', 'NiCd', 'sensible', 'latent'] :return: string """ return self._storage_type diff --git a/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py b/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py index ea565e49..574ca24c 100644 --- a/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py +++ b/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py @@ -19,18 +19,18 @@ class ThermalStorageSystem(EnergyStorageSystem): volume, height, layers, maximum_operating_temperature): super().__init__(storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio) - self._physical_volume = volume + self._volume = volume self._height = height self._layers = layers self._maximum_operating_temperature = maximum_operating_temperature @property - def physical_volume(self): + def volume(self): """ Get the physical volume of the storage system in cubic meters :return: float """ - return self._physical_volume + return self._volume @property def height(self): @@ -69,7 +69,7 @@ class ThermalStorageSystem(EnergyStorageSystem): 'storage type': self.storage_type, 'nominal capacity [J]': self.nominal_capacity, 'losses-ratio [J/J]': self.losses_ratio, - 'physical volume [m3]': self.physical_volume, + 'volume [m3]': self.volume, 'height [m]': self.height, 'layers': _layers, 'maximum operating temperature [Celsius]': self.maximum_operating_temperature From 8dbeeaafa1af265a4ba96ffd3a6004ae22e3f115 Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 29 Aug 2023 12:29:11 -0400 Subject: [PATCH 31/38] changed some units in electrical storage --- .../energy_systems/electrical_storage_system.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py b/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py index face6903..3cd5b31d 100644 --- a/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py +++ b/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py @@ -27,7 +27,7 @@ class ElectricalStorageSystem(EnergyStorageSystem): @property def rated_output_power(self): """ - Get the rated output power of storage system in kW + Get the rated output power of storage system in Watts :return: float """ return self._rated_output_power @@ -43,7 +43,7 @@ class ElectricalStorageSystem(EnergyStorageSystem): @property def battery_voltage(self): """ - Get the battery voltage in Volt + Get the battery voltage in Volts :return: float """ return self._battery_voltage @@ -74,10 +74,10 @@ class ElectricalStorageSystem(EnergyStorageSystem): 'storage type': self.storage_type, 'nominal capacity [J]': self.nominal_capacity, 'losses-ratio [J/J]': self.losses_ratio, - 'rated power [kW]': self.rated_output_power, + 'rated power [W]': self.rated_output_power, 'nominal efficiency': self.nominal_efficiency, 'battery voltage [V]': self.battery_voltage, - 'depth of discharge': self.depth_of_discharge, + 'depth of discharge [%]': self.depth_of_discharge, 'self discharge rate': self.self_discharge_rate } } From d4b424357dcbb9ead7761083721a671d9f7e2f1d Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 29 Aug 2023 12:31:06 -0400 Subject: [PATCH 32/38] added to_dictionary to abstract class --- .../data_models/energy_systems/energy_storage_system.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 e23d176c..c0e3adef 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 @@ -11,7 +11,7 @@ from abc import ABC class EnergyStorageSystem(ABC): """" - Energy Storage System Class + Energy Storage System Abstract Class """ def __init__(self, storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio): @@ -79,3 +79,7 @@ class EnergyStorageSystem(ABC): :return: float """ return self._losses_ratio + + def to_dictionary(self): + """Class content to dictionary""" + raise NotImplementedError From 7810f8f91dff16563630d19168bf30803f539cda Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 29 Aug 2023 12:34:04 -0400 Subject: [PATCH 33/38] extracted storage type from abstract class --- .../energy_systems/electrical_storage_system.py | 11 ++++++++++- .../energy_systems/energy_storage_system.py | 12 +----------- .../energy_systems/thermal_storage_system.py | 11 ++++++++++- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py b/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py index 3cd5b31d..6f5d6d14 100644 --- a/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py +++ b/hub/catalog_factories/data_models/energy_systems/electrical_storage_system.py @@ -17,13 +17,22 @@ class ElectricalStorageSystem(EnergyStorageSystem): def __init__(self, storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio, rated_output_power, nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate): - super().__init__(storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio) + super().__init__(storage_id, name, model_name, manufacturer, nominal_capacity, losses_ratio) + self._storage_type = storage_type self._rated_output_power = rated_output_power self._nominal_efficiency = nominal_efficiency self._battery_voltage = battery_voltage self._depth_of_discharge = depth_of_discharge self._self_discharge_rate = self_discharge_rate + @property + def storage_type(self): + """ + Get storage type from ['electrical', 'lithium_ion', 'lead_acid', 'NiCd'] + :return: string + """ + return self._storage_type + @property def rated_output_power(self): """ 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 c0e3adef..a5302cb4 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 @@ -14,12 +14,11 @@ class EnergyStorageSystem(ABC): Energy Storage System Abstract Class """ - def __init__(self, storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio): + def __init__(self, storage_id, name, model_name, manufacturer, nominal_capacity, losses_ratio): self._storage_id = storage_id self._name = name self._model_name = model_name self._manufacturer = manufacturer - self._storage_type = storage_type self._nominal_capacity = nominal_capacity self._losses_ratio = losses_ratio @@ -55,15 +54,6 @@ class EnergyStorageSystem(ABC): """ return self._manufacturer - @property - def storage_type(self): - """ - Get storage type from ['electricity', 'thermal', 'chemical', - 'lithium_ion', 'lead_acid', 'NiCd', 'sensible', 'latent'] - :return: string - """ - return self._storage_type - @property def nominal_capacity(self): """ diff --git a/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py b/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py index 574ca24c..679669a4 100644 --- a/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py +++ b/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py @@ -18,12 +18,21 @@ class ThermalStorageSystem(EnergyStorageSystem): def __init__(self, storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio, volume, height, layers, maximum_operating_temperature): - super().__init__(storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio) + super().__init__(storage_id, name, model_name, manufacturer, nominal_capacity, losses_ratio) + self._storage_type = storage_type self._volume = volume self._height = height self._layers = layers self._maximum_operating_temperature = maximum_operating_temperature + @property + def storage_type(self): + """ + Get storage type from ['thermal', 'sensible', 'latent'] + :return: string + """ + return self._storage_type + @property def volume(self): """ From 8763523d3b60566b26909ff237fc43c4bb62e27f Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 29 Aug 2023 12:50:49 -0400 Subject: [PATCH 34/38] added S to some lists, updated montreal_custom_catalog.py to new catalog classes and removed __future__ from those classes that didn't need it --- .../energy_systems/generation_system.py | 28 +--------- .../energy_systems/pv_generation_system.py | 1 - .../data_models/energy_systems/system.py | 52 +++++++++---------- .../energy_systems/montreal_custom_catalog.py | 38 +++++++++----- ...ontreal_custom_energy_system_parameters.py | 6 +-- tests/test_systems_factory.py | 4 +- 6 files changed, 59 insertions(+), 70 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/generation_system.py b/hub/catalog_factories/data_models/energy_systems/generation_system.py index afc7c5c4..c2fd9a75 100644 --- a/hub/catalog_factories/data_models/energy_systems/generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/generation_system.py @@ -6,7 +6,6 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca """ -from __future__ import annotations from typing import Union from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves @@ -23,7 +22,7 @@ class GenerationSystem: 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, storage, auxiliary_equipment): + cooling_efficiency_curve): self._system_id = system_id self._name = name self._model_name = model_name @@ -54,8 +53,6 @@ class GenerationSystem: self._cooling_output_curve = cooling_output_curve self._cooling_fuel_consumption_curve = cooling_fuel_consumption_curve self._cooling_efficiency_curve = cooling_efficiency_curve - self._storage = storage - self._auxiliary_equipment = auxiliary_equipment @property def id(self): @@ -297,27 +294,8 @@ class GenerationSystem: """ return self._cooling_efficiency_curve - @property - def storage(self): - """ - Get boolean storage exists - :return: bool - """ - return self._storage - - @property - def auxiliary_equipment(self) -> Union[None, GenerationSystem]: - """ - Get auxiliary_equipment - :return: GenerationSystem - """ - return self._auxiliary_equipment - def to_dictionary(self): """Class content to dictionary""" - _auxiliary_equipment = [] - if self.auxiliary_equipment is not None: - _auxiliary_equipment = self.auxiliary_equipment.to_dictionary() content = {'Energy Generation component': { 'id': self.id, 'name': self.name, @@ -348,9 +326,7 @@ class GenerationSystem: 'heat efficiency curve': self.heat_efficiency_curve, 'cooling output curve': self.cooling_output_curve, 'cooling fuel consumption curve': self.cooling_fuel_consumption_curve, - 'cooling efficiency curve': self.cooling_efficiency_curve, - 'it has storage': self.storage, - 'auxiliary equipment': _auxiliary_equipment + 'cooling efficiency curve': self.cooling_efficiency_curve } } return content diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index 1cbe69e5..ecadcdb8 100644 --- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -6,7 +6,6 @@ Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ -from __future__ import annotations from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index 9dd0ab83..7acb930b 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -25,15 +25,15 @@ class System: name, demand_types, generation_systems, - distribution_system, - emission_system, + distribution_systems, + emission_systems, energy_storage_systems): self._lod = lod self._system_id = system_id self._name = name self._demand_types = demand_types - self._distribution_system = distribution_system - self._emission_system = emission_system + self._distribution_systems = distribution_systems + self._emission_systems = emission_systems self._generation_systems = generation_systems self._energy_storage_systems = energy_storage_systems # self._configuration = configuration @@ -73,32 +73,32 @@ class System: @property def generation_systems(self) -> List[GenerationSystem]: """ - Get generation system - :return: GenerationSystem + Get generation systems + :return: [GenerationSystem] """ return self._generation_systems @property - def distribution_system(self) -> Union[None, List[DistributionSystem]]: + def distribution_systems(self) -> Union[None, List[DistributionSystem]]: """ - Get distribution system - :return: DistributionSystem + Get distribution systems + :return: [DistributionSystem] """ - return self._distribution_system + return self._distribution_systems @property - def emission_system(self) -> Union[None, List[EmissionSystem]]: + def emission_systems(self) -> Union[None, List[EmissionSystem]]: """ - Get emission system - :return: EmissionSystem + Get emission systems + :return: [EmissionSystem] """ - return self._emission_system + return self._emission_systems @property - def energy_storage_system(self) -> Union[None, List[EnergyStorageSystem]]: + def energy_storage_systems(self) -> Union[None, List[EnergyStorageSystem]]: """ - Get energy storage system - :return: EnergyStorageSystem + Get energy storage systems + :return: [EnergyStorageSystem] """ return self._energy_storage_systems @@ -107,21 +107,21 @@ class System: _generation_systems = [] for _generation in self.generation_systems: _generation_systems.append(_generation.to_dictionary()) - _distribution_system = [_distribution.to_dictionary() for _distribution in - self.distribution_system] if self.distribution_system is not None else None - _emission_system = [_emission.to_dictionary() for _emission in - self.emission_system] if self.emission_system is not None else None - _storage_system = [_storage.to_dictionary() for _storage in - self.energy_storage_system] if self.energy_storage_system is not None else None + _distribution_systems = [_distribution.to_dictionary() for _distribution in + self.distribution_systems] if self.distribution_systems is not None else None + _emission_systems = [_emission.to_dictionary() for _emission in + self.emission_systems] if self.emission_systems is not None else None + _storage_systems = [_storage.to_dictionary() for _storage in + self.energy_storage_systems] if self.energy_storage_systems is not None else None 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(s)': _distribution_system, - 'emission system(s)': _emission_system, - 'energy storage system(s)': _storage_system, + 'distribution system(s)': _distribution_systems, + 'emission system(s)': _emission_systems, + 'energy storage system(s)': _storage_systems, } } 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 39707c0b..a9696c21 100644 --- a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py +++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py @@ -14,6 +14,8 @@ from hub.catalog_factories.data_models.energy_systems.generation_system import G 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.archetype import Archetype +from hub.catalog_factories.data_models.energy_systems.thermal_storage_system import ThermalStorageSystem +from hub.catalog_factories.data_models.energy_systems.electrical_storage_system import ElectricalStorageSystem class MontrealCustomCatalog(Catalog): @@ -29,7 +31,8 @@ class MontrealCustomCatalog(Catalog): self._lod = float(self._archetypes['catalog']['@lod']) - self._catalog_generation_equipments = self._load_generation_equipments() + self._catalog_generation_equipments, self._catalog_storage_equipments = \ + self._load_generation_and_storage_equipments() self._catalog_distribution_equipments = self._load_distribution_equipments() self._catalog_emission_equipments = self._load_emission_equipments() self._catalog_systems = self._load_systems() @@ -40,10 +43,11 @@ class MontrealCustomCatalog(Catalog): self._catalog_generation_equipments, self._catalog_distribution_equipments, self._catalog_emission_equipments, - storages=None) + None) - def _load_generation_equipments(self): + def _load_generation_and_storage_equipments(self): _equipments = [] + _storages = [] equipments = self._archetypes['catalog']['generation_equipments']['equipment'] for equipment in equipments: equipment_id = float(equipment['@id']) @@ -59,7 +63,6 @@ class MontrealCustomCatalog(Catalog): 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, None, @@ -89,12 +92,19 @@ class MontrealCustomCatalog(Catalog): None, None, None, - None, - storage, None) - _equipments.append(generation_system) - return _equipments + storage = literal_eval(equipment['storage'].capitalize()) + if storage: + if equipment_type == 'electricity generator': + storage_system = ElectricalStorageSystem(equipment_id, None, None, None, 'electrical', None, None, None, None, + None, None, None) + else: + storage_system = ThermalStorageSystem(equipment_id, None, None, None, 'thermal', None, None, None, None, None, + None) + _storages.append(storage_system) + + return _equipments, _storages def _load_distribution_equipments(self): _equipments = [] @@ -156,6 +166,10 @@ class MontrealCustomCatalog(Catalog): for equipment_archetype in self._catalog_generation_equipments: if int(equipment_archetype.id) == int(generation_equipment): _generation_equipment = equipment_archetype + _storage_equipment = None + for equipment_archetype in self._catalog_storage_equipments: + if int(equipment_archetype.id) == int(generation_equipment): + _storage_equipment = equipment_archetype distribution_equipment = system['equipments']['distribution_id'] _distribution_equipment = None for equipment_archetype in self._catalog_distribution_equipments: @@ -171,10 +185,10 @@ class MontrealCustomCatalog(Catalog): system_id, name, demands, - _generation_equipment, - _distribution_equipment, - _emission_equipment, - energy_storage_systems=None)) + [_generation_equipment], + [_distribution_equipment], + [_emission_equipment], + [_storage_equipment])) return _catalog_systems def _load_archetypes(self): diff --git a/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py b/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py index 3982221b..49f7086f 100644 --- a/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py +++ b/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py @@ -104,7 +104,7 @@ class MontrealCustomEnergySystemParameters: energy_system.generation_system = _generation_system _distribution_system = GenericDistributionSystem() - archetype_distribution_equipment = system.distribution_system + archetype_distribution_equipment = system.distribution_systems _distribution_system.type = archetype_distribution_equipment.type _distribution_system.supply_temperature = archetype_distribution_equipment.supply_temperature _distribution_system.distribution_consumption_fix_flow = \ @@ -139,10 +139,10 @@ class MontrealCustomEnergySystemParameters: _building_distribution_system = DistributionSystem() _building_distribution_system.generic_distribution_system = \ - copy.deepcopy(_generic_building_energy_system.distribution_system) + copy.deepcopy(_generic_building_energy_system.distribution_systems) _building_emission_system = EmissionSystem() _building_emission_system.generic_emission_system = \ - copy.deepcopy(_generic_building_energy_system.emission_system) + copy.deepcopy(_generic_building_energy_system.emission_systems) _building_generation_system = GenerationSystem() _building_generation_system.generic_generation_system = \ copy.deepcopy(_generic_building_energy_system.generation_system) diff --git a/tests/test_systems_factory.py b/tests/test_systems_factory.py index 8d191043..9044ad18 100644 --- a/tests/test_systems_factory.py +++ b/tests/test_systems_factory.py @@ -90,11 +90,11 @@ class TestSystemsFactory(TestCase): _building_distribution_system = DistributionSystem() _building_distribution_system.generic_distribution_system = ( - copy.deepcopy(_generic_building_energy_system.distribution_system) + copy.deepcopy(_generic_building_energy_system.distribution_systems) ) _building_emission_system = EmissionSystem() _building_emission_system.generic_emission_system = ( - copy.deepcopy(_generic_building_energy_system.emission_system) + copy.deepcopy(_generic_building_energy_system.emission_systems) ) _building_generation_system = GenerationSystem() _building_generation_system.generic_generation_system = ( From b7c2bbae96f82ebf9d3e71924b9d3259fac1cfe1 Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 29 Aug 2023 13:02:28 -0400 Subject: [PATCH 35/38] removed last two values in generationSystems as they are not used anymore --- .../energy_systems/pv_generation_system.py | 2 +- .../north_america_energy_system_catalog.py | 12 ++++-------- tests/test_systems_catalog.py | 7 ++++--- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index ecadcdb8..e1ee8226 100644 --- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -33,7 +33,7 @@ class PvGenerationSystem(GenerationSystem): minimum_cooling_supply_temperature=None, heat_output_curve=None, heat_fuel_consumption_curve=None, heat_efficiency_curve=None, cooling_output_curve=None, cooling_fuel_consumption_curve=None, - cooling_efficiency_curve=None, storage=None, auxiliary_equipment=None) + cooling_efficiency_curve=None) self._nominal_ambient_temperature = nominal_ambient_temperature self._nominal_cell_temperature = nominal_cell_temperature self._nominal_radiation = nominal_radiation 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 a1e4798e..206fd4a8 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 @@ -86,8 +86,6 @@ class NorthAmericaEnergySystemCatalog(Catalog): None, None, None, - None, - None, None) generation_components.append(boiler_component) for heat_pump in heat_pumps: @@ -142,8 +140,6 @@ class NorthAmericaEnergySystemCatalog(Catalog): cop_curve, None, None, - None, - None, None) generation_components.append(heat_pump_component) for pv in photovoltaics: @@ -215,8 +211,6 @@ class NorthAmericaEnergySystemCatalog(Catalog): None, None, None, - None, - None, None) generation_components.append(boiler_template) elif "Heat Pump" in system_name: @@ -254,8 +248,6 @@ class NorthAmericaEnergySystemCatalog(Catalog): None, None, None, - None, - None, None) generation_components.append(heat_pump_template) else: @@ -309,6 +301,8 @@ class NorthAmericaEnergySystemCatalog(Catalog): model_name, manufacturer, storage_type, + None, + None, volume, height, layers, @@ -338,6 +332,8 @@ class NorthAmericaEnergySystemCatalog(Catalog): None, storage_type, None, + None, + None, height, layers, maximum_temperature) diff --git a/tests/test_systems_catalog.py b/tests/test_systems_catalog.py index a0720708..862ea874 100644 --- a/tests/test_systems_catalog.py +++ b/tests/test_systems_catalog.py @@ -13,6 +13,7 @@ class TestSystemsCatalog(TestCase): def test_montreal_custom_catalog(self): catalog = EnergySystemsCatalogFactory('montreal_custom').catalog + catalog_categories = catalog.names() archetypes = catalog.names('archetypes') self.assertEqual(23, len(archetypes['archetypes'])) @@ -32,13 +33,13 @@ class TestSystemsCatalog(TestCase): for value in catalog_categories[category]: catalog.get_entry(value) + print(catalog.entries()) + with self.assertRaises(IndexError): catalog.get_entry('unknown') def test_north_america_systems_catalog(self): catalog = EnergySystemsCatalogFactory('north_america').catalog + print(catalog.entries()) - - # def test_montreal_catalog(self): - # catalog = EnergySystemsCatalogFactory('montreal_custom').catalog From a5f70f472037d530b165f0942d909d7137f57d3a Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 29 Aug 2023 13:12:56 -0400 Subject: [PATCH 36/38] erased forgotten not needed print --- .../energy_systems/north_america_energy_system_catalog.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 206fd4a8..b5702215 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 @@ -38,7 +38,7 @@ class NorthAmericaEnergySystemCatalog(Catalog): None, None, self._storage_components) - print(self._content) + def _load_generation_components(self): generation_components = [] boilers = self._archetypes['EnergySystemCatalog']['energy_generation_components']['boilers'] From 56c84ad39988c8cb2a6c230bcbaee0b6bc3046fa Mon Sep 17 00:00:00 2001 From: p_monsalvete Date: Tue, 29 Aug 2023 13:29:51 -0400 Subject: [PATCH 37/38] solved bugs in adapting montreal_custom_catalog.py to new catalog data --- .../data_models/energy_systems/content.py | 7 ++++++ .../data_models/energy_systems/system.py | 5 ++-- .../energy_systems/thermal_storage_system.py | 8 ++++--- .../energy_systems/montreal_custom_catalog.py | 24 +++++++++---------- 4 files changed, 27 insertions(+), 17 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/content.py b/hub/catalog_factories/data_models/energy_systems/content.py index f6a03ea0..d3fd9068 100644 --- a/hub/catalog_factories/data_models/energy_systems/content.py +++ b/hub/catalog_factories/data_models/energy_systems/content.py @@ -69,4 +69,11 @@ class Content: return content + def __str__(self): + """Print content""" + _archetypes = [] + for _archetype in self.archetypes: + _archetypes.append(_archetype.to_dictionary()) + content = {'Archetypes': _archetypes} + return str(content) diff --git a/hub/catalog_factories/data_models/energy_systems/system.py b/hub/catalog_factories/data_models/energy_systems/system.py index 7acb930b..30ee9292 100644 --- a/hub/catalog_factories/data_models/energy_systems/system.py +++ b/hub/catalog_factories/data_models/energy_systems/system.py @@ -9,7 +9,8 @@ Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca from typing import Union, List from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem -from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem +from hub.catalog_factories.data_models.energy_systems.thermal_storage_system import ThermalStorageSystem +from hub.catalog_factories.data_models.energy_systems.electrical_storage_system import ElectricalStorageSystem from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem @@ -95,7 +96,7 @@ class System: return self._emission_systems @property - def energy_storage_systems(self) -> Union[None, List[EnergyStorageSystem]]: + def energy_storage_systems(self) -> Union[None, List[ThermalStorageSystem], List[ElectricalStorageSystem]]: """ Get energy storage systems :return: [EnergyStorageSystem] diff --git a/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py b/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py index 679669a4..71b4f931 100644 --- a/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py +++ b/hub/catalog_factories/data_models/energy_systems/thermal_storage_system.py @@ -67,9 +67,11 @@ class ThermalStorageSystem(EnergyStorageSystem): def to_dictionary(self): """Class content to dictionary""" - _layers = [] - for _layer in self.layers: - _layers.append(_layer.to_dictionary()) + _layers = None + if self.layers is not None: + _layers = [] + for _layer in self.layers: + _layers.append(_layer.to_dictionary()) content = {'Storage component': { 'storage id': self.id, 'name': self.name, diff --git a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py index a9696c21..b2df20c2 100644 --- a/hub/catalog_factories/energy_systems/montreal_custom_catalog.py +++ b/hub/catalog_factories/energy_systems/montreal_custom_catalog.py @@ -162,33 +162,33 @@ class MontrealCustomCatalog(Catalog): name = system['name'] demands = system['demands']['demand'] generation_equipment = system['equipments']['generation_id'] - _generation_equipment = None + _generation_equipments = None for equipment_archetype in self._catalog_generation_equipments: if int(equipment_archetype.id) == int(generation_equipment): - _generation_equipment = equipment_archetype - _storage_equipment = None + _generation_equipments = [equipment_archetype] + _storage_equipments = None for equipment_archetype in self._catalog_storage_equipments: if int(equipment_archetype.id) == int(generation_equipment): - _storage_equipment = equipment_archetype + _storage_equipments = [equipment_archetype] distribution_equipment = system['equipments']['distribution_id'] - _distribution_equipment = None + _distribution_equipments = None for equipment_archetype in self._catalog_distribution_equipments: if int(equipment_archetype.id) == int(distribution_equipment): - _distribution_equipment = equipment_archetype + _distribution_equipments = [equipment_archetype] emission_equipment = system['equipments']['dissipation_id'] - _emission_equipment = None + _emission_equipments = None for equipment_archetype in self._catalog_emission_equipments: if int(equipment_archetype.id) == int(emission_equipment): - _emission_equipment = equipment_archetype + _emission_equipments = [equipment_archetype] _catalog_systems.append(System(self._lod, system_id, name, demands, - [_generation_equipment], - [_distribution_equipment], - [_emission_equipment], - [_storage_equipment])) + _generation_equipments, + _distribution_equipments, + _emission_equipments, + _storage_equipments)) return _catalog_systems def _load_archetypes(self): From c072527dc6aae5885412203a4b0fc5b97ca0a98a Mon Sep 17 00:00:00 2001 From: Saeed Ranjbar Date: Tue, 29 Aug 2023 14:03:30 -0400 Subject: [PATCH 38/38] small changes to pv_generation_system.py --- .../energy_systems/pv_generation_system.py | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py index e1ee8226..ce0e71f1 100644 --- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py +++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py @@ -18,22 +18,22 @@ class PvGenerationSystem(GenerationSystem): nominal_electricity_output, nominal_ambient_temperature, nominal_cell_temperature, nominal_radiation, standard_test_condition_cell_temperature, standard_test_condition_maximum_power, cell_temperature_coefficient, width, height): - super(PvGenerationSystem, self).__init__(system_id=system_id, name=name, model_name=model_name, - manufacturer=manufacturer, system_type='pv', fuel_type='renewable', - nominal_thermal_output=None, maximum_heat_output=None, - minimum_heat_output=None, source_medium=None, - supply_medium=None, heat_efficiency=None, nominal_cooling_output=None, - maximum_cooling_output=None, minimum_cooling_output=None, - cooling_efficiency=None, electricity_efficiency=electricity_efficiency, - source_temperature=None, source_mass_flow=None, - nominal_electricity_output=nominal_electricity_output, - maximum_heat_supply_temperature=None, - minimum_heat_supply_temperature=None, - maximum_cooling_supply_temperature=None, - minimum_cooling_supply_temperature=None, heat_output_curve=None, - heat_fuel_consumption_curve=None, heat_efficiency_curve=None, - cooling_output_curve=None, cooling_fuel_consumption_curve=None, - cooling_efficiency_curve=None) + super().__init__(system_id=system_id, name=name, model_name=model_name, + manufacturer=manufacturer, system_type='pv', fuel_type='renewable', + nominal_thermal_output=None, maximum_heat_output=None, + minimum_heat_output=None, source_medium=None, + supply_medium=None, heat_efficiency=None, nominal_cooling_output=None, + maximum_cooling_output=None, minimum_cooling_output=None, + cooling_efficiency=None, electricity_efficiency=electricity_efficiency, + source_temperature=None, source_mass_flow=None, + nominal_electricity_output=nominal_electricity_output, + maximum_heat_supply_temperature=None, + minimum_heat_supply_temperature=None, + maximum_cooling_supply_temperature=None, + minimum_cooling_supply_temperature=None, heat_output_curve=None, + heat_fuel_consumption_curve=None, heat_efficiency_curve=None, + cooling_output_curve=None, cooling_fuel_consumption_curve=None, + cooling_efficiency_curve=None) self._nominal_ambient_temperature = nominal_ambient_temperature self._nominal_cell_temperature = nominal_cell_temperature self._nominal_radiation = nominal_radiation