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.internal_zone import InternalZone
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):
@ -371,8 +371,6 @@ class Building(CityObject):
:return: dict{DataFrame(float)}
"""
results = {}
# todo: needed??
monthly_values = None
if cte.HOUR in self.heating:
monthly_values = PeakLoads().\
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()
@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
:return: [GenericEnergySystem]
:return: [EnergySystem]
"""
return self._energy_systems
@ -512,7 +510,7 @@ class Building(CityObject):
def energy_systems(self, value):
"""
Set list of energy systems installed to cover the building demands
:param value: [GenericEnergySystem]
:param value: [EnergySystem]
"""
self._energy_systems = value
@ -538,11 +536,12 @@ class Building(CityObject):
Get energy consumption for heating according to the heating system installed
return: dict
"""
for heating_demand_key in self.heating:
demand = self.heating[heating_demand_key][cte.INSEL_MEB]
consumption_type = cte.HEATING
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
self._heating_consumption[heating_demand_key] = final_energy_consumed
if len(self._heating_consumption) == 0:
for heating_demand_key in self.heating:
demand = self.heating[heating_demand_key][cte.INSEL_MEB]
consumption_type = cte.HEATING
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
self._heating_consumption[heating_demand_key] = final_energy_consumed
return self._heating_consumption
@property
@ -551,11 +550,12 @@ class Building(CityObject):
Get energy consumption for cooling according to the cooling system installed
return: dict
"""
for cooling_demand_key in self.cooling:
demand = self.cooling[cooling_demand_key][cte.INSEL_MEB]
consumption_type = cte.COOLING
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
self._cooling_consumption[cooling_demand_key] = final_energy_consumed
if len(self._cooling_consumption) == 0:
for cooling_demand_key in self.cooling:
demand = self.cooling[cooling_demand_key][cte.INSEL_MEB]
consumption_type = cte.COOLING
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
self._cooling_consumption[cooling_demand_key] = final_energy_consumed
return self._cooling_consumption
@property
@ -564,11 +564,12 @@ class Building(CityObject):
Get energy consumption for domestic according to the domestic hot water system installed
return: dict
"""
for domestic_hot_water_demand_key in self.domestic_hot_water_heat_demand:
demand = self.domestic_hot_water_heat_demand[domestic_hot_water_demand_key][cte.INSEL_MEB]
consumption_type = cte.DOMESTIC_HOT_WATER
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
self._domestic_hot_water_consumption[domestic_hot_water_demand_key] = final_energy_consumed
if len(self._domestic_hot_water_consumption) == 0:
for domestic_hot_water_demand_key in self.domestic_hot_water_heat_demand:
demand = self.domestic_hot_water_heat_demand[domestic_hot_water_demand_key][cte.INSEL_MEB]
consumption_type = cte.DOMESTIC_HOT_WATER
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
def _calculate_consumption(self, consumption_type, demand):
@ -578,15 +579,17 @@ class Building(CityObject):
for demand_type in energy_system.demand_types:
if demand_type.lower() == consumption_type.lower():
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:
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:
coefficient_of_performance = energy_system.generation_system.electricity_efficiency
final_energy_consumed = []
coefficient_of_performance = \
energy_system.generation_system.generic_generation_system.electricity_efficiency
if coefficient_of_performance == 0:
final_energy_consumed.append(0)
values = [0]*len(demand)
final_energy_consumed = values
else:
final_energy_consumed = []
for demand_value in demand:
final_energy_consumed.append(demand_value / coefficient_of_performance)
return final_energy_consumed
@ -599,8 +602,8 @@ class Building(CityObject):
"""
# Add other systems whenever new ones appear
for energy_system in self.energy_systems:
if energy_system.generation_system.type == cte.PHOTOVOLTAIC:
_efficiency = energy_system.generation_system.electricity_efficiency
if energy_system.generation_system.generic_generation_system.type == cte.PHOTOVOLTAIC:
_efficiency = energy_system.generation_system.generic_generation_system.electricity_efficiency
self._onsite_electrical_production = {}
for _key in self.roofs[0].global_irradiance.keys():
_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 pyproj import Transformer
from pathlib import Path
from pandas import DataFrame
from hub.city_model_structure.building import Building
from hub.city_model_structure.city_object import CityObject
from hub.city_model_structure.city_objects_cluster import CityObjectsCluster
@ -61,6 +62,8 @@ class City:
self._lca_materials = None
self._level_of_detail = LevelOfDetail()
self._city_objects_dictionary = {}
self._energy_systems_connection_table = None
self._generic_energy_systems = None
@property
def fuels(self) -> [Fuel]:
@ -490,4 +493,36 @@ class City:
"""
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
"""
def __init__(self):
self._name = None
self._demand_types = None
self._generation_system = None
self._distribution_system = None
self._emission_system = 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
def demand_types(self):
"""
@ -46,9 +63,16 @@ class GenericEnergySystem:
Get generation system
:return: GenerationSystem
"""
self._generation_system = GenericGenerationSystem(self.connected_city_objects)
return self._generation_system
@generation_system.setter
def generation_system(self, value):
"""
Set generation system
:return: GenerationSystem
"""
self._generation_system = value
@property
def distribution_system(self) -> Union[None, GenericDistributionSystem]:
"""
@ -80,19 +104,3 @@ class GenericEnergySystem:
: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

View File

@ -8,30 +8,22 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
from __future__ import annotations
from typing import Union
import hub.helpers.constants as cte
class GenericGenerationSystem:
"""
GenericGenerationSystem class
"""
def __init__(self, city_objects=None, heat_power=None, cooling_power=None, electricity_power=None):
self._city_objects = city_objects
def __init__(self):
self._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._heat_efficiency = None
self._cooling_efficiency = None
self._electricity_efficiency = None
self._source_temperature = None
self._source_mass_flow = None
self._storage_capacity = None
self._storage = None
self._auxiliary_equipment = None
self._peak_coverages = None
@property
def type(self):
@ -81,52 +73,6 @@ class GenericGenerationSystem:
"""
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
def heat_efficiency(self):
"""
@ -207,14 +153,6 @@ class GenericGenerationSystem:
"""
self._source_mass_flow = value
@property
def storage_capacity(self):
"""
Get storage_capacity in J
:return: float
"""
return self._storage_capacity
@property
def storage(self):
"""
@ -239,18 +177,10 @@ class GenericGenerationSystem:
"""
return self._auxiliary_equipment
@property
def peak_coverages(self) -> dict:
@auxiliary_equipment.setter
def auxiliary_equipment(self, value):
"""
Get ratio of each energy type power peak covered by the system
:return: dict {Heating: value, Cooling: value, Domestic Hot Water: value, Electricity: value}
Set auxiliary_equipment
:return: GenerationSystem
"""
return self._peak_coverages
@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
self._auxiliary_equipment = 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
"""
import sys
import math
from hub.hub_logger import logger
import hub.helpers.constants as cte
from hub.helpers.peak_calculation.loads_calculation import LoadsCalculation
@ -61,7 +59,7 @@ class PeakLoads:
@property
def heating_peak_loads_from_methodology(self):
if self._can_be_calculated():
if not self._can_be_calculated():
return None
monthly_heating_loads = []
ambient_temperature = self._building.external_temperature[cte.HOUR]['epw']
@ -88,7 +86,7 @@ class PeakLoads:
@property
def cooling_peak_loads_from_methodology(self):
if self._can_be_calculated():
if not self._can_be_calculated():
return None
monthly_cooling_loads = []
ambient_temperature = self._building.external_temperature[cte.HOUR]['epw']

View File

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

View File

@ -6,6 +6,7 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import sys
from pandas import DataFrame
from hub.hub_logger import logger
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_distribution_system import GenericDistributionSystem
from hub.helpers.dictionaries import Dictionaries
import hub.helpers.constants as cte
class MontrealCustomEnergySystemParameters:
@ -31,25 +31,34 @@ class MontrealCustomEnergySystemParameters:
"""
city = self._city
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:
archetype_name = f'{building.energy_systems_archetype_name}_lod1.0'
# archetype_name = building.energy_systems_archetype_name
try:
print(archetype_name)
archetype = self._search_archetypes(montreal_custom_catalog, archetype_name)
except KeyError:
print('ERROR')
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 '
f'for system name: {archetype_name}')
print('END ERROR')
continue
building_systems = []
data = [archetype_name, building.name]
_energy_systems_connection_table.loc[len(_energy_systems_connection_table)] = data
for equipment in archetype.equipments:
energy_system = GenericEnergySystem()
_hub_demand_types = []
for demand_type in equipment.demand_types:
_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
_generation_system = GenericGenerationSystem()
archetype_generation_equipment = equipment.generation_system
@ -63,11 +72,6 @@ class MontrealCustomEnergySystemParameters:
_generation_system.electricity_efficiency = archetype_generation_equipment.electricity_efficiency
_generation_system.source_temperature = archetype_generation_equipment.source_temperature
_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.auxiliary_equipment = None
@ -83,7 +87,11 @@ class MontrealCustomEnergySystemParameters:
energy_system.distribution_system = _distribution_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
def _search_archetypes(catalog, name):

View File

@ -8,6 +8,7 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
import subprocess
from pathlib import Path
from unittest import TestCase
import copy
import hub.helpers.constants as cte
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.usage_factory import UsageFactory
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):
@ -44,9 +49,7 @@ class TestSystemsFactory(TestCase):
building.energy_systems_archetype_name = 'system 1 gas'
EnergySystemsFactory('montreal_custom', self._city).enrich()
for building in self._city.buildings:
self.assertEqual(2, len(building.energy_systems[0].demand_types))
self.assertEqual(1, len(building.energy_systems[1].demand_types))
self.assertEqual(1, len(self._city.energy_systems_connection_table))
def test_montreal_custom_system_results(self):
"""
@ -64,10 +67,42 @@ class TestSystemsFactory(TestCase):
insel_path = (self._output_path / f'{building.name}.insel')
subprocess.run(['insel', str(insel_path)])
ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich()
self._city.save(self._output_path / 'city.pickle')
for building in self._city.buildings:
building.energy_systems_archetype_name = 'system 1 gas'
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:
self.assertLess(0, building.heating_consumption[cte.YEAR][0])