energy systems importer finished

energy systems workflow defined in the unittest
This commit is contained in:
Pilar Monsalvete 2023-05-15 11:03:54 -04:00
parent ffae3f3a04
commit d8386d179d
13 changed files with 495 additions and 142 deletions

View File

@ -19,7 +19,7 @@ from hub.city_model_structure.city_object import CityObject
from hub.city_model_structure.building_demand.household import Household from hub.city_model_structure.building_demand.household import Household
from hub.city_model_structure.building_demand.internal_zone import InternalZone from hub.city_model_structure.building_demand.internal_zone import InternalZone
from hub.city_model_structure.attributes.polyhedron import Polyhedron from hub.city_model_structure.attributes.polyhedron import Polyhedron
from hub.city_model_structure.energy_systems.generic_energy_system import GenericEnergySystem from hub.city_model_structure.energy_systems.energy_system import EnergySystem
class Building(CityObject): class Building(CityObject):
@ -371,8 +371,6 @@ class Building(CityObject):
:return: dict{DataFrame(float)} :return: dict{DataFrame(float)}
""" """
results = {} results = {}
# todo: needed??
monthly_values = None
if cte.HOUR in self.heating: if cte.HOUR in self.heating:
monthly_values = PeakLoads().\ monthly_values = PeakLoads().\
peak_loads_from_hourly(self.heating[cte.HOUR][next(iter(self.heating[cte.HOUR]))].values) peak_loads_from_hourly(self.heating[cte.HOUR][next(iter(self.heating[cte.HOUR]))].values)
@ -501,10 +499,10 @@ class Building(CityObject):
return _usage.rstrip() return _usage.rstrip()
@property @property
def energy_systems(self) -> Union[None, List[GenericEnergySystem]]: def energy_systems(self) -> Union[None, List[EnergySystem]]:
""" """
Get list of energy systems installed to cover the building demands Get list of energy systems installed to cover the building demands
:return: [GenericEnergySystem] :return: [EnergySystem]
""" """
return self._energy_systems return self._energy_systems
@ -512,7 +510,7 @@ class Building(CityObject):
def energy_systems(self, value): def energy_systems(self, value):
""" """
Set list of energy systems installed to cover the building demands Set list of energy systems installed to cover the building demands
:param value: [GenericEnergySystem] :param value: [EnergySystem]
""" """
self._energy_systems = value self._energy_systems = value
@ -538,11 +536,12 @@ class Building(CityObject):
Get energy consumption for heating according to the heating system installed Get energy consumption for heating according to the heating system installed
return: dict return: dict
""" """
for heating_demand_key in self.heating: if len(self._heating_consumption) == 0:
demand = self.heating[heating_demand_key][cte.INSEL_MEB] for heating_demand_key in self.heating:
consumption_type = cte.HEATING demand = self.heating[heating_demand_key][cte.INSEL_MEB]
final_energy_consumed = self._calculate_consumption(consumption_type, demand) consumption_type = cte.HEATING
self._heating_consumption[heating_demand_key] = final_energy_consumed final_energy_consumed = self._calculate_consumption(consumption_type, demand)
self._heating_consumption[heating_demand_key] = final_energy_consumed
return self._heating_consumption return self._heating_consumption
@property @property
@ -551,11 +550,12 @@ class Building(CityObject):
Get energy consumption for cooling according to the cooling system installed Get energy consumption for cooling according to the cooling system installed
return: dict return: dict
""" """
for cooling_demand_key in self.cooling: if len(self._cooling_consumption) == 0:
demand = self.cooling[cooling_demand_key][cte.INSEL_MEB] for cooling_demand_key in self.cooling:
consumption_type = cte.COOLING demand = self.cooling[cooling_demand_key][cte.INSEL_MEB]
final_energy_consumed = self._calculate_consumption(consumption_type, demand) consumption_type = cte.COOLING
self._cooling_consumption[cooling_demand_key] = final_energy_consumed final_energy_consumed = self._calculate_consumption(consumption_type, demand)
self._cooling_consumption[cooling_demand_key] = final_energy_consumed
return self._cooling_consumption return self._cooling_consumption
@property @property
@ -564,11 +564,12 @@ class Building(CityObject):
Get energy consumption for domestic according to the domestic hot water system installed Get energy consumption for domestic according to the domestic hot water system installed
return: dict return: dict
""" """
for domestic_hot_water_demand_key in self.domestic_hot_water_heat_demand: if len(self._domestic_hot_water_consumption) == 0:
demand = self.domestic_hot_water_heat_demand[domestic_hot_water_demand_key][cte.INSEL_MEB] for domestic_hot_water_demand_key in self.domestic_hot_water_heat_demand:
consumption_type = cte.DOMESTIC_HOT_WATER demand = self.domestic_hot_water_heat_demand[domestic_hot_water_demand_key][cte.INSEL_MEB]
final_energy_consumed = self._calculate_consumption(consumption_type, demand) consumption_type = cte.DOMESTIC_HOT_WATER
self._domestic_hot_water_consumption[domestic_hot_water_demand_key] = final_energy_consumed final_energy_consumed = self._calculate_consumption(consumption_type, demand)
self._domestic_hot_water_consumption[domestic_hot_water_demand_key] = final_energy_consumed
return self._domestic_hot_water_consumption return self._domestic_hot_water_consumption
def _calculate_consumption(self, consumption_type, demand): def _calculate_consumption(self, consumption_type, demand):
@ -578,15 +579,17 @@ class Building(CityObject):
for demand_type in energy_system.demand_types: for demand_type in energy_system.demand_types:
if demand_type.lower() == consumption_type.lower(): if demand_type.lower() == consumption_type.lower():
if consumption_type == cte.HEATING or consumption_type == cte.DOMESTIC_HOT_WATER: if consumption_type == cte.HEATING or consumption_type == cte.DOMESTIC_HOT_WATER:
coefficient_of_performance = energy_system.generation_system.heat_efficiency coefficient_of_performance = energy_system.generation_system.generic_generation_system.heat_efficiency
elif consumption_type == cte.COOLING: elif consumption_type == cte.COOLING:
coefficient_of_performance = energy_system.generation_system.cooling_efficiency coefficient_of_performance = energy_system.generation_system.generic_generation_system.cooling_efficiency
elif consumption_type == cte.ELECTRICITY: elif consumption_type == cte.ELECTRICITY:
coefficient_of_performance = energy_system.generation_system.electricity_efficiency coefficient_of_performance = \
final_energy_consumed = [] energy_system.generation_system.generic_generation_system.electricity_efficiency
if coefficient_of_performance == 0: if coefficient_of_performance == 0:
final_energy_consumed.append(0) values = [0]*len(demand)
final_energy_consumed = values
else: else:
final_energy_consumed = []
for demand_value in demand: for demand_value in demand:
final_energy_consumed.append(demand_value / coefficient_of_performance) final_energy_consumed.append(demand_value / coefficient_of_performance)
return final_energy_consumed return final_energy_consumed
@ -599,8 +602,8 @@ class Building(CityObject):
""" """
# Add other systems whenever new ones appear # Add other systems whenever new ones appear
for energy_system in self.energy_systems: for energy_system in self.energy_systems:
if energy_system.generation_system.type == cte.PHOTOVOLTAIC: if energy_system.generation_system.generic_generation_system.type == cte.PHOTOVOLTAIC:
_efficiency = energy_system.generation_system.electricity_efficiency _efficiency = energy_system.generation_system.generic_generation_system.electricity_efficiency
self._onsite_electrical_production = {} self._onsite_electrical_production = {}
for _key in self.roofs[0].global_irradiance.keys(): for _key in self.roofs[0].global_irradiance.keys():
_results = [0 for _ in range(0, len(self.roofs[0].global_irradiance[_key]))] _results = [0 for _ in range(0, len(self.roofs[0].global_irradiance[_key]))]

View File

@ -16,6 +16,7 @@ import pyproj
from typing import List, Union from typing import List, Union
from pyproj import Transformer from pyproj import Transformer
from pathlib import Path from pathlib import Path
from pandas import DataFrame
from hub.city_model_structure.building import Building from hub.city_model_structure.building import Building
from hub.city_model_structure.city_object import CityObject from hub.city_model_structure.city_object import CityObject
from hub.city_model_structure.city_objects_cluster import CityObjectsCluster from hub.city_model_structure.city_objects_cluster import CityObjectsCluster
@ -61,6 +62,8 @@ class City:
self._lca_materials = None self._lca_materials = None
self._level_of_detail = LevelOfDetail() self._level_of_detail = LevelOfDetail()
self._city_objects_dictionary = {} self._city_objects_dictionary = {}
self._energy_systems_connection_table = None
self._generic_energy_systems = None
@property @property
def fuels(self) -> [Fuel]: def fuels(self) -> [Fuel]:
@ -490,4 +493,36 @@ class City:
""" """
return self._level_of_detail return self._level_of_detail
@property
def energy_systems_connection_table(self) -> Union[None, DataFrame]:
"""
Get energy systems connection table which includes at least two columns: energy_system_type and associated_building
and may also include dimensioned_energy_system and connection_building_to_dimensioned_energy_system
:return: DataFrame
"""
return self._energy_systems_connection_table
@energy_systems_connection_table.setter
def energy_systems_connection_table(self, value):
"""
Set energy systems connection table which includes at least two columns: energy_system_type and associated_building
and may also include dimensioned_energy_system and connection_building_to_dimensioned_energy_system
:param value: DataFrame
"""
self._energy_systems_connection_table = value
@property
def generic_energy_systems(self) -> dict:
"""
Get dictionary with generic energy systems installed in the city
:return: dict
"""
return self._generic_energy_systems
@generic_energy_systems.setter
def generic_energy_systems(self, value):
"""
Set dictionary with generic energy systems installed in the city
:return: dict
"""
self._generic_energy_systems = value

View File

@ -0,0 +1,30 @@
"""
Energy control system definition
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 ControlSystem:
"""
ControlSystem class
"""
def __init__(self):
self._control_type = None
@property
def type(self):
"""
Get control type
:return: string
"""
return self._control_type
@type.setter
def type(self, value):
"""
Set control type
:param value: string
"""
self._control_type = value

View File

@ -0,0 +1,32 @@
"""
Energy distribution system definition
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 hub.city_model_structure.energy_systems.generic_distribution_system import GenericDistributionSystem
class DistributionSystem:
"""
DistributionSystem class
"""
def __init__(self):
self._generic_distribution_system = None
@property
def generic_distribution_system(self) -> GenericDistributionSystem:
"""
Get generic_distribution_system
:return: GenericDistributionSystem
"""
return self._generic_distribution_system
@generic_distribution_system.setter
def generic_distribution_system(self, value):
"""
Set associated generic_distribution_system
:param value: GenericDistributionSystem
"""
self._generic_distribution_system = value

View File

@ -0,0 +1,32 @@
"""
Energy emission system definition
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 hub.city_model_structure.energy_systems.generic_emission_system import GenericEmissionSystem
class EmissionSystem:
"""
EmissionSystem class
"""
def __init__(self):
self._generic_emission_system = None
@property
def generic_emission_system(self) -> GenericEmissionSystem:
"""
Get associated generic_emission_system
:return: GenericEmissionSystem
"""
return self._generic_emission_system
@generic_emission_system.setter
def generic_emission_system(self, value):
"""
Set associated
:param value: GenericEmissionSystem
"""
self._generic_emission_system = value

View File

@ -0,0 +1,124 @@
"""
Energy system definition
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 typing import Union, List
from hub.city_model_structure.energy_systems.generic_energy_system import GenericEnergySystem
from hub.city_model_structure.energy_systems.generation_system import GenerationSystem
from hub.city_model_structure.energy_systems.distribution_system import DistributionSystem
from hub.city_model_structure.energy_systems.emission_system import EmissionSystem
from hub.city_model_structure.energy_systems.control_system import ControlSystem
from hub.city_model_structure.city_object import CityObject
class EnergySystem:
"""
EnergySystem class
"""
def __init__(self):
self._generic_energy_system = None
self._generation_system = None
self._distribution_system = None
self._emission_system = None
self._connected_city_objects = None
self._control_system = None
@property
def generic_energy_system(self) -> GenericEnergySystem:
"""
Get associated generic_energy_system
:return: GenericEnergySystem
"""
return self._generic_energy_system
@generic_energy_system.setter
def generic_energy_system(self, value):
"""
Set associated generic_energy_system
:param value: GenericEnergySystem
"""
self._generic_energy_system = value
@property
def generation_system(self) -> GenerationSystem:
"""
Get generation system
:return: GenerationSystem
"""
return self._generation_system
@generation_system.setter
def generation_system(self, value):
"""
Set generation system
:param value: GenerationSystem
"""
self._generation_system = value
@property
def distribution_system(self) -> Union[None, DistributionSystem]:
"""
Get distribution system
:return: DistributionSystem
"""
return self._distribution_system
@distribution_system.setter
def distribution_system(self, value):
"""
Set distribution system
:param value: DistributionSystem
"""
self._distribution_system = value
@property
def emission_system(self) -> Union[None, EmissionSystem]:
"""
Get emission system
:return: EmissionSystem
"""
return self._emission_system
@emission_system.setter
def emission_system(self, value):
"""
Set emission system
:param value: EmissionSystem
"""
self._emission_system = value
@property
def connected_city_objects(self) -> Union[None, List[CityObject]]:
"""
Get list of city objects that are connected to this energy system
:return: List[CityObject]
"""
return self._connected_city_objects
@connected_city_objects.setter
def connected_city_objects(self, value):
"""
Set list of city objects that are connected to this energy system
:param value: List[CityObject]
"""
self._connected_city_objects = value
@property
def control_system(self) -> Union[None, ControlSystem]:
"""
Get control system of the energy system
:return: ControlSystem
"""
return self._control_system
@control_system.setter
def control_system(self, value):
"""
Set control system of the energy system
:param value: ControlSystem
"""
self._control_system = value

View File

@ -0,0 +1,120 @@
"""
Energy generation system definition
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
from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem
class GenerationSystem:
"""
GenerationSystem class
"""
def __init__(self):
self._heat_power = None
self._cooling_power = None
self._electricity_power = None
self._storage_capacity = None
self._generic_generation_system = None
self._auxiliary_equipment = None
@property
def generic_generation_system(self) -> GenericGenerationSystem:
"""
Get associated generic_generation_system
:return: GenericGenerationSystem
"""
return self._generic_generation_system
@generic_generation_system.setter
def generic_generation_system(self, value):
"""
Set associated generic_generation_system
:param value: GenericGenerationSystem
"""
self._generic_generation_system = value
@property
def heat_power(self):
"""
Get heat_power in W
:return: float
"""
return self._heat_power
@heat_power.setter
def heat_power(self, value):
"""
Set heat_power in W
:param value: float
"""
self._heat_power = value
@property
def cooling_power(self):
"""
Get cooling_power in W
:return: float
"""
return self._cooling_power
@cooling_power.setter
def cooling_power(self, value):
"""
Set cooling_power in W
:param value: float
"""
self._cooling_power = value
@property
def electricity_power(self):
"""
Get electricity_power in W
:return: float
"""
return self._electricity_power
@electricity_power.setter
def electricity_power(self, value):
"""
Set electricity_power in W
:param value: float
"""
self._electricity_power = value
@property
def storage_capacity(self):
"""
Get storage_capacity in J
:return: float
"""
return self._storage_capacity
@storage_capacity.setter
def storage_capacity(self, value):
"""
Set storage_capacity in J
:param value: float
"""
self._storage_capacity = value
@property
def auxiliary_equipment(self) -> Union[None, GenerationSystem]:
"""
Get auxiliary_equipment
:return: GenerationSystem
"""
return self._auxiliary_equipment
@auxiliary_equipment.setter
def auxiliary_equipment(self, value):
"""
Set auxiliary_equipment
:param value: GenerationSystem
"""
self._auxiliary_equipment = value

View File

@ -18,12 +18,29 @@ class GenericEnergySystem:
GenericEnergySystem class GenericEnergySystem class
""" """
def __init__(self): def __init__(self):
self._name = None
self._demand_types = None self._demand_types = None
self._generation_system = None self._generation_system = None
self._distribution_system = None self._distribution_system = None
self._emission_system = None self._emission_system = None
self._connected_city_objects = None self._connected_city_objects = None
@property
def name(self):
"""
Get energy system name
:return: str
"""
return self._name
@name.setter
def name(self, value):
"""
Set energy system name
:param value:
"""
self._name = value
@property @property
def demand_types(self): def demand_types(self):
""" """
@ -46,9 +63,16 @@ class GenericEnergySystem:
Get generation system Get generation system
:return: GenerationSystem :return: GenerationSystem
""" """
self._generation_system = GenericGenerationSystem(self.connected_city_objects)
return self._generation_system return self._generation_system
@generation_system.setter
def generation_system(self, value):
"""
Set generation system
:return: GenerationSystem
"""
self._generation_system = value
@property @property
def distribution_system(self) -> Union[None, GenericDistributionSystem]: def distribution_system(self) -> Union[None, GenericDistributionSystem]:
""" """
@ -80,19 +104,3 @@ class GenericEnergySystem:
:param value: EmissionSystem :param value: EmissionSystem
""" """
self._emission_system = value self._emission_system = value
@property
def connected_city_objects(self) -> Union[None, List[CityObject]]:
"""
Get list of city objects that are connected to this energy system
:return: List[CityObject]
"""
return self._connected_city_objects
@connected_city_objects.setter
def connected_city_objects(self, value):
"""
Set list of city objects that are connected to this energy system
:param value: List[CityObject]
"""
self._connected_city_objects = value

View File

@ -8,30 +8,22 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
from __future__ import annotations from __future__ import annotations
from typing import Union from typing import Union
import hub.helpers.constants as cte
class GenericGenerationSystem: class GenericGenerationSystem:
""" """
GenericGenerationSystem class GenericGenerationSystem class
""" """
def __init__(self, city_objects=None, heat_power=None, cooling_power=None, electricity_power=None): def __init__(self):
self._city_objects = city_objects
self._type = None self._type = None
self._fuel_type = None self._fuel_type = None
self._heat_power = heat_power
self._cooling_power = cooling_power
self._electricity_power = electricity_power
self._source_types = None self._source_types = None
self._heat_efficiency = None self._heat_efficiency = None
self._cooling_efficiency = None self._cooling_efficiency = None
self._electricity_efficiency = None self._electricity_efficiency = None
self._source_temperature = None self._source_temperature = None
self._source_mass_flow = None self._source_mass_flow = None
self._storage_capacity = None
self._storage = None self._storage = None
self._auxiliary_equipment = None self._auxiliary_equipment = None
self._peak_coverages = None
@property @property
def type(self): def type(self):
@ -81,52 +73,6 @@ class GenericGenerationSystem:
""" """
self._source_types = value self._source_types = value
@property
def heat_power(self):
"""
Get heat_power in W
:return: float
"""
if self._heat_power is None:
self._heat_power = 0
for city_object in self._city_objects:
if city_object.heating_peak_load is not None:
if self.peak_coverages[cte.HEATING] is None:
return None
self._heat_power += city_object.heating_peak_load[cte.YEAR][0] * self.peak_coverages[cte.HEATING]
return self._heat_power
@property
def cooling_power(self):
"""
Get cooling_power in W
:return: float
"""
if self._cooling_power is None:
self._cooling_power = 0
for city_object in self._city_objects:
if city_object.cooling_peak_load is not None:
if self.peak_coverages[cte.COOLING] is None:
return None
self._cooling_power += city_object.cooling_peak_load[cte.YEAR][0] * self.peak_coverages[cte.COOLING]
return self._cooling_power
@property
def electricity_power(self):
"""
Get electricity_power in W
:return: float
"""
if self._electricity_power is None:
self._electricity_power = 0
for city_object in self._city_objects:
if city_object.electricity_peak_load is not None:
if self.peak_coverages[cte.ELECTRICITY] is None:
return None
self._electricity_power += city_object.electricity_peak_load[cte.YEAR][0]\
* self.peak_coverages[cte.ELECTRICITY]
return self._electricity_power
@property @property
def heat_efficiency(self): def heat_efficiency(self):
""" """
@ -207,14 +153,6 @@ class GenericGenerationSystem:
""" """
self._source_mass_flow = value self._source_mass_flow = value
@property
def storage_capacity(self):
"""
Get storage_capacity in J
:return: float
"""
return self._storage_capacity
@property @property
def storage(self): def storage(self):
""" """
@ -239,18 +177,10 @@ class GenericGenerationSystem:
""" """
return self._auxiliary_equipment return self._auxiliary_equipment
@property @auxiliary_equipment.setter
def peak_coverages(self) -> dict: def auxiliary_equipment(self, value):
""" """
Get ratio of each energy type power peak covered by the system Set auxiliary_equipment
:return: dict {Heating: value, Cooling: value, Domestic Hot Water: value, Electricity: value} :return: GenerationSystem
""" """
return self._peak_coverages self._auxiliary_equipment = value
@peak_coverages.setter
def peak_coverages(self, value):
"""
Set ratio of each energy type power peak covered by the system
:param value: dict
"""
self._peak_coverages = value

View File

@ -6,10 +6,8 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Guille Gutierrez guillermo.gutierrezmorote@concordia.ca Code contributors: Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
""" """
import sys
import math import math
from hub.hub_logger import logger
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.helpers.peak_calculation.loads_calculation import LoadsCalculation from hub.helpers.peak_calculation.loads_calculation import LoadsCalculation
@ -61,7 +59,7 @@ class PeakLoads:
@property @property
def heating_peak_loads_from_methodology(self): def heating_peak_loads_from_methodology(self):
if self._can_be_calculated(): if not self._can_be_calculated():
return None return None
monthly_heating_loads = [] monthly_heating_loads = []
ambient_temperature = self._building.external_temperature[cte.HOUR]['epw'] ambient_temperature = self._building.external_temperature[cte.HOUR]['epw']
@ -88,7 +86,7 @@ class PeakLoads:
@property @property
def cooling_peak_loads_from_methodology(self): def cooling_peak_loads_from_methodology(self):
if self._can_be_calculated(): if not self._can_be_calculated():
return None return None
monthly_cooling_loads = [] monthly_cooling_loads = []
ambient_temperature = self._building.external_temperature[cte.HOUR]['epw'] ambient_temperature = self._building.external_temperature[cte.HOUR]['epw']

View File

@ -1,7 +1,6 @@
import logging as logger import logging as logger
from pathlib import Path from pathlib import Path
import os import os
import logging
import sys import sys
@ -27,7 +26,6 @@ def get_logger(file_logger=False):
except IOError as err: except IOError as err:
print(f'I/O exception: {err}') print(f'I/O exception: {err}')
else: else:
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout)) logger.getLogger().addHandler(logger.StreamHandler(stream=sys.stdout))
logging.getLogger().setLevel(logging.DEBUG) logger.getLogger().setLevel(logger.DEBUG)
return logger.getLogger() return logger.getLogger()

View File

@ -6,6 +6,7 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
import sys import sys
from pandas import DataFrame
from hub.hub_logger import logger from hub.hub_logger import logger
from hub.catalog_factories.energy_systems_catalog_factory import EnergySystemsCatalogFactory from hub.catalog_factories.energy_systems_catalog_factory import EnergySystemsCatalogFactory
@ -13,7 +14,6 @@ from hub.city_model_structure.energy_systems.generic_energy_system import Generi
from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem
from hub.city_model_structure.energy_systems.generic_distribution_system import GenericDistributionSystem from hub.city_model_structure.energy_systems.generic_distribution_system import GenericDistributionSystem
from hub.helpers.dictionaries import Dictionaries from hub.helpers.dictionaries import Dictionaries
import hub.helpers.constants as cte
class MontrealCustomEnergySystemParameters: class MontrealCustomEnergySystemParameters:
@ -31,25 +31,34 @@ class MontrealCustomEnergySystemParameters:
""" """
city = self._city city = self._city
montreal_custom_catalog = EnergySystemsCatalogFactory('montreal_custom').catalog montreal_custom_catalog = EnergySystemsCatalogFactory('montreal_custom').catalog
if city.energy_systems_connection_table is None:
_energy_systems_connection_table = DataFrame(columns=['Energy System Type', 'Building'])
else:
_energy_systems_connection_table = city.energy_systems_connection_table
if city.generic_energy_systems is None:
_generic_energy_systems = {}
else:
_generic_energy_systems = city.generic_energy_systems
for building in city.buildings: for building in city.buildings:
archetype_name = f'{building.energy_systems_archetype_name}_lod1.0' archetype_name = f'{building.energy_systems_archetype_name}_lod1.0'
# archetype_name = building.energy_systems_archetype_name # archetype_name = building.energy_systems_archetype_name
try: try:
print(archetype_name)
archetype = self._search_archetypes(montreal_custom_catalog, archetype_name) archetype = self._search_archetypes(montreal_custom_catalog, archetype_name)
except KeyError: except KeyError:
print('ERROR')
logger.error(f'Building {building.name} has unknown energy system archetype for system name: {archetype_name}') logger.error(f'Building {building.name} has unknown energy system archetype for system name: {archetype_name}')
sys.stderr.write(f'Building {building.name} has unknown energy system archetype ' sys.stderr.write(f'Building {building.name} has unknown energy system archetype '
f'for system name: {archetype_name}') f'for system name: {archetype_name}')
print('END ERROR')
continue continue
building_systems = [] building_systems = []
data = [archetype_name, building.name]
_energy_systems_connection_table.loc[len(_energy_systems_connection_table)] = data
for equipment in archetype.equipments: for equipment in archetype.equipments:
energy_system = GenericEnergySystem() energy_system = GenericEnergySystem()
_hub_demand_types = [] _hub_demand_types = []
for demand_type in equipment.demand_types: for demand_type in equipment.demand_types:
_hub_demand_types.append(Dictionaries().montreal_demand_type_to_hub_energy_demand_type[demand_type]) _hub_demand_types.append(Dictionaries().montreal_demand_type_to_hub_energy_demand_type[demand_type])
energy_system.name = archetype_name
energy_system.demand_types = _hub_demand_types energy_system.demand_types = _hub_demand_types
_generation_system = GenericGenerationSystem() _generation_system = GenericGenerationSystem()
archetype_generation_equipment = equipment.generation_system archetype_generation_equipment = equipment.generation_system
@ -63,11 +72,6 @@ class MontrealCustomEnergySystemParameters:
_generation_system.electricity_efficiency = archetype_generation_equipment.electricity_efficiency _generation_system.electricity_efficiency = archetype_generation_equipment.electricity_efficiency
_generation_system.source_temperature = archetype_generation_equipment.source_temperature _generation_system.source_temperature = archetype_generation_equipment.source_temperature
_generation_system.source_mass_flow = archetype_generation_equipment.source_mass_flow _generation_system.source_mass_flow = archetype_generation_equipment.source_mass_flow
# dhw peak does not add anything to the total heat peak
_generation_system.peak_coverages = {cte.HEATING: 1,
cte.COOLING: 1,
cte.DOMESTIC_HOT_WATER: 0,
cte.ELECTRICITY: 0}
_generation_system.storage = archetype_generation_equipment.storage _generation_system.storage = archetype_generation_equipment.storage
_generation_system.auxiliary_equipment = None _generation_system.auxiliary_equipment = None
@ -83,7 +87,11 @@ class MontrealCustomEnergySystemParameters:
energy_system.distribution_system = _distribution_system energy_system.distribution_system = _distribution_system
building_systems.append(energy_system) building_systems.append(energy_system)
building.energy_systems = building_systems if archetype_name not in _generic_energy_systems:
_generic_energy_systems[archetype_name] = building_systems
city.energy_systems_connection_table = _energy_systems_connection_table
city.generic_energy_systems = _generic_energy_systems
@staticmethod @staticmethod
def _search_archetypes(catalog, name): def _search_archetypes(catalog, name):

View File

@ -8,6 +8,7 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
import subprocess import subprocess
from pathlib import Path from pathlib import Path
from unittest import TestCase from unittest import TestCase
import copy
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.exports.energy_building_exports_factory import EnergyBuildingsExportsFactory from hub.exports.energy_building_exports_factory import EnergyBuildingsExportsFactory
@ -18,6 +19,10 @@ from hub.imports.geometry_factory import GeometryFactory
from hub.imports.results_factory import ResultFactory from hub.imports.results_factory import ResultFactory
from hub.imports.usage_factory import UsageFactory from hub.imports.usage_factory import UsageFactory
from hub.imports.energy_systems_factory import EnergySystemsFactory from hub.imports.energy_systems_factory import EnergySystemsFactory
from hub.city_model_structure.energy_systems.energy_system import EnergySystem
from hub.city_model_structure.energy_systems.generation_system import GenerationSystem
from hub.city_model_structure.energy_systems.distribution_system import DistributionSystem
from hub.city_model_structure.energy_systems.emission_system import EmissionSystem
class TestSystemsFactory(TestCase): class TestSystemsFactory(TestCase):
@ -44,9 +49,7 @@ class TestSystemsFactory(TestCase):
building.energy_systems_archetype_name = 'system 1 gas' building.energy_systems_archetype_name = 'system 1 gas'
EnergySystemsFactory('montreal_custom', self._city).enrich() EnergySystemsFactory('montreal_custom', self._city).enrich()
for building in self._city.buildings: self.assertEqual(1, len(self._city.energy_systems_connection_table))
self.assertEqual(2, len(building.energy_systems[0].demand_types))
self.assertEqual(1, len(building.energy_systems[1].demand_types))
def test_montreal_custom_system_results(self): def test_montreal_custom_system_results(self):
""" """
@ -64,10 +67,42 @@ class TestSystemsFactory(TestCase):
insel_path = (self._output_path / f'{building.name}.insel') insel_path = (self._output_path / f'{building.name}.insel')
subprocess.run(['insel', str(insel_path)]) subprocess.run(['insel', str(insel_path)])
ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich() ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich()
self._city.save(self._output_path / 'city.pickle')
for building in self._city.buildings: for building in self._city.buildings:
building.energy_systems_archetype_name = 'system 1 gas' building.energy_systems_archetype_name = 'system 1 gas'
EnergySystemsFactory('montreal_custom', self._city).enrich() EnergySystemsFactory('montreal_custom', self._city).enrich()
# Need to assign energy systems to buildings:
energy_systems_connection = self._city.energy_systems_connection_table
for building in self._city.buildings:
_building_energy_systems = []
energy_systems = energy_systems_connection['Energy System Type']\
.where(energy_systems_connection['Building'] == building.name)
for energy_system in energy_systems:
_generic_building_energy_systems = self._city.generic_energy_systems[energy_system]
for _generic_building_energy_system in _generic_building_energy_systems:
_building_energy_equipment = EnergySystem()
_building_energy_equipment.demand_types = _generic_building_energy_system.demand_types
_building_distribution_system = DistributionSystem()
_building_distribution_system.generic_distribution_system = \
copy.deepcopy(_generic_building_energy_system.distribution_system)
_building_emission_system = EmissionSystem()
_building_emission_system.generic_emission_system = \
copy.deepcopy(_generic_building_energy_system.emission_system)
_building_generation_system = GenerationSystem()
_building_generation_system.generic_generation_system = \
copy.deepcopy(_generic_building_energy_system.generation_system)
if cte.HEATING in _building_energy_equipment.demand_types:
_building_generation_system.heat_power = building.heating_peak_load[cte.YEAR]['heating peak loads'][0]
if cte.COOLING in _building_energy_equipment.demand_types:
_building_generation_system.cooling_power = building.cooling_peak_load[cte.YEAR]['cooling peak loads'][0]
_building_energy_equipment.generation_system = _building_generation_system
_building_energy_equipment.distribution_system = _building_distribution_system
_building_energy_equipment.emission_system = _building_emission_system
_building_energy_systems.append(_building_energy_equipment)
building.energy_systems = _building_energy_systems
for building in self._city.buildings: for building in self._city.buildings:
self.assertLess(0, building.heating_consumption[cte.YEAR][0]) self.assertLess(0, building.heating_consumption[cte.YEAR][0])