Compare commits

..

6 Commits

165 changed files with 105464 additions and 42639 deletions

View File

@ -22,7 +22,6 @@ class EilatCatalog(Catalog):
"""
Eilat catalog class
"""
def __init__(self, path):
_path_archetypes = Path(path / 'eilat_archetypes.json').resolve()
_path_constructions = (path / 'eilat_constructions.json').resolve()
@ -122,10 +121,8 @@ class EilatCatalog(Catalog):
construction_period = archetype['period_of_construction']
average_storey_height = archetype['average_storey_height']
extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges']
infiltration_rate_for_ventilation_system_off = archetype[
'infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_on = archetype[
'infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
archetype_constructions = []
for archetype_construction in archetype['constructions']:
@ -163,9 +160,7 @@ class EilatCatalog(Catalog):
extra_loses_due_to_thermal_bridges,
None,
infiltration_rate_for_ventilation_system_off,
infiltration_rate_for_ventilation_system_on,
0,
0))
infiltration_rate_for_ventilation_system_on))
return _catalog_archetypes
def names(self, category=None):

View File

@ -113,6 +113,7 @@ class NrcanCatalog(Catalog):
def _load_archetypes(self):
_catalog_archetypes = []
archetypes = self._archetypes['archetypes']
for archetype in archetypes:
archetype_id = f'{archetype["function"]}_{archetype["period_of_construction"]}_{archetype["climate_zone"]}'
function = archetype['function']
@ -128,11 +129,11 @@ class NrcanCatalog(Catalog):
infiltration_rate_for_ventilation_system_on = (
archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
)
infiltration_rate_area_for_ventilation_system_off = (
archetype['infiltration_rate_area_for_ventilation_system_off'] * 1
)
infiltration_rate_area_for_ventilation_system_on = (
archetype['infiltration_rate_area_for_ventilation_system_on'] * 1
archetype['infiltration_rate_area_for_ventilation_system_on']
)
infiltration_rate_area_for_ventilation_system_off = (
archetype['infiltration_rate_area_for_ventilation_system_off']
)
archetype_constructions = []
@ -159,6 +160,7 @@ class NrcanCatalog(Catalog):
_window)
archetype_constructions.append(_construction)
break
_catalog_archetypes.append(Archetype(archetype_id,
name,
function,

View File

@ -162,9 +162,7 @@ class NrelCatalog(Catalog):
extra_loses_due_to_thermal_bridges,
indirect_heated_ratio,
infiltration_rate_for_ventilation_system_off,
infiltration_rate_for_ventilation_system_on,
0,
0))
infiltration_rate_for_ventilation_system_on))
return _catalog_archetypes
def names(self, category=None):

View File

@ -1,242 +0,0 @@
"""
Palma construction catalog
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Cecilia Pérez Pérez cperez@irec.cat
"""
import json
from pathlib import Path
from hub.catalog_factories.catalog import Catalog
from hub.catalog_factories.data_models.construction.content import Content
from hub.catalog_factories.construction.construction_helper import ConstructionHelper
from hub.catalog_factories.data_models.construction.construction import Construction
from hub.catalog_factories.data_models.construction.archetype import Archetype
from hub.catalog_factories.data_models.construction.window import Window
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 PalmaCatalog(Catalog):
"""
Palma catalog class
"""
def __init__(self, path):
_path_archetypes = Path(path / 'palma_archetypes.json').resolve()
_path_constructions = (path / 'palma_constructions.json').resolve()
with open(_path_archetypes, 'r', encoding='utf-8') as file:
self._archetypes = json.load(file)
with open(_path_constructions, 'r', encoding='utf-8') as file:
self._constructions = json.load(file)
self._catalog_windows = self._load_windows()
self._catalog_materials = self._load_materials()
self._catalog_constructions = self._load_constructions()
self._catalog_archetypes = self._load_archetypes()
# store the full catalog data model in self._content
self._content = Content(self._catalog_archetypes,
self._catalog_constructions,
self._catalog_materials,
self._catalog_windows)
def _load_windows(self):
_catalog_windows = []
windows = self._constructions['transparent_surfaces']
for window in windows:
name = list(window.keys())[0]
window_id = name
g_value = window[name]['shgc']
window_type = window[name]['type']
frame_ratio = window[name]['frame_ratio']
overall_u_value = window[name]['u_value']
_catalog_windows.append(Window(window_id, frame_ratio, g_value, overall_u_value, name, window_type))
return _catalog_windows
def _load_materials(self):
_catalog_materials = []
materials = self._constructions['materials']
for material in materials:
name = list(material.keys())[0]
material_id = name
no_mass = material[name]['no_mass']
thermal_resistance = None
conductivity = None
density = None
specific_heat = None
solar_absorptance = None
thermal_absorptance = None
visible_absorptance = None
if no_mass:
thermal_resistance = material[name]['thermal_resistance']
else:
solar_absorptance = material[name]['solar_absorptance']
thermal_absorptance = str(1 - float(material[name]['thermal_emittance']))
visible_absorptance = material[name]['visible_absorptance']
conductivity = material[name]['conductivity']
density = material[name]['density']
specific_heat = material[name]['specific_heat']
_material = Material(material_id,
name,
solar_absorptance,
thermal_absorptance,
visible_absorptance,
no_mass,
thermal_resistance,
conductivity,
density,
specific_heat)
_catalog_materials.append(_material)
return _catalog_materials
def _load_constructions(self):
_catalog_constructions = []
constructions = self._constructions['opaque_surfaces']
for construction in constructions:
name = list(construction.keys())[0]
construction_id = name
construction_type = ConstructionHelper().nrcan_surfaces_types_to_hub_types[construction[name]['type']]
layers = []
for layer in construction[name]['layers']:
layer_id = layer
layer_name = layer
material_id = layer
thickness = construction[name]['layers'][layer]
for material in self._catalog_materials:
if str(material_id) == str(material.id):
layers.append(Layer(layer_id, layer_name, material, thickness))
break
_catalog_constructions.append(Construction(construction_id, construction_type, name, layers))
return _catalog_constructions
def _load_archetypes(self):
_catalog_archetypes = []
archetypes = self._archetypes['archetypes']
for archetype in archetypes:
archetype_id = f'{archetype["function"]}_{archetype["period_of_construction"]}_{archetype["climate_zone"]}'
function = archetype['function']
name = archetype_id
climate_zone = archetype['climate_zone']
construction_period = archetype['period_of_construction']
average_storey_height = archetype['average_storey_height']
thermal_capacity = float(archetype['thermal_capacity']) * 1000
extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges']
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
infiltration_rate_area_for_ventilation_system_off = (
archetype['infiltration_rate_area_for_ventilation_system_off'] * 1
)
infiltration_rate_area_for_ventilation_system_on = (
archetype['infiltration_rate_area_for_ventilation_system_on'] * 1
)
archetype_constructions = []
for archetype_construction in archetype['constructions']:
archetype_construction_type = ConstructionHelper().nrcan_surfaces_types_to_hub_types[archetype_construction]
archetype_construction_name = archetype['constructions'][archetype_construction]['opaque_surface_name']
for construction in self._catalog_constructions:
if archetype_construction_type == construction.type and construction.name == archetype_construction_name:
_construction = None
_window = None
_window_ratio = None
if 'transparent_surface_name' in archetype['constructions'][archetype_construction].keys():
_window_ratio = archetype['constructions'][archetype_construction]['transparent_ratio']
_window_id = archetype['constructions'][archetype_construction]['transparent_surface_name']
for window in self._catalog_windows:
if _window_id == window.id:
_window = window
break
_construction = Construction(construction.id,
construction.type,
construction.name,
construction.layers,
_window_ratio,
_window)
archetype_constructions.append(_construction)
break
_catalog_archetypes.append(Archetype(archetype_id,
name,
function,
climate_zone,
construction_period,
archetype_constructions,
average_storey_height,
thermal_capacity,
extra_loses_due_to_thermal_bridges,
None,
infiltration_rate_for_ventilation_system_off,
infiltration_rate_for_ventilation_system_on,
infiltration_rate_area_for_ventilation_system_off,
infiltration_rate_area_for_ventilation_system_on))
return _catalog_archetypes
def names(self, category=None):
"""
Get the catalog elements names
:parm: optional category filter
"""
if category is None:
_names = {'archetypes': [], 'constructions': [], 'materials': [], 'windows': []}
for archetype in self._content.archetypes:
_names['archetypes'].append(archetype.name)
for construction in self._content.constructions:
_names['constructions'].append(construction.name)
for material in self._content.materials:
_names['materials'].append(material.name)
for window in self._content.windows:
_names['windows'].append(window.name)
else:
_names = {category: []}
if category.lower() == 'archetypes':
for archetype in self._content.archetypes:
_names[category].append(archetype.name)
elif category.lower() == 'constructions':
for construction in self._content.constructions:
_names[category].append(construction.name)
elif category.lower() == 'materials':
for material in self._content.materials:
_names[category].append(material.name)
elif category.lower() == 'windows':
for window in self._content.windows:
_names[category].append(window.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() == 'constructions':
return self._content.constructions
if category.lower() == 'materials':
return self._content.materials
if category.lower() == 'windows':
return self._content.windows
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.constructions:
if entry.name.lower() == name.lower():
return entry
for entry in self._content.materials:
if entry.name.lower() == name.lower():
return entry
for entry in self._content.windows:
if entry.name.lower() == name.lower():
return entry
raise IndexError(f"{name} doesn't exists in the catalog")

View File

@ -11,7 +11,6 @@ from typing import TypeVar
from hub.catalog_factories.construction.nrcan_catalog import NrcanCatalog
from hub.catalog_factories.construction.nrel_catalog import NrelCatalog
from hub.catalog_factories.construction.eilat_catalog import EilatCatalog
from hub.catalog_factories.construction.palma_catalog import PalmaCatalog
from hub.helpers.utils import validate_import_export_type
Catalog = TypeVar('Catalog')
@ -49,13 +48,6 @@ class ConstructionCatalogFactory:
"""
return EilatCatalog(self._path)
@property
def _palma(self):
"""
Retrieve Palma catalog
"""
return PalmaCatalog(self._path)
@property
def catalog(self) -> Catalog:
"""

View File

@ -24,9 +24,8 @@ class Archetype:
indirect_heated_ratio,
infiltration_rate_for_ventilation_system_off,
infiltration_rate_for_ventilation_system_on,
infiltration_rate_area_for_ventilation_system_off,
infiltration_rate_area_for_ventilation_system_on
):
infiltration_rate_area_for_ventilation_system_off = 0,
infiltration_rate_area_for_ventilation_system_on = 0):
self._id = archetype_id
self._name = name
self._function = function
@ -141,7 +140,7 @@ class Archetype:
@property
def infiltration_rate_area_for_ventilation_system_off(self):
"""
Get archetype infiltration rate for ventilation system off in m3/sm2
Get archetype infiltration rate area for ventilation system off
:return: float
"""
return self._infiltration_rate_area_for_ventilation_system_off
@ -149,10 +148,11 @@ class Archetype:
@property
def infiltration_rate_area_for_ventilation_system_on(self):
"""
Get archetype infiltration rate for ventilation system on in m3/sm2
Get archetype infiltration rate area for ventilation system on
:return: float
"""
return self._infiltration_rate_for_ventilation_system_on
return self._infiltration_rate_area_for_ventilation_system_on
def to_dictionary(self):
"""Class content to dictionary"""
@ -170,8 +170,8 @@ class Archetype:
'indirect heated ratio': self.indirect_heated_ratio,
'infiltration rate for ventilation off [1/s]': self.infiltration_rate_for_ventilation_system_off,
'infiltration rate for ventilation on [1/s]': self.infiltration_rate_for_ventilation_system_on,
'infiltration rate area for ventilation off [m3/sm2]': self.infiltration_rate_area_for_ventilation_system_off,
'infiltration rate area for ventilation on [m3/sm2]': self.infiltration_rate_area_for_ventilation_system_on,
'infiltration rate area for ventilation off': self.infiltration_rate_area_for_ventilation_system_off,
'infiltration rate area for ventilation on': self.infiltration_rate_area_for_ventilation_system_on,
'constructions': _constructions
}
}

View File

@ -1,9 +1,8 @@
"""
Energy System catalog archetype, understood as a cluster of energy systems
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
@ -15,19 +14,19 @@ class Archetype:
"""
Archetype class
"""
def __init__(self, lod, name, systems):
def __init__(self, name, systems, archetype_cluster_id=None):
self._cluster_id = archetype_cluster_id
self._lod = lod
self._name = name
self._systems = systems
@property
def cluster_id(self):
def lod(self):
"""
Get id
Get level of detail of the catalog
:return: string
"""
return self._cluster_id
return self._lod
@property
def name(self):
@ -50,10 +49,8 @@ class Archetype:
_systems = []
for _system in self.systems:
_systems.append(_system.to_dictionary())
content = {
'Archetype': {
'cluster_id': self.cluster_id,
'name': self.name,
content = {'Archetype': {'name': self.name,
'level of detail': self.lod,
'systems': _systems
}
}

View File

@ -10,11 +10,12 @@ class Content:
"""
Content class
"""
def __init__(self, archetypes, systems, generations=None, distributions=None):
def __init__(self, archetypes, systems, generations, distributions, emissions):
self._archetypes = archetypes
self._systems = systems
self._generations = generations
self._distributions = distributions
self._emissions = emissions
@property
def archetypes(self):
@ -44,6 +45,13 @@ class Content:
"""
return self._distributions
@property
def emission_equipments(self):
"""
All emission equipments in the catalog
"""
return self._emissions
def to_dictionary(self):
"""Class content to dictionary"""
_archetypes = []

View File

@ -3,35 +3,23 @@ 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 typing import Union, List, TypeVar
from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem
from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem
GenerationSystem = TypeVar('GenerationSystem')
class DistributionSystem:
"""
Distribution system class
"""
def __init__(self, system_id, model_name=None, system_type=None, supply_temperature=None,
distribution_consumption_fix_flow=None, distribution_consumption_variable_flow=None, heat_losses=None,
generation_systems=None, energy_storage_systems=None, emission_systems=None):
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._model_name = model_name
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._generation_systems = generation_systems
self._energy_storage_systems = energy_storage_systems
self._emission_systems = emission_systems
@property
def id(self):
@ -42,12 +30,12 @@ class DistributionSystem:
return self._system_id
@property
def model_name(self):
def name(self):
"""
Get model name
Get name
:return: string
"""
return self._model_name
return self._name
@property
def type(self):
@ -90,51 +78,17 @@ class DistributionSystem:
"""
return self._heat_losses
@property
def generation_systems(self) -> Union[None, List[GenerationSystem]]:
"""
Get generation systems connected to the distribution system
:return: [GenerationSystem]
"""
return self._generation_systems
@property
def energy_storage_systems(self) -> Union[None, List[EnergyStorageSystem]]:
"""
Get energy storage systems connected to this distribution system
:return: [EnergyStorageSystem]
"""
return self._energy_storage_systems
@property
def emission_systems(self) -> Union[None, List[EmissionSystem]]:
"""
Get energy emission systems connected to this distribution system
:return: [EmissionSystem]
"""
return self._emission_systems
def to_dictionary(self):
"""Class content to dictionary"""
_generation_systems = [_generation_system.to_dictionary() for _generation_system in
self.generation_systems] if self.generation_systems is not None else None
_energy_storage_systems = [_energy_storage_system.to_dictionary() for _energy_storage_system in
self.energy_storage_systems] if self.energy_storage_systems is not None else None
_emission_systems = [_emission_system.to_dictionary() for _emission_system in
self.emission_systems] if self.emission_systems is not None else None
content = {
'Layer': {
'id': self.id,
'model name': self.model_name,
'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,
'generation systems connected': _generation_systems,
'energy storage systems connected': _energy_storage_systems,
'emission systems connected': _emission_systems
'heat losses per energy produced [J/J]': self.heat_losses
}
}
return content

View File

@ -1,103 +0,0 @@
"""
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, type_energy_stored=None, model_name=None, manufacturer=None, storage_type=None,
nominal_capacity=None, losses_ratio=None, rated_output_power=None, nominal_efficiency=None,
battery_voltage=None, depth_of_discharge=None, self_discharge_rate=None):
super().__init__(storage_id, model_name, manufacturer, nominal_capacity, losses_ratio)
self._type_energy_stored = type_energy_stored
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 type_energy_stored(self):
"""
Get type of energy stored from ['electrical', 'thermal']
:return: string
"""
return self._type_energy_stored
@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 Watts
: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 Volts
: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,
'type of energy stored': self.type_energy_stored,
'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 [W]': 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

View File

@ -10,10 +10,10 @@ class EmissionSystem:
"""
Emission system class
"""
def __init__(self, system_id, model_name=None, system_type=None, parasitic_energy_consumption=0):
def __init__(self, system_id, name, system_type, parasitic_energy_consumption):
self._system_id = system_id
self._model_name = model_name
self._name = name
self._type = system_type
self._parasitic_energy_consumption = parasitic_energy_consumption
@ -26,12 +26,12 @@ class EmissionSystem:
return self._system_id
@property
def model_name(self):
def name(self):
"""
Get model name
Get name
:return: string
"""
return self._model_name
return self._name
@property
def type(self):
@ -52,7 +52,7 @@ class EmissionSystem:
def to_dictionary(self):
"""Class content to dictionary"""
content = {'Layer': {'id': self.id,
'model name': self.model_name,
'name': self.name,
'type': self.type,
'parasitic energy consumption per energy produced [J/J]': self.parasitic_energy_consumption
}

View File

@ -1,75 +0,0 @@
"""
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 abc import ABC
class EnergyStorageSystem(ABC):
""""
Energy Storage System Abstract Class
"""
def __init__(self, storage_id, model_name=None, manufacturer=None,
nominal_capacity=None, losses_ratio=None):
self._storage_id = storage_id
self._model_name = model_name
self._manufacturer = manufacturer
self._nominal_capacity = nominal_capacity
self._losses_ratio = losses_ratio
@property
def id(self):
"""
Get storage id
:return: string
"""
return self._storage_id
@property
def type_energy_stored(self):
"""
Get type of energy stored from ['electrical', 'thermal']
:return: string
"""
raise NotImplementedError
@property
def model_name(self):
"""
Get system model
:return: string
"""
return self._model_name
@property
def manufacturer(self):
"""
Get name of manufacturer
:return: string
"""
return self._manufacturer
@property
def nominal_capacity(self):
"""
Get the nominal capacity of the storage system in Jules
:return: float
"""
return self._nominal_capacity
@property
def losses_ratio(self):
"""
Get the losses-ratio of storage system in Jules lost / Jules stored
:return: float
"""
return self._losses_ratio
def to_dictionary(self):
"""Class content to dictionary"""
raise NotImplementedError

View File

@ -1,33 +1,33 @@
"""
Energy System catalog heat generation system
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
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
from __future__ import annotations
from abc import ABC
from typing import List, Union
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 typing import Union
class GenerationSystem(ABC):
class GenerationSystem:
"""
Heat Generation system class
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):
def __init__(self, system_id, name, model_name=None, manufacturer=None, fuel_type=None,
distribution_systems=None, energy_storage_systems=None):
self._system_id = system_id
self._name = name
self._model_name = model_name
self._manufacturer = manufacturer
self._type = system_type
self._fuel_type = fuel_type
self._distribution_systems = distribution_systems
self._energy_storage_systems = energy_storage_systems
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):
@ -40,59 +40,108 @@ class GenerationSystem(ABC):
@property
def name(self):
"""
Get system name
Get name
:return: string
"""
return self._name
@property
def system_type(self):
def type(self):
"""
Get type
:return: string
"""
raise NotImplementedError
@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
return self._type
@property
def fuel_type(self):
"""
Get fuel_type from [renewable, gas, diesel, electricity, wood, coal, biogas]
Get fuel_type from [renewable, gas, diesel, electricity, wood, coal]
:return: string
"""
return self._fuel_type
@property
def distribution_systems(self) -> Union[None, List[DistributionSystem]]:
def source_types(self):
"""
Get distributions systems connected to this generation system
:return: [DistributionSystem]
Get source_type from [air, water, geothermal, district_heating, grid, on_site_electricity]
:return: [string]
"""
return self._distribution_systems
return self._source_types
@property
def energy_storage_systems(self) -> Union[None, List[EnergyStorageSystem]]:
def heat_efficiency(self):
"""
Get energy storage systems connected to this generation system
:return: [EnergyStorageSystem]
Get heat_efficiency
:return: float
"""
return self._energy_storage_systems
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"""
raise NotImplementedError
_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

View File

@ -1,344 +0,0 @@
"""
Energy System catalog non PV 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 hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves
from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem
class NonPvGenerationSystem(GenerationSystem):
"""
Non PV Generation system class
"""
def __init__(self, system_id, name, system_type, model_name=None, manufacturer=None, fuel_type=None,
nominal_heat_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=None,
source_temperature=None, source_mass_flow=None, nominal_electricity_output=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, cooling_output_curve=None,
cooling_fuel_consumption_curve=None, cooling_efficiency_curve=None,
distribution_systems=None, energy_storage_systems=None, domestic_hot_water=False,
reversible=None, simultaneous_heat_cold=None):
super().__init__(system_id=system_id, name=name, model_name=model_name, manufacturer=manufacturer,
fuel_type=fuel_type, distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems)
self._system_type = system_type
self._nominal_heat_output = nominal_heat_output
self._maximum_heat_output = maximum_heat_output
self._minimum_heat_output = minimum_heat_output
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._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
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._domestic_hot_water = domestic_hot_water
self._reversible = reversible
self._simultaneous_heat_cold = simultaneous_heat_cold
@property
def system_type(self):
"""
Get type
:return: string
"""
return self._system_type
@property
def nominal_heat_output(self):
"""
Get nominal heat output of heat generation devices in W
:return: float
"""
return self._nominal_heat_output
@property
def maximum_heat_output(self):
"""
Get maximum heat output of heat generation devices in W
:return: float
"""
return self._maximum_heat_output
@property
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_medium
@property
def supply_medium(self):
"""
Get the supply medium from ['air', 'water']
:return: string
"""
return self._supply_medium
@property
def heat_efficiency(self):
"""
Get heat_efficiency
:return: float
"""
return self._heat_efficiency
@property
def nominal_cooling_output(self):
"""
Get nominal cooling output of heat generation devices in W
: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):
"""
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 nominal_electricity_output(self):
"""
Get nominal_power_output of electricity generation devices or inverters in W
:return: float
"""
return self._nominal_electricity_output
@property
def maximum_heat_supply_temperature(self):
"""
Get the maximum heat supply temperature in degree Celsius
:return: float
"""
return self._minimum_heat_supply_temperature
@property
def minimum_heat_supply_temperature(self):
"""
Get the minimum heat supply temperature in degree Celsius
:return: float
"""
return self._minimum_heat_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
@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 domestic_hot_water(self):
"""
Get the ability to produce domestic hot water
:return: bool
"""
return self._domestic_hot_water
@property
def reversibility(self):
"""
Get the ability to produce heating and cooling
:return: bool
"""
return self._reversible
@property
def simultaneous_heat_cold(self):
"""
Get the ability to produce heating and cooling at the same time
:return: bool
"""
return self._simultaneous_heat_cold
def to_dictionary(self):
"""Class content to dictionary"""
_distribution_systems = [_distribution_system.to_dictionary() for _distribution_system in
self.distribution_systems] if self.distribution_systems is not None else None
_energy_storage_systems = [_energy_storage_system.to_dictionary() for _energy_storage_system in
self.energy_storage_systems] if self.energy_storage_systems is not None else None
_heat_output_curve = self.heat_output_curve.to_dictionary() if (
self.heat_output_curve is not None) else None
_heat_fuel_consumption_curve = self.heat_fuel_consumption_curve.to_dictionary() if (
self.heat_fuel_consumption_curve is not None) else None
_heat_efficiency_curve = self.heat_efficiency_curve.to_dictionary() if (
self.heat_efficiency_curve is not None) else None
_cooling_output_curve = self.cooling_output_curve.to_dictionary() if (
self.cooling_output_curve is not None) else None
_cooling_fuel_consumption_curve = self.cooling_fuel_consumption_curve.to_dictionary() if (
self.cooling_fuel_consumption_curve is not None) else None
_cooling_efficiency_curve = self.cooling_efficiency_curve.to_dictionary() if (
self.cooling_efficiency_curve is not None) else None
content = {
'Energy Generation component':
{
'id': self.id,
'model name': self.model_name,
'manufacturer': self.manufacturer,
'type': self.system_type,
'fuel type': self.fuel_type,
'nominal heat output [W]': self.nominal_heat_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 [W]': self.nominal_electricity_output,
'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,
'heat fuel consumption curve': self.heat_fuel_consumption_curve,
'heat efficiency curve': _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,
'distribution systems connected': _distribution_systems,
'storage systems connected': _energy_storage_systems,
'domestic hot water production capability': self.domestic_hot_water,
'reversible cycle': self.reversibility,
'simultaneous heat and cooling production': self.simultaneous_heat_cold
}
}
return content

View File

@ -1,72 +0,0 @@
"""
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
class PerformanceCurves:
"""
Parameter function class
"""
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
@property
def curve_type(self):
"""
The type of the fit function from the following
Linear =>>> y = a + b*x
Exponential =>>> y = a*(b**x)
Second degree polynomial =>>> y = a + b*x + c*(x**2)
Power =>>> y = a*(x**b)
Bi-Quadratic =>>> y = a + b*x + c*(x**2) + d*z + e*(z**2) + f*x*z
Get the type of function from ['linear', 'exponential', 'second degree polynomial', 'power', 'bi-quadratic']
:return: string
"""
return self._curve_type
@property
def dependant_variable(self):
"""
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._dependant_variable
@property
def parameters(self):
"""
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
@property
def coefficients(self):
"""
Get the coefficients of the functions as list of ['a', 'b', 'c', 'd', 'e', 'f']
:return: [coefficients]
"""
return self._coefficients
def to_dictionary(self):
"""Class content to dictionary"""
content = {'Parameter Function': {
'curve type': self.curve_type,
'dependant variable': self.dependant_variable,
'parameter(s)': self.parameters,
'coefficients': self.coefficients,
}
}
return content

View File

@ -1,165 +0,0 @@
"""
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 hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem
class PvGenerationSystem(GenerationSystem):
"""
Electricity Generation system class
"""
def __init__(self, system_id, name, system_type, model_name=None, manufacturer=None, electricity_efficiency=None,
nominal_electricity_output=None, nominal_ambient_temperature=None, nominal_cell_temperature=None,
nominal_radiation=None, standard_test_condition_cell_temperature=None,
standard_test_condition_maximum_power=None, standard_test_condition_radiation=None,
cell_temperature_coefficient=None, width=None, height=None, distribution_systems=None,
energy_storage_systems=None):
super().__init__(system_id=system_id, name=name, model_name=model_name,
manufacturer=manufacturer, fuel_type='renewable', distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems)
self._system_type = system_type
self._electricity_efficiency = electricity_efficiency
self._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
self._standard_test_condition_cell_temperature = standard_test_condition_cell_temperature
self._standard_test_condition_maximum_power = standard_test_condition_maximum_power
self._standard_test_condition_radiation = standard_test_condition_radiation
self._cell_temperature_coefficient = cell_temperature_coefficient
self._width = width
self._height = height
@property
def system_type(self):
"""
Get type
:return: string
"""
return self._system_type
@property
def nominal_electricity_output(self):
"""
Get nominal_power_output of electricity generation devices or inverters in W
:return: float
"""
return self._nominal_electricity_output
@property
def electricity_efficiency(self):
"""
Get electricity_efficiency
:return: float
"""
return self._electricity_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 W
:return: float
"""
return self._standard_test_condition_maximum_power
@property
def standard_test_condition_radiation(self):
"""
Get standard test condition cell temperature of PV panels in W/m2
:return: float
"""
return self._standard_test_condition_radiation
@property
def cell_temperature_coefficient(self):
"""
Get cell temperature coefficient of PV module
:return: float
"""
return self._cell_temperature_coefficient
@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
def to_dictionary(self):
"""Class content to dictionary"""
_distribution_systems = [_distribution_system.to_dictionary() for _distribution_system in
self.distribution_systems] if self.distribution_systems is not None else None
_energy_storage_systems = [_energy_storage_system.to_dictionary() for _energy_storage_system in
self.energy_storage_systems] if self.energy_storage_systems is not None else None
content = {
'Energy Generation component':
{
'id': self.id,
'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 [W]': 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 [W]': self.standard_test_condition_maximum_power,
'standard test condition radiation [W/m2]': self.standard_test_condition_radiation,
'cell temperature coefficient': self.cell_temperature_coefficient,
'width': self.width,
'height': self.height,
'distribution systems connected': _distribution_systems,
'storage systems connected': _energy_storage_systems
}
}
return content

View File

@ -1,36 +1,45 @@
"""
Energy Systems catalog System
Energy System catalog equipment
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, List
from pathlib import Path
from typing import Union
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
class System:
"""
System class
"""
def __init__(self,
lod,
system_id,
name,
demand_types,
name=None,
generation_systems=None,
distribution_systems=None,
configuration_schema=None):
generation_system,
distribution_system,
emission_system):
self._lod = lod
self._system_id = system_id
self._name = name
self._demand_types = demand_types
self._generation_systems = generation_systems
self._distribution_systems = distribution_systems
self._configuration_schema = configuration_schema
self._generation_system = generation_system
self._distribution_system = distribution_system
self._emission_system = emission_system
@property
def lod(self):
"""
Get level of detail of the catalog
:return: string
"""
return self._lod
@property
def id(self):
@ -43,7 +52,7 @@ class System:
@property
def name(self):
"""
Get the system name
Get name
:return: string
"""
return self._name
@ -51,49 +60,50 @@ class System:
@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 generation_systems(self) -> Union[None, List[GenerationSystem]]:
def generation_system(self) -> GenerationSystem:
"""
Get generation systems
:return: [GenerationSystem]
Get generation system
:return: GenerationSystem
"""
return self._generation_systems
return self._generation_system
@property
def distribution_systems(self) -> Union[None, List[DistributionSystem]]:
def distribution_system(self) -> Union[None, DistributionSystem]:
"""
Get distribution systems
:return: [DistributionSystem]
Get distribution system
:return: DistributionSystem
"""
return self._distribution_systems
return self._distribution_system
@property
def configuration_schema(self) -> Path:
def emission_system(self) -> Union[None, EmissionSystem]:
"""
Get system configuration schema
:return: Path
Get emission system
:return: EmissionSystem
"""
return self._configuration_schema
return self._emission_system
def to_dictionary(self):
"""Class content to dictionary"""
_generation_systems = []
for _generation in self.generation_systems:
_generation_systems.append(_generation.to_dictionary())
_distribution_systems = [_distribution.to_dictionary() for _distribution in
self.distribution_systems] if self.distribution_systems is not None else None
content = {'system': {'id': self.id,
_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()
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(s)': _distribution_systems,
'configuration schema path': self.configuration_schema
'generation system': self.generation_system.to_dictionary(),
'distribution system': _distribution_system,
'emission system': _emission_system
}
}
return content

View File

@ -1,126 +0,0 @@
"""
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
from hub.catalog_factories.data_models.construction.material import Material
class ThermalStorageSystem(EnergyStorageSystem):
""""
Energy Storage System Class
"""
def __init__(self, storage_id, type_energy_stored=None, model_name=None, manufacturer=None, storage_type=None,
nominal_capacity=None, losses_ratio=None, volume=None, height=None, layers=None,
maximum_operating_temperature=None, storage_medium=None, heating_coil_capacity=None):
super().__init__(storage_id, model_name, manufacturer, nominal_capacity, losses_ratio)
self._type_energy_stored = type_energy_stored
self._storage_type = storage_type
self._volume = volume
self._height = height
self._layers = layers
self._maximum_operating_temperature = maximum_operating_temperature
self._storage_medium = storage_medium
self._heating_coil_capacity = heating_coil_capacity
@property
def type_energy_stored(self):
"""
Get type of energy stored from ['electrical', 'thermal']
:return: string
"""
return self._type_energy_stored
@property
def storage_type(self):
"""
Get storage type from ['thermal', '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
@property
def storage_medium(self) -> Material:
"""
Get thermodynamic characteristics of the storage medium
:return: [material
"""
return self._storage_medium
@property
def heating_coil_capacity(self):
"""
Get heating coil capacity in Watts
:return: [material
"""
return self._heating_coil_capacity
def to_dictionary(self):
"""Class content to dictionary"""
_layers = None
_medias = None
if self.layers is not None:
_layers = []
for _layer in self.layers:
_layers.append(_layer.to_dictionary())
if self.storage_medium is not None:
_medias = self.storage_medium.to_dictionary()
content = {
'Storage component':
{
'storage id': self.id,
'type of energy stored': self.type_energy_stored,
'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,
'volume [m3]': self.volume,
'height [m]': self.height,
'layers': _layers,
'maximum operating temperature [Celsius]': self.maximum_operating_temperature,
'storage_medium': _medias,
'heating coil capacity [W]': self.heating_coil_capacity
}
}
return content

View File

@ -10,46 +10,45 @@ 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.non_pv_generation_system import NonPvGenerationSystem
from hub.catalog_factories.data_models.energy_systems.pv_generation_system import PvGenerationSystem
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 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):
"""
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_emission_equipments = self._load_emission_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_distribution_equipments,
self._catalog_emission_equipments)
def _load_generation_equipments(self):
_equipments = []
_storages = []
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']
model_name = equipment['name']
name = equipment['name']
heating_efficiency = None
if 'heating_efficiency' in equipment:
heating_efficiency = float(equipment['heating_efficiency'])
@ -59,38 +58,21 @@ class MontrealCustomCatalog(Catalog):
electricity_efficiency = None
if 'electrical_efficiency' in equipment:
electricity_efficiency = float(equipment['electrical_efficiency'])
storage_systems = None
storage = literal_eval(equipment['storage'].capitalize())
if storage:
if equipment_type == 'electricity generator':
storage_system = ElectricalStorageSystem(equipment_id)
else:
storage_system = ThermalStorageSystem(equipment_id)
storage_systems = [storage_system]
if model_name == 'PV system':
system_type = 'photovoltaic'
generation_system = PvGenerationSystem(equipment_id,
name=None,
system_type=system_type,
model_name=model_name,
electricity_efficiency=electricity_efficiency,
energy_storage_systems=storage_systems
)
else:
generation_system = NonPvGenerationSystem(equipment_id,
name=None,
model_name=model_name,
system_type=equipment_type,
fuel_type=fuel_type,
heat_efficiency=heating_efficiency,
cooling_efficiency=cooling_efficiency,
electricity_efficiency=electricity_efficiency,
energy_storage_systems=storage_systems,
domestic_hot_water=False
)
_equipments.append(generation_system)
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):
@ -99,7 +81,7 @@ class MontrealCustomCatalog(Catalog):
for equipment in equipments:
equipment_id = float(equipment['@id'])
equipment_type = equipment['@type']
model_name = equipment['name']
name = equipment['name']
distribution_heat_losses = None
if 'distribution_heat_losses' in equipment:
distribution_heat_losses = float(equipment['distribution_heat_losses']['#text']) / 100
@ -108,22 +90,15 @@ 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
emission_equipment = equipment['dissipation_id']
_emission_equipments = None
for equipment_archetype in self._catalog_emission_equipments:
if int(equipment_archetype.id) == int(emission_equipment):
_emission_equipments = [equipment_archetype]
distribution_consumption_variable_flow = float(equipment['distribution_consumption_variable_flow']['#text']) / 100
distribution_system = DistributionSystem(equipment_id,
model_name=model_name,
system_type=equipment_type,
distribution_consumption_fix_flow=distribution_consumption_fix_flow,
distribution_consumption_variable_flow=distribution_consumption_variable_flow,
heat_losses=distribution_heat_losses,
emission_systems=_emission_equipments)
name,
equipment_type,
None,
distribution_consumption_fix_flow,
distribution_consumption_variable_flow,
distribution_heat_losses)
_equipments.append(distribution_system)
return _equipments
@ -134,15 +109,15 @@ class MontrealCustomCatalog(Catalog):
for equipment in equipments:
equipment_id = float(equipment['@id'])
equipment_type = equipment['@type']
model_name = equipment['name']
parasitic_consumption = 0
name = equipment['name']
parasitic_consumption = None
if 'parasitic_consumption' in equipment:
parasitic_consumption = float(equipment['parasitic_consumption']['#text']) / 100
emission_system = EmissionSystem(equipment_id,
model_name=model_name,
system_type=equipment_type,
parasitic_energy_consumption=parasitic_consumption)
name,
equipment_type,
parasitic_consumption)
_equipments.append(emission_system)
return _equipments
@ -155,21 +130,28 @@ class MontrealCustomCatalog(Catalog):
name = system['name']
demands = system['demands']['demand']
generation_equipment = system['equipments']['generation_id']
_generation_equipments = None
_generation_equipment = None
for equipment_archetype in self._catalog_generation_equipments:
if int(equipment_archetype.id) == int(generation_equipment):
_generation_equipments = [equipment_archetype]
_generation_equipment = equipment_archetype
distribution_equipment = system['equipments']['distribution_id']
_distribution_equipments = None
_distribution_equipment = None
for equipment_archetype in self._catalog_distribution_equipments:
if int(equipment_archetype.id) == int(distribution_equipment):
_distribution_equipments = [equipment_archetype]
_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(system_id,
_catalog_systems.append(System(self._lod,
system_id,
name,
demands,
name=name,
generation_systems=_generation_equipments,
distribution_systems=_distribution_equipments))
_generation_equipment,
_distribution_equipment,
_emission_equipment))
return _catalog_systems
def _load_archetypes(self):
@ -183,7 +165,7 @@ class MontrealCustomCatalog(Catalog):
for system_archetype in self._catalog_systems:
if int(system_archetype.id) == int(system):
_systems.append(system_archetype)
_catalog_archetypes.append(Archetype(name, _systems))
_catalog_archetypes.append(Archetype(self._lod, name, _systems))
return _catalog_archetypes
def names(self, category=None):
@ -199,9 +181,11 @@ class MontrealCustomCatalog(Catalog):
for system in self._content.systems:
_names['systems'].append(system.name)
for equipment in self._content.generation_equipments:
_names['generation_equipments'].append(equipment.model_name)
_names['generation_equipments'].append(equipment.name)
for equipment in self._content.distribution_equipments:
_names['distribution_equipments'].append(equipment.model_name)
_names['distribution_equipments'].append(equipment.name)
for equipment in self._content.emission_equipments:
_names['emission_equipments'].append(equipment.name)
else:
_names = {category: []}
if category.lower() == 'archetypes':
@ -212,10 +196,13 @@ class MontrealCustomCatalog(Catalog):
_names[category].append(system.name)
elif category.lower() == 'generation_equipments':
for system in self._content.generation_equipments:
_names[category].append(system.model_name)
_names[category].append(system.name)
elif category.lower() == 'distribution_equipments':
for system in self._content.distribution_equipments:
_names[category].append(system.model_name)
_names[category].append(system.name)
elif category.lower() == 'emission_equipments':
for system in self._content.emission_equipments:
_names[category].append(system.name)
else:
raise ValueError(f'Unknown category [{category}]')
return _names
@ -235,6 +222,9 @@ class MontrealCustomCatalog(Catalog):
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):
"""
@ -248,9 +238,12 @@ class MontrealCustomCatalog(Catalog):
if entry.name.lower() == name.lower():
return entry
for entry in self._content.generation_equipments:
if entry.model_name.lower() == name.lower():
if entry.name.lower() == name.lower():
return entry
for entry in self._content.distribution_equipments:
if entry.model_name.lower() == name.lower():
if entry.name.lower() == name.lower():
return entry
for entry in self._content.emission_equipments:
if entry.name.lower() == name.lower():
return entry
raise IndexError(f"{name} doesn't exists in the catalog")

View File

@ -1,561 +0,0 @@
"""
Montreal future energy system catalog
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import xmltodict
from pathlib import Path
from hub.catalog_factories.catalog import Catalog
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.system import System
from hub.catalog_factories.data_models.energy_systems.content import Content
from hub.catalog_factories.data_models.energy_systems.non_pv_generation_system import NonPvGenerationSystem
from hub.catalog_factories.data_models.energy_systems.pv_generation_system import PvGenerationSystem
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
from hub.catalog_factories.data_models.construction.layer import Layer
class MontrealFutureSystemCatalogue(Catalog):
"""
North america energy system catalog class
"""
def __init__(self, path):
path = str(path / 'montreal_future_systems.xml')
with open(path, 'r', encoding='utf-8') as xml:
self._archetypes = xmltodict.parse(xml.read(),
force_list=['pv_generation_component', 'templateStorages', 'demand',
'system', 'system_id'])
self._storage_components = self._load_storage_components()
self._generation_components = self._load_generation_components()
self._energy_emission_components = self._load_emission_equipments()
self._distribution_components = self._load_distribution_equipments()
self._systems = self._load_systems()
self._system_archetypes = self._load_archetypes()
self._content = Content(self._system_archetypes,
self._systems,
generations=self._generation_components,
distributions=self._distribution_components)
def _load_generation_components(self):
generation_components = []
non_pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][
'non_pv_generation_component']
if non_pv_generation_components is not None:
for non_pv in non_pv_generation_components:
system_id = non_pv['generation_system_id']
name = non_pv['name']
system_type = non_pv['system_type']
model_name = non_pv['model_name']
manufacturer = non_pv['manufacturer']
fuel_type = non_pv['fuel_type']
distribution_systems = non_pv['distribution_systems']
energy_storage_systems = None
if non_pv['energy_storage_systems'] is not None:
storage_component = non_pv['energy_storage_systems']['storage_id']
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component)
energy_storage_systems = storage_systems
nominal_heat_output = non_pv['nominal_heat_output']
maximum_heat_output = non_pv['maximum_heat_output']
minimum_heat_output = non_pv['minimum_heat_output']
source_medium = non_pv['source_medium']
supply_medium = non_pv['supply_medium']
heat_efficiency = non_pv['heat_efficiency']
nominal_cooling_output = non_pv['nominal_cooling_output']
maximum_cooling_output = non_pv['maximum_cooling_output']
minimum_cooling_output = non_pv['minimum_cooling_output']
cooling_efficiency = non_pv['cooling_efficiency']
electricity_efficiency = non_pv['electricity_efficiency']
source_temperature = non_pv['source_temperature']
source_mass_flow = non_pv['source_mass_flow']
nominal_electricity_output = non_pv['nominal_electricity_output']
maximum_heat_supply_temperature = non_pv['maximum_heat_supply_temperature']
minimum_heat_supply_temperature = non_pv['minimum_heat_supply_temperature']
maximum_cooling_supply_temperature = non_pv['maximum_cooling_supply_temperature']
minimum_cooling_supply_temperature = non_pv['minimum_cooling_supply_temperature']
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
if non_pv['heat_output_curve'] is not None:
curve_type = non_pv['heat_output_curve']['curve_type']
dependant_variable = non_pv['heat_output_curve']['dependant_variable']
parameters = non_pv['heat_output_curve']['parameters']
coefficients = list(non_pv['heat_output_curve']['coefficients'].values())
heat_output_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
if non_pv['heat_fuel_consumption_curve'] is not None:
curve_type = non_pv['heat_fuel_consumption_curve']['curve_type']
dependant_variable = non_pv['heat_fuel_consumption_curve']['dependant_variable']
parameters = non_pv['heat_fuel_consumption_curve']['parameters']
coefficients = list(non_pv['heat_fuel_consumption_curve']['coefficients'].values())
heat_fuel_consumption_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
if non_pv['heat_efficiency_curve'] is not None:
curve_type = non_pv['heat_efficiency_curve']['curve_type']
dependant_variable = non_pv['heat_efficiency_curve']['dependant_variable']
parameters = non_pv['heat_efficiency_curve']['parameters']
coefficients = list(non_pv['heat_efficiency_curve']['coefficients'].values())
heat_efficiency_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
if non_pv['cooling_output_curve'] is not None:
curve_type = non_pv['cooling_output_curve']['curve_type']
dependant_variable = non_pv['cooling_output_curve']['dependant_variable']
parameters = non_pv['cooling_output_curve']['parameters']
coefficients = list(non_pv['cooling_output_curve']['coefficients'].values())
cooling_output_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
if non_pv['cooling_fuel_consumption_curve'] is not None:
curve_type = non_pv['cooling_fuel_consumption_curve']['curve_type']
dependant_variable = non_pv['cooling_fuel_consumption_curve']['dependant_variable']
parameters = non_pv['cooling_fuel_consumption_curve']['parameters']
coefficients = list(non_pv['cooling_fuel_consumption_curve']['coefficients'].values())
cooling_fuel_consumption_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
if non_pv['cooling_efficiency_curve'] is not None:
curve_type = non_pv['cooling_efficiency_curve']['curve_type']
dependant_variable = non_pv['cooling_efficiency_curve']['dependant_variable']
parameters = non_pv['cooling_efficiency_curve']['parameters']
coefficients = list(non_pv['cooling_efficiency_curve']['coefficients'].values())
cooling_efficiency_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
dhw = None
if non_pv['domestic_hot_water'] is not None:
if non_pv['domestic_hot_water'] == 'True':
dhw = True
else:
dhw = False
reversible = None
if non_pv['reversible'] is not None:
if non_pv['reversible'] == 'True':
reversible = True
else:
reversible = False
dual_supply = None
if non_pv['simultaneous_heat_cold'] is not None:
if non_pv['simultaneous_heat_cold'] == 'True':
dual_supply = True
else:
dual_supply = False
non_pv_component = NonPvGenerationSystem(system_id=system_id,
name=name,
system_type=system_type,
model_name=model_name,
manufacturer=manufacturer,
fuel_type=fuel_type,
nominal_heat_output=nominal_heat_output,
maximum_heat_output=maximum_heat_output,
minimum_heat_output=minimum_heat_output,
source_medium=source_medium,
supply_medium=supply_medium,
heat_efficiency=heat_efficiency,
nominal_cooling_output=nominal_cooling_output,
maximum_cooling_output=maximum_cooling_output,
minimum_cooling_output=minimum_cooling_output,
cooling_efficiency=cooling_efficiency,
electricity_efficiency=electricity_efficiency,
source_temperature=source_temperature,
source_mass_flow=source_mass_flow,
nominal_electricity_output=nominal_electricity_output,
maximum_heat_supply_temperature=maximum_heat_supply_temperature,
minimum_heat_supply_temperature=minimum_heat_supply_temperature,
maximum_cooling_supply_temperature=maximum_cooling_supply_temperature,
minimum_cooling_supply_temperature=minimum_cooling_supply_temperature,
heat_output_curve=heat_output_curve,
heat_fuel_consumption_curve=heat_fuel_consumption_curve,
heat_efficiency_curve=heat_efficiency_curve,
cooling_output_curve=cooling_output_curve,
cooling_fuel_consumption_curve=cooling_fuel_consumption_curve,
cooling_efficiency_curve=cooling_efficiency_curve,
distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems,
domestic_hot_water=dhw,
reversible=reversible,
simultaneous_heat_cold=dual_supply)
generation_components.append(non_pv_component)
pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][
'pv_generation_component']
if pv_generation_components is not None:
for pv in pv_generation_components:
system_id = pv['generation_system_id']
name = pv['name']
system_type = pv['system_type']
model_name = pv['model_name']
manufacturer = pv['manufacturer']
electricity_efficiency = pv['electricity_efficiency']
nominal_electricity_output = pv['nominal_electricity_output']
nominal_ambient_temperature = pv['nominal_ambient_temperature']
nominal_cell_temperature = pv['nominal_cell_temperature']
nominal_radiation = pv['nominal_radiation']
standard_test_condition_cell_temperature = pv['standard_test_condition_cell_temperature']
standard_test_condition_maximum_power = pv['standard_test_condition_maximum_power']
standard_test_condition_radiation = pv['standard_test_condition_radiation']
cell_temperature_coefficient = pv['cell_temperature_coefficient']
width = pv['width']
height = pv['height']
distribution_systems = pv['distribution_systems']
energy_storage_systems = None
if pv['energy_storage_systems'] is not None:
storage_component = pv['energy_storage_systems']['storage_id']
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component)
energy_storage_systems = storage_systems
pv_component = PvGenerationSystem(system_id=system_id,
name=name,
system_type=system_type,
model_name=model_name,
manufacturer=manufacturer,
electricity_efficiency=electricity_efficiency,
nominal_electricity_output=nominal_electricity_output,
nominal_ambient_temperature=nominal_ambient_temperature,
nominal_cell_temperature=nominal_cell_temperature,
nominal_radiation=nominal_radiation,
standard_test_condition_cell_temperature=
standard_test_condition_cell_temperature,
standard_test_condition_maximum_power=standard_test_condition_maximum_power,
standard_test_condition_radiation=standard_test_condition_radiation,
cell_temperature_coefficient=cell_temperature_coefficient,
width=width,
height=height,
distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems)
generation_components.append(pv_component)
return generation_components
def _load_distribution_equipments(self):
_equipments = []
distribution_systems = self._archetypes['EnergySystemCatalog']['distribution_systems']['distribution_system']
if distribution_systems is not None:
for distribution_system in distribution_systems:
system_id = None
model_name = None
system_type = None
supply_temperature = None
distribution_consumption_fix_flow = None
distribution_consumption_variable_flow = None
heat_losses = None
generation_systems = None
energy_storage_systems = None
emission_systems = None
distribution_equipment = DistributionSystem(system_id=system_id,
model_name=model_name,
system_type=system_type,
supply_temperature=supply_temperature,
distribution_consumption_fix_flow=distribution_consumption_fix_flow,
distribution_consumption_variable_flow=
distribution_consumption_variable_flow,
heat_losses=heat_losses,
generation_systems=generation_systems,
energy_storage_systems=energy_storage_systems,
emission_systems=emission_systems
)
_equipments.append(distribution_equipment)
return _equipments
def _load_emission_equipments(self):
_equipments = []
dissipation_systems = self._archetypes['EnergySystemCatalog']['dissipation_systems']['dissipation_system']
if dissipation_systems is not None:
for dissipation_system in dissipation_systems:
system_id = None
model_name = None
system_type = None
parasitic_energy_consumption = 0
emission_system = EmissionSystem(system_id=system_id,
model_name=model_name,
system_type=system_type,
parasitic_energy_consumption=parasitic_energy_consumption)
_equipments.append(emission_system)
return _equipments
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']
type_energy_stored = tes['type_energy_stored']
model_name = tes['model_name']
manufacturer = tes['manufacturer']
storage_type = tes['storage_type']
volume = tes['physical_characteristics']['volume']
height = tes['physical_characteristics']['height']
maximum_operating_temperature = tes['maximum_operating_temperature']
materials = self._load_materials()
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['physical_characteristics']['tankThickness']) / 100 # from cm to m
tank_layer = Layer(None, 'tank', tank_material, thickness)
media = self._load_media()
media_id = tes['storage_medium']['medium_id']
medium = self._search_media(media, media_id)
layers = [insulation_layer, tank_layer]
nominal_capacity = tes['nominal_capacity']
losses_ratio = tes['losses_ratio']
heating_coil_capacity = tes['heating_coil_capacity']
storage_component = ThermalStorageSystem(storage_id=storage_id,
model_name=model_name,
type_energy_stored=type_energy_stored,
manufacturer=manufacturer,
storage_type=storage_type,
nominal_capacity=nominal_capacity,
losses_ratio=losses_ratio,
volume=volume,
height=height,
layers=layers,
maximum_operating_temperature=maximum_operating_temperature,
storage_medium=medium,
heating_coil_capacity=heating_coil_capacity)
storage_components.append(storage_component)
for template in template_storages:
storage_id = template['storage_id']
storage_type = template['storage_type']
type_energy_stored = template['type_energy_stored']
maximum_operating_temperature = template['maximum_operating_temperature']
height = float(template['physical_characteristics']['height'])
materials = self._load_materials()
insulation_material_id = template['insulation']['material_id']
insulation_material = self._search_material(materials, insulation_material_id)
material_id = template['physical_characteristics']['material_id']
tank_material = self._search_material(materials, material_id)
thickness = float(template['insulation']['insulationThickness']) / 100 # from cm to m
insulation_layer = Layer(None, 'insulation', insulation_material, thickness)
thickness = float(template['physical_characteristics']['tankThickness']) / 100 # from cm to m
tank_layer = Layer(None, 'tank', tank_material, thickness)
layers = [insulation_layer, tank_layer]
media = self._load_media()
media_id = template['storage_medium']['medium_id']
medium = self._search_media(media, media_id)
model_name = template['model_name']
manufacturer = template['manufacturer']
nominal_capacity = template['nominal_capacity']
losses_ratio = template['losses_ratio']
volume = template['physical_characteristics']['volume']
heating_coil_capacity = template['heating_coil_capacity']
storage_component = ThermalStorageSystem(storage_id=storage_id,
model_name=model_name,
type_energy_stored=type_energy_stored,
manufacturer=manufacturer,
storage_type=storage_type,
nominal_capacity=nominal_capacity,
losses_ratio=losses_ratio,
volume=volume,
height=height,
layers=layers,
maximum_operating_temperature=maximum_operating_temperature,
storage_medium=medium,
heating_coil_capacity=heating_coil_capacity)
storage_components.append(storage_component)
return storage_components
def _load_systems(self):
base_path = Path(Path(__file__).parent.parent.parent / 'data/energy_systems')
_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)
configuration_schema = Path(base_path / system['schema'])
energy_system = System(system_id=system_id,
name=name,
demand_types=demands,
generation_systems=generation_systems,
distribution_systems=None,
configuration_schema=configuration_schema)
_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:
archetype_id = system_cluster['@cluster_id']
name = system_cluster['name']
systems = system_cluster['systems']['system_id']
integer_system_ids = [int(item) for item in systems]
_systems = []
for system_archetype in self._systems:
if int(system_archetype.id) in integer_system_ids:
_systems.append(system_archetype)
_system_archetypes.append(Archetype(archetype_cluster_id=archetype_id, name=name, systems=_systems))
return _system_archetypes
def _load_materials(self):
materials = []
_materials = self._archetypes['EnergySystemCatalog']['materials']['material']
for _material in _materials:
material_id = _material['material_id']
name = _material['name']
conductivity = _material['conductivity']
solar_absorptance = _material['solar_absorptance']
thermal_absorptance = _material['thermal_absorptance']
density = _material['density']
specific_heat = _material['specific_heat']
no_mass = _material['no_mass']
visible_absorptance = _material['visible_absorptance']
thermal_resistance = _material['thermal_resistance']
material = Material(material_id,
name,
solar_absorptance=solar_absorptance,
thermal_absorptance=thermal_absorptance,
density=density,
conductivity=conductivity,
thermal_resistance=thermal_resistance,
visible_absorptance=visible_absorptance,
no_mass=no_mass,
specific_heat=specific_heat)
materials.append(material)
return materials
@staticmethod
def _search_material(materials, material_id):
_material = None
for material in materials:
if int(material.id) == int(material_id):
_material = material
break
if _material is None:
raise ValueError(f'Material with the id = [{material_id}] not found in catalog ')
return _material
def _load_media(self):
media = []
_media = [self._archetypes['EnergySystemCatalog']['media']['medium']]
for _medium in _media:
medium_id = _medium['medium_id']
density = _medium['density']
name = _medium['name']
conductivity = _medium['conductivity']
solar_absorptance = _medium['solar_absorptance']
thermal_absorptance = _medium['thermal_absorptance']
specific_heat = _medium['specific_heat']
no_mass = _medium['no_mass']
visible_absorptance = _medium['visible_absorptance']
thermal_resistance = _medium['thermal_resistance']
medium = Material(material_id=medium_id,
name=name,
solar_absorptance=solar_absorptance,
thermal_absorptance=thermal_absorptance,
visible_absorptance=visible_absorptance,
no_mass=no_mass,
thermal_resistance=thermal_resistance,
conductivity=conductivity,
density=density,
specific_heat=specific_heat)
media.append(medium)
return media
@staticmethod
def _search_media(media, medium_id):
_medium = None
for medium in media:
if int(medium.id) == int(medium_id):
_medium = medium
break
if _medium is None:
raise ValueError(f'media with the id = [{medium_id}] not found in catalog ')
return _medium
@staticmethod
def _search_generation_equipment(generation_systems, generation_id):
_generation_systems = []
if isinstance(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}]')
return _generation_systems
@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 = 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)
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)
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
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
raise IndexError(f"{name} doesn't exists in the catalog")

View File

@ -1,520 +0,0 @@
"""
Palma energy system catalog
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import xmltodict
from pathlib import Path
from hub.catalog_factories.catalog import Catalog
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.system import System
from hub.catalog_factories.data_models.energy_systems.content import Content
from hub.catalog_factories.data_models.energy_systems.non_pv_generation_system import NonPvGenerationSystem
from hub.catalog_factories.data_models.energy_systems.pv_generation_system import PvGenerationSystem
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
from hub.catalog_factories.data_models.construction.layer import Layer
class PalmaSystemCatalogue(Catalog):
"""
North america energy system catalog class
"""
def __init__(self, path):
path = str(path / 'palma_systems.xml')
with open(path, 'r', encoding='utf-8') as xml:
self._archetypes = xmltodict.parse(xml.read(),
force_list=['pv_generation_component', 'demand'])
self._storage_components = self._load_storage_components()
self._generation_components = self._load_generation_components()
self._energy_emission_components = self._load_emission_equipments()
self._distribution_components = self._load_distribution_equipments()
self._systems = self._load_systems()
self._system_archetypes = self._load_archetypes()
self._content = Content(self._system_archetypes,
self._systems,
generations=self._generation_components,
distributions=self._distribution_components)
def _load_generation_components(self):
generation_components = []
non_pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][
'non_pv_generation_component']
if non_pv_generation_components is not None:
for non_pv in non_pv_generation_components:
system_id = non_pv['system_id']
name = non_pv['name']
system_type = non_pv['system_type']
model_name = non_pv['model_name']
manufacturer = non_pv['manufacturer']
fuel_type = non_pv['fuel_type']
distribution_systems = non_pv['distribution_systems']
energy_storage_systems = None
if non_pv['energy_storage_systems'] is not None:
storage_component = non_pv['energy_storage_systems']['storage_id']
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component)
energy_storage_systems = storage_systems
nominal_heat_output = non_pv['nominal_heat_output']
maximum_heat_output = non_pv['maximum_heat_output']
minimum_heat_output = non_pv['minimum_heat_output']
source_medium = non_pv['source_medium']
supply_medium = non_pv['supply_medium']
heat_efficiency = non_pv['heat_efficiency']
nominal_cooling_output = non_pv['nominal_cooling_output']
maximum_cooling_output = non_pv['maximum_cooling_output']
minimum_cooling_output = non_pv['minimum_cooling_output']
cooling_efficiency = non_pv['cooling_efficiency']
electricity_efficiency = non_pv['electricity_efficiency']
source_temperature = non_pv['source_temperature']
source_mass_flow = non_pv['source_mass_flow']
nominal_electricity_output = non_pv['nominal_electricity_output']
maximum_heat_supply_temperature = non_pv['maximum_heat_supply_temperature']
minimum_heat_supply_temperature = non_pv['minimum_heat_supply_temperature']
maximum_cooling_supply_temperature = non_pv['maximum_cooling_supply_temperature']
minimum_cooling_supply_temperature = non_pv['minimum_cooling_supply_temperature']
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
if non_pv['heat_output_curve'] is not None:
curve_type = non_pv['heat_output_curve']['curve_type']
dependant_variable = non_pv['heat_output_curve']['dependant_variable']
parameters = non_pv['heat_output_curve']['parameters']
coefficients = list(non_pv['heat_output_curve']['coefficients'].values())
heat_output_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
if non_pv['heat_fuel_consumption_curve'] is not None:
curve_type = non_pv['heat_fuel_consumption_curve']['curve_type']
dependant_variable = non_pv['heat_fuel_consumption_curve']['dependant_variable']
parameters = non_pv['heat_fuel_consumption_curve']['parameters']
coefficients = list(non_pv['heat_fuel_consumption_curve']['coefficients'].values())
heat_fuel_consumption_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
if non_pv['heat_efficiency_curve'] is not None:
curve_type = non_pv['heat_efficiency_curve']['curve_type']
dependant_variable = non_pv['heat_efficiency_curve']['dependant_variable']
parameters = non_pv['heat_efficiency_curve']['parameters']
coefficients = list(non_pv['heat_efficiency_curve']['coefficients'].values())
heat_efficiency_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
if non_pv['cooling_output_curve'] is not None:
curve_type = non_pv['cooling_output_curve']['curve_type']
dependant_variable = non_pv['cooling_output_curve']['dependant_variable']
parameters = non_pv['cooling_output_curve']['parameters']
coefficients = list(non_pv['cooling_output_curve']['coefficients'].values())
cooling_output_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
if non_pv['cooling_fuel_consumption_curve'] is not None:
curve_type = non_pv['cooling_fuel_consumption_curve']['curve_type']
dependant_variable = non_pv['cooling_fuel_consumption_curve']['dependant_variable']
parameters = non_pv['cooling_fuel_consumption_curve']['parameters']
coefficients = list(non_pv['cooling_fuel_consumption_curve']['coefficients'].values())
cooling_fuel_consumption_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
if non_pv['cooling_efficiency_curve'] is not None:
curve_type = non_pv['cooling_efficiency_curve']['curve_type']
dependant_variable = non_pv['cooling_efficiency_curve']['dependant_variable']
parameters = non_pv['cooling_efficiency_curve']['parameters']
coefficients = list(non_pv['cooling_efficiency_curve']['coefficients'].values())
cooling_efficiency_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
dhw = None
if non_pv['domestic_hot_water'] is not None:
if non_pv['domestic_hot_water'] == 'True':
dhw = True
else:
dhw = False
reversible = None
if non_pv['reversible'] is not None:
if non_pv['reversible'] == 'True':
reversible = True
else:
reversible = False
dual_supply = None
if non_pv['simultaneous_heat_cold'] is not None:
if non_pv['simultaneous_heat_cold'] == 'True':
dual_supply = True
else:
dual_supply = False
non_pv_component = NonPvGenerationSystem(system_id=system_id,
name=name,
system_type=system_type,
model_name=model_name,
manufacturer=manufacturer,
fuel_type=fuel_type,
nominal_heat_output=nominal_heat_output,
maximum_heat_output=maximum_heat_output,
minimum_heat_output=minimum_heat_output,
source_medium=source_medium,
supply_medium=supply_medium,
heat_efficiency=heat_efficiency,
nominal_cooling_output=nominal_cooling_output,
maximum_cooling_output=maximum_cooling_output,
minimum_cooling_output=minimum_cooling_output,
cooling_efficiency=cooling_efficiency,
electricity_efficiency=electricity_efficiency,
source_temperature=source_temperature,
source_mass_flow=source_mass_flow,
nominal_electricity_output=nominal_electricity_output,
maximum_heat_supply_temperature=maximum_heat_supply_temperature,
minimum_heat_supply_temperature=minimum_heat_supply_temperature,
maximum_cooling_supply_temperature=maximum_cooling_supply_temperature,
minimum_cooling_supply_temperature=minimum_cooling_supply_temperature,
heat_output_curve=heat_output_curve,
heat_fuel_consumption_curve=heat_fuel_consumption_curve,
heat_efficiency_curve=heat_efficiency_curve,
cooling_output_curve=cooling_output_curve,
cooling_fuel_consumption_curve=cooling_fuel_consumption_curve,
cooling_efficiency_curve=cooling_efficiency_curve,
distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems,
domestic_hot_water=dhw,
reversible=reversible,
simultaneous_heat_cold=dual_supply)
generation_components.append(non_pv_component)
pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][
'pv_generation_component']
if pv_generation_components is not None:
for pv in pv_generation_components:
system_id = pv['system_id']
name = pv['name']
system_type = pv['system_type']
model_name = pv['model_name']
manufacturer = pv['manufacturer']
electricity_efficiency = pv['electricity_efficiency']
nominal_electricity_output = pv['nominal_electricity_output']
nominal_ambient_temperature = pv['nominal_ambient_temperature']
nominal_cell_temperature = pv['nominal_cell_temperature']
nominal_radiation = pv['nominal_radiation']
standard_test_condition_cell_temperature = pv['standard_test_condition_cell_temperature']
standard_test_condition_maximum_power = pv['standard_test_condition_maximum_power']
standard_test_condition_radiation = pv['standard_test_condition_radiation']
cell_temperature_coefficient = pv['cell_temperature_coefficient']
width = pv['width']
height = pv['height']
distribution_systems = pv['distribution_systems']
energy_storage_systems = None
if pv['energy_storage_systems'] is not None:
storage_component = pv['energy_storage_systems']['storage_id']
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component)
energy_storage_systems = storage_systems
pv_component = PvGenerationSystem(system_id=system_id,
name=name,
system_type=system_type,
model_name=model_name,
manufacturer=manufacturer,
electricity_efficiency=electricity_efficiency,
nominal_electricity_output=nominal_electricity_output,
nominal_ambient_temperature=nominal_ambient_temperature,
nominal_cell_temperature=nominal_cell_temperature,
nominal_radiation=nominal_radiation,
standard_test_condition_cell_temperature=
standard_test_condition_cell_temperature,
standard_test_condition_maximum_power=standard_test_condition_maximum_power,
standard_test_condition_radiation=standard_test_condition_radiation,
cell_temperature_coefficient=cell_temperature_coefficient,
width=width,
height=height,
distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems)
generation_components.append(pv_component)
return generation_components
def _load_distribution_equipments(self):
_equipments = []
distribution_systems = self._archetypes['EnergySystemCatalog']['distribution_systems']['distribution_system']
if distribution_systems is not None:
for distribution_system in distribution_systems:
system_id = None
model_name = None
system_type = None
supply_temperature = None
distribution_consumption_fix_flow = None
distribution_consumption_variable_flow = None
heat_losses = None
generation_systems = None
energy_storage_systems = None
emission_systems = None
distribution_equipment = DistributionSystem(system_id=system_id,
model_name=model_name,
system_type=system_type,
supply_temperature=supply_temperature,
distribution_consumption_fix_flow=distribution_consumption_fix_flow,
distribution_consumption_variable_flow=
distribution_consumption_variable_flow,
heat_losses=heat_losses,
generation_systems=generation_systems,
energy_storage_systems=energy_storage_systems,
emission_systems=emission_systems
)
_equipments.append(distribution_equipment)
return _equipments
def _load_emission_equipments(self):
_equipments = []
dissipation_systems = self._archetypes['EnergySystemCatalog']['dissipation_systems']['dissipation_system']
if dissipation_systems is not None:
for dissipation_system in dissipation_systems:
system_id = None
model_name = None
system_type = None
parasitic_energy_consumption = 0
emission_system = EmissionSystem(system_id=system_id,
model_name=model_name,
system_type=system_type,
parasitic_energy_consumption=parasitic_energy_consumption)
_equipments.append(emission_system)
return _equipments
def _load_storage_components(self):
storage_components = []
thermal_storages = self._archetypes['EnergySystemCatalog']['energy_storage_components']['thermalStorages']
for tes in thermal_storages:
storage_id = tes['storage_id']
type_energy_stored = tes['type_energy_stored']
model_name = tes['model_name']
manufacturer = tes['manufacturer']
storage_type = tes['storage_type']
volume = tes['physical_characteristics']['volume']
height = tes['physical_characteristics']['height']
maximum_operating_temperature = tes['maximum_operating_temperature']
materials = self._load_materials()
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['physical_characteristics']['tankThickness']) / 100 # from cm to m
tank_layer = Layer(None, 'tank', tank_material, thickness)
media = self._load_media()
media_id = tes['storage_medium']['medium_id']
medium = self._search_media(media, media_id)
layers = [insulation_layer, tank_layer]
nominal_capacity = tes['nominal_capacity']
losses_ratio = tes['losses_ratio']
heating_coil_capacity = tes['heating_coil_capacity']
storage_component = ThermalStorageSystem(storage_id=storage_id,
model_name=model_name,
type_energy_stored=type_energy_stored,
manufacturer=manufacturer,
storage_type=storage_type,
nominal_capacity=nominal_capacity,
losses_ratio=losses_ratio,
volume=volume,
height=height,
layers=layers,
maximum_operating_temperature=maximum_operating_temperature,
storage_medium=medium,
heating_coil_capacity=heating_coil_capacity)
storage_components.append(storage_component)
return storage_components
def _load_systems(self):
base_path = Path(Path(__file__).parent.parent.parent / 'data/energy_systems')
_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)
configuration_schema = None
if system['schema'] is not None:
configuration_schema = Path(base_path / system['schema'])
energy_system = System(system_id=system_id,
name=name,
demand_types=demands,
generation_systems=generation_systems,
distribution_systems=None,
configuration_schema=configuration_schema)
_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']
integer_system_ids = [int(item) for item in systems]
_systems = []
for system_archetype in self._systems:
if int(system_archetype.id) in integer_system_ids:
_systems.append(system_archetype)
_system_archetypes.append(Archetype(name=name, systems=_systems))
return _system_archetypes
def _load_materials(self):
materials = []
_materials = self._archetypes['EnergySystemCatalog']['materials']['material']
for _material in _materials:
material_id = _material['material_id']
name = _material['name']
conductivity = _material['conductivity']
solar_absorptance = _material['solar_absorptance']
thermal_absorptance = _material['thermal_absorptance']
density = _material['density']
specific_heat = _material['specific_heat']
no_mass = _material['no_mass']
visible_absorptance = _material['visible_absorptance']
thermal_resistance = _material['thermal_resistance']
material = Material(material_id,
name,
solar_absorptance=solar_absorptance,
thermal_absorptance=thermal_absorptance,
density=density,
conductivity=conductivity,
thermal_resistance=thermal_resistance,
visible_absorptance=visible_absorptance,
no_mass=no_mass,
specific_heat=specific_heat)
materials.append(material)
return materials
@staticmethod
def _search_material(materials, material_id):
_material = None
for material in materials:
if int(material.id) == int(material_id):
_material = material
break
if _material is None:
raise ValueError(f'Material with the id = [{material_id}] not found in catalog ')
return _material
def _load_media(self):
media = []
_media = [self._archetypes['EnergySystemCatalog']['media']['medium']]
for _medium in _media:
medium_id = _medium['medium_id']
density = _medium['density']
name = _medium['name']
conductivity = _medium['conductivity']
solar_absorptance = _medium['solar_absorptance']
thermal_absorptance = _medium['thermal_absorptance']
specific_heat = _medium['specific_heat']
no_mass = _medium['no_mass']
visible_absorptance = _medium['visible_absorptance']
thermal_resistance = _medium['thermal_resistance']
medium = Material(material_id=medium_id,
name=name,
solar_absorptance=solar_absorptance,
thermal_absorptance=thermal_absorptance,
visible_absorptance=visible_absorptance,
no_mass=no_mass,
thermal_resistance=thermal_resistance,
conductivity=conductivity,
density=density,
specific_heat=specific_heat)
media.append(medium)
return media
@staticmethod
def _search_media(media, medium_id):
_medium = None
for medium in media:
if int(medium.id) == int(medium_id):
_medium = medium
break
if _medium is None:
raise ValueError(f'media with the id = [{medium_id}] not found in catalog ')
return _medium
@staticmethod
def _search_generation_equipment(generation_systems, generation_id):
_generation_systems = []
if isinstance(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}]')
return _generation_systems
@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 = 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)
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)
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
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
raise IndexError(f"{name} doesn't exists in the catalog")

View File

@ -9,8 +9,6 @@ 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.montreal_future_system_catalogue import MontrealFutureSystemCatalogue
from hub.catalog_factories.energy_systems.palma_system_catalgue import PalmaSystemCatalogue
from hub.helpers.utils import validate_import_export_type
Catalog = TypeVar('Catalog')
@ -34,20 +32,6 @@ class EnergySystemsCatalogFactory:
"""
return MontrealCustomCatalog(self._path)
@property
def _montreal_future(self):
"""
Retrieve North American catalog
"""
return MontrealFutureSystemCatalogue(self._path)
@property
def _palma(self):
"""
Retrieve Palma catalog
"""
return PalmaSystemCatalogue(self._path)
@property
def catalog(self) -> Catalog:
"""

View File

@ -190,14 +190,14 @@ class ComnetCatalog(Catalog):
schedules_key = {}
for j in range(0, number_usage_types-1):
usage_parameters = _extracted_data.iloc[j]
usage_type = usage_parameters.iloc[0]
lighting_data[usage_type] = usage_parameters.iloc[1:6].values.tolist()
plug_loads_data[usage_type] = usage_parameters.iloc[8:13].values.tolist()
occupancy_data[usage_type] = usage_parameters.iloc[17:20].values.tolist()
ventilation_rate[usage_type] = usage_parameters.iloc[20:21].item()
water_heating[usage_type] = usage_parameters.iloc[23:24].item()
process_data[usage_type] = usage_parameters.iloc[24:26].values.tolist()
schedules_key[usage_type] = usage_parameters.iloc[27:28].item()
usage_type = usage_parameters[0]
lighting_data[usage_type] = usage_parameters[1:6].values.tolist()
plug_loads_data[usage_type] = usage_parameters[8:13].values.tolist()
occupancy_data[usage_type] = usage_parameters[17:20].values.tolist()
ventilation_rate[usage_type] = usage_parameters[20:21].item()
water_heating[usage_type] = usage_parameters[23:24].item()
process_data[usage_type] = usage_parameters[24:26].values.tolist()
schedules_key[usage_type] = usage_parameters[27:28].item()
return {'lighting': lighting_data,
'plug loads': plug_loads_data,

View File

@ -1,227 +0,0 @@
"""
Palma usage catalog
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Cecilia Pérez cperez@irec.cat
"""
import json
import urllib.request
from pathlib import Path
import xmltodict
import hub.helpers.constants as cte
from hub.catalog_factories.catalog import Catalog
from hub.catalog_factories.data_models.usages.appliances import Appliances
from hub.catalog_factories.data_models.usages.content import Content
from hub.catalog_factories.data_models.usages.lighting import Lighting
from hub.catalog_factories.data_models.usages.occupancy import Occupancy
from hub.catalog_factories.data_models.usages.domestic_hot_water import DomesticHotWater
from hub.catalog_factories.data_models.usages.schedule import Schedule
from hub.catalog_factories.data_models.usages.thermal_control import ThermalControl
from hub.catalog_factories.data_models.usages.usage import Usage
from hub.catalog_factories.usage.usage_helper import UsageHelper
class PalmaCatalog(Catalog):
"""
Palma catalog class
"""
def __init__(self, path):
self._schedules_path = Path(path / 'palma_schedules.json').resolve()
self._space_types_path = Path(path / 'palma_space_types.json').resolve()
self._space_compliance_path = Path(path / 'palma_space_compliance.json').resolve()
self._content = None
self._schedules = {}
self._load_schedules()
self._content = Content(self._load_archetypes())
@staticmethod
def _extract_schedule(raw):
nrcan_schedule_type = raw['category']
if 'Heating' in raw['name'] and 'Water' not in raw['name']:
nrcan_schedule_type = f'{nrcan_schedule_type} Heating'
elif 'Cooling' in raw['name']:
nrcan_schedule_type = f'{nrcan_schedule_type} Cooling'
if nrcan_schedule_type not in UsageHelper().nrcan_schedule_type_to_hub_schedule_type:
return None
hub_type = UsageHelper().nrcan_schedule_type_to_hub_schedule_type[nrcan_schedule_type]
data_type = UsageHelper().nrcan_data_type_to_hub_data_type[raw['units']]
time_step = UsageHelper().nrcan_time_to_hub_time[raw['type']]
# nrcan only uses daily range for the schedules
time_range = cte.DAY
day_types = UsageHelper().nrcan_day_type_to_hub_days[raw['day_types']]
return Schedule(hub_type, raw['values'], data_type, time_step, time_range, day_types)
def _load_schedules(self):
_schedule_types = []
with open(self._schedules_path, 'r') as f:
schedules_type = json.load(f)
for schedule_type in schedules_type['tables']['schedules']['table']:
schedule = PalmaCatalog._extract_schedule(schedule_type)
if schedule_type['name'] not in _schedule_types:
_schedule_types.append(schedule_type['name'])
if schedule is not None:
self._schedules[schedule_type['name']] = [schedule]
else:
if schedule is not None:
_schedules = self._schedules[schedule_type['name']]
_schedules.append(schedule)
self._schedules[schedule_type['name']] = _schedules
def _get_schedules(self, name):
schedule = None
if name in self._schedules:
schedule = self._schedules[name]
return schedule
def _load_archetypes(self):
usages = []
with open(self._space_types_path, 'r') as f:
space_types = json.load(f)['tables']['space_types']['table']
space_types = [st for st in space_types if st['space_type'] == 'WholeBuilding']
with open(self._space_compliance_path, 'r') as f:
space_types_compliance = json.load(f)['tables']['space_compliance']['table']
space_types_compliance = [st for st in space_types_compliance if st['space_type'] == 'WholeBuilding']
space_types_dictionary = {}
for space_type in space_types_compliance:
usage_type = space_type['building_type']
# people/m2
occupancy_density = space_type['occupancy_per_area_people_per_m2']
# W/m2
lighting_density = space_type['lighting_per_area_w_per_m2']
# W/m2
appliances_density = space_type['electric_equipment_per_area_w_per_m2']
# peak flow in gallons/h/m2
domestic_hot_water_peak_flow = (
space_type['service_water_heating_peak_flow_per_area'] *
cte.GALLONS_TO_QUBIC_METERS / cte.HOUR_TO_SECONDS
)
space_types_dictionary[usage_type] = {'occupancy_per_area': occupancy_density,
'lighting_per_area': lighting_density,
'electric_equipment_per_area': appliances_density,
'service_water_heating_peak_flow_per_area': domestic_hot_water_peak_flow
}
for space_type in space_types:
usage_type = space_type['building_type']
space_type_compliance = space_types_dictionary[usage_type]
occupancy_density = space_type_compliance['occupancy_per_area']
sensible_convective_internal_gain = space_type['sensible_convective_internal_gain']
sensible_radiative_internal_gain = space_type['sensible_radiative_internal_gain']
latent_internal_gain = space_type['latent_internal_gain']
lighting_density = space_type_compliance['lighting_per_area']
appliances_density = space_type_compliance['electric_equipment_per_area']
domestic_hot_water_peak_flow = space_type_compliance['service_water_heating_peak_flow_per_area']
occupancy_schedule_name = space_type['occupancy_schedule']
lighting_schedule_name = space_type['lighting_schedule']
appliance_schedule_name = space_type['electric_equipment_schedule']
hvac_schedule_name = space_type['exhaust_schedule']
if hvac_schedule_name and 'FAN' in hvac_schedule_name:
hvac_schedule_name = hvac_schedule_name.replace('FAN', 'Fan')
if not hvac_schedule_name:
hvac_schedule_name = 'default_HVAC_schedule'
heating_setpoint_schedule_name = space_type['heating_setpoint_schedule']
cooling_setpoint_schedule_name = space_type['cooling_setpoint_schedule']
domestic_hot_water_schedule_name = space_type['service_water_heating_schedule']
occupancy_schedule = self._get_schedules(occupancy_schedule_name)
lighting_schedule = self._get_schedules(lighting_schedule_name)
appliance_schedule = self._get_schedules(appliance_schedule_name)
heating_schedule = self._get_schedules(heating_setpoint_schedule_name)
cooling_schedule = self._get_schedules(cooling_setpoint_schedule_name)
hvac_availability = self._get_schedules(hvac_schedule_name)
domestic_hot_water_load_schedule = self._get_schedules(domestic_hot_water_schedule_name)
# ACH -> 1/s
mechanical_air_change = space_type['ventilation_air_changes'] / cte.HOUR_TO_SECONDS
# cfm/ft2 to m3/m2.s
ventilation_rate = space_type['ventilation_per_area'] / (cte.METERS_TO_FEET * cte.MINUTES_TO_SECONDS)
# cfm/person to m3/m2.s
ventilation_rate += space_type['ventilation_per_person'] / (
pow(cte.METERS_TO_FEET, 3) * cte.MINUTES_TO_SECONDS
) * occupancy_density
lighting_radiative_fraction = space_type['lighting_fraction_radiant']
lighting_convective_fraction = 0
if lighting_radiative_fraction is not None:
lighting_convective_fraction = 1 - lighting_radiative_fraction
lighting_latent_fraction = 0
appliances_radiative_fraction = space_type['electric_equipment_fraction_radiant']
appliances_latent_fraction = space_type['electric_equipment_fraction_latent']
appliances_convective_fraction = 0
if appliances_radiative_fraction is not None and appliances_latent_fraction is not None:
appliances_convective_fraction = 1 - appliances_radiative_fraction - appliances_latent_fraction
domestic_hot_water_service_temperature = space_type['service_water_heating_target_temperature']
occupancy = Occupancy(occupancy_density,
sensible_convective_internal_gain,
sensible_radiative_internal_gain,
latent_internal_gain,
occupancy_schedule)
lighting = Lighting(lighting_density,
lighting_convective_fraction,
lighting_radiative_fraction,
lighting_latent_fraction,
lighting_schedule)
appliances = Appliances(appliances_density,
appliances_convective_fraction,
appliances_radiative_fraction,
appliances_latent_fraction,
appliance_schedule)
thermal_control = ThermalControl(None,
None,
None,
hvac_availability,
heating_schedule,
cooling_schedule)
domestic_hot_water = DomesticHotWater(None,
domestic_hot_water_peak_flow,
domestic_hot_water_service_temperature,
domestic_hot_water_load_schedule)
hours_day = None
days_year = None
usages.append(Usage(usage_type,
hours_day,
days_year,
mechanical_air_change,
ventilation_rate,
occupancy,
lighting,
appliances,
thermal_control,
domestic_hot_water))
return usages
def names(self, category=None):
"""
Get the catalog elements names
:parm: for usage catalog category filter does nothing as there is only one category (usages)
"""
_names = {'usages': []}
for usage in self._content.usages:
_names['usages'].append(usage.name)
return _names
def entries(self, category=None):
"""
Get the catalog elements
:parm: for usage catalog category filter does nothing as there is only one category (usages)
"""
return self._content
def get_entry(self, name):
"""
Get one catalog element by names
:parm: entry name
"""
for usage in self._content.usages:
if usage.name.lower() == name.lower():
return usage
raise IndexError(f"{name} doesn't exists in the catalog")

View File

@ -11,7 +11,6 @@ from typing import TypeVar
from hub.catalog_factories.usage.comnet_catalog import ComnetCatalog
from hub.catalog_factories.usage.nrcan_catalog import NrcanCatalog
from hub.catalog_factories.usage.eilat_catalog import EilatCatalog
from hub.catalog_factories.usage.palma_catalog import PalmaCatalog
from hub.helpers.utils import validate_import_export_type
Catalog = TypeVar('Catalog')
@ -43,13 +42,6 @@ class UsageCatalogFactory:
# nrcan retrieves the data directly from github
return NrcanCatalog(self._path)
@property
def _palma(self):
"""
Retrieve Palma catalog
"""
return PalmaCatalog(self._path)
@property
def _eilat(self):
"""

View File

@ -27,7 +27,7 @@ class Building(CityObject):
"""
Building(CityObject) class
"""
def __init__(self, name, surfaces, year_of_construction, function, usages=None, terrains=None, city=None):
def __init__(self, name, surfaces, year_of_construction, function, terrains=None, city=None):
super().__init__(name, surfaces)
self._city = city
self._households = None
@ -36,7 +36,6 @@ class Building(CityObject):
self._terrains = terrains
self._year_of_construction = year_of_construction
self._function = function
self._usages = usages
self._average_storey_height = None
self._storeys_above_ground = None
self._floor_area = None
@ -90,11 +89,7 @@ class Building(CityObject):
elif surface.type == cte.INTERIOR_SLAB:
self._interior_slabs.append(surface)
else:
logging.error('Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type)
self._domestic_hot_water_peak_load = None
self._fuel_consumption_breakdown = {}
self._systems_archetype_cluster_id = None
self._pv_generation = {}
logging.error(f'Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type)
@property
def shell(self) -> Polyhedron:
@ -258,17 +253,7 @@ class Building(CityObject):
:param value: str
"""
if value is not None:
self._function = value
@property
def usages(self) -> Union[None, list]:
"""
Get building usages, if none, assume usage is function
:return: None or list of functions
"""
if self._usages is None and self._function is not None:
self._usages = [{'usage': self._function, 'ratio': 1 }]
return self._usages
self._function = str(value)
@property
def average_storey_height(self) -> Union[None, float]:
@ -304,10 +289,7 @@ class Building(CityObject):
"""
if self._storeys_above_ground is None:
if self.eave_height is not None and self.average_storey_height is not None:
storeys_above_ground = int(self.eave_height / self.average_storey_height)
if storeys_above_ground == 0:
storeys_above_ground += 1
self._storeys_above_ground = storeys_above_ground
self._storeys_above_ground = int(self.eave_height / self.average_storey_height)
return self._storeys_above_ground
@storeys_above_ground.setter
@ -466,8 +448,8 @@ class Building(CityObject):
monthly_values = PeakLoads(self).heating_peak_loads_from_methodology
if monthly_values is None:
return None
results[cte.MONTH] = [x / cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES]
results[cte.MONTH] = [x * cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values)]
return results
@property
@ -483,24 +465,8 @@ class Building(CityObject):
monthly_values = PeakLoads(self).cooling_peak_loads_from_methodology
if monthly_values is None:
return None
results[cte.MONTH] = [x / cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES]
return results
@property
def domestic_hot_water_peak_load(self) -> Union[None, dict]:
"""
Get cooling peak load in W
:return: dict{[float]}
"""
results = {}
monthly_values = None
if cte.HOUR in self.domestic_hot_water_heat_demand:
monthly_values = PeakLoads().peak_loads_from_hourly(self.domestic_hot_water_heat_demand[cte.HOUR])
if monthly_values is None:
return None
results[cte.MONTH] = [x / cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES]
results[cte.MONTH] = [x * cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values)]
return results
@property
@ -605,6 +571,19 @@ class Building(CityObject):
"""
self._city = value
@property
def usages_percentage(self):
"""
Get the usages and percentages for the building
"""
_usage = ''
for internal_zone in self.internal_zones:
if internal_zone.usages is None:
continue
for usage in internal_zone.usages:
_usage = f'{_usage}{usage.name}_{usage.percentage} '
return _usage.rstrip()
@property
def energy_systems(self) -> Union[None, List[EnergySystem]]:
"""
@ -723,7 +702,6 @@ class Building(CityObject):
Get total electricity consumption for distribution and emission systems in J
return: dict
"""
_distribution_systems_electrical_consumption = {}
if len(self._distribution_systems_electrical_consumption) != 0:
return self._distribution_systems_electrical_consumption
_peak_load = self.heating_peak_load[cte.YEAR][0]
@ -737,14 +715,11 @@ class Building(CityObject):
if self.energy_systems is None:
return self._distribution_systems_electrical_consumption
for energy_system in self.energy_systems:
distribution_systems = energy_system.distribution_systems
if distribution_systems is not None:
for distribution_system in distribution_systems:
emission_systems = distribution_system.emission_systems
emission_system = energy_system.emission_system.generic_emission_system
parasitic_energy_consumption = 0
if emission_systems is not None:
for emission_system in emission_systems:
parasitic_energy_consumption += emission_system.parasitic_energy_consumption
if emission_system is not None:
parasitic_energy_consumption = emission_system.parasitic_energy_consumption
distribution_system = energy_system.distribution_system.generic_distribution_system
consumption_variable_flow = distribution_system.distribution_consumption_variable_flow
for demand_type in energy_system.demand_types:
if demand_type.lower() == cte.HEATING.lower():
@ -783,21 +758,15 @@ class Building(CityObject):
if self.energy_systems is None:
return None
for energy_system in self.energy_systems:
generation_systems = energy_system.generation_systems
for demand_type in energy_system.demand_types:
if demand_type.lower() == consumption_type.lower():
if consumption_type in (cte.HEATING, cte.DOMESTIC_HOT_WATER):
for generation_system in generation_systems:
if generation_system.heat_efficiency is not None:
coefficient_of_performance = float(generation_system.heat_efficiency)
coefficient_of_performance = energy_system.generation_system.generic_generation_system.heat_efficiency
elif consumption_type == cte.COOLING:
for generation_system in generation_systems:
if generation_system.cooling_efficiency is not None:
coefficient_of_performance = float(generation_system.cooling_efficiency)
coefficient_of_performance = energy_system.generation_system.generic_generation_system.cooling_efficiency
elif consumption_type == cte.ELECTRICITY:
for generation_system in generation_systems:
if generation_system.electricity_efficiency is not None:
coefficient_of_performance = float(generation_system.electricity_efficiency)
coefficient_of_performance = \
energy_system.generation_system.generic_generation_system.electricity_efficiency
if coefficient_of_performance == 0:
values = [0]*len(demand)
final_energy_consumed = values
@ -828,12 +797,8 @@ class Building(CityObject):
if self.energy_systems is None:
return self._onsite_electrical_production
for energy_system in self.energy_systems:
for generation_system in energy_system.generation_systems:
if generation_system.system_type == cte.PHOTOVOLTAIC:
if generation_system.electricity_efficiency is not None:
_efficiency = float(generation_system.electricity_efficiency)
else:
_efficiency = 0
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]))]
@ -859,94 +824,3 @@ class Building(CityObject):
Get building upper corner.
"""
return [self._max_x, self._max_y, self._max_z]
@property
def energy_consumption_breakdown(self) -> dict:
"""
Get energy consumption of different sectors
return: dict
"""
fuel_breakdown = {cte.ELECTRICITY: {cte.LIGHTING: self.lighting_electrical_demand[cte.YEAR][0] if self.lighting_electrical_demand else 0,
cte.APPLIANCES: self.appliances_electrical_demand[cte.YEAR][0] if self.appliances_electrical_demand else 0}}
energy_systems = self.energy_systems
if energy_systems is not None:
for energy_system in energy_systems:
demand_types = energy_system.demand_types
generation_systems = energy_system.generation_systems
for demand_type in demand_types:
for generation_system in generation_systems:
if generation_system.system_type != cte.PHOTOVOLTAIC:
if generation_system.fuel_type not in fuel_breakdown:
fuel_breakdown[generation_system.fuel_type] = {}
if demand_type in generation_system.energy_consumption:
fuel_breakdown[f'{generation_system.fuel_type}'][f'{demand_type}'] = (
generation_system.energy_consumption)[f'{demand_type}'][cte.YEAR][0]
storage_systems = generation_system.energy_storage_systems
if storage_systems:
for storage_system in storage_systems:
if storage_system.type_energy_stored == 'thermal' and storage_system.heating_coil_energy_consumption:
fuel_breakdown[cte.ELECTRICITY][f'{demand_type}'] += (
storage_system.heating_coil_energy_consumption)[f'{demand_type}'][cte.YEAR][0]
#TODO: When simulation models of all energy system archetypes are created, this part can be removed
heating_fuels = []
dhw_fuels = []
for energy_system in self.energy_systems:
if cte.HEATING in energy_system.demand_types:
for generation_system in energy_system.generation_systems:
heating_fuels.append(generation_system.fuel_type)
if cte.DOMESTIC_HOT_WATER in energy_system.demand_types:
for generation_system in energy_system.generation_systems:
dhw_fuels.append(generation_system.fuel_type)
for key in fuel_breakdown:
if key == cte.ELECTRICITY and cte.COOLING not in fuel_breakdown[key]:
for energy_system in energy_systems:
if cte.COOLING in energy_system.demand_types and cte.COOLING not in fuel_breakdown[key]:
if self.cooling_consumption:
fuel_breakdown[energy_system.generation_systems[0].fuel_type][cte.COOLING] = self.cooling_consumption[cte.YEAR][0]
for fuel in heating_fuels:
if cte.HEATING not in fuel_breakdown[fuel]:
for energy_system in energy_systems:
if cte.HEATING in energy_system.demand_types:
if self.heating_consumption:
fuel_breakdown[energy_system.generation_systems[0].fuel_type][cte.HEATING] = self.heating_consumption[cte.YEAR][0]
for fuel in dhw_fuels:
if cte.DOMESTIC_HOT_WATER not in fuel_breakdown[fuel]:
for energy_system in energy_systems:
if cte.DOMESTIC_HOT_WATER in energy_system.demand_types:
if self.domestic_hot_water_consumption:
fuel_breakdown[energy_system.generation_systems[0].fuel_type][cte.DOMESTIC_HOT_WATER] = self.domestic_hot_water_consumption[cte.YEAR][0]
self._fuel_consumption_breakdown = fuel_breakdown
return self._fuel_consumption_breakdown
@property
def energy_systems_archetype_cluster_id(self):
"""
Get energy systems archetype id
:return: str
"""
return self._systems_archetype_cluster_id
@energy_systems_archetype_cluster_id.setter
def energy_systems_archetype_cluster_id(self, value):
"""
Set energy systems archetype id
:param value: str
"""
self._systems_archetype_cluster_id = value
@property
def pv_generation(self):
"""
temporary attribute to get the onsite pv generation in W
:return: dict
"""
return self._pv_generation
@pv_generation.setter
def pv_generation(self, value):
"""
temporary attribute to set the onsite pv generation in W
:param value: float
"""
self._pv_generation = value

View File

@ -132,11 +132,7 @@ class InternalZone:
_thermal_boundary = ThermalBoundary(surface, surface.solid_polygon.area, windows_areas)
surface.associated_thermal_boundaries = [_thermal_boundary]
_thermal_boundaries.append(_thermal_boundary)
if self.thermal_archetype is None:
return None # there are no archetype
_number_of_storeys = int(self.volume / self.area / self.thermal_archetype.average_storey_height)
if _number_of_storeys == 0:
_number_of_storeys = 1
_thermal_zone = ThermalZone(_thermal_boundaries, self, self.volume, self.area, _number_of_storeys)
for thermal_boundary in _thermal_zone.thermal_boundaries:
thermal_boundary.thermal_zones = [_thermal_zone]

View File

@ -42,12 +42,10 @@ class Surface:
self._short_wave_reflectance = None
self._long_wave_emittance = None
self._inverse = None
self._associated_thermal_boundaries = None
self._associated_thermal_boundaries = []
self._vegetation = None
self._percentage_shared = None
self._solar_collectors_area_reduction_factor = None
self._global_irradiance_tilted = {}
self._installed_solar_collector_area = None
@property
def name(self):
@ -157,7 +155,6 @@ class Surface:
if self._inclination is None:
self._inclination = np.arccos(self.perimeter_polygon.normal[2])
return self._inclination
@property
def type(self):
"""
@ -181,7 +178,7 @@ class Surface:
@property
def global_irradiance(self) -> dict:
"""
Get global irradiance on surface in W/m2
Get global irradiance on surface in J/m2
:return: dict
"""
return self._global_irradiance
@ -189,7 +186,7 @@ class Surface:
@global_irradiance.setter
def global_irradiance(self, value):
"""
Set global irradiance on surface in W/m2
Set global irradiance on surface in J/m2
:param value: dict
"""
self._global_irradiance = value
@ -387,35 +384,3 @@ class Surface:
:param value: float
"""
self._solar_collectors_area_reduction_factor = value
@property
def global_irradiance_tilted(self) -> dict:
"""
Get global irradiance on a tilted surface in W/m2
:return: dict
"""
return self._global_irradiance_tilted
@global_irradiance_tilted.setter
def global_irradiance_tilted(self, value):
"""
Set global irradiance on a tilted surface in W/m2
:param value: dict
"""
self._global_irradiance_tilted = value
@property
def installed_solar_collector_area(self):
"""
Get installed solar collector area in m2
:return: dict
"""
return self._installed_solar_collector_area
@installed_solar_collector_area.setter
def installed_solar_collector_area(self, value):
"""
Set installed solar collector area in m2
:return: dict
"""
self._installed_solar_collector_area = value

View File

@ -20,8 +20,8 @@ class ThermalArchetype:
self._indirect_heated_ratio = None
self._infiltration_rate_for_ventilation_system_off = None
self._infiltration_rate_for_ventilation_system_on = None
self._infiltration_rate_area_for_ventilation_system_off=None
self._infiltration_rate_area_for_ventilation_system_on=None
self._infiltration_rate_area_for_ventilation_system_off = 0
self._infiltration_rate_area_for_ventilation_system_on = 0
@property
def constructions(self) -> [Construction]:
@ -138,31 +138,31 @@ class ThermalArchetype:
@property
def infiltration_rate_area_for_ventilation_system_off(self):
"""
Get infiltration rate for ventilation system off in l/s/m2
Get infiltration rate for ventilation system off in ACH
:return: float
"""
return self._infiltration_rate_for_ventilation_system_off
return self._infiltration_rate_area_for_ventilation_system_off
@infiltration_rate_area_for_ventilation_system_off.setter
def infiltration_rate_area_for_ventilation_system_off(self, value):
"""
Set infiltration rate for ventilation system off in l/s/m2
Set infiltration rate for ventilation system off in ACH
:param value: float
"""
self._infiltration_rate_for_ventilation_system_off = value
self._infiltration_rate_area_for_ventilation_system_off = value
@property
def infiltration_rate_area_for_ventilation_system_on(self):
"""
Get infiltration rate for ventilation system on in l/s/m2
Get infiltration rate for ventilation system on in ACH
:return: float
"""
return self._infiltration_rate_for_ventilation_system_on
return self._infiltration_rate_area_for_ventilation_system_on
@infiltration_rate_area_for_ventilation_system_on.setter
def infiltration_rate_area_for_ventilation_system_on(self, value):
"""
Set infiltration rate for ventilation system on in l/s/m2
Set infiltration rate for ventilation system on in ACH
:param value: float
"""
self._infiltration_rate_for_ventilation_system_on = value
self._infiltration_rate_area_for_ventilation_system_on = value

View File

@ -34,7 +34,7 @@ class ThermalZone:
volume,
footprint_area,
number_of_storeys,
usages=None):
usage_name=None):
self._id = None
self._parent_internal_zone = parent_internal_zone
self._footprint_area = footprint_area
@ -51,6 +51,10 @@ class ThermalZone:
self._view_factors_matrix = None
self._total_floor_area = None
self._number_of_storeys = number_of_storeys
self._usage_name = usage_name
self._usage_from_parent = False
if usage_name is None:
self._usage_from_parent = True
self._hours_day = None
self._days_year = None
self._mechanical_air_change = None
@ -60,12 +64,7 @@ class ThermalZone:
self._internal_gains = None
self._thermal_control = None
self._domestic_hot_water = None
self._usage_name = None
self._usages = usages
self._usage_from_parent = False
if usages is None:
self._usage_from_parent = True
self._usages = None
@property
def parent_internal_zone(self) -> InternalZone:
@ -78,11 +77,24 @@ class ThermalZone:
@property
def usages(self):
"""
Get the thermal zone usages
Get the thermal zone usages including percentage with the format [percentage]-usage_[percentage]-usage...
Eg: 70-office_30-residential
:return: str
"""
if self._usage_from_parent:
self._usages = copy.deepcopy(self._parent_internal_zone.usages)
else:
values = self._usage_name.split('_')
usages = []
for value in values:
usages.append(value.split('-'))
self._usages = []
for parent_usage in self._parent_internal_zone.usages:
for value in usages:
if parent_usage.name == value[1]:
new_usage = copy.deepcopy(parent_usage)
new_usage.percentage = float(value[0]) / 100
self._usages.append(new_usage)
return self._usages
@property
@ -162,8 +174,8 @@ class ThermalZone:
Get thermal zone infiltration rate system on in air changes per second (1/s)
:return: None or float
"""
self._infiltration_rate_area_system_on = self._parent_internal_zone.thermal_archetype.infiltration_rate_area_for_ventilation_system_on
return self._infiltration_rate_area_system_on
self._infiltration_rate_system_on = self._parent_internal_zone.thermal_archetype.infiltration_rate_area_for_ventilation_system_on
return self._infiltration_rate_system_on
@property
def infiltration_rate_area_system_off(self):
@ -171,8 +183,8 @@ class ThermalZone:
Get thermal zone infiltration rate system off in air changes per second (1/s)
:return: None or float
"""
self._infiltration_rate_area_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_area_for_ventilation_system_off
return self._infiltration_rate_area_system_off
self._infiltration_rate_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_area_for_ventilation_system_off
return self._infiltration_rate_system_off
@property
def volume(self):

View File

@ -62,6 +62,7 @@ class City:
self._level_of_detail = LevelOfDetail()
self._city_objects_dictionary = {}
self._city_objects_alias_dictionary = {}
self._energy_systems_connection_table = None
self._generic_energy_systems = None
def _get_location(self) -> Location:
@ -504,6 +505,24 @@ 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:
"""

View File

@ -41,10 +41,9 @@ class CityObject:
self._ground_temperature = {}
self._global_horizontal = {}
self._diffuse = {}
self._direct_normal = {}
self._beam = {}
self._sensors = []
self._neighbours = None
self._beam = {}
@property
def level_of_detail(self) -> LevelOfDetail:
@ -239,20 +238,20 @@ class CityObject:
self._diffuse = value
@property
def direct_normal(self) -> dict:
def beam(self) -> dict:
"""
Get beam radiation surrounding the city object in J/m2
:return: dict{dict{[float]}}
"""
return self._direct_normal
return self._beam
@direct_normal.setter
def direct_normal(self, value):
@beam.setter
def beam(self, value):
"""
Set beam radiation surrounding the city object in J/m2
:param value: dict{dict{[float]}}
"""
self._direct_normal = value
self._beam = value
@property
def lower_corner(self):
@ -303,19 +302,3 @@ class CityObject:
Set the list of neighbour_objects and their properties associated to the current city_object
"""
self._neighbours = value
@property
def beam(self) -> dict:
"""
Get beam radiation surrounding the city object in J/m2
:return: dict{dict{[float]}}
"""
return self._beam
@beam.setter
def beam(self, value):
"""
Set beam radiation surrounding the city object in J/m2
:param value: dict{dict{[float]}}
"""
self._beam = value

View File

@ -5,12 +5,7 @@ Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import Union, List, TypeVar
from hub.city_model_structure.energy_systems.emission_system import EmissionSystem
from hub.city_model_structure.energy_systems.energy_storage_system import EnergyStorageSystem
GenerationSystem = TypeVar('GenerationSystem')
from hub.city_model_structure.energy_systems.generic_distribution_system import GenericDistributionSystem
class DistributionSystem:
@ -18,158 +13,20 @@ class DistributionSystem:
DistributionSystem class
"""
def __init__(self):
self._model_name = None
self._type = None
self._supply_temperature = None
self._distribution_consumption_fix_flow = None
self._distribution_consumption_variable_flow = None
self._heat_losses = None
self._generation_systems = None
self._energy_storage_systems = None
self._emission_systems = None
self._generic_distribution_system = None
@property
def model_name(self):
def generic_distribution_system(self) -> GenericDistributionSystem:
"""
Get model name
:return: string
Get generic_distribution_system
:return: GenericDistributionSystem
"""
return self._model_name
return self._generic_distribution_system
@model_name.setter
def model_name(self, value):
@generic_distribution_system.setter
def generic_distribution_system(self, value):
"""
Set model name
:param value: string
Set associated generic_distribution_system
:param value: GenericDistributionSystem
"""
self._model_name = value
@property
def type(self):
"""
Get type from [air, water, refrigerant]
:return: string
"""
return self._type
@type.setter
def type(self, value):
"""
Set type from [air, water, refrigerant]
:param value: string
"""
self._type = value
@property
def supply_temperature(self):
"""
Get supply_temperature in degree Celsius
:return: float
"""
return self._supply_temperature
@supply_temperature.setter
def supply_temperature(self, value):
"""
Set supply_temperature in degree Celsius
:param value: float
"""
self._supply_temperature = value
@property
def distribution_consumption_fix_flow(self):
"""
Get distribution_consumption if the pump or fan work at fix mass or volume flow in ratio over peak power (W/W)
:return: float
"""
return self._distribution_consumption_fix_flow
@distribution_consumption_fix_flow.setter
def distribution_consumption_fix_flow(self, value):
"""
Set distribution_consumption if the pump or fan work at fix mass or volume flow in ratio over peak power (W/W)
:return: float
"""
self._distribution_consumption_fix_flow = value
@property
def distribution_consumption_variable_flow(self):
"""
Get distribution_consumption if the pump or fan work at variable mass or volume flow in ratio
over energy produced (J/J)
:return: float
"""
return self._distribution_consumption_variable_flow
@distribution_consumption_variable_flow.setter
def distribution_consumption_variable_flow(self, value):
"""
Set distribution_consumption if the pump or fan work at variable mass or volume flow in ratio
over energy produced (J/J)
:return: float
"""
self._distribution_consumption_variable_flow = value
@property
def heat_losses(self):
"""
Get heat_losses in ratio over energy produced
:return: float
"""
return self._heat_losses
@heat_losses.setter
def heat_losses(self, value):
"""
Set heat_losses in ratio over energy produced
:param value: float
"""
self._heat_losses = value
@property
def generation_systems(self) -> Union[None, List[GenerationSystem]]:
"""
Get generation systems connected to the distribution system
:return: [GenerationSystem]
"""
return self._generation_systems
@generation_systems.setter
def generation_systems(self, value):
"""
Set generation systems connected to the distribution system
:param value: [GenerationSystem]
"""
self._generation_systems = value
@property
def energy_storage_systems(self) -> Union[None, List[EnergyStorageSystem]]:
"""
Get energy storage systems connected to this distribution system
:return: [EnergyStorageSystem]
"""
return self._energy_storage_systems
@energy_storage_systems.setter
def energy_storage_systems(self, value):
"""
Set energy storage systems connected to this distribution system
:param value: [EnergyStorageSystem]
"""
self._energy_storage_systems = value
@property
def emission_systems(self) -> Union[None, List[EmissionSystem]]:
"""
Get energy emission systems connected to this distribution system
:return: [EmissionSystem]
"""
return self._emission_systems
@emission_systems.setter
def emission_systems(self, value):
"""
Set energy emission systems connected to this distribution system
:param value: [EmissionSystem]
"""
self._emission_systems = value
self._generic_distribution_system = value

View File

@ -1,104 +0,0 @@
"""
Electrical storage 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 hub.city_model_structure.energy_systems.energy_storage_system import EnergyStorageSystem
class ElectricalStorageSystem(EnergyStorageSystem):
""""
Electrical Storage System Class
"""
def __init__(self):
super().__init__()
self._rated_output_power = None
self._nominal_efficiency = None
self._battery_voltage = None
self._depth_of_discharge = None
self._self_discharge_rate = None
@property
def rated_output_power(self):
"""
Get the rated output power of storage system in Watts
:return: float
"""
return self._rated_output_power
@rated_output_power.setter
def rated_output_power(self, value):
"""
Set the rated output power of storage system in Watts
:param value: float
"""
self._rated_output_power = value
@property
def nominal_efficiency(self):
"""
Get the nominal efficiency of the storage system
:return: float
"""
return self._nominal_efficiency
@nominal_efficiency.setter
def nominal_efficiency(self, value):
"""
Set the nominal efficiency of the storage system
:param value: float
"""
self._nominal_efficiency = value
@property
def battery_voltage(self):
"""
Get the battery voltage in Volts
:return: float
"""
return self._battery_voltage
@battery_voltage.setter
def battery_voltage(self, value):
"""
Set the battery voltage in Volts
:param value: float
"""
self._battery_voltage = value
@property
def depth_of_discharge(self):
"""
Get the depth of discharge as a percentage
:return: float
"""
return self._depth_of_discharge
@depth_of_discharge.setter
def depth_of_discharge(self, value):
"""
Set the depth of discharge as a percentage
:param value: float
"""
self._depth_of_discharge = value
@property
def self_discharge_rate(self):
"""
Get the self discharge rate of battery as a percentage
:return: float
"""
return self._self_discharge_rate
@self_discharge_rate.setter
def self_discharge_rate(self, value):
"""
Set the self discharge rate of battery as a percentage
:param value: float
"""
self._self_discharge_rate = value

View File

@ -1,64 +1,32 @@
"""
Emission system module
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._model_name = None
self._type = None
self._parasitic_energy_consumption = 0
self._generic_emission_system = None
@property
def model_name(self):
def generic_emission_system(self) -> GenericEmissionSystem:
"""
Get model name
:return: string
Get associated generic_emission_system
:return: GenericEmissionSystem
"""
return self._model_name
return self._generic_emission_system
@model_name.setter
def model_name(self, value):
@generic_emission_system.setter
def generic_emission_system(self, value):
"""
Set model name
:param value: string
Set associated
:param value: GenericEmissionSystem
"""
self._model_name = value
@property
def type(self):
"""
Get type
:return: string
"""
return self._type
@type.setter
def type(self, value):
"""
Set type
:param value: string
"""
self._type = value
@property
def parasitic_energy_consumption(self):
"""
Get parasitic_energy_consumption in ratio (W/W)
:return: float
"""
return self._parasitic_energy_consumption
@parasitic_energy_consumption.setter
def parasitic_energy_consumption(self, value):
"""
Set parasitic_energy_consumption in ratio (W/W)
:param value: float
"""
self._parasitic_energy_consumption = value
self._generic_emission_system = value

View File

@ -1,118 +0,0 @@
"""
Energy storage system. Abstract class
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 abc import ABC
class EnergyStorageSystem(ABC):
"""
Energy storage System class
"""
def __init__(self):
self._type_energy_stored = None
self._storage_type = None
self._model_name = None
self._manufacturer = None
self._nominal_capacity = None
self._losses_ratio = None
@property
def type_energy_stored(self):
"""
Get type of energy stored from ['electrical', 'thermal']
:return: string
"""
return self._type_energy_stored
@type_energy_stored.setter
def type_energy_stored(self, value):
"""
Set type of energy stored from ['electrical', 'thermal']
:return: string
"""
self._type_energy_stored = value
@property
def storage_type(self):
"""
Get storage type
:return: string
"""
return self._storage_type
@storage_type.setter
def storage_type(self, value):
"""
Get storage type
:param value: string
"""
self._storage_type = value
@property
def model_name(self):
"""
Get system model
:return: string
"""
return self._model_name
@model_name.setter
def model_name(self, value):
"""
Set system model
:param value: string
"""
self._model_name = value
@property
def manufacturer(self):
"""
Get name of manufacturer
:return: string
"""
return self._manufacturer
@manufacturer.setter
def manufacturer(self, value):
"""
Set name of manufacturer
:param value: string
"""
self._manufacturer = value
@property
def nominal_capacity(self):
"""
Get the nominal capacity of storage systems in Jules
:return: float
"""
return self._nominal_capacity
@nominal_capacity.setter
def nominal_capacity(self, value):
"""
Set the nominal capacity of storage systems in Jules
:return: float
"""
self._nominal_capacity = value
@property
def losses_ratio(self):
"""
Get the losses-ratio of storage system in Jules lost / Jules stored
:return: float
"""
return self._losses_ratio
@losses_ratio.setter
def losses_ratio(self, value):
"""
Set the losses-ratio of storage system in Jules lost / Jules stored
:return: float
"""
self._losses_ratio = value

View File

@ -6,11 +6,10 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import Union, List
from pathlib import Path
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.non_pv_generation_system import NonPvGenerationSystem
from hub.city_model_structure.energy_systems.pv_generation_system import PvGenerationSystem
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
@ -20,30 +19,14 @@ class EnergySystem:
EnergySystem class
"""
def __init__(self):
self._demand_types = None
self._name = None
self._generation_systems = None
self._distribution_systems = None
self._configuration_schema = None
self._demand_types = None
self._generation_system = None
self._distribution_system = None
self._emission_system = None
self._connected_city_objects = None
self._control_system = None
@property
def demand_types(self):
"""
Get demand able to cover from [Heating, Cooling, Domestic Hot Water, Electricity]
:return: [string]
"""
return self._demand_types
@demand_types.setter
def demand_types(self, value):
"""
Set demand able to cover from [Heating, Cooling, Domestic Hot Water, Electricity]
:param value: [string]
"""
self._demand_types = value
@property
def name(self):
"""
@ -61,58 +44,74 @@ class EnergySystem:
self._name = value
@property
def generation_systems(self) -> Union[List[NonPvGenerationSystem], List[PvGenerationSystem]]:
def demand_types(self):
"""
Get generation systems
:return: [GenerationSystem]
Get demand able to cover from [Heating, Cooling, Domestic Hot Water, Electricity]
:return: [string]
"""
return self._generation_systems
return self._demand_types
@generation_systems.setter
def generation_systems(self, value):
@demand_types.setter
def demand_types(self, value):
"""
Set generation systems
:return: [GenerationSystem]
Set demand able to cover from [Heating, Cooling, Domestic Hot Water, Electricity]
:param value: [string]
"""
self._generation_systems = value
self._demand_types = value
@property
def distribution_systems(self) -> Union[None, List[DistributionSystem]]:
def generation_system(self) -> GenerationSystem:
"""
Get distribution systems
:return: [DistributionSystem]
Get generation system
:return: GenerationSystem
"""
return self._distribution_systems
return self._generation_system
@distribution_systems.setter
def distribution_systems(self, value):
@generation_system.setter
def generation_system(self, value):
"""
Set distribution systems
:param value: [DistributionSystem]
Set generation system
:param value: GenerationSystem
"""
self._distribution_systems = value
self._generation_system = value
@property
def configuration_schema(self) -> Path:
def distribution_system(self) -> Union[None, DistributionSystem]:
"""
Get the schema of the system configuration
:return: Path
Get distribution system
:return: DistributionSystem
"""
return self._configuration_schema
return self._distribution_system
@configuration_schema.setter
def configuration_schema(self, value):
@distribution_system.setter
def distribution_system(self, value):
"""
Set the schema of the system configuration
:param value: Path
Set distribution system
:param value: DistributionSystem
"""
self._configuration_schema = value
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: [CityObject]
:return: List[CityObject]
"""
return self._connected_city_objects
@ -120,7 +119,7 @@ class EnergySystem:
def connected_city_objects(self, value):
"""
Set list of city objects that are connected to this energy system
:param value: [CityObject]
:param value: List[CityObject]
"""
self._connected_city_objects = value

View File

@ -1,158 +1,120 @@
"""
Energy generation system (abstract class)
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
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
from __future__ import annotations
from abc import ABC
from typing import Union, List
from typing import Union
from hub.city_model_structure.energy_systems.distribution_system import DistributionSystem
from hub.city_model_structure.energy_systems.thermal_storage_system import ThermalStorageSystem
from hub.city_model_structure.energy_systems.electrical_storage_system import ElectricalStorageSystem
from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem
class GenerationSystem(ABC):
class GenerationSystem:
"""
GenerationSystem class
"""
def __init__(self):
self._system_type = None
self._name = None
self._model_name = None
self._manufacturer = None
self._fuel_type = None
self._distribution_systems = None
self._energy_storage_systems = None
self._number_of_units = None
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 system_type(self):
def generic_generation_system(self) -> GenericGenerationSystem:
"""
Get type
:return: string
Get associated generic_generation_system
:return: GenericGenerationSystem
"""
return self._system_type
return self._generic_generation_system
@system_type.setter
def system_type(self, value):
@generic_generation_system.setter
def generic_generation_system(self, value):
"""
Set type
:param value: string
Set associated generic_generation_system
:param value: GenericGenerationSystem
"""
self._system_type = value
self._generic_generation_system = value
@property
def name(self):
def heat_power(self):
"""
Get name
:return: string
Get heat_power in W
:return: float
"""
return self._name
return self._heat_power
@name.setter
def name(self, value):
@heat_power.setter
def heat_power(self, value):
"""
Set name
:param value: string
Set heat_power in W
:param value: float
"""
self._name = value
self._heat_power = value
@property
def model_name(self):
def cooling_power(self):
"""
Get model name
:return: string
Get cooling_power in W
:return: float
"""
return self._model_name
return self._cooling_power
@model_name.setter
def model_name(self, value):
@cooling_power.setter
def cooling_power(self, value):
"""
Set model name
:param value: string
Set cooling_power in W
:param value: float
"""
self._model_name = value
self._cooling_power = value
@property
def manufacturer(self):
def electricity_power(self):
"""
Get manufacturer's name
:return: string
Get electricity_power in W
:return: float
"""
return self._manufacturer
return self._electricity_power
@manufacturer.setter
def manufacturer(self, value):
@electricity_power.setter
def electricity_power(self, value):
"""
Set manufacturer's name
:param value: string
Set electricity_power in W
:param value: float
"""
self._manufacturer = value
self._electricity_power = value
@property
def fuel_type(self):
def storage_capacity(self):
"""
Get fuel_type from [Renewable, Gas, Diesel, Electricity, Wood, Coal]
:return: string
Get storage_capacity in J
:return: float
"""
return self._fuel_type
return self._storage_capacity
@fuel_type.setter
def fuel_type(self, value):
@storage_capacity.setter
def storage_capacity(self, value):
"""
Set fuel_type from [Renewable, Gas, Diesel, Electricity, Wood, Coal]
:param value: string
Set storage_capacity in J
:param value: float
"""
self._fuel_type = value
self._storage_capacity = value
@property
def distribution_systems(self) -> Union[None, List[DistributionSystem]]:
def auxiliary_equipment(self) -> Union[None, GenerationSystem]:
"""
Get distributions systems connected to this generation system
:return: [DistributionSystem]
Get auxiliary_equipment
:return: GenerationSystem
"""
return self._distribution_systems
return self._auxiliary_equipment
@distribution_systems.setter
def distribution_systems(self, value):
@auxiliary_equipment.setter
def auxiliary_equipment(self, value):
"""
Set distributions systems connected to this generation system
:param value: [DistributionSystem]
Set auxiliary_equipment
:param value: GenerationSystem
"""
self._distribution_systems = value
@property
def energy_storage_systems(self) -> Union[None, List[ThermalStorageSystem], List[ElectricalStorageSystem]]:
"""
Get energy storage systems connected to this generation system
:return: [EnergyStorageSystem]
"""
return self._energy_storage_systems
@energy_storage_systems.setter
def energy_storage_systems(self, value):
"""
Set energy storage systems connected to this generation system
:param value: [EnergyStorageSystem]
"""
self._energy_storage_systems = value
@property
def number_of_units(self):
"""
Get number of a specific generation unit
:return: int
"""
return self._number_of_units
@number_of_units.setter
def number_of_units(self, value):
"""
Set number of a specific generation unit
:return: int
"""
self._number_of_units = value
self._auxiliary_equipment = value

View File

@ -0,0 +1,100 @@
"""
Generic 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
"""
class GenericDistributionSystem:
"""
GenericDistributionSystem class
"""
def __init__(self):
self._type = None
self._supply_temperature = None
self._distribution_consumption_fix_flow = None
self._distribution_consumption_variable_flow = None
self._heat_losses = None
@property
def type(self):
"""
Get type from [air, water, refrigerant]
:return: string
"""
return self._type
@type.setter
def type(self, value):
"""
Set type from [air, water, refrigerant]
:param value: string
"""
self._type = value
@property
def supply_temperature(self):
"""
Get supply_temperature in degree Celsius
:return: float
"""
return self._supply_temperature
@supply_temperature.setter
def supply_temperature(self, value):
"""
Set supply_temperature in degree Celsius
:param value: float
"""
self._supply_temperature = value
@property
def distribution_consumption_fix_flow(self):
"""
Get distribution_consumption if the pump or fan work at fix mass or volume flow in ratio over peak power (W/W)
:return: float
"""
return self._distribution_consumption_fix_flow
@distribution_consumption_fix_flow.setter
def distribution_consumption_fix_flow(self, value):
"""
Set distribution_consumption if the pump or fan work at fix mass or volume flow in ratio over peak power (W/W)
:return: float
"""
self._distribution_consumption_fix_flow = value
@property
def distribution_consumption_variable_flow(self):
"""
Get distribution_consumption if the pump or fan work at variable mass or volume flow in ratio
over energy produced (J/J)
:return: float
"""
return self._distribution_consumption_variable_flow
@distribution_consumption_variable_flow.setter
def distribution_consumption_variable_flow(self, value):
"""
Set distribution_consumption if the pump or fan work at variable mass or volume flow in ratio
over energy produced (J/J)
:return: float
"""
self._distribution_consumption_variable_flow = value
@property
def heat_losses(self):
"""
Get heat_losses in ratio over energy produced
:return: float
"""
return self._heat_losses
@heat_losses.setter
def heat_losses(self, value):
"""
Set heat_losses in ratio over energy produced
:param value: float
"""
self._heat_losses = value

View File

@ -0,0 +1,30 @@
"""
Generic energy emission system module
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 GenericEmissionSystem:
"""
GenericEmissionSystem class
"""
def __init__(self):
self._parasitic_energy_consumption = None
@property
def parasitic_energy_consumption(self):
"""
Get parasitic_energy_consumption in ratio (W/W)
:return: float
"""
return self._parasitic_energy_consumption
@parasitic_energy_consumption.setter
def parasitic_energy_consumption(self, value):
"""
Set parasitic_energy_consumption in ratio (W/W)
:param value: float
"""
self._parasitic_energy_consumption = value

View File

@ -0,0 +1,105 @@
"""
Generic 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
from hub.city_model_structure.energy_systems.generic_distribution_system import GenericDistributionSystem
from hub.city_model_structure.energy_systems.generic_emission_system import GenericEmissionSystem
from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem
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):
"""
Get demand able to cover from [Heating, Cooling, Domestic Hot Water, Electricity]
:return: [string]
"""
return self._demand_types
@demand_types.setter
def demand_types(self, value):
"""
Set demand able to cover from [Heating, Cooling, Domestic Hot Water, Electricity]
:param value: [string]
"""
self._demand_types = value
@property
def generation_system(self) -> GenericGenerationSystem:
"""
Get generation system
:return: GenerationSystem
"""
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]:
"""
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, GenericEmissionSystem]:
"""
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

View File

@ -0,0 +1,186 @@
"""
Generic 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
class GenericGenerationSystem:
"""
GenericGenerationSystem class
"""
def __init__(self):
self._type = None
self._fuel_type = None
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 = None
self._auxiliary_equipment = None
@property
def type(self):
"""
Get system type
:return: string
"""
return self._type
@type.setter
def type(self, value):
"""
Set system type
:param value: string
"""
self._type = value
@property
def fuel_type(self):
"""
Get fuel_type from [Renewable, Gas, Diesel, Electricity, Wood, Coal]
:return: string
"""
return self._fuel_type
@fuel_type.setter
def fuel_type(self, value):
"""
Set fuel_type from [Renewable, Gas, Diesel, Electricity, Wood, Coal]
:param value: string
"""
self._fuel_type = value
@property
def source_types(self):
"""
Get source_type from [Air, Water, Geothermal, District Heating, Grid, Onsite Electricity]
:return: [string]
"""
return self._source_types
@source_types.setter
def source_types(self, value):
"""
Set source_type from [Air, Water, Geothermal, District Heating, Grid, Onsite Electricity]
:param value: [string]
"""
self._source_types = value
@property
def heat_efficiency(self):
"""
Get heat_efficiency
:return: float
"""
return self._heat_efficiency
@heat_efficiency.setter
def heat_efficiency(self, value):
"""
Set heat_efficiency
:param value: float
"""
self._heat_efficiency = value
@property
def cooling_efficiency(self):
"""
Get cooling_efficiency
:return: float
"""
return self._cooling_efficiency
@cooling_efficiency.setter
def cooling_efficiency(self, value):
"""
Set cooling_efficiency
:param value: float
"""
self._cooling_efficiency = value
@property
def electricity_efficiency(self):
"""
Get electricity_efficiency
:return: float
"""
return self._electricity_efficiency
@electricity_efficiency.setter
def electricity_efficiency(self, value):
"""
Set electricity_efficiency
:param value: float
"""
self._electricity_efficiency = value
@property
def source_temperature(self):
"""
Get source_temperature in degree Celsius
:return: float
"""
return self._source_temperature
@source_temperature.setter
def source_temperature(self, value):
"""
Set source_temperature in degree Celsius
:param value: float
"""
self._source_temperature = value
@property
def source_mass_flow(self):
"""
Get source_mass_flow in kg/s
:return: float
"""
return self._source_mass_flow
@source_mass_flow.setter
def source_mass_flow(self, value):
"""
Set source_mass_flow in kg/s
:param value: float
"""
self._source_mass_flow = value
@property
def storage(self):
"""
Get boolean storage exists
:return: bool
"""
return self._storage
@storage.setter
def storage(self, value):
"""
Set boolean storage exists
:return: bool
"""
self._storage = value
@property
def auxiliary_equipment(self) -> Union[None, GenericGenerationSystem]:
"""
Get auxiliary_equipment
:return: GenerationSystem
"""
return self._auxiliary_equipment
@auxiliary_equipment.setter
def auxiliary_equipment(self, value):
"""
Set auxiliary_equipment
:return: GenerationSystem
"""
self._auxiliary_equipment = value

View File

@ -0,0 +1,64 @@
"""
heat_pump module defines a heat pump
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
from typing import List
from pandas.core.series import Series
class HeatPump:
"""
HeatPump class
"""
def __init__(self):
self._model = None
self._hp_monthly_fossil_consumption = None
self._hp_monthly_electricity_demand = None
@property
def model(self) -> str:
"""
Get model name
:return: str
"""
return self._model
@model.setter
def model(self, value):
"""
Set model (name, indicated in capacity)
:param value: str
"""
if self._model is None:
self._model = value
@property
def hp_monthly_fossil_consumption(self) -> List:
"""
Fossil fuel consumption that results from insel simulation
":return: []
:return:
"""
return self._hp_monthly_fossil_consumption
@hp_monthly_fossil_consumption.setter
def hp_monthly_fossil_consumption(self, value):
if isinstance(value, Series):
self._hp_monthly_fossil_consumption = value
@property
def hp_monthly_electricity_demand(self) -> List:
"""
Electricity demand that results from insel simulation
":return: []
:return:
"""
return self._hp_monthly_electricity_demand
@hp_monthly_electricity_demand.setter
def hp_monthly_electricity_demand(self, value):
if isinstance(value, Series):
self._hp_monthly_electricity_demand = value

View File

@ -0,0 +1,32 @@
"""
HvacTerminalUnit 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
"""
from typing import Union
class HvacTerminalUnit:
"""
HvacTerminalUnit class
"""
def __init__(self):
self._type = None
@property
def type(self) -> Union[None, str]:
"""
Get type of hvac terminal unit defined for a thermal zone
:return: None or str
"""
return self._type
@type.setter
def type(self, value):
"""
Set type of hvac terminal unit defined for a thermal zone
:param value: str
"""
if value is not None:
self._type = str(value)

View File

@ -1,539 +0,0 @@
"""
Non PV energy 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 hub.city_model_structure.energy_systems.generation_system import GenerationSystem
from hub.city_model_structure.energy_systems.performance_curve import PerformanceCurves
class NonPvGenerationSystem(GenerationSystem):
"""
NonPvGenerationSystem class
"""
def __init__(self):
super().__init__()
self._nominal_heat_output = None
self._maximum_heat_output = None
self._minimum_heat_output = None
self._heat_efficiency = None
self._nominal_cooling_output = None
self._maximum_cooling_output = None
self._minimum_cooling_output = None
self._cooling_efficiency = None
self._electricity_efficiency = None
self._nominal_electricity_output = None
self._source_medium = None
self._source_temperature = None
self._source_mass_flow = None
self._supply_medium = None
self._maximum_heat_supply_temperature = None
self._minimum_heat_supply_temperature = None
self._maximum_cooling_supply_temperature = None
self._minimum_cooling_supply_temperature = None
self._heat_output_curve = None
self._heat_fuel_consumption_curve = None
self._heat_efficiency_curve = None
self._cooling_output_curve = None
self._cooling_fuel_consumption_curve = None
self._cooling_efficiency_curve = None
self._domestic_hot_water = None
self._heat_supply_temperature = None
self._cooling_supply_temperature = None
self._reversible = None
self._simultaneous_heat_cold = None
self._energy_consumption = {}
@property
def nominal_heat_output(self):
"""
Get nominal heat output of heat generation devices in W
:return: float
"""
return self._nominal_heat_output
@nominal_heat_output.setter
def nominal_heat_output(self, value):
"""
Set nominal heat output of heat generation devices in W
:param value: float
"""
self._nominal_heat_output = value
@property
def maximum_heat_output(self):
"""
Get maximum heat output of heat generation devices in W
:return: float
"""
return self._maximum_heat_output
@maximum_heat_output.setter
def maximum_heat_output(self, value):
"""
Set maximum heat output of heat generation devices in W
:param value: float
"""
self._maximum_heat_output = value
@property
def minimum_heat_output(self):
"""
Get minimum heat output of heat generation devices in W
:return: float
"""
return self._minimum_heat_output
@minimum_heat_output.setter
def minimum_heat_output(self, value):
"""
Set minimum heat output of heat generation devices in W
:param value: float
"""
self._minimum_heat_output = value
@property
def source_medium(self):
"""
Get source_type from [air, water, ground, district_heating, grid, on_site_electricity]
:return: string
"""
return self._source_medium
@source_medium.setter
def source_medium(self, value):
"""
Set source medium from [Air, Water, Geothermal, District Heating, Grid, Onsite Electricity]
:param value: [string]
"""
self._source_medium = value
@property
def supply_medium(self):
"""
Get the supply medium from ['air', 'water']
:return: string
"""
return self._supply_medium
@supply_medium.setter
def supply_medium(self, value):
"""
Set the supply medium from ['air', 'water']
:param value: string
"""
self._supply_medium = value
@property
def heat_efficiency(self):
"""
Get heat_efficiency
:return: float
"""
return self._heat_efficiency
@heat_efficiency.setter
def heat_efficiency(self, value):
"""
Set heat_efficiency
:param value: float
"""
self._heat_efficiency = value
@property
def nominal_cooling_output(self):
"""
Get nominal cooling output of heat generation devices in W
:return: float
"""
return self._nominal_cooling_output
@nominal_cooling_output.setter
def nominal_cooling_output(self, value):
"""
Set nominal cooling output of heat generation devices in W
:param value: float
"""
self._nominal_cooling_output = value
@property
def maximum_cooling_output(self):
"""
Get maximum heat output of heat generation devices in W
:return: float
"""
return self._maximum_cooling_output
@maximum_cooling_output.setter
def maximum_cooling_output(self, value):
"""
Set maximum heat output of heat generation devices in W
:param value: float
"""
self._maximum_cooling_output = value
@property
def minimum_cooling_output(self):
"""
Get minimum heat output of heat generation devices in W
:return: float
"""
return self._minimum_cooling_output
@minimum_cooling_output.setter
def minimum_cooling_output(self, value):
"""
Set minimum heat output of heat generation devices in W
:param value: float
"""
self._minimum_cooling_output = value
@property
def cooling_efficiency(self):
"""
Get cooling_efficiency
:return: float
"""
return self._cooling_efficiency
@cooling_efficiency.setter
def cooling_efficiency(self, value):
"""
Set cooling_efficiency
:param value: float
"""
self._cooling_efficiency = value
@property
def electricity_efficiency(self):
"""
Get electricity_efficiency
:return: float
"""
return self._electricity_efficiency
@electricity_efficiency.setter
def electricity_efficiency(self, value):
"""
Set electricity_efficiency
:param value: float
"""
self._electricity_efficiency = value
@property
def source_temperature(self):
"""
Get source_temperature in degree Celsius
:return: float
"""
return self._source_temperature
@source_temperature.setter
def source_temperature(self, value):
"""
Set source_temperature in degree Celsius
:param value: float
"""
self._source_temperature = value
@property
def source_mass_flow(self):
"""
Get source_mass_flow in kg/s
:return: float
"""
return self._source_mass_flow
@source_mass_flow.setter
def source_mass_flow(self, value):
"""
Set source_mass_flow in kg/s
:param value: float
"""
self._source_mass_flow = value
@property
def nominal_electricity_output(self):
"""
Get nominal_power_output of electricity generation devices or inverters in W
:return: float
"""
return self._nominal_electricity_output
@nominal_electricity_output.setter
def nominal_electricity_output(self, value):
"""
Get nominal_power_output of electricity generation devices or inverters in W
:param value: float
"""
self._nominal_electricity_output = value
@property
def maximum_heat_supply_temperature(self):
"""
Get the maximum heat supply temperature in degree Celsius
:return: float
"""
return self._minimum_heat_supply_temperature
@maximum_heat_supply_temperature.setter
def maximum_heat_supply_temperature(self, value):
"""
Set maximum heating supply temperature in degree Celsius
:param value: float
"""
self._maximum_heat_supply_temperature = value
@property
def minimum_heat_supply_temperature(self):
"""
Get the minimum heat supply temperature in degree Celsius
:return: float
"""
return self._minimum_heat_supply_temperature
@minimum_heat_supply_temperature.setter
def minimum_heat_supply_temperature(self, value):
"""
Set minimum heating supply temperature in degree Celsius
:param value: float
"""
self._minimum_heat_supply_temperature = value
@property
def maximum_cooling_supply_temperature(self):
"""
Get the maximum cooling supply temperature in degree Celsius
:return: float
"""
return self._maximum_cooling_supply_temperature
@maximum_cooling_supply_temperature.setter
def maximum_cooling_supply_temperature(self, value):
"""
Set maximum cooling supply temperature in degree Celsius
:param value: float
"""
self._maximum_cooling_supply_temperature = value
@property
def minimum_cooling_supply_temperature(self):
"""
Get the minimum cooling supply temperature in degree Celsius
:return: float
"""
return self._minimum_cooling_supply_temperature
@minimum_cooling_supply_temperature.setter
def minimum_cooling_supply_temperature(self, value):
"""
Set minimum cooling supply temperature in degree Celsius
:param value: float
"""
self._minimum_cooling_supply_temperature = value
@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
@heat_output_curve.setter
def heat_output_curve(self, value):
"""
Set the heat output curve of the heat generation device
:return: PerformanceCurve
"""
self._heat_output_curve = value
@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
@heat_fuel_consumption_curve.setter
def heat_fuel_consumption_curve(self, value):
"""
Set the heating fuel consumption curve of the heat generation device
:return: PerformanceCurve
"""
self._heat_fuel_consumption_curve = value
@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
@heat_efficiency_curve.setter
def heat_efficiency_curve(self, value):
"""
Set the heating efficiency curve of the heat generation device
:return: PerformanceCurve
"""
self._heat_efficiency_curve = value
@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
@cooling_output_curve.setter
def cooling_output_curve(self, value):
"""
Set the cooling output curve of the heat generation device
:return: PerformanceCurve
"""
self._cooling_output_curve = value
@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
@cooling_fuel_consumption_curve.setter
def cooling_fuel_consumption_curve(self, value):
"""
Set the heating fuel consumption curve of the heat generation device
:return: PerformanceCurve
"""
self._cooling_fuel_consumption_curve = value
@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
@cooling_efficiency_curve.setter
def cooling_efficiency_curve(self, value):
"""
Set the heating efficiency curve of the heat generation device
:return: PerformanceCurve
"""
self._cooling_efficiency_curve = value
@property
def domestic_hot_water(self):
"""
Get the capability of generating domestic hot water
:return: bool
"""
return self._domestic_hot_water
@domestic_hot_water.setter
def domestic_hot_water(self, value):
"""
Set the capability of generating domestic hot water
:return: bool
"""
self._domestic_hot_water = value
@property
def heat_supply_temperature(self):
"""
Get the hourly heat supply temperature
:return: list
"""
return self._heat_supply_temperature
@heat_supply_temperature.setter
def heat_supply_temperature(self, value):
"""
set the hourly heat supply temperature
:param value:
:return: list
"""
self._heat_supply_temperature = value
@property
def cooling_supply_temperature(self):
"""
Get the hourly cooling supply temperature
:return: list
"""
return self._heat_supply_temperature
@cooling_supply_temperature.setter
def cooling_supply_temperature(self, value):
"""
set the hourly cooling supply temperature
:param value:
:return: list
"""
self._cooling_supply_temperature = value
@property
def reversibility(self):
"""
Get the capability of generating both heating and cooling
:return: bool
"""
return self._reversible
@reversibility.setter
def reversibility(self, value):
"""
Set the capability of generating domestic hot water
:return: bool
"""
self._reversible = value
@property
def simultaneous_heat_cold(self):
"""
Get the capability of generating both heating and cooling at the same time
:return: bool
"""
return self._simultaneous_heat_cold
@simultaneous_heat_cold.setter
def simultaneous_heat_cold(self, value):
"""
Set the capability of generating domestic hot water at the same time
:return: bool
"""
self._simultaneous_heat_cold = value
@property
def energy_consumption(self) -> dict:
"""
Get energy consumption in W
:return: dict{[float]}
"""
return self._energy_consumption
@energy_consumption.setter
def energy_consumption(self, value):
"""
Set energy consumption in W
:param value: dict{[float]}
"""
self._energy_consumption = value

View File

@ -1,104 +0,0 @@
"""
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
class PerformanceCurves:
"""
Parameter function class
"""
def __init__(self):
self._curve_type = None
self._dependant_variable = None
self._parameters = None
self._coefficients = None
@property
def curve_type(self):
"""
Get the type of the fit function from the following
Linear =>>> y = a + b*x
Exponential =>>> y = a*(b**x)
Second degree polynomial =>>> y = a + b*x + c*(x**2)
Power =>>> y = a*(x**b)
Bi-Quadratic =>>> y = a + b*x + c*(x**2) + d*z + e*(z**2) + f*x*z
Get the type of function from ['linear', 'exponential', 'second degree polynomial', 'power', 'bi-quadratic']
:return: string
"""
return self._curve_type
@curve_type.setter
def curve_type(self, value):
"""
Set the type of the fit function from the following
Linear =>>> y = a + b*x
Exponential =>>> y = a*(b**x)
Second degree polynomial =>>> y = a + b*x + c*(x**2)
Power =>>> y = a*(x**b)
Bi-Quadratic =>>> y = a + b*x + c*(x**2) + d*z + e*(z**2) + f*x*z
Get the type of function from ['linear', 'exponential', 'second degree polynomial', 'power', 'bi-quadratic']
:return: string
"""
self._curve_type = value
@property
def dependant_variable(self):
"""
Get 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._dependant_variable
@dependant_variable.setter
def dependant_variable(self, value):
"""
Set 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)
"""
self._dependant_variable = value
@property
def parameters(self):
"""
Get the list of parameters involved in fitting process as ['x', 'z'] (e.g. [source temperature, supply temperature]
in COP= *source temperature**2 + b*source temperature + c*source temperature*supply temperature +
d*supply temperature + e*supply temperature**2 + f)
:return: string
"""
return self._parameters
@parameters.setter
def parameters(self, value):
"""
Set the list of parameters involved in fitting process as ['x', 'z'] (e.g. [source temperature, supply temperature]
in COP= *source temperature**2 + b*source temperature + c*source temperature*supply temperature +
d*supply temperature + e*supply temperature**2 + f)
:return: string
"""
self._parameters = value
@property
def coefficients(self):
"""
Get the coefficients of the functions as list of ['a', 'b', 'c', 'd', 'e', 'f']
:return: [coefficients]
"""
return self._coefficients
@coefficients.setter
def coefficients(self, value):
"""
Set the coefficients of the functions as list of ['a', 'b', 'c', 'd', 'e', 'f']
:return: [coefficients]
"""
self._coefficients = value

View File

@ -1,239 +0,0 @@
"""
PV energy 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 hub.city_model_structure.energy_systems.generation_system import GenerationSystem
class PvGenerationSystem(GenerationSystem):
"""
PvGenerationSystem class
"""
def __init__(self):
super().__init__()
self._electricity_efficiency = None
self._nominal_electricity_output = None
self._nominal_ambient_temperature = None
self._nominal_cell_temperature = None
self._nominal_radiation = None
self._standard_test_condition_cell_temperature = None
self._standard_test_condition_maximum_power = None
self._standard_test_condition_radiation = None
self._cell_temperature_coefficient = None
self._width = None
self._height = None
self._electricity_power_output = {}
self._tilt_angle = None
self._installed_capacity = None
@property
def nominal_electricity_output(self):
"""
Get nominal_power_output of electricity generation devices or inverters in W
:return: float
"""
return self._nominal_electricity_output
@nominal_electricity_output.setter
def nominal_electricity_output(self, value):
"""
Set nominal_power_output of electricity generation devices or inverters in W
:param value: float
"""
self._nominal_electricity_output = value
@property
def electricity_efficiency(self):
"""
Get electricity_efficiency
:return: float
"""
return self._electricity_efficiency
@electricity_efficiency.setter
def electricity_efficiency(self, value):
"""
Set electricity_efficiency
:param value: float
"""
self._electricity_efficiency = value
@property
def nominal_ambient_temperature(self):
"""
Get nominal ambient temperature of PV panels in degree Celsius
:return: float
"""
return self._nominal_ambient_temperature
@nominal_ambient_temperature.setter
def nominal_ambient_temperature(self, value):
"""
Set nominal ambient temperature of PV panels in degree Celsius
:param value: float
"""
self._nominal_ambient_temperature = value
@property
def nominal_cell_temperature(self):
"""
Get nominal cell temperature of PV panels in degree Celsius
:return: float
"""
return self._nominal_cell_temperature
@nominal_cell_temperature.setter
def nominal_cell_temperature(self, value):
"""
Set nominal cell temperature of PV panels in degree Celsius
:param value: float
"""
self._nominal_cell_temperature = value
@property
def nominal_radiation(self):
"""
Get nominal radiation of PV panels
:return: float
"""
return self._nominal_radiation
@nominal_radiation.setter
def nominal_radiation(self, value):
"""
Set nominal radiation of PV panels
:param value: float
"""
self._nominal_radiation = value
@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
@standard_test_condition_cell_temperature.setter
def standard_test_condition_cell_temperature(self, value):
"""
Set standard test condition cell temperature of PV panels in degree Celsius
:param value: float
"""
self._standard_test_condition_cell_temperature = value
@property
def standard_test_condition_maximum_power(self):
"""
Get standard test condition maximum power of PV panels in W
:return: float
"""
return self._standard_test_condition_maximum_power
@standard_test_condition_maximum_power.setter
def standard_test_condition_maximum_power(self, value):
"""
Set standard test condition maximum power of PV panels in W
:param value: float
"""
self._standard_test_condition_maximum_power = value
@property
def standard_test_condition_radiation(self):
"""
Get standard test condition radiation in W/m2
:return: float
"""
return self._standard_test_condition_radiation
@standard_test_condition_radiation.setter
def standard_test_condition_radiation(self, value):
"""
Set standard test condition radiation in W/m2
:param value: float
"""
self._standard_test_condition_radiation = value
@property
def cell_temperature_coefficient(self):
"""
Get cell temperature coefficient of PV module
:return: float
"""
return self._cell_temperature_coefficient
@cell_temperature_coefficient.setter
def cell_temperature_coefficient(self, value):
"""
Set cell temperature coefficient of PV module
:param value: float
"""
self._cell_temperature_coefficient = value
@property
def width(self):
"""
Get PV module width in m
:return: float
"""
return self._width
@width.setter
def width(self, value):
"""
Set PV module width in m
:param value: float
"""
self._width = value
@property
def height(self):
"""
Get PV module height in m
:return: float
"""
return self._height
@height.setter
def height(self, value):
"""
Set PV module height in m
:param value: float
"""
self._height = value
@property
def electricity_power_output(self):
"""
Get electricity_power in W
:return: float
"""
return self._electricity_power_output
@electricity_power_output.setter
def electricity_power_output(self, value):
"""
Set electricity_power in W
:param value: float
"""
self._electricity_power_output = value
@property
def installed_capacity(self):
"""
Get the total installed nominal capacity in W
:return: float
"""
return self._installed_capacity
@installed_capacity.setter
def installed_capacity(self, value):
"""
Set the total installed nominal capacity in W
:param value: float
"""
self._installed_capacity = value

View File

@ -1,139 +0,0 @@
"""
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.city_model_structure.energy_systems.energy_storage_system import EnergyStorageSystem
from hub.city_model_structure.building_demand.layer import Layer
class ThermalStorageSystem(EnergyStorageSystem):
""""
Thermal Storage System Class
"""
def __init__(self):
super().__init__()
self._volume = None
self._height = None
self._layers = None
self._maximum_operating_temperature = None
self._heating_coil_capacity = None
self._temperature = None
self._heating_coil_energy_consumption = None
@property
def volume(self):
"""
Get the physical volume of the storage system in cubic meters
:return: float
"""
return self._volume
@volume.setter
def volume(self, value):
"""
Set the physical volume of the storage system in cubic meters
:param value: float
"""
self._volume = value
@property
def height(self):
"""
Get the diameter of the storage system in meters
:return: float
"""
return self._height
@height.setter
def height(self, value):
"""
Set the diameter of the storage system in meters
:param value: float
"""
self._height = value
@property
def layers(self) -> [Layer]:
"""
Get construction layers
:return: [layer]
"""
return self._layers
@layers.setter
def layers(self, value):
"""
Set construction layers
:param value: [layer]
"""
self._layers = value
@property
def maximum_operating_temperature(self):
"""
Get maximum operating temperature of the storage system in degree Celsius
:return: float
"""
return self._maximum_operating_temperature
@maximum_operating_temperature.setter
def maximum_operating_temperature(self, value):
"""
Set maximum operating temperature of the storage system in degree Celsius
:param value: float
"""
self._maximum_operating_temperature = value
@property
def heating_coil_capacity(self):
"""
Get heating coil capacity in Watts
:return: float
"""
return self._heating_coil_capacity
@heating_coil_capacity.setter
def heating_coil_capacity(self, value):
"""
Set heating coil capacity in Watts
:param value: float
"""
self._heating_coil_capacity = value
@property
def temperature(self) -> dict:
"""
Get fuel consumption in W, m3, or kg
:return: dict{[float]}
"""
return self._temperature
@temperature.setter
def temperature(self, value):
"""
Set fuel consumption in W, m3, or kg
:param value: dict{[float]}
"""
self._temperature = value
@property
def heating_coil_energy_consumption(self) -> dict:
"""
Get fuel consumption in W, m3, or kg
:return: dict{[float]}
"""
return self._heating_coil_energy_consumption
@heating_coil_energy_consumption.setter
def heating_coil_energy_consumption(self, value):
"""
Set fuel consumption in W, m3, or kg
:param value: dict{[float]}
"""
self._heating_coil_energy_consumption = value

View File

@ -1,774 +0,0 @@
{
"archetypes": [
{
"function": "Large multifamily building",
"period_of_construction": "2021_2050",
"climate_zone": "B3",
"average_storey_height": 3.57,
"thermal_capacity": 83.018,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
"transparent_ratio": {
"north": "60",
"east": "5",
"south": "60",
"west": "5"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
},
"GroundWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
},
"GroundRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
}
}
},
{
"function": "Medium multifamily building",
"period_of_construction": "2021_2050",
"climate_zone": "B3",
"average_storey_height": 3.57,
"thermal_capacity": 83.018,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
"transparent_ratio": {
"north": "60",
"east": "5",
"south": "60",
"west": "5"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
},
"GroundWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
},
"GroundRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
}
}
},
{
"function": "Small multifamily building",
"period_of_construction": "2021_2050",
"climate_zone": "B3",
"average_storey_height": 3.57,
"thermal_capacity": 83.018,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
"transparent_ratio": {
"north": "60",
"east": "5",
"south": "60",
"west": "5"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
},
"GroundWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
},
"GroundRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
}
}
},
{
"function": "Single-family building",
"period_of_construction": "2021_2050",
"climate_zone": "B3",
"average_storey_height": 3.57,
"thermal_capacity": 83.018,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
"transparent_ratio": {
"north": "60",
"east": "5",
"south": "60",
"west": "5"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
},
"GroundWall": {
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
},
"GroundRoofCeiling": {
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
}
}
},
{
"function": "Large multifamily building",
"period_of_construction": "1961_1980",
"climate_zone": "B3",
"average_storey_height": 3.57,
"thermal_capacity": 3000,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0045,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1",
"transparent_surface_name": "PA1_PA2_1961_1980_WIN1",
"transparent_ratio": {
"north": "60",
"east": "60",
"south": "60",
"west": "60"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_1961_1980_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR1"
},
"GroundWall": {
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1"
},
"GroundRoofCeiling": {
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR4"
}
}
},
{
"function": "Large multifamily building",
"period_of_construction": "1981_2007",
"climate_zone": "B3",
"average_storey_height": 3.2,
"thermal_capacity": 3179,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.003,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "E_1981_2007_FACEXT1",
"transparent_surface_name": "E_1981_2007_WIN1",
"transparent_ratio": {
"north": "45",
"east": "45",
"south": "45",
"west": "45"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "E_1981_2007_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "E_1981_2007_FLOORGR1"
}
}
},
{
"function": "Medium multifamily building",
"period_of_construction": "1800_1900",
"climate_zone": "B3",
"average_storey_height": 4.39,
"thermal_capacity": 3330,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.006,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "A_B1900_FACEXT1",
"transparent_surface_name": "A_B1900_WIN2",
"transparent_ratio": {
"north": "20",
"east": "20",
"south": "20",
"west": "20"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "A_B1900_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "A_B1900_FLOORGR1"
}
}
},
{
"function": "Medium multifamily building",
"period_of_construction": "1901_1940",
"climate_zone": "B3",
"average_storey_height": 3.65,
"thermal_capacity": 3420,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.006,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "B_1901_1940_FACEXT1",
"transparent_surface_name": "B_1901_1940_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "B_1901_1940_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "B_1901_1940_FLOORGR1"
}
}
},
{
"function": "Medium multifamily building",
"period_of_construction": "1941_1960",
"climate_zone": "B3",
"average_storey_height": 3.6,
"thermal_capacity": 3000,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0055,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "C_1941_1960_FACEXT1",
"transparent_surface_name": "C_1941_1960_WIN1",
"transparent_ratio": {
"north": "30",
"east": "30",
"south": "30",
"west": "30"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "C_1941_1960_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "C_1941_1960_FLOORGR1"
}
}
},
{
"function": "Medium multifamily building",
"period_of_construction": "1961_1980",
"climate_zone": "B3",
"average_storey_height": 4.5,
"thermal_capacity": 3540,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0045,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1",
"transparent_surface_name": "PA1_PA2_1961_1980_WIN1",
"transparent_ratio": {
"north": "55",
"east": "55",
"south": "55",
"west": "55"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA1_PA2_1961_1980_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR1"
}
}
},
{
"function": "Medium multifamily building",
"period_of_construction": "1981_2007",
"climate_zone": "B3",
"average_storey_height": 3.2,
"thermal_capacity": 3179,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.003,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "E_1981_2007_FACEXT1",
"transparent_surface_name": "E_1981_2007_WIN1",
"transparent_ratio": {
"north": "45",
"east": "45",
"south": "45",
"west": "45"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "E_1981_2007_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "E_1981_2007_FLOORGR1"
}
}
},
{
"function": "Medium multifamily building",
"period_of_construction": "2008_2014",
"climate_zone": "B3",
"average_storey_height": 2.75,
"thermal_capacity": 3290,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0015,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "F_2008_2014_FACEXT1",
"transparent_surface_name": "F_2008_2014_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "F_2008_2014_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "F_2008_2014_FLOORGR1"
}
}
},
{
"function": "Small multifamily building",
"period_of_construction": "1800_1980",
"climate_zone": "B3",
"average_storey_height": 3.8,
"thermal_capacity": 3527.9,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.006,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA3_PA4_1901_1940_FACEXT1",
"transparent_surface_name": "PA3_PA4_1901_1940_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA3_PA4_1901_1940_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA3_PA4_1901_1940_FLOORGR1"
}
}
},
{
"function": "Small multifamily building",
"period_of_construction": "1981_2007",
"climate_zone": "B3",
"average_storey_height": 3.2,
"thermal_capacity": 3179,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.003,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "E_1981_2007_FACEXT1",
"transparent_surface_name": "E_1981_2007_WIN1",
"transparent_ratio": {
"north": "45",
"east": "45",
"south": "45",
"west": "45"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "E_1981_2007_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "E_1981_2007_FLOORGR1"
}
}
},
{
"function": "Small multifamily building",
"period_of_construction": "2008_2014",
"climate_zone": "B3",
"average_storey_height": 2.75,
"thermal_capacity": 3290,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0015,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "F_2008_2014_FACEXT1",
"transparent_surface_name": "F_2008_2014_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "F_2008_2014_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "F_2008_2014_FLOORGR1"
}
}
},
{
"function": "Small multifamily building",
"period_of_construction": "2015_2019",
"climate_zone": "B3",
"average_storey_height": 2.75,
"thermal_capacity": 3290,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "G_2015_2019_FACEXT1",
"transparent_surface_name": "G_2015_2019_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "G_2015_2019_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "G_2015_2019_FLOORGR1"
}
}
},
{
"function": "Single-family building",
"period_of_construction": "1800_1980",
"climate_zone": "B3",
"average_storey_height": 3.68,
"thermal_capacity": 4400,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.006,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "PA3_PA4_1901_1940_FACEXT1",
"transparent_surface_name": "PA3_PA4_1901_1940_WIN1",
"transparent_ratio": {
"north": "40",
"east": "40",
"south": "40",
"west": "40"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "PA3_PA4_1901_1940_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "PA3_PA4_1901_1940_FLOORGR1"
}
}
},
{
"function": "Single-family building",
"period_of_construction": "1981_2007",
"climate_zone": "B3",
"average_storey_height": 3.2,
"thermal_capacity": 3179,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.003,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "E_1981_2007_FACEXT1",
"transparent_surface_name": "E_1981_2007_WIN1",
"transparent_ratio": {
"north": "45",
"east": "45",
"south": "45",
"west": "45"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "E_1981_2007_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "E_1981_2007_FLOORGR1"
}
}
},
{
"function": "Single-family building",
"period_of_construction": "2008_2014",
"climate_zone": "B3",
"average_storey_height": 3.75,
"thermal_capacity": 3200,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0015,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "F_2008_2014_FACEXT1",
"transparent_surface_name": "F_2008_2014_WIN1",
"transparent_ratio": {
"north": "60",
"east": "60",
"south": "60",
"west": "60"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "F_2008_2014_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "F_2008_2014_FLOORGR1"
}
}
},
{
"function": "Single-family building",
"period_of_construction": "2015_2019",
"climate_zone": "B3",
"average_storey_height": 3.75,
"thermal_capacity": 3200,
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.9,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "G_2015_2019_FACEXT1",
"transparent_surface_name": "G_2015_2019_WIN1",
"transparent_ratio": {
"north": "60",
"east": "60",
"south": "60",
"west": "60"
}
},
"OutdoorsRoofCeiling": {
"opaque_surface_name": "G_2015_2019_ROOF1",
"transparent_surface_name": null,
"transparent_ratio": {
"north": null,
"east": null,
"south": null,
"west": null
}
},
"GroundFloor": {
"opaque_surface_name": "G_2015_2019_FLOORGR1"
}
}
}
]
}

File diff suppressed because it is too large Load Diff

View File

@ -38,96 +38,53 @@
</equipment>
</generation_equipments>
<distribution_equipments>
<equipment id="1" type="Water distribution heating with baseboards">
<equipment id="1" type="Water distribution heating">
<name>Water distribution heating</name>
<distribution_heat_losses units="%">10</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">2</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">0</distribution_consumption_variable_flow>
<dissipation_id>1</dissipation_id>
</equipment>
<equipment id="2" type="Water distribution heating with fan-coils">
<name>Water distribution heating</name>
<distribution_heat_losses units="%">10</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">2</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">0</distribution_consumption_variable_flow>
<dissipation_id>2</dissipation_id>
</equipment>
<equipment id="3" type="Water distribution heating with inductors">
<name>Water distribution heating</name>
<distribution_heat_losses units="%">10</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">2</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">0</distribution_consumption_variable_flow>
<dissipation_id>3</dissipation_id>
</equipment>
<equipment id="4" type="Water distribution cooling with fan-coils">
<equipment id="2" type="Water distribution cooling">
<name>Water distribution cooling</name>
<distribution_heat_losses units="%">5</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">4</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">0</distribution_consumption_variable_flow>
<dissipation_id>2</dissipation_id>
</equipment>
<equipment id="5" type="Central air distribution heating with fan-coils">
<equipment id="3" type="Central air distribution heating">
<name>Central air distribution heating</name>
<distribution_heat_losses units="%">10</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">0</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">13</distribution_consumption_variable_flow>
<dissipation_id>2</dissipation_id>
</equipment>
<equipment id="6" type="Central air distribution heating with inductors">
<name>Central air distribution heating</name>
<distribution_heat_losses units="%">10</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">0</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">13</distribution_consumption_variable_flow>
<dissipation_id>3</dissipation_id>
</equipment>
<equipment id="7" type="Central air distribution cooling with fan-coils">
<equipment id="4" type="Central air distribution cooling">
<name>Central air distribution cooling</name>
<distribution_heat_losses units="%">5</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">0</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">13</distribution_consumption_variable_flow>
<dissipation_id>2</dissipation_id>
</equipment>
<equipment id="8" type="Local air distribution heating with baseboards">
<equipment id="5" type="Local air distribution heating">
<name>Local air distribution heating</name>
<distribution_heat_losses units="%">5</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">8</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">0</distribution_consumption_variable_flow>
<dissipation_id>1</dissipation_id>
</equipment>
<equipment id="9" type="Local air distribution heating with inductors">
<name>Local air distribution heating</name>
<distribution_heat_losses units="%">5</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">8</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">0</distribution_consumption_variable_flow>
<dissipation_id>3</dissipation_id>
</equipment>
<equipment id="10" type="Local air distribution cooling with inductors">
<equipment id="6" type="Local air distribution cooling">
<name>Local air distribution cooling</name>
<distribution_heat_losses units="%">2</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">8</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">0</distribution_consumption_variable_flow>
<dissipation_id>3</dissipation_id>
</equipment>
<equipment id="11" type="Refrigerant distribution with fan-coils">
<equipment id="7" type="Refrigerant distribution">
<name>Refrigerant distribution</name>
<distribution_heat_losses units="%">1</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">1</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">0</distribution_consumption_variable_flow>
<dissipation_id>2</dissipation_id>
</equipment>
<equipment id="12" type="No distribution with baseboards">
<equipment id="8" type="No distribution">
<name>No distribution</name>
<distribution_heat_losses units="%">0</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">0</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">0</distribution_consumption_variable_flow>
<dissipation_id>1</dissipation_id>
</equipment>
<equipment id="13" type="No distribution with inductors">
<name>No distribution</name>
<distribution_heat_losses units="%">0</distribution_heat_losses>
<distribution_consumption_fix_flow units="%">0</distribution_consumption_fix_flow>
<distribution_consumption_variable_flow units="%">0</distribution_consumption_variable_flow>
<dissipation_id>3</dissipation_id>
</equipment>
</distribution_equipments>
<dissipation_equipments>
@ -154,6 +111,7 @@
<equipments>
<generation_id>1</generation_id>
<distribution_id>1</distribution_id>
<dissipation_id>1</dissipation_id>
</equipments>
</system>
<system id = "16">
@ -164,7 +122,8 @@
</demands>
<equipments>
<generation_id>2</generation_id>
<distribution_id>12</distribution_id>
<distribution_id>8</distribution_id>
<dissipation_id>1</dissipation_id>
</equipments>
</system>
<system id = "2">
@ -175,7 +134,8 @@
</demands>
<equipments>
<generation_id>1</generation_id>
<distribution_id>2</distribution_id>
<distribution_id>1</distribution_id>
<dissipation_id>2</dissipation_id>
</equipments>
</system>
<system id="3">
@ -186,7 +146,8 @@
</demands>
<equipments>
<generation_id>2</generation_id>
<distribution_id>2</distribution_id>
<distribution_id>1</distribution_id>
<dissipation_id>2</dissipation_id>
</equipments>
</system>
<system id="4">
@ -197,7 +158,8 @@
</demands>
<equipments>
<generation_id>3</generation_id>
<distribution_id>8</distribution_id>
<distribution_id>5</distribution_id>
<dissipation_id>1</dissipation_id>
</equipments>
</system>
<system id="5">
@ -208,7 +170,8 @@
</demands>
<equipments>
<generation_id>4</generation_id>
<distribution_id>8</distribution_id>
<distribution_id>5</distribution_id>
<dissipation_id>1</dissipation_id>
</equipments>
</system>
<system id="6">
@ -220,6 +183,7 @@
<equipments>
<generation_id>1</generation_id>
<distribution_id>1</distribution_id>
<dissipation_id>1</dissipation_id>
</equipments>
</system>
<system id="7">
@ -230,7 +194,8 @@
</demands>
<equipments>
<generation_id>2</generation_id>
<distribution_id>13</distribution_id>
<distribution_id>8</distribution_id>
<dissipation_id>3</dissipation_id>
</equipments>
</system>
<system id="8">
@ -240,8 +205,9 @@
<demand>domestic_hot_water</demand>
</demands>
<equipments>
<generation_id>1</generation_id>
<distribution_id>3</distribution_id>
<generation_id>2</generation_id>
<distribution_id>1</distribution_id>
<dissipation_id>3</dissipation_id>
</equipments>
</system>
<system id="9">
@ -252,7 +218,8 @@
</demands>
<equipments>
<generation_id>2</generation_id>
<distribution_id>13</distribution_id>
<distribution_id>8</distribution_id>
<dissipation_id>3</dissipation_id>
</equipments>
</system>
<system id="10">
@ -262,7 +229,8 @@
</demands>
<equipments>
<generation_id>5</generation_id>
<distribution_id>10</distribution_id>
<distribution_id>6</distribution_id>
<dissipation_id>3</dissipation_id>
</equipments>
</system>
<system id="11">
@ -272,7 +240,8 @@
</demands>
<equipments>
<generation_id>5</generation_id>
<distribution_id>4</distribution_id>
<distribution_id>2</distribution_id>
<dissipation_id>2</dissipation_id>
</equipments>
</system>
<system id="12">
@ -282,7 +251,8 @@
</demands>
<equipments>
<generation_id>5</generation_id>
<distribution_id>10</distribution_id>
<distribution_id>6</distribution_id>
<dissipation_id>3</dissipation_id>
</equipments>
</system>
<system id="13">
@ -292,7 +262,8 @@
</demands>
<equipments>
<generation_id>5</generation_id>
<distribution_id>10</distribution_id>
<distribution_id>6</distribution_id>
<dissipation_id>3</dissipation_id>
</equipments>
</system>
<system id="14">
@ -302,7 +273,8 @@
</demands>
<equipments>
<generation_id>5</generation_id>
<distribution_id>4</distribution_id>
<distribution_id>3</distribution_id>
<dissipation_id>3</dissipation_id>
</equipments>
</system>
<system id="15">
@ -312,7 +284,8 @@
</demands>
<equipments>
<generation_id>6</generation_id>
<distribution_id>9</distribution_id>
<distribution_id>5</distribution_id>
<dissipation_id>3</dissipation_id>
</equipments>
</system>
<system id="17">
@ -323,7 +296,8 @@
</demands>
<equipments>
<generation_id>7</generation_id>
<distribution_id>5</distribution_id>
<distribution_id>3</distribution_id>
<dissipation_id>2</dissipation_id>
</equipments>
</system>
<system id="18">
@ -333,7 +307,8 @@
</demands>
<equipments>
<generation_id>7</generation_id>
<distribution_id>7</distribution_id>
<distribution_id>4</distribution_id>
<dissipation_id>2</dissipation_id>
</equipments>
</system>
</systems>

File diff suppressed because it is too large Load Diff

View File

@ -1,809 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<EnergySystemCatalog>
<schemas_path>./schemas/</schemas_path>
<media>
<medium>
<medium_id>1</medium_id>
<name>Water</name>
<solar_absorptance/>
<thermal_absorptance/>
<visible_absorptance/>
<no_mass/>
<thermal_resistance/>
<density>981.0</density>
<specific_heat>4180.0</specific_heat>
<conductivity>0.6</conductivity>
</medium>
</media>
<energy_generation_components>
<non_pv_generation_component>
<system_id>1</system_id>
<name>Natural-Gas Boiler</name>
<system_type>boiler</system_type>
<model_name/>
<manufacturer/>
<nominal_heat_output/>
<minimum_heat_output/>
<maximum_heat_output/>
<heat_efficiency>0.7</heat_efficiency>
<reversible>False</reversible>
<fuel_type>natural gas</fuel_type>
<source_medium/>
<supply_medium/>
<nominal_cooling_output/>
<minimum_cooling_output/>
<maximum_cooling_output/>
<cooling_efficiency/>
<electricity_efficiency/>
<source_temperature/>
<source_mass_flow/>
<nominal_electricity_output/>
<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/>
<distribution_systems/>
<energy_storage_systems/>
<domestic_hot_water>True</domestic_hot_water>
<heat_supply_temperature/>
<cooling_supply_temperature/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>2</system_id>
<name>Joule</name>
<system_type>joule</system_type>
<model_name/>
<manufacturer/>
<nominal_heat_output/>
<minimum_heat_output/>
<maximum_heat_output/>
<heat_efficiency>1</heat_efficiency>
<reversible>False</reversible>
<fuel_type>electricity</fuel_type>
<source_medium/>
<supply_medium/>
<nominal_cooling_output/>
<minimum_cooling_output/>
<maximum_cooling_output/>
<cooling_efficiency/>
<electricity_efficiency/>
<source_temperature/>
<source_mass_flow/>
<nominal_electricity_output/>
<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/>
<distribution_systems/>
<energy_storage_systems/>
<domestic_hot_water>True</domestic_hot_water>
<heat_supply_temperature/>
<cooling_supply_temperature/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>3</system_id>
<name>Heat Pump</name>
<system_type>heat pump</system_type>
<model_name/>
<manufacturer/>
<nominal_heat_output/>
<minimum_heat_output/>
<maximum_heat_output/>
<heat_efficiency>2</heat_efficiency>
<reversible>True</reversible>
<fuel_type>electricity</fuel_type>
<source_medium>Air</source_medium>
<supply_medium>Water</supply_medium>
<nominal_cooling_output/>
<minimum_cooling_output/>
<maximum_cooling_output/>
<cooling_efficiency>2</cooling_efficiency>
<electricity_efficiency/>
<source_temperature/>
<source_mass_flow/>
<nominal_electricity_output/>
<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/>
<distribution_systems/>
<energy_storage_systems/>
<domestic_hot_water>False</domestic_hot_water>
<heat_supply_temperature/>
<cooling_supply_temperature/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>4</system_id>
<name>Butane Heater</name>
<system_type>butane heater</system_type>
<model_name/>
<manufacturer/>
<nominal_heat_output/>
<minimum_heat_output/>
<maximum_heat_output/>
<heat_efficiency>0.7</heat_efficiency>
<reversible>False</reversible>
<fuel_type>butane</fuel_type>
<source_medium/>
<supply_medium/>
<nominal_cooling_output/>
<minimum_cooling_output/>
<maximum_cooling_output/>
<cooling_efficiency/>
<electricity_efficiency/>
<source_temperature/>
<source_mass_flow/>
<nominal_electricity_output/>
<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/>
<distribution_systems/>
<energy_storage_systems/>
<domestic_hot_water>True</domestic_hot_water>
<heat_supply_temperature/>
<cooling_supply_temperature/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>5</system_id>
<name>Split</name>
<system_type>split</system_type>
<model_name/>
<manufacturer/>
<nominal_heat_output/>
<minimum_heat_output/>
<maximum_heat_output/>
<heat_efficiency/>
<reversible>False</reversible>
<fuel_type>electricity</fuel_type>
<source_medium/>
<supply_medium/>
<nominal_cooling_output/>
<minimum_cooling_output/>
<maximum_cooling_output/>
<cooling_efficiency>2</cooling_efficiency>
<electricity_efficiency/>
<source_temperature/>
<source_mass_flow/>
<nominal_electricity_output/>
<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/>
<distribution_systems/>
<energy_storage_systems/>
<domestic_hot_water>False</domestic_hot_water>
<heat_supply_temperature/>
<cooling_supply_temperature/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</non_pv_generation_component>
<non_pv_generation_component>
<system_id>6</system_id>
<name>Domestic Hot Water Heat Pump</name>
<system_type>heat pump</system_type>
<model_name/>
<manufacturer/>
<nominal_heat_output/>
<minimum_heat_output/>
<maximum_heat_output/>
<heat_efficiency>3</heat_efficiency>
<reversible>False</reversible>
<fuel_type>electricity</fuel_type>
<source_medium>Air</source_medium>
<supply_medium>Water</supply_medium>
<nominal_cooling_output/>
<minimum_cooling_output/>
<maximum_cooling_output/>
<cooling_efficiency/>
<electricity_efficiency/>
<source_temperature/>
<source_mass_flow/>
<nominal_electricity_output/>
<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/>
<distribution_systems/>
<energy_storage_systems/>
<domestic_hot_water>True</domestic_hot_water>
<heat_supply_temperature/>
<cooling_supply_temperature/>
<simultaneous_heat_cold/>
</non_pv_generation_component>
<pv_generation_component>
<system_id>7</system_id>
<name>template Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name/>
<manufacturer/>
<nominal_electricity_output/>
<electricity_efficiency>0.2</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>45</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>500</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.3</cell_temperature_coefficient>
<width>2.0</width>
<height>1.0</height>
<distribution_systems/>
<energy_storage_systems/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>8</system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>RE400CAA Pure 2</model_name>
<manufacturer>REC</manufacturer>
<nominal_electricity_output>305</nominal_electricity_output>
<electricity_efficiency>0.206</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>44</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>400</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.24</cell_temperature_coefficient>
<width>1.86</width>
<height>1.04</height>
<distribution_systems/>
<energy_storage_systems/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>9</system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>RE410CAA Pure 2</model_name>
<manufacturer>REC</manufacturer>
<nominal_electricity_output>312</nominal_electricity_output>
<electricity_efficiency>0.211</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>44</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>410</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.24</cell_temperature_coefficient>
<width>1.86</width>
<height>1.04</height>
<distribution_systems/>
<energy_storage_systems/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>10</system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>RE420CAA Pure 2</model_name>
<manufacturer>REC</manufacturer>
<nominal_electricity_output>320</nominal_electricity_output>
<electricity_efficiency>0.217</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>44</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>420</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.24</cell_temperature_coefficient>
<width>1.86</width>
<height>1.04</height>
<distribution_systems/>
<energy_storage_systems/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>11</system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>RE430CAA Pure 2</model_name>
<manufacturer>REC</manufacturer>
<nominal_electricity_output>327</nominal_electricity_output>
<electricity_efficiency>0.222</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>44</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>430</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.24</cell_temperature_coefficient>
<width>1.86</width>
<height>1.04</height>
<distribution_systems/>
<energy_storage_systems/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>12</system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>REC600AA Pro M</model_name>
<manufacturer>REC</manufacturer>
<nominal_electricity_output>457</nominal_electricity_output>
<electricity_efficiency>0.211</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>44</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>600</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.24</cell_temperature_coefficient>
<width>2.17</width>
<height>1.3</height>
<distribution_systems/>
<energy_storage_systems/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>13</system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>REC610AA Pro M</model_name>
<manufacturer>REC</manufacturer>
<nominal_electricity_output>464</nominal_electricity_output>
<electricity_efficiency>0.215</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>44</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>610</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.24</cell_temperature_coefficient>
<width>2.17</width>
<height>1.3</height>
<distribution_systems/>
<energy_storage_systems/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>14</system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>REC620AA Pro M</model_name>
<manufacturer>REC</manufacturer>
<nominal_electricity_output>472</nominal_electricity_output>
<electricity_efficiency>0.218</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>44</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>620</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.24</cell_temperature_coefficient>
<width>2.17</width>
<height>1.3</height>
<distribution_systems/>
<energy_storage_systems/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>15</system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>REC630AA Pro M</model_name>
<manufacturer>REC</manufacturer>
<nominal_electricity_output>480</nominal_electricity_output>
<electricity_efficiency>0.222</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>44</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>630</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.24</cell_temperature_coefficient>
<width>2.17</width>
<height>1.3</height>
<distribution_systems/>
<energy_storage_systems/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
<pv_generation_component>
<system_id>16</system_id>
<name>Photovoltaic Module</name>
<system_type>photovoltaic</system_type>
<model_name>REC640AA Pro M</model_name>
<manufacturer>REC</manufacturer>
<nominal_electricity_output>487</nominal_electricity_output>
<electricity_efficiency>0.215</electricity_efficiency>
<nominal_ambient_temperature>20</nominal_ambient_temperature>
<nominal_cell_temperature>44</nominal_cell_temperature>
<nominal_radiation>800</nominal_radiation>
<standard_test_condition_cell_temperature>25</standard_test_condition_cell_temperature>
<standard_test_condition_radiation>1000</standard_test_condition_radiation>
<standard_test_condition_maximum_power>640</standard_test_condition_maximum_power>
<cell_temperature_coefficient>0.24</cell_temperature_coefficient>
<width>2.17</width>
<height>1.3</height>
<distribution_systems/>
<energy_storage_systems/>
<simultaneous_heat_cold>False</simultaneous_heat_cold>
</pv_generation_component>
</energy_generation_components>
<energy_storage_components>
<thermalStorages>
<storage_id>6</storage_id>
<name>template Hot Water Storage Tank</name>
<type_energy_stored>thermal</type_energy_stored>
<model_name/>
<manufacturer/>
<maximum_operating_temperature>95.0</maximum_operating_temperature>
<insulation>
<material_id>1</material_id>
<insulationThickness>90.0</insulationThickness>
</insulation>
<physical_characteristics>
<material_id>2</material_id>
<tankThickness>0</tankThickness>
<height>1.5</height>
<tankMaterial>Steel</tankMaterial>
<volume/>
</physical_characteristics>
<storage_medium>
<medium_id>1</medium_id>
</storage_medium>
<storage_type>sensible</storage_type>
<nominal_capacity/>
<losses_ratio/>
<heating_coil_capacity/>
</thermalStorages>
<thermalStorages>
<storage_id>7</storage_id>
<name>template Hot Water Storage Tank with Heating Coil</name>
<type_energy_stored>thermal</type_energy_stored>
<model_name/>
<manufacturer/>
<maximum_operating_temperature>95.0</maximum_operating_temperature>
<insulation>
<material_id>1</material_id>
<insulationThickness>90.0</insulationThickness>
</insulation>
<physical_characteristics>
<material_id>2</material_id>
<tankThickness>0</tankThickness>
<height>1.5</height>
<tankMaterial>Steel</tankMaterial>
<volume/>
</physical_characteristics>
<storage_medium>
<medium_id>1</medium_id>
</storage_medium>
<storage_type>sensible</storage_type>
<nominal_capacity/>
<losses_ratio/>
<heating_coil_capacity>5000</heating_coil_capacity>
</thermalStorages>
</energy_storage_components>
<materials>
<material>
<material_id>1</material_id>
<name>Polyurethane</name>
<solar_absorptance/>
<thermal_absorptance/>
<visible_absorptance/>
<no_mass/>
<thermal_resistance/>
<density/>
<specific_heat/>
<conductivity>0.028</conductivity>
</material>
<material>
<material_id>2</material_id>
<name>Steel</name>
<solar_absorptance/>
<thermal_absorptance/>
<visible_absorptance/>
<no_mass/>
<thermal_resistance/>
<density/>
<specific_heat/>
<conductivity>18</conductivity>
</material>
</materials>
<distribution_systems>
<distribution_system/>
</distribution_systems>
<dissipation_systems>
<dissipation_system/>
</dissipation_systems>
<systems>
<system>
<id>1</id>
<name>Central gas system</name>
<schema/>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>1</generation_id>
</components>
</system>
<system>
<id>2</id>
<name>Central Joule system</name>
<schema/>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>2</generation_id>
</components>
</system>
<system>
<id>3</id>
<name>Central butane system</name>
<schema/>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>4</generation_id>
</components>
</system>
<system>
<id>4</id>
<name>Single zone split system</name>
<schema/>
<demands>
<demand>cooling</demand>
</demands>
<components>
<generation_id>5</generation_id>
</components>
</system>
<system>
<id>5</id>
<name>4 pipe heat pump system</name>
<schema/>
<demands>
<demand>heating</demand>
<demand>cooling</demand>
</demands>
<components>
<generation_id>3</generation_id>
</components>
</system>
<system>
<id>6</id>
<name>PV</name>
<schema/>
<demands>
<demand>electricity</demand>
</demands>
<components>
<generation_id>7</generation_id>
</components>
</system>
<system>
<id>7</id>
<name>Gas heating</name>
<schema/>
<demands>
<demand>heating</demand>
</demands>
<components>
<generation_id>1</generation_id>
</components>
</system>
<system>
<id>8</id>
<name>Electrical heating</name>
<schema/>
<demands>
<demand>heating</demand>
</demands>
<components>
<generation_id>2</generation_id>
</components>
</system>
<system>
<id>9</id>
<name>Butane heating</name>
<schema/>
<demands>
<demand>heating</demand>
</demands>
<components>
<generation_id>4</generation_id>
</components>
</system>
<system>
<id>10</id>
<name>Gas hot water system</name>
<schema/>
<demands>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>1</generation_id>
</components>
</system>
<system>
<id>11</id>
<name>Electrical hot water system</name>
<schema/>
<demands>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>2</generation_id>
</components>
</system>
<system>
<id>12</id>
<name>Butane hot water system</name>
<schema/>
<demands>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>4</generation_id>
</components>
</system>
<system>
<id>13</id>
<name>Heat Pump hot water system</name>
<schema/>
<demands>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>6</generation_id>
</components>
</system>
</systems>
<system_archetypes>
<system_archetype id="1">
<name>Gas boiler for heating and hot water heater with split cooling</name>
<systems>
<system_id>1</system_id>
<system_id>4</system_id>
</systems>
</system_archetype>
<system_archetype id="2">
<name>Joule heater for heating and hot water heater with split cooling</name>
<systems>
<system_id>2</system_id>
<system_id>4</system_id>
</systems>
</system_archetype>
<system_archetype id="3">
<name>Butane heater for heating and hot water heater with split cooling</name>
<systems>
<system_id>3</system_id>
<system_id>4</system_id>
</systems>
</system_archetype>
<system_archetype id="4">
<name>Gas heating</name>
<systems>
<system_id>1</system_id>
</systems>
</system_archetype>
<system_archetype id="5">
<name>Electrical joule heating</name>
<systems>
<system_id>2</system_id>
</systems>
</system_archetype>
<system_archetype id="6">
<name>Butane heating</name>
<systems>
<system_id>3</system_id>
</systems>
</system_archetype>
<system_archetype id="7">
<name>Heat pump with gas water heater</name>
<systems>
<system_id>5</system_id>
<system_id>7</system_id>
</systems>
</system_archetype>
<system_archetype id="8">
<name>Heat pump with joule water heater</name>
<systems>
<system_id>5</system_id>
<system_id>8</system_id>
</systems>
</system_archetype>
<system_archetype id="9">
<name>Heat pump with butane water heater</name>
<systems>
<system_id>5</system_id>
<system_id>9</system_id>
</systems>
</system_archetype>
<system_archetype id="10">
<name>Heat pump with gas water heater and rooftop PV</name>
<systems>
<system_id>5</system_id>
<system_id>7</system_id>
<system_id>6</system_id>
</systems>
</system_archetype>
<system_archetype id="11">
<name>Heat pump with joule water heater and rooftop PV</name>
<systems>
<system_id>5</system_id>
<system_id>8</system_id>
<system_id>6</system_id>
</systems>
</system_archetype>
<system_archetype id="12">
<name>Rooftop PV</name>
<systems>
<system_id>6</system_id>
</systems>
</system_archetype>
<system_archetype id="13">
<name>Joule heater with split cooling and gas hot water</name>
<systems>
<system_id>4</system_id>
<system_id>8</system_id>
<system_id>10</system_id>
</systems>
</system_archetype>
<system_archetype id="14">
<name>Joule heater with split cooling and butane hot water</name>
<systems>
<system_id>4</system_id>
<system_id>8</system_id>
<system_id>12</system_id>
</systems>
</system_archetype>
<system_archetype id="15">
<name>PV and heat pump</name>
<systems>
<system_id>5</system_id>
<system_id>6</system_id>
<system_id>13</system_id>
</systems>
</system_archetype>
</system_archetypes>
</EnergySystemCatalog>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

View File

@ -1,904 +0,0 @@
{
"tables": {
"schedules": {
"data_type": "table",
"refs": [
"DBHE CTE Tabla b-Anejo D"
],
"table": [
{
"name": "DBHE-CTE-Occupancy-sensible",
"category": "Occupancy",
"units": "FRACTION",
"day_types": "Default|Wkdy",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
1,
1,
1,
1,
1,
1,
0.25,
0.25,
0.25,
0.25,
0.25,
0.25,
0.25,
0.25,
0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
1
]
},
{
"name": "DBHE-CTE-Occupancy-sensible",
"category": "Occupancy",
"units": "FRACTION",
"day_types": "Sat",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
]
},
{
"name": "DBHE-CTE-Occupancy-sensible",
"category": "Occupancy",
"units": "FRACTION",
"day_types": "Sun|Hol",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
]
},
{
"name": "DBHE-CTE-Occupancy-latent",
"category": "Occupancy",
"units": "FRACTION",
"day_types": "Default|Wkdy",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
1,
1,
1,
1,
1,
1,
0.25,
0.25,
0.25,
0.25,
0.25,
0.25,
0.25,
0.25,
0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
0.5,
1
]
},
{
"name": "DBHE-CTE-Occupancy-latent",
"category": "Occupancy",
"units": "FRACTION",
"day_types": "Sat",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
]
},
{
"name": "DBHE-CTE-Occupancy-latent",
"category": "Occupancy",
"units": "FRACTION",
"day_types": "Sun|Hol",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
]
},
{
"name": "DBHE-CTE-Lighting",
"category": "Lighting",
"units": "FRACTION",
"day_types": "Default|Wkdy",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
0.1,
0.1,
0.1,
0.1,
0.1,
0.1,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.5,
1,
1,
1,
1,
1,
0.5
]
},
{
"name": "DBHE-CTE-Lighting",
"category": "Lighting",
"units": "FRACTION",
"day_types": "Sat",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
0.1,
0.1,
0.1,
0.1,
0.1,
0.1,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.5,
1,
1,
1,
1,
1,
0.5
]
},
{
"name": "DBHE-CTE-Lighting",
"category": "Lighting",
"units": "FRACTION",
"day_types": "Sun|Hol",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
0.1,
0.1,
0.1,
0.1,
0.1,
0.1,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.5,
1,
1,
1,
1,
1,
0.5
]
},
{
"name": "DBHE-CTE-Equipment",
"category": "Equipment",
"units": "FRACTION",
"day_types": "Default|Wkdy",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
0.1,
0.1,
0.1,
0.1,
0.1,
0.1,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.5,
1,
1,
1,
1,
1,
0.5
]
},
{
"name": "DBHE-CTE-Equipment",
"category": "Equipment",
"units": "FRACTION",
"day_types": "Sat",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
0.1,
0.1,
0.1,
0.1,
0.1,
0.1,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.5,
1,
1,
1,
1,
1,
0.5
]
},
{
"name": "DBHE-CTE-Equipment",
"category": "Equipment",
"units": "FRACTION",
"day_types": "Sun|Hol",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
0.1,
0.1,
0.1,
0.1,
0.1,
0.1,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.33,
0.5,
1,
1,
1,
1,
1,
0.5
]
},
{
"name": "DBHE-CTE-Thermostat Setpoint-Heating",
"category": "Thermostat Setpoint",
"units": "TEMPERATURE",
"day_types": "Default|Wkdy",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
17.0,
17.0,
17.0,
17.0,
17.0,
17.0,
17.0,
21.0,
21.0,
21.0,
21.0,
21.0,
21.0,
21.0,
21.0,
21.0,
21.0,
21.0,
21.0,
21.0,
21.0,
20.0,
17.0,
17.0
]
},
{
"name": "DBHE-CTE-Thermostat Setpoint-Heating",
"category": "Thermostat Setpoint",
"units": "TEMPERATURE",
"day_types": "Sat",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
22.0,
18.0,
18.0,
18.0,
18.0,
18.0,
18.0,
20.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0
]
},
{
"name": "DBHE-CTE-Thermostat Setpoint-Heating",
"category": "Thermostat Setpoint",
"units": "TEMPERATURE",
"day_types": "Sun|Hol",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
22.0,
18.0,
18.0,
18.0,
18.0,
18.0,
18.0,
20.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0,
22.0
]
},
{
"name": "DBHE-CTE-Thermostat Setpoint-Cooling",
"category": "Thermostat Setpoint",
"units": "TEMPERATURE",
"day_types": "Default|Wkdy",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
28.0,
28.0,
28.0,
28.0,
28.0,
28.0,
28.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
28.0,
28.0
]
},
{
"name": "DBHE-CTE-Thermostat Setpoint-Cooling",
"category": "Thermostat Setpoint",
"units": "TEMPERATURE",
"day_types": "Sat",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
28.0,
28.0,
28.0,
28.0,
28.0,
28.0,
28.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
28.0,
28.0
]
},
{
"name": "DBHE-CTE-Thermostat Setpoint-Cooling",
"category": "Thermostat Setpoint",
"units": "TEMPERATURE",
"day_types": "Sun|Hol",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
28.0,
28.0,
28.0,
28.0,
28.0,
28.0,
28.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
25.0,
28.0,
28.0
]
},
{
"name": "Always On",
"category": "Unknown",
"units": null,
"day_types": "Default",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Constant",
"notes": null,
"values": [
1.0
]
},
{
"name": "default_HVAC_schedule",
"category": "Fan",
"units": "ON_OFF",
"day_types": "Default|Wkdy",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0
]
},
{
"name": "default_HVAC_schedule",
"category": "Fan",
"units": "ON_OFF",
"day_types": "Sat",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0
]
},
{
"name": "default_HVAC_schedule",
"category": "Fan",
"units": "ON_OFF",
"day_types": "Sun|Hol",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0,
1.0
]
},
{
"name": "DBHE-CTE-Service Water Heating",
"category": "Service Water Heating",
"units": "FRACTION",
"day_types": "Default|Wkdy",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
0.01,
0.00,
0.00,
0.00,
0.00,
0.01,
0.03,
0.1,
0.07,
0.07,
0.06,
0.06,
0.05,
0.05,
0.04,
0.03,
0.04,
0.04,
0.05,
0.07,
0.06,
0.06,
0.05,
0.05
]
},
{
"name": "DBHE-CTE-Service Water Heating",
"category": "Service Water Heating",
"units": "FRACTION",
"day_types": "Sat",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
0.01,
0.00,
0.00,
0.00,
0.00,
0.01,
0.03,
0.1,
0.07,
0.07,
0.06,
0.06,
0.05,
0.05,
0.04,
0.03,
0.04,
0.04,
0.05,
0.07,
0.06,
0.06,
0.05,
0.05
]
},
{
"name": "DBHE-CTE-Service Water Heating",
"category": "Service Water Heating",
"units": "FRACTION",
"day_types": "Sun|Hol",
"start_date": "2014-01-01T00:00:00+00:00",
"end_date": "2014-12-31T00:00:00+00:00",
"type": "Hourly",
"notes": null,
"values": [
0.01,
0.00,
0.00,
0.00,
0.00,
0.01,
0.03,
0.1,
0.07,
0.07,
0.06,
0.06,
0.05,
0.05,
0.04,
0.03,
0.04,
0.04,
0.05,
0.07,
0.06,
0.06,
0.05,
0.05
]
}
]
}}}

View File

@ -1,30 +0,0 @@
{
"tables": {
"space_compliance": {
"data_type": "table",
"refs": {
"lighting_per_area_w_per_m2": "DBHE-CTE Tabla b-Anejo D",
"occupancy_per_area_people_per_m2": "DBHE CTE Tabla b-Anejo D",
"occupancy_schedule": "DBHE-CTE Tabla b-Anejo D",
"electric_equipment_per_area_w_per_m2": "DBHE CTE Tabla b-Anejo D"
},
"tolerance": {
"lighting_per_area_w_per_m2": 1,
"occupancy_per_area_people_per_m2": 3,
"occupancy_schedule": null,
"electric_equipment_per_area_w_per_m2": 1
},
"table": [
{
"template": "DBHE-CTE",
"building_type": "residential",
"space_type": "WholeBuilding",
"lighting_per_area_w_per_m2": 4.4,
"occupancy_per_area_people_per_m2": 0.014333333,
"occupancy_schedule": "DBHE-CTE-Occupancy",
"electric_equipment_per_area_w_per_m2": 4.4,
"service_water_heating_peak_flow_per_area": 0.02272990107962068
}]
}
}
}

View File

@ -1,97 +0,0 @@
{
"tables": {
"space_types": {
"data_type": "table",
"refs": [
"assumption"
],
"table": [
{
"building_type": "residential",
"space_type": "WholeBuilding",
"rgb": "255_255_255",
"lighting_standard": "DBHE-CTE",
"lighting_primary_space_type": "residential",
"lighting_secondary_space_type": "WholeBuilding",
"lighting_per_area": 4.4,
"lighting_per_person": null,
"additional_lighting_per_area": null,
"rel_absence_occ": 0.0,
"personal_control": 0.0,
"occ_sense": 0.0,
"lighting_fraction_to_return_air": 0.0,
"lighting_fraction_radiant": 0.5,
"lighting_fraction_visible": 0.2,
"lighting_fraction_replaceable": null,
"lpd_fractionlinear_fluorescent": 1.0,
"lpd_fractioncompact_fluorescent": null,
"lpd_fractionhigh_bay": null,
"lpd_fractionspecialty_lighting": null,
"lpd_fractionexit_lighting": null,
"lighting_schedule": "DBHE-CTE-Lighting",
"compact_fluorescent_lighting_schedule": null,
"high_bay_lighting_schedule": null,
"specialty_lighting_schedule": null,
"exit_lighting_schedule": null,
"target_illuminance_setpoint": 125,
"target_illuminance_setpoint_ref": null,
"psa_nongeometry_fraction": null,
"ssa_nongeometry_fraction": null,
"ventilation_standard": null,
"ventilation_primary_space_type": "residential",
"ventilation_secondary_space_type": "WholeBuilding",
"ventilation_per_area": 0,
"ventilation_per_person": 0,
"ventilation_air_changes": 0.4,
"minimum_total_air_changes": null,
"occupancy_per_area": 2.15,
"occupancy_schedule": "DBHE-CTE-Occupancy-sensible",
"occupancy_activity_schedule": null,
"infiltration_per_exterior_area": 0.4,
"infiltration_per_exterior_wall_area": null,
"infiltration_air_changes": null,
"infiltration_schedule": "Always On",
"infiltration_schedule_perimeter": null,
"gas_equipment_per_area": null,
"gas_equipment_fraction_latent": null,
"gas_equipment_fraction_radiant": null,
"gas_equipment_fraction_lost": null,
"gas_equipment_schedule": null,
"electric_equipment_per_area": 4.4,
"electric_equipment_fraction_latent": 0.0,
"electric_equipment_fraction_radiant": 0.5,
"electric_equipment_fraction_lost": 0.0,
"electric_equipment_schedule": "DBHE-CTE-Equipment",
"additional_electric_equipment_schedule": null,
"additional_gas_equipment_schedule": null,
"heating_setpoint_schedule": "DBHE-CTE-Thermostat Setpoint-Heating",
"cooling_setpoint_schedule": "DBHE-CTE-Thermostat Setpoint-Cooling",
"service_water_heating_peak_flow_rate": null,
"service_water_heating_area": null,
"service_water_heating_peak_flow_per_area": 0.009385225,
"service_water_heating_target_temperature": 60.0,
"service_water_heating_fraction_sensible": null,
"service_water_heating_fraction_latent": null,
"service_water_heating_schedule": "DBHE-CTE-Service Water Heating",
"exhaust_per_area": null,
"exhaust_fan_efficiency": null,
"exhaust_fan_power": null,
"exhaust_fan_pressure_rise": null,
"exhaust_fan_maximum_flow_rate": null,
"exhaust_schedule": null,
"balanced_exhaust_fraction_schedule": null,
"is_residential": null,
"necb_hvac_system_selection_type": "residential",
"necb_schedule_type": "G",
"notes": null,
"ventilation_occupancy_rate_people_per_1000ft2": 10,
"ventilation_occupancy_standard": null,
"ventilation_standard_space_type": null,
"sensible_convective_internal_gain": 0.86,
"sensible_radiative_internal_gain": 1.29,
"latent_internal_gain": 1.36
}
]
}
}
}

View File

@ -1,248 +0,0 @@
"""
Cerc Idf exports one city or some buildings to idf format
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Guillermo.GutierrezMorote@concordia.ca
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Oriol Gavalda Torrellas oriol.gavalda@concordia.ca
"""
import copy
import os
import shutil
import subprocess
import hub.exports.building_energy.idf_helper as idf_cte
import hub.helpers.constants as cte
from hub.city_model_structure.attributes.schedule import Schedule
from hub.exports.building_energy.idf_helper.idf_appliance import IdfAppliance
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
from hub.exports.building_energy.idf_helper.idf_construction import IdfConstruction
from hub.exports.building_energy.idf_helper.idf_dhw import IdfDhw
from hub.exports.building_energy.idf_helper.idf_file_schedule import IdfFileSchedule
from hub.exports.building_energy.idf_helper.idf_heating_system import IdfHeatingSystem
from hub.exports.building_energy.idf_helper.idf_infiltration import IdfInfiltration
from hub.exports.building_energy.idf_helper.idf_lighting import IdfLighting
from hub.exports.building_energy.idf_helper.idf_material import IdfMaterial
from hub.exports.building_energy.idf_helper.idf_occupancy import IdfOccupancy
from hub.exports.building_energy.idf_helper.idf_schedule import IdfSchedule
from hub.exports.building_energy.idf_helper.idf_shading import IdfShading
from hub.exports.building_energy.idf_helper.idf_surfaces import IdfSurfaces
from hub.exports.building_energy.idf_helper.idf_thermostat import IdfThermostat
from hub.exports.building_energy.idf_helper.idf_ventilation import IdfVentilation
from hub.exports.building_energy.idf_helper.idf_window import IdfWindow
from hub.exports.building_energy.idf_helper.idf_windows_constructions import IdfWindowsConstructions
from hub.exports.building_energy.idf_helper.idf_windows_material import IdfWindowsMaterial
from hub.exports.building_energy.idf_helper.idf_zone import IdfZone
class CercIdf(IdfBase):
"""
Exports city to IDF
"""
_schedules_added_to_idf = {}
_materials_added_to_idf = {}
_windows_added_to_idf = {}
_constructions_added_to_idf = {}
_thermostat_added_to_idf = {}
def __init__(self, city, output_path, idf_file_path, idd_file_path, epw_file_path, target_buildings=None):
super().__init__(city, output_path, idf_file_path, idd_file_path, epw_file_path, target_buildings)
self._add_surfaces = IdfSurfaces.add
self._add_file_schedule = IdfFileSchedule.add
self._add_idf_schedule = IdfSchedule.add
self._add_construction = IdfConstruction.add
self._add_material = IdfMaterial.add
self._add_windows_material = IdfWindowsMaterial.add
self._add_windows_constructions = IdfWindowsConstructions.add
self._add_occupancy = IdfOccupancy.add
self._add_lighting = IdfLighting.add
self._add_appliance = IdfAppliance.add
self._add_infiltration = IdfInfiltration.add
self._add_infiltration_surface = IdfInfiltration.add_surface
self._add_ventilation = IdfVentilation.add
self._add_zone = IdfZone.add
self._add_thermostat = IdfThermostat.add
self._add_heating_system = IdfHeatingSystem.add
self._add_dhw = IdfDhw.add
self._add_shading = IdfShading.add
self._add_windows = IdfWindow.add
with open(self._idf_file_path, 'r', encoding='UTF-8') as base_idf:
lines = base_idf.readlines()
# Change city name
comment = f' !- Name'
field = f' Buildings in {self._city.name},'.ljust(26, ' ')
lines[15] = f'{field}{comment}\n'
with open(self._output_file_path, 'w', encoding='UTF-8') as self._idf_file:
self._idf_file.writelines(lines)
self._export()
def _create_geometry_rules(self):
file = self._files['constructions']
self._write_to_idf_format(file, idf_cte.GLOBAL_GEOMETRY_RULES)
self._write_to_idf_format(file, 'UpperLeftCorner', 'Starting Vertex Position')
self._write_to_idf_format(file, 'CounterClockWise', 'Vertex Entry Direction')
self._write_to_idf_format(file, 'World', 'Coordinate System', ';')
def _merge_files(self):
for file in self._files.values():
file.close()
for path in self._file_paths.values():
with open(path, 'r', encoding='UTF-8') as file:
lines = file.readlines()
self._idf_file.writelines(lines)
for path in self._file_paths.values():
os.unlink(path)
def _add_outputs(self):
with open(self._outputs_file_path, 'r', encoding='UTF-8') as base_idf:
lines = base_idf.readlines()
self._idf_file.writelines(lines)
@staticmethod
def _create_infiltration_schedules(thermal_zone):
_infiltration_schedules = []
if thermal_zone.thermal_control is None:
return []
for hvac_availability_schedule in thermal_zone.thermal_control.hvac_availability_schedules:
_schedule = Schedule()
_schedule.type = cte.INFILTRATION
_schedule.data_type = cte.FRACTION
_schedule.time_step = cte.HOUR
_schedule.time_range = cte.DAY
_schedule.day_types = copy.deepcopy(hvac_availability_schedule.day_types)
_infiltration_values = []
for hvac_value in hvac_availability_schedule.values:
if hvac_value == 0:
_infiltration_values.append(1.0)
else:
if thermal_zone.infiltration_rate_system_off == 0:
_infiltration_values.append(0.0)
else:
_infiltration_values.append(
thermal_zone.infiltration_rate_system_on / thermal_zone.infiltration_rate_system_off)
_schedule.values = _infiltration_values
_infiltration_schedules.append(_schedule)
return _infiltration_schedules
@staticmethod
def _create_ventilation_schedules(thermal_zone):
_ventilation_schedules = []
if thermal_zone.thermal_control is None:
return []
for hvac_availability_schedule in thermal_zone.thermal_control.hvac_availability_schedules:
_schedule = Schedule()
_schedule.type = cte.VENTILATION
_schedule.data_type = cte.FRACTION
_schedule.time_step = cte.HOUR
_schedule.time_range = cte.DAY
_schedule.day_types = copy.deepcopy(hvac_availability_schedule.day_types)
_ventilation_schedules = thermal_zone.thermal_control.hvac_availability_schedules
return _ventilation_schedules
@staticmethod
def _create_constant_value_schedules(value, amount):
_schedule = Schedule()
_schedule.type = ''
_schedule.data_type = cte.ANY_NUMBER
_schedule.time_step = cte.HOUR
_schedule.time_range = cte.DAY
_schedule.day_types = ['monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
'sunday',
'holiday',
'winter_design_day',
'summer_design_day']
_schedule.values = [value for _ in range(0, amount)]
return [_schedule]
def _export(self):
for building in self._city.buildings:
is_target = building.name in self._target_buildings or building.name in self._adjacent_buildings
for internal_zone in building.internal_zones:
if internal_zone.thermal_zones_from_internal_zones is None:
is_target = False
continue
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
if is_target:
service_temperature = thermal_zone.domestic_hot_water.service_temperature
usage = thermal_zone.usage_name
occ = thermal_zone.occupancy
if occ.occupancy_density == 0:
total_heat = 0
else:
total_heat = (
occ.sensible_convective_internal_gain +
occ.sensible_radiative_internal_gain +
occ.latent_internal_gain
) / occ.occupancy_density
self._add_idf_schedule(self, usage, 'Infiltration', self._create_infiltration_schedules(thermal_zone))
self._add_idf_schedule(self, usage, 'Ventilation', self._create_ventilation_schedules(thermal_zone))
self._add_idf_schedule(self, usage, 'Occupancy', thermal_zone.occupancy.occupancy_schedules)
self._add_idf_schedule(self, usage, 'HVAC AVAIL', thermal_zone.thermal_control.hvac_availability_schedules)
self._add_idf_schedule(self, usage, 'Heating thermostat',
thermal_zone.thermal_control.heating_set_point_schedules)
self._add_idf_schedule(self, usage, 'Cooling thermostat',
thermal_zone.thermal_control.cooling_set_point_schedules)
self._add_idf_schedule(self, usage, 'Lighting', thermal_zone.lighting.schedules)
self._add_idf_schedule(self, usage, 'Appliance', thermal_zone.appliances.schedules)
self._add_idf_schedule(self, usage, 'DHW_prof', thermal_zone.domestic_hot_water.schedules)
self._add_idf_schedule(self, usage, 'DHW_temp',
self._create_constant_value_schedules(service_temperature, 24))
self._add_idf_schedule(self, usage, 'Activity Level', self._create_constant_value_schedules(total_heat, 24))
self._add_file_schedule(self, usage, 'cold_temp',
self._create_constant_value_schedules(building.cold_water_temperature[cte.HOUR],
24))
for thermal_boundary in thermal_zone.thermal_boundaries:
self._add_material(self, thermal_boundary)
self._add_construction(self, thermal_boundary)
for thermal_opening in thermal_boundary.thermal_openings:
self._add_windows_material(self, thermal_boundary, thermal_opening)
self._add_windows_constructions(self, thermal_boundary)
self._add_zone(self, thermal_zone, building.name)
self._add_occupancy(self, thermal_zone, building.name)
self._add_lighting(self, thermal_zone, building.name)
self._add_appliance(self, thermal_zone, building.name)
if self._calculate_with_new_infiltration: # ToDo: Check with oriol if we want to keep the old method too
self._add_infiltration_surface(self, thermal_zone, building.name)
else:
self._add_infiltration(self, thermal_zone, building.name)
self._add_ventilation(self, thermal_zone, building.name)
self._add_thermostat(self, thermal_zone)
self._add_heating_system(self, thermal_zone, building.name)
self._add_dhw(self, thermal_zone, building.name)
if is_target:
self._add_surfaces(self, building, building.name)
self._add_windows(self, building)
else:
self._add_shading(self, building)
self._create_output_control_lighting() # Add lighting control to the lighting
# Create base values
self._create_geometry_rules()
# Merge files
self._merge_files()
self._add_outputs()
@property
def _energy_plus(self):
return shutil.which('energyplus')
def run(self):
cmd = [self._energy_plus,
'--weather', self._epw_file_path,
'--output-directory', self._output_path,
'--idd', self._idd_file_path,
'--expandobjects',
'--readvars',
'--output-prefix', f'{self._city.name}_',
self._output_file_path]
subprocess.run(cmd, cwd=self._output_path)

View File

@ -169,7 +169,7 @@ class EnergyAde:
def _building_geometry(self, building, building_dic, city):
building_dic['bldg:Building']['bldg:function'] = building.function
building_dic['bldg:Building']['bldg:usage'] = building.usages
building_dic['bldg:Building']['bldg:usage'] = building.usages_percentage
building_dic['bldg:Building']['bldg:yearOfConstruction'] = building.year_of_construction
building_dic['bldg:Building']['bldg:roofType'] = building.roof_type
building_dic['bldg:Building']['bldg:measuredHeight'] = {

View File

@ -7,13 +7,8 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
Oriol Gavalda Torrellas oriol.gavalda@concordia.ca
"""
import copy
import datetime
import shutil
import subprocess
from pathlib import Path
from geomeppy import IDF
import hub.helpers.constants as cte
from hub.city_model_structure.attributes.schedule import Schedule
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
@ -59,6 +54,14 @@ class Idf:
_SIZING_PERIODS = 'SIZINGPERIOD:DESIGNDAY'
_LOCATION = 'SITE:LOCATION'
_SIMPLE = 'Simple'
_EQUIPMENT_CONNECTIONS = 'ZONEHVAC:EQUIPMENTCONNECTIONS'
_NODE_LIST = 'NODELIST'
_BASEBOARD = 'ZONEHVAC:BASEBOARD:CONVECTIVE:ELECTRIC'
_AIR_TERMINAL_NO_REHEAT = 'AIRTERMINAL:SINGLEDUCT:CONSTANTVOLUME:NOREHEAT'
_AIR_DISTRIBUTION = 'ZONEHVAC:AIRDISTRIBUTIONUNIT'
_EQUIPMENT_LIST = 'ZONEHVAC:EQUIPMENTLIST'
_SIZING_ZONE = 'SIZING:ZONE'
_DESIGN_SPECIFICATION_OUTDOOR_AIR = 'DESIGNSPECIFICATION:OUTDOORAIR'
idf_surfaces = {
cte.WALL: 'wall',
@ -109,7 +112,6 @@ class Idf:
else:
for building_name in target_buildings:
building = city.city_object(building_name)
print('Name: ', building_name)
if building.neighbours is not None:
self._adjacent_buildings += building.neighbours
self._export()
@ -123,7 +125,8 @@ class Idf:
if levels_of_detail.construction is None:
raise AttributeError('Level of detail of construction not assigned')
if levels_of_detail.construction < 2:
raise AttributeError(f'Level of detail of construction = {levels_of_detail.construction}. Required minimum level 2')
raise AttributeError(
f'Level of detail of construction = {levels_of_detail.construction}. Required minimum level 2')
if levels_of_detail.usage is None:
raise AttributeError('Level of detail of usage not assigned')
if levels_of_detail.usage < 2:
@ -281,9 +284,8 @@ class Idf:
_kwargs[f'Field_{counter + 2}'] = 'Until: 24:00,0.0'
self._idf.newidfobject(self._COMPACT_SCHEDULE, **_kwargs)
def _write_schedules_file(self, schedule, usage):
file_name = str((Path(self._output_path) / f'{schedule.type} schedules {usage.replace("/","_")}.csv').resolve())
if not Path(file_name).exists():
def _write_schedules_file(self, usage, schedule):
file_name = str((Path(self._output_path) / f'{schedule.type} schedules {usage}.csv').resolve())
with open(file_name, 'w', encoding='utf8') as file:
for value in schedule.values:
file.write(f'{str(value)},\n')
@ -311,7 +313,7 @@ class Idf:
for schedule in self._idf.idfobjects[self._FILE_SCHEDULE]:
if schedule.Name == f'{schedule_type} schedules {usage}':
return
file_name = self._write_schedules_file(new_schedules[0], usage)
file_name = self._write_schedules_file(usage, new_schedules[0])
self._add_file_schedule(usage, new_schedules[0], file_name)
return
@ -328,13 +330,12 @@ class Idf:
if construction.Name == vegetation_name:
return
else:
if construction.Name == f'{thermal_boundary.construction_name} {thermal_boundary.parent_surface.type}':
if construction.Name == thermal_boundary.construction_name:
return
if thermal_boundary.layers is None:
for material in self._idf.idfobjects[self._MATERIAL]:
if material.Name == "DefaultMaterial":
return
self._idf.set_default_constructions()
return
for layer in thermal_boundary.layers:
@ -348,8 +349,7 @@ class Idf:
for i in range(0, len(layers) - 1):
_kwargs[f'Layer_{i + 2}'] = layers[i].material_name
else:
_kwargs = {'Name': f'{thermal_boundary.construction_name} {thermal_boundary.parent_surface.type}',
'Outside_Layer': layers[0].material_name}
_kwargs = {'Name': thermal_boundary.construction_name, 'Outside_Layer': layers[0].material_name}
for i in range(1, len(layers) - 1):
_kwargs[f'Layer_{i + 1}'] = layers[i].material_name
self._idf.newidfobject(self._CONSTRUCTION, **_kwargs)
@ -390,16 +390,80 @@ class Idf:
)
def _add_heating_system(self, thermal_zone, zone_name):
for air_system in self._idf.idfobjects[self._IDEAL_LOAD_AIR_SYSTEM]:
for air_system in self._idf.idfobjects[self._EQUIPMENT_CONNECTIONS]:
if air_system.Zone_Name == zone_name:
return
thermostat = self._add_thermostat(thermal_zone)
self._idf.newidfobject(self._IDEAL_LOAD_AIR_SYSTEM,
self._idf.newidfobject(self._EQUIPMENT_CONNECTIONS,
Zone_Name=zone_name,
System_Availability_Schedule_Name=f'Thermostat_availability schedules {thermal_zone.usage_name}',
Heating_Availability_Schedule_Name=f'Thermostat_availability schedules {thermal_zone.usage_name}',
Cooling_Availability_Schedule_Name=f'Thermostat_availability schedules {thermal_zone.usage_name}',
Template_Thermostat_Name=thermostat.Name)
Zone_Conditioning_Equipment_List_Name=f'{zone_name} Equipment List',
Zone_Air_Inlet_Node_or_NodeList_Name=f'{zone_name} Inlet Node List',
Zone_Air_Node_Name=f'Node 1',
Zone_Return_Air_Node_or_NodeList_Name=f'{zone_name} Return Node List')
def _add_nodelist_system(self, thermal_zone, zone_name):
self._idf.newidfobject(self._NODE_LIST,
Name=f'{zone_name} Inlet Node List',
Node_1_Name='Node 2')
self._idf.newidfobject(self._NODE_LIST,
Name=f'{zone_name} Return Node List',
Node_1_Name='Node 3')
def _add_baseboard_system(self, thermal_zone, zone_name):
for baseboard in self._idf.idfobjects[self._BASEBOARD]:
if baseboard.Zone_Name == zone_name:
return
self._idf.newidfobject(self._BASEBOARD, Name=f'Elec Baseboard',Availability_Schedule_Name='HVAC AVAIL')
def _add_air_terminal_system(self, thermal_zone, zone_name):
"""for air_terminal in self._idf.idfobjects[self._AIR_TERMINAL_NO_REHEAT]:
if air_terminal.Zone_Name == zone_name:
return"""
self._idf.newidfobject(self._AIR_TERMINAL_NO_REHEAT, Name=f'Diffuser',
Availability_Schedule_Name='HVAC AVAIL',
Air_Inlet_Node_Name='Node 4',
Air_Outlet_Node_Name='Node 2',
Maximum_Air_Flow_Rate='AutoSize')
def _add_air_distribution_system(self, thermal_zone, zone_name):
for air_distribution in self._idf.idfobjects[self._AIR_DISTRIBUTION]:
if air_distribution.Zone_Name == zone_name:
return
self._idf.newidfobject(self._AIR_DISTRIBUTION,
Name='ADU Diffuser',
Air_Distribution_Unit_Outlet_Node_Name='Node 2',
Air_Terminal_Object_Type='AirTerminal:SingleDuct:ConstantVolume:NoReheat',
Air_Terminal_Name='Diffuser')
def _add_equipment_list_system(self, thermal_zone, zone_name):
for air_distribution in self._idf.idfobjects[self._EQUIPMENT_LIST]:
if air_distribution.Zone_Name == zone_name:
return
self._idf.newidfobject(self._EQUIPMENT_LIST,
Name=f'{zone_name} Equipment List',
Load_Distribution_Scheme='SequentialLoad',
Zone_Equipment_1_Object_Type='ZoneHVAC:Baseboard:Convective:Electric',
Zone_Equipment_1_Name='Elec Baseboard',
Zone_Equipment_1_Cooling_Sequence='1',
Zone_Equipment_1_Heating_or_NoLoad_Sequence='1',
Zone_Equipment_2_Object_Type='ZoneHVAC:AirDistributionUnit',
Zone_Equipment_2_Name='ADU Diffuser',
Zone_Equipment_2_Cooling_Sequence='2',
Zone_Equipment_2_Heating_or_NoLoad_Sequence='2'
)
def _add_sizing_zone(self, thermal_zone, zone_name):
koa=self._idf.newidfobject(self._SIZING_ZONE,
Zone_or_ZoneList_Name=f'{zone_name}',
Zone_Cooling_Design_Supply_Air_Humidity_Ratio='0.0085',
Zone_Heating_Design_Supply_Air_Humidity_Ratio='0.008'
)
def _add_outdoor_air_design_specification(self, thermal_zone, zone_name):
self._idf.newidfobject(self._DESIGN_SPECIFICATION_OUTDOOR_AIR,
Name='MidriseApartment Apartment Ventilation',
Outdoor_Air_Method='Sum',
Outdoor_Air_Flow_per_Person='0.0169901079552')
def _add_occupancy(self, thermal_zone, zone_name):
number_of_people = thermal_zone.occupancy.occupancy_density * thermal_zone.total_floor_area
@ -447,7 +511,7 @@ class Idf:
subcategory = f'ELECTRIC EQUIPMENT#{zone_name}#InteriorEquipment'
self._idf.newidfobject(self._APPLIANCES,
Fuel_Type=fuel_type,
Name=zone_name,
Name=f'{zone_name}_appliance',
Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Schedule_Name=f'Appliance schedules {thermal_zone.usage_name}',
Design_Level_Calculation_Method=method,
@ -458,7 +522,7 @@ class Idf:
)
def _add_infiltration(self, thermal_zone, zone_name):
schedule = f'INF_CONST schedules {thermal_zone.usage_name}'
schedule = f'Infiltration schedules {thermal_zone.usage_name}'
_infiltration = thermal_zone.infiltration_rate_system_off * cte.HOUR_TO_SECONDS
self._idf.newidfobject(self._INFILTRATION,
Name=f'{zone_name}_infiltration',
@ -468,17 +532,6 @@ class Idf:
Air_Changes_per_Hour=_infiltration
)
def _add_infiltration_surface(self, thermal_zone, zone_name):
schedule = f'INF_CONST schedules {thermal_zone.usage_name}'
_infiltration = thermal_zone.infiltration_rate_area_system_off* cte.INFILTRATION_75PA_TO_4PA
self._idf.newidfobject(self._INFILTRATION,
Name=f'{zone_name}_infiltration',
Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Schedule_Name=schedule,
Design_Flow_Rate_Calculation_Method='Flow/ExteriorWallArea',
Flow_Rate_per_Exterior_Surface_Area=_infiltration
)
def _add_ventilation(self, thermal_zone, zone_name):
schedule = f'Ventilation schedules {thermal_zone.usage_name}'
_air_change = thermal_zone.mechanical_air_change * cte.HOUR_TO_SECONDS
@ -490,7 +543,7 @@ class Idf:
Air_Changes_per_Hour=_air_change
)
def _add_dhw(self, thermal_zone, zone_name, usage):
def _add_dhw(self, thermal_zone, zone_name):
peak_flow_rate = thermal_zone.domestic_hot_water.peak_flow * thermal_zone.total_floor_area
self._idf.newidfobject(self._DHW,
Name=f'DHW {zone_name}',
@ -498,13 +551,13 @@ class Idf:
Flow_Rate_Fraction_Schedule_Name=f'DHW_prof schedules {thermal_zone.usage_name}',
Target_Temperature_Schedule_Name=f'DHW_temp schedules {thermal_zone.usage_name}',
Hot_Water_Supply_Temperature_Schedule_Name=f'DHW_temp schedules {thermal_zone.usage_name}',
Cold_Water_Supply_Temperature_Schedule_Name=f'cold_temp schedules {usage}',
Cold_Water_Supply_Temperature_Schedule_Name=f'cold_temp schedules {zone_name}',
EndUse_Subcategory=f'DHW {zone_name}',
Zone_Name=zone_name
)
def _rename_building(self, city_name):
name = str(city_name.encode("utf-8"))
name = str(str(city_name.encode("utf-8")))
for building in self._idf.idfobjects[self._BUILDING]:
building.Name = f'Buildings in {name}'
building['Solar_Distribution'] = 'FullExterior'
@ -531,27 +584,20 @@ class Idf:
self._remove_sizing_periods()
self._rename_building(self._city.name)
self._lod = self._city.level_of_detail.geometry
is_target = False
for building in self._city.buildings:
is_target = building.name in self._target_buildings or building.name in self._adjacent_buildings
for internal_zone in building.internal_zones:
if internal_zone.thermal_zones_from_internal_zones is None:
self._target_buildings.remove(building.name)
is_target = False
continue
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries:
self._add_construction(thermal_boundary)
if thermal_boundary.parent_surface.vegetation is not None:
self._add_vegetation_material(thermal_boundary.parent_surface.vegetation)
for thermal_opening in thermal_boundary.thermal_openings:
self._add_window_construction_and_material(thermal_opening)
if is_target:
start = datetime.datetime.now()
service_temperature = thermal_zone.domestic_hot_water.service_temperature
usage = thermal_zone.usage_name
if building.name in self._target_buildings or building.name in self._adjacent_buildings:
_new_schedules = self._create_infiltration_schedules(thermal_zone)
self._add_schedules(usage, 'Infiltration', _new_schedules)
_new_schedules = self._create_ventilation_schedules(thermal_zone)
@ -563,14 +609,12 @@ class Idf:
self._add_schedules(usage, 'Lighting', thermal_zone.lighting.schedules)
self._add_schedules(usage, 'Appliance', thermal_zone.appliances.schedules)
self._add_schedules(usage, 'DHW_prof', thermal_zone.domestic_hot_water.schedules)
_new_schedules = self._create_yearly_values_schedules('cold_temp', building.cold_water_temperature[cte.HOUR])
self._add_schedules(usage, 'cold_temp', _new_schedules)
_new_schedules = self._create_constant_value_schedules('DHW_temp', service_temperature)
_new_schedules = self._create_yearly_values_schedules('cold_temp',
building.cold_water_temperature[cte.HOUR])
self._add_schedules(building.name, 'cold_temp', _new_schedules)
value = thermal_zone.domestic_hot_water.service_temperature
_new_schedules = self._create_constant_value_schedules('DHW_temp', value)
self._add_schedules(usage, 'DHW_temp', _new_schedules)
_new_schedules = self._create_constant_value_schedules('INF_CONST', 1)
self._add_schedules(usage, 'INF_CONST', _new_schedules)
_new_schedules = self._create_constant_value_schedules('Thermostat_availability', 1)
self._add_schedules(usage, 'Thermostat_availability', _new_schedules)
_occ = thermal_zone.occupancy
if _occ.occupancy_density == 0:
_total_heat = 0
@ -581,14 +625,10 @@ class Idf:
self._add_schedules(usage, 'Activity Level', _new_schedules)
self._add_zone(thermal_zone, building.name)
self._add_heating_system(thermal_zone, building.name)
self._add_infiltration_surface(thermal_zone, building.name)
self._add_ventilation(thermal_zone, building.name)
self._add_occupancy(thermal_zone, building.name)
self._add_lighting(thermal_zone, building.name)
self._add_appliances(thermal_zone, building.name)
self._add_dhw(thermal_zone, building.name, usage)
self._add_infiltration(thermal_zone, building.name)
self._add_dhw(thermal_zone, building.name)
if self._export_type == "Surfaces":
if is_target:
if building.name in self._target_buildings or building.name in self._adjacent_buildings:
if building.thermal_zones_from_internal_zones is not None:
self._add_surfaces(building, building.name)
else:
@ -628,18 +668,6 @@ class Idf:
Reporting_Frequency="Hourly",
)
self._idf.newidfobject(
"OUTPUT:VARIABLE",
Variable_Name="Zone Air Temperature",
Reporting_Frequency="Hourly",
)
self._idf.newidfobject(
"OUTPUT:VARIABLE",
Variable_Name="Zone Air Relative Humidity",
Reporting_Frequency="Hourly",
)
# post-process to erase windows associated to adiabatic walls
windows_list = []
for window in self._idf.idfobjects[self._WINDOW]:
@ -651,28 +679,15 @@ class Idf:
windows_list.append(window)
for window in windows_list:
self._idf.removeidfobject(window)
self._idf.saveas(str(self._output_file))
for building in self._city.buildings:
if self._export_type == "Surfaces":
if is_target and building.thermal_zones_from_internal_zones is not None:
self._add_surfaces(building, building.name)
return self._idf
@property
def _energy_plus(self):
return shutil.which('energyplus')
def run(self):
cmd = [self._energy_plus,
'--weather', self._epw_file_path,
'--output-directory', self._output_path,
'--idd', self._idd_file_path,
'--expandobjects',
'--readvars',
'--output-prefix', f'{self._city.name}_',
self._idf_file_path]
subprocess.run(cmd, cwd=self._output_path)
"""
Start the energy plus simulation
"""
self._idf.run(expandobjects=False, readvars=True, output_directory=self._output_path,
output_prefix=f'{self._city.name}_')
def _add_block(self, building):
_points = self._matrix_to_2d_list(building.foot_print.coordinates)
@ -741,10 +756,7 @@ class Idf:
else:
# idf only allows setting wwr for external walls
wwr = 0
try:
self._idf.set_wwr(wwr, construction='window_construction_1')
except ValueError:
self._idf.set_wwr(0, construction='window_construction_1')
self._idf.set_wwr(wwr)
def _add_surfaces(self, building, zone_name):
for thermal_zone in building.thermal_zones_from_internal_zones:
@ -773,13 +785,15 @@ class Idf:
if boundary.parent_surface.vegetation is not None:
construction_name = f'{boundary.construction_name}_{boundary.parent_surface.vegetation.name}'
else:
construction_name = f'{boundary.construction_name} {boundary.parent_surface.type}'
construction_name = boundary.construction_name
_kwargs['Construction_Name'] = construction_name
start = datetime.datetime.now()
surface = self._idf.newidfobject(self._SURFACE, **_kwargs)
coordinates = self._matrix_to_list(boundary.parent_surface.solid_polygon.coordinates,
self._city.lower_corner)
surface.setcoords(coordinates)
if self._lod >= 3:
for internal_zone in building.internal_zones:
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
@ -791,10 +805,7 @@ class Idf:
for surface in building.surfaces:
if surface.type == cte.WALL:
wwr = surface.associated_thermal_boundaries[0].window_ratio
try:
self._idf.set_wwr(wwr, construction='window_construction_1')
except ValueError:
self._idf.set_wwr(0, construction='window_construction_1')
def _add_windows_by_vertices(self, boundary):
raise NotImplementedError

View File

@ -1,4 +1,4 @@
!IDD_Version 24.1.0
!IDD_Version 23.2.0
!IDD_BUILD 7636e6b3e9
! ***************************************************************************
! This file is the Input Data Dictionary (IDD) for EnergyPlus.
@ -30002,10 +30002,10 @@ People,
A7 , \field Mean Radiant Temperature Calculation Type
\note optional (only required for thermal comfort runs)
\type choice
\key EnclosureAveraged
\key ZoneAveraged
\key SurfaceWeighted
\key AngleFactor
\default EnclosureAveraged
\default ZoneAveraged
A8 , \field Surface Name/Angle Factor List Name
\type object-list
\object-list AllHeatTranAngFacNames

File diff suppressed because it is too large Load Diff

View File

@ -122,8 +122,8 @@
No, !- Do Zone Sizing Calculation
No, !- Do System Sizing Calculation
No, !- Do Plant Sizing Calculation
No, !- Run Simulation for Sizing Periods
Yes, !- Run Simulation for Weather File Run Periods
Yes, !- Run Simulation for Sizing Periods
No, !- Run Simulation for Weather File Run Periods
No, !- Do HVAC Sizing Simulation for Sizing Periods
1; !- Maximum Number of HVAC Sizing Simulation Passes
@ -148,10 +148,5 @@
OutputControl:Table:Style, CommaAndHTML,JtoKWH;
Output:Meter,DISTRICTHEATING:Facility,hourly;
Output:Meter,DISTRICTCOOLING:Facility,hourly;
Output:Meter,InteriorEquipment:Electricity,hourly;
Output:Meter,InteriorLights:Electricity,hourly;
OutputControl:IlluminanceMap:Style,
Comma; !- Column separator

View File

@ -0,0 +1,157 @@
! Minimal.idf
! Basic file description: This is a minimal configuration necessary to run.
! Highlights: Illustrates minimal items necessary to perform run.
! BUILDING, SURFACEGEOMETRY, LOCATION and DESIGNDAY (or RUNPERIOD) are the absolute minimal required input objects.
! TIME STEP IN HOUR is included so as to not get warning error.
! Including two design days, Run Control object and RunPeriod to facilitate use.
! Although not incredibly useful, this could be used as a weather/solar calculator.
! Simulation Location/Run: Denver is included. Any could be used.
! Building: None.
!
! Internal gains description: None.
!
! HVAC: None.
!
Version,9.5;
Timestep,4;
Building,
None, !- Name
0.0000000E+00, !- North Axis {deg}
Suburbs, !- Terrain
0.04, !- Loads Convergence Tolerance Value {W}
0.40, !- Temperature Convergence Tolerance Value {deltaC}
FullInteriorAndExterior, !- Solar Distribution
25, !- Maximum Number of Warmup Days
6; !- Minimum Number of Warmup Days
GlobalGeometryRules,
UpperLeftCorner, !- Starting Vertex Position
CounterClockWise, !- Vertex Entry Direction
World; !- Coordinate System
Site:Location,
DENVER_STAPLETON_CO_USA_WMO_724690, !- Name
39.77, !- Latitude {deg}
-104.87, !- Longitude {deg}
-7.00, !- Time Zone {hr}
1611.00; !- Elevation {m}
! DENVER_STAPLETON_CO_USA Annual Heating Design Conditions Wind Speed=2.3m/s Wind Dir=180
! Coldest Month=December
! DENVER_STAPLETON_CO_USA Annual Heating 99.6%, MaxDB=-20°C
SizingPeriod:DesignDay,
DENVER_STAPLETON Ann Htg 99.6% Condns DB, !- Name
12, !- Month
21, !- Day of Month
WinterDesignDay, !- Day Type
-20, !- Maximum Dry-Bulb Temperature {C}
0.0, !- Daily Dry-Bulb Temperature Range {deltaC}
, !- Dry-Bulb Temperature Range Modifier Type
, !- Dry-Bulb Temperature Range Modifier Day Schedule Name
Wetbulb, !- Humidity Condition Type
-20, !- Wetbulb or DewPoint at Maximum Dry-Bulb {C}
, !- Humidity Condition Day Schedule Name
, !- Humidity Ratio at Maximum Dry-Bulb {kgWater/kgDryAir}
, !- Enthalpy at Maximum Dry-Bulb {J/kg}
, !- Daily Wet-Bulb Temperature Range {deltaC}
83411., !- Barometric Pressure {Pa}
2.3, !- Wind Speed {m/s}
180, !- Wind Direction {deg}
No, !- Rain Indicator
No, !- Snow Indicator
No, !- Daylight Saving Time Indicator
ASHRAEClearSky, !- Solar Model Indicator
, !- Beam Solar Day Schedule Name
, !- Diffuse Solar Day Schedule Name
, !- ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub) {dimensionless}
, !- ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud) {dimensionless}
0.00; !- Sky Clearness
! DENVER_STAPLETON Annual Cooling Design Conditions Wind Speed=4m/s Wind Dir=120
! Hottest Month=July
! DENVER_STAPLETON_CO_USA Annual Cooling (DB=>MWB) .4%, MaxDB=34.1°C MWB=15.8°C
SizingPeriod:DesignDay,
DENVER_STAPLETON Ann Clg .4% Condns DB=>MWB, !- Name
7, !- Month
21, !- Day of Month
SummerDesignDay, !- Day Type
34.1, !- Maximum Dry-Bulb Temperature {C}
15.2, !- Daily Dry-Bulb Temperature Range {deltaC}
, !- Dry-Bulb Temperature Range Modifier Type
, !- Dry-Bulb Temperature Range Modifier Day Schedule Name
Wetbulb, !- Humidity Condition Type
15.8, !- Wetbulb or DewPoint at Maximum Dry-Bulb {C}
, !- Humidity Condition Day Schedule Name
, !- Humidity Ratio at Maximum Dry-Bulb {kgWater/kgDryAir}
, !- Enthalpy at Maximum Dry-Bulb {J/kg}
, !- Daily Wet-Bulb Temperature Range {deltaC}
83411., !- Barometric Pressure {Pa}
4, !- Wind Speed {m/s}
120, !- Wind Direction {deg}
No, !- Rain Indicator
No, !- Snow Indicator
No, !- Daylight Saving Time Indicator
ASHRAEClearSky, !- Solar Model Indicator
, !- Beam Solar Day Schedule Name
, !- Diffuse Solar Day Schedule Name
, !- ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub) {dimensionless}
, !- ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud) {dimensionless}
1.00; !- Sky Clearness
RunPeriod,
Run Period 1, !- Name
1, !- Begin Month
1, !- Begin Day of Month
, !- Begin Year
12, !- End Month
31, !- End Day of Month
, !- End Year
Tuesday, !- Day of Week for Start Day
Yes, !- Use Weather File Holidays and Special Days
Yes, !- Use Weather File Daylight Saving Period
No, !- Apply Weekend Holiday Rule
Yes, !- Use Weather File Rain Indicators
Yes; !- Use Weather File Snow Indicators
SimulationControl,
No, !- Do Zone Sizing Calculation
No, !- Do System Sizing Calculation
No, !- Do Plant Sizing Calculation
No, !- Run Simulation for Sizing Periods
Yes, !- Run Simulation for Weather File Run Periods
No, !- Do HVAC Sizing Simulation for Sizing Periods
1; !- Maximum Number of HVAC Sizing Simulation Passes
Output:Table:SummaryReports, AnnualBuildingUtilityPerformanceSummary,
DemandEndUseComponentsSummary,
SensibleHeatGainSummary,
InputVerificationandResultsSummary,
AdaptiveComfortSummary,
Standard62.1Summary,
ClimaticDataSummary,
EquipmentSummary,
EnvelopeSummary,
LightingSummary,
HVACSizingSummary,
SystemSummary,
ComponentSizingSummary,
OutdoorAirSummary,
ObjectCountSummary,
EndUseEnergyConsumptionOtherFuelsMonthly,
PeakEnergyEndUseOtherFuelsMonthly;
OutputControl:Table:Style, CommaAndHTML,JtoKWH;
Output:Meter,DISTRICTHEATING:Facility,hourly;
Output:Meter,DISTRICTCOOLING:Facility,hourly;
Output:Meter,InteriorEquipment:Electricity,hourly;
Output:Meter,InteriorLights:Electricity,hourly;
OutputControl:IlluminanceMap:Style,
Comma; !- Column separator

View File

@ -1,62 +0,0 @@
!- Linux Line endings
Version,
24.1; !- Version Identifier
SimulationControl,
No, !- Do Zone Sizing Calculation
No, !- Do System Sizing Calculation
No, !- Do Plant Sizing Calculation
No, !- Run Simulation for Sizing Periods
Yes, !- Run Simulation for Weather File Run Periods
No, !- Do HVAC Sizing Simulation for Sizing Periods
1; !- Maximum Number of HVAC Sizing Simulation Passes
Building,
Buildings in #CITY#, !- Name
0, !- North Axis
Suburbs, !- Terrain
0.04, !- Loads Convergence Tolerance Value
0.4, !- Temperature Convergence Tolerance Value
FullExterior, !- Solar Distribution
25, !- Maximum Number of Warmup Days
6; !- Minimum Number of Warmup Days
Timestep,
4; !- Number of Timesteps per Hour
RunPeriod,
Run Period 1, !- Name
1, !- Begin Month
1, !- Begin Day of Month
, !- Begin Year
12, !- End Month
31, !- End Day of Month
, !- End Year
Tuesday, !- Day of Week for Start Day
Yes, !- Use Weather File Holidays and Special Days
Yes, !- Use Weather File Daylight Saving Period
No, !- Apply Weekend Holiday Rule
Yes, !- Use Weather File Rain Indicators
Yes; !- Use Weather File Snow Indicators
SCHEDULETYPELIMITS,
Any Number, !- Name
, !- Lower Limit Value
, !- Upper Limit Value
, !- Numeric Type
Dimensionless; !- Unit Type
SCHEDULETYPELIMITS,
Fraction, !- Name
0, !- Lower Limit Value
1, !- Upper Limit Value
Continuous, !- Numeric Type
Dimensionless; !- Unit Type
SCHEDULETYPELIMITS,
On/Off, !- Name
0, !- Lower Limit Value
1, !- Upper Limit Value
Discrete, !- Numeric Type
Dimensionless; !- Unit Type

View File

@ -1,74 +0,0 @@
Output:Table:SummaryReports,
AnnualBuildingUtilityPerformanceSummary, !- Report 1 Name
DemandEndUseComponentsSummary, !- Report 2 Name
SensibleHeatGainSummary, !- Report 3 Name
InputVerificationandResultsSummary, !- Report 4 Name
AdaptiveComfortSummary, !- Report 5 Name
Standard62.1Summary, !- Report 6 Name
ClimaticDataSummary, !- Report 7 Name
EquipmentSummary, !- Report 8 Name
EnvelopeSummary, !- Report 9 Name
LightingSummary, !- Report 10 Name
HVACSizingSummary, !- Report 11 Name
SystemSummary, !- Report 12 Name
ComponentSizingSummary, !- Report 13 Name
OutdoorAirSummary, !- Report 14 Name
ObjectCountSummary, !- Report 15 Name
EndUseEnergyConsumptionOtherFuelsMonthly, !- Report 16 Name
PeakEnergyEndUseOtherFuelsMonthly; !- Report 17 Name
OutputControl:Table:Style,
CommaAndHTML, !- Column Separator
JtoKWH; !- Unit Conversion
OUTPUT:VARIABLE,
*, !- Key Value
Zone Ideal Loads Supply Air Total Heating Energy, !- Variable Name
Hourly; !- Reporting Frequency
OUTPUT:VARIABLE,
*, !- Key Value
Zone Ideal Loads Supply Air Total Cooling Energy, !- Variable Name
Hourly; !- Reporting Frequency
OUTPUT:VARIABLE,
*, !- Key Value
Water Use Equipment Heating Rate, !- Variable Name
Hourly; !- Reporting Frequency
OUTPUT:VARIABLE,
*, !- Key Value
Zone Lights Electricity Rate, !- Variable Name
Hourly; !- Reporting Frequency
OUTPUT:VARIABLE,
*, !- Key Value
Other Equipment Electricity Rate, !- Variable Name
Hourly; !- Reporting Frequency
OUTPUT:VARIABLE,
*, !- Key Value
Zone Air Temperature, !- Variable Name
Hourly; !- Reporting Frequency
OUTPUT:VARIABLE,
*, !- Key Value
Zone Air Relative Humidity, !- Variable Name
Hourly; !- Reporting Frequency
Output:Meter,
DISTRICTHEATING:Facility, !- Key Name
hourly; !- Reporting Frequency
Output:Meter,
DISTRICTCOOLING:Facility, !- Key Name
hourly; !- Reporting Frequency
Output:Meter,
InteriorEquipment:Electricity, !- Key Name
hourly; !- Reporting Frequency
Output:Meter,
InteriorLights:Electricity, !- Key Name
hourly; !- Reporting Frequency

View File

@ -1,60 +0,0 @@
import hub.helpers.constants as cte
BUILDING_SURFACE = '\nBUILDINGSURFACE:DETAILED,\n'
WINDOW_SURFACE = '\nFENESTRATIONSURFACE:DETAILED,\n'
COMPACT_SCHEDULE = '\nSCHEDULE:COMPACT,\n'
FILE_SCHEDULE = '\nSCHEDULE:FILE,\n'
NOMASS_MATERIAL = '\nMATERIAL:NOMASS,\n'
SOLID_MATERIAL = '\nMATERIAL,\n'
WINDOW_MATERIAL = '\nWINDOWMATERIAL:SIMPLEGLAZINGSYSTEM,\n'
CONSTRUCTION = '\nCONSTRUCTION,\n'
ZONE = '\nZONE,\n'
GLOBAL_GEOMETRY_RULES = '\nGlobalGeometryRules,\n'
PEOPLE = '\nPEOPLE,\n'
LIGHTS = '\nLIGHTS,\n'
APPLIANCES = '\nOTHEREQUIPMENT,\n'
OUTPUT_CONTROL = '\nOutputControl:IlluminanceMap:Style,\n'
INFILTRATION = '\nZONEINFILTRATION:DESIGNFLOWRATE,\n'
VENTILATION = '\nZONEVENTILATION:DESIGNFLOWRATE,\n'
THERMOSTAT = '\nHVACTEMPLATE:THERMOSTAT,\n'
IDEAL_LOAD_SYSTEM = '\nHVACTEMPLATE:ZONE:IDEALLOADSAIRSYSTEM,\n'
DHW = '\nWATERUSE:EQUIPMENT,\n'
SHADING = '\nSHADING:BUILDING:DETAILED,\n'
AUTOCALCULATE = 'autocalculate'
ROUGHNESS = 'MediumRough'
OUTDOORS = 'Outdoors'
GROUND = 'Ground'
SURFACE = 'Surface'
SUN_EXPOSED = 'SunExposed'
WIND_EXPOSED = 'WindExposed'
NON_SUN_EXPOSED = 'NoSun'
NON_WIND_EXPOSED = 'NoWind'
EMPTY = ''
idf_surfaces_dictionary = {
cte.WALL: 'wall',
cte.GROUND: 'floor',
cte.ROOF: 'roof'
}
idf_type_limits = {
cte.ON_OFF: 'on/off',
cte.FRACTION: 'Fraction',
cte.ANY_NUMBER: 'Any Number',
cte.CONTINUOUS: 'Continuous',
cte.DISCRETE: 'Discrete'
}
idf_day_types = {
cte.MONDAY: 'Monday',
cte.TUESDAY: 'Tuesday',
cte.WEDNESDAY: 'Wednesday',
cte.THURSDAY: 'Thursday',
cte.FRIDAY: 'Friday',
cte.SATURDAY: 'Saturday',
cte.SUNDAY: 'Sunday',
cte.HOLIDAY: 'Holidays',
cte.WINTER_DESIGN_DAY: 'WinterDesignDay',
cte.SUMMER_DESIGN_DAY: 'SummerDesignDay'
}

View File

@ -1,26 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfAppliance(IdfBase):
@staticmethod
def add(self, thermal_zone, zone_name):
schedule_name = f'Appliance schedules {thermal_zone.usage_name}'
storeys_number = int(thermal_zone.total_floor_area / thermal_zone.footprint_area)
watts_per_zone_floor_area = thermal_zone.appliances.density * storeys_number
subcategory = f'ELECTRIC EQUIPMENT#{zone_name}#InteriorEquipment'
file = self._files['appliances']
self._write_to_idf_format(file, idf_cte.APPLIANCES)
self._write_to_idf_format(file, zone_name, 'Name')
self._write_to_idf_format(file, 'Electricity', 'Fuel Type')
self._write_to_idf_format(file, zone_name, 'Zone or ZoneList or Space or SpaceList Name')
self._write_to_idf_format(file, schedule_name, 'Schedule Name')
self._write_to_idf_format(file, 'Watts/Area', 'Design Level Calculation Method')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Level')
self._write_to_idf_format(file, watts_per_zone_floor_area, 'Power per Zone Floor Area')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Power per Person')
self._write_to_idf_format(file, thermal_zone.appliances.latent_fraction, 'Fraction Latent')
self._write_to_idf_format(file, thermal_zone.appliances.radiative_fraction, 'Fraction Radiant')
self._write_to_idf_format(file, 0, 'Fraction Lost')
self._write_to_idf_format(file, 0, 'Carbon Dioxide Generation Rate')
self._write_to_idf_format(file, subcategory, 'EndUse Subcategory', ';')

View File

@ -1,78 +0,0 @@
import os
from pathlib import Path
import hub.exports.building_energy.idf_helper as idf_cte
class IdfBase:
def __init__(self, city, output_path, idf_file_path, idd_file_path, epw_file_path, target_buildings=None,
_calculate_with_new_infiltration=True):
self._city = city
self._output_path = str(output_path.resolve())
self._output_file_path = str((output_path / f'{city.name}.idf').resolve())
self._file_paths = {
'schedules': str((output_path / 'schedules.idf').resolve()),
'file_schedules': str((output_path / 'file_schedules.idf').resolve()),
'solid_materials': str((output_path / 'solid_materials.idf').resolve()),
'nomass_materials': str((output_path / 'nomass_materials.idf').resolve()),
'window_materials': str((output_path / 'window_materials.idf').resolve()),
'constructions': str((output_path / 'constructions.idf').resolve()),
'zones': str((output_path / 'zones.idf').resolve()),
'surfaces': str((output_path / 'surfaces.idf').resolve()),
'fenestration': str((output_path / 'fenestration.idf').resolve()),
'occupancy': str((output_path / 'occupancy.idf').resolve()),
'lighting': str((output_path / 'lights.idf').resolve()),
'appliances': str((output_path / 'appliances.idf').resolve()),
'shading': str((output_path / 'shading.idf').resolve()),
'infiltration': str((output_path / 'infiltration.idf').resolve()),
'ventilation': str((output_path / 'ventilation.idf').resolve()),
'thermostat': str((output_path / 'thermostat.idf').resolve()),
'ideal_load_system': str((output_path / 'ideal_load_system.idf').resolve()),
'dhw': str((output_path / 'dhw.idf').resolve()),
}
self._files = {}
for key, value in self._file_paths.items():
self._files[key] = open(value, 'w', encoding='UTF-8')
self._idd_file_path = str(idd_file_path)
self._idf_file_path = str(idf_file_path)
self._outputs_file_path = str(Path(idf_file_path).parent / 'outputs.idf')
self._epw_file_path = str(epw_file_path)
self._target_buildings = target_buildings
self._adjacent_buildings = []
if target_buildings is None:
self._target_buildings = [building.name for building in self._city.buildings]
else:
for building_name in target_buildings:
building = city.city_object(building_name)
if building.neighbours is not None:
self._adjacent_buildings += building.neighbours
self._calculate_with_new_infiltration = _calculate_with_new_infiltration
def _create_output_control_lighting(self):
file = self._files['appliances']
self._write_to_idf_format(file, idf_cte.OUTPUT_CONTROL)
self._write_to_idf_format(file, 'Comma', 'Column Separator', ';')
@staticmethod
def _write_to_idf_format(file, field, comment='', eol=','):
if comment != '':
comment = f' !- {comment}'
field = f' {field}{eol}'.ljust(26, ' ')
file.write(f'{field}{comment}\n')
else:
file.write(f'{field}{comment}')
@staticmethod
def _matrix_to_list(points, lower_corner):
lower_x = lower_corner[0]
lower_y = lower_corner[1]
lower_z = lower_corner[2]
points_list = []
for point in points:
point_tuple = (point[0] - lower_x, point[1] - lower_y, point[2] - lower_z)
points_list.append(point_tuple)
return points_list

View File

@ -1,56 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.city_model_structure.building_demand.layer import Layer
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfConstruction(IdfBase):
@staticmethod
def _add_solid_material(self, layer):
file = self._files['solid_materials']
self._write_to_idf_format(file, idf_cte.SOLID_MATERIAL)
self._write_to_idf_format(file, layer.material_name, 'Name')
self._write_to_idf_format(file, idf_cte.ROUGHNESS, 'Roughness')
self._write_to_idf_format(file, layer.thickness, 'Thickness')
self._write_to_idf_format(file, layer.conductivity, 'Conductivity')
self._write_to_idf_format(file, layer.density, 'Density')
self._write_to_idf_format(file, layer.specific_heat, 'Specific Heat')
self._write_to_idf_format(file, layer.thermal_absorptance, 'Thermal Absorptance')
self._write_to_idf_format(file, layer.solar_absorptance, 'Solar Absorptance')
self._write_to_idf_format(file, layer.visible_absorptance, 'Visible Absorptance', ';')
@staticmethod
def _add_default_material(self):
layer = Layer()
layer.material_name = 'DefaultMaterial'
layer.thickness = 0.1
layer.conductivity = 0.1
layer.density = 1000
layer.specific_heat = 1000
layer.thermal_absorptance = 0.9
layer.solar_absorptance = 0.9
layer.visible_absorptance = 0.7
IdfConstruction._add_solid_material(self, layer)
return layer
@staticmethod
def add(self, thermal_boundary):
if thermal_boundary.layers is None:
thermal_boundary.layers = [IdfConstruction._add_default_material(self)]
name = f'{thermal_boundary.construction_name} {thermal_boundary.parent_surface.type}'
if name not in self._constructions_added_to_idf:
self._constructions_added_to_idf[name] = True
file = self._files['constructions']
self._write_to_idf_format(file, idf_cte.CONSTRUCTION)
self._write_to_idf_format(file, name, 'Name')
eol = ','
if len(thermal_boundary.layers) == 1:
eol = ';'
self._write_to_idf_format(file, thermal_boundary.layers[0].material_name, 'Outside Layer', eol)
for i in range(1, len(thermal_boundary.layers) - 1):
comment = f'Layer {i + 1}'
material_name = thermal_boundary.layers[i].material_name
if i == len(thermal_boundary.layers) - 2:
eol = ';'
self._write_to_idf_format(file, material_name, comment, eol)

View File

@ -1,21 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfDhw(IdfBase):
@staticmethod
def add(self, thermal_zone, zone_name):
peak_flow_rate = thermal_zone.domestic_hot_water.peak_flow * thermal_zone.total_floor_area
flow_rate_schedule = f'DHW_prof schedules {thermal_zone.usage_name}'
dhw_schedule = f'DHW_temp schedules {thermal_zone.usage_name}'
cold_temp_schedule = f'cold_temp schedules {thermal_zone.usage_name}'
file = self._files['dhw']
self._write_to_idf_format(file, idf_cte.DHW)
self._write_to_idf_format(file, zone_name, 'Name')
self._write_to_idf_format(file, zone_name, 'EndUse Subcategory')
self._write_to_idf_format(file, peak_flow_rate, 'Peak Flow Rate')
self._write_to_idf_format(file, flow_rate_schedule, 'Flow Rate Fraction Schedule Name')
self._write_to_idf_format(file, dhw_schedule, 'Target Temperature Schedule Name')
self._write_to_idf_format(file, dhw_schedule, 'Hot Water Supply Temperature Schedule Name')
self._write_to_idf_format(file, cold_temp_schedule, 'Cold Water Supply Temperature Schedule Name')
self._write_to_idf_format(file, zone_name, 'Zone Name', ';')

View File

@ -1,30 +0,0 @@
from pathlib import Path
import hub.helpers.constants as cte
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfFileSchedule(IdfBase):
@staticmethod
def add(self, usage, schedule_type, schedules):
schedule_name = f'{schedule_type} schedules {usage}'
for schedule in schedules:
if schedule_name not in self._schedules_added_to_idf:
self._schedules_added_to_idf[schedule_name] = True
file_name = str(
(Path(self._output_path) / f'{schedule_type} schedules {usage.replace("/", "_")}.csv').resolve())
with open(file_name, 'w', encoding='utf8') as file:
for value in schedule.values[0]:
file.write(f'{value},\n')
file = self._files['file_schedules']
self._write_to_idf_format(file, idf_cte.FILE_SCHEDULE)
self._write_to_idf_format(file, schedule_name, 'Name')
self._write_to_idf_format(file, idf_cte.idf_type_limits[schedule.data_type], 'Schedule Type Limits Name')
self._write_to_idf_format(file, Path(file_name).name, 'File Name')
self._write_to_idf_format(file, 1, 'Column Number')
self._write_to_idf_format(file, 0, 'Rows to Skip at Top')
self._write_to_idf_format(file, 8760, 'Number of Hours of Data')
self._write_to_idf_format(file, 'Comma', 'Column Separator')
self._write_to_idf_format(file, 'No', 'Interpolate to Timestep')
self._write_to_idf_format(file, '60', 'Minutes per Item')
self._write_to_idf_format(file, 'Yes', 'Adjust Schedule for Daylight Savings', ';')

View File

@ -1,41 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfHeatingSystem(IdfBase):
@staticmethod
def add(self, thermal_zone, zone_name):
availability_schedule = f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}'
thermostat_name = f'Thermostat {thermal_zone.usage_name}'
file = self._files['ideal_load_system']
self._write_to_idf_format(file, idf_cte.IDEAL_LOAD_SYSTEM)
self._write_to_idf_format(file, zone_name, 'Zone Name')
self._write_to_idf_format(file, thermostat_name, 'Template Thermostat Name')
self._write_to_idf_format(file, availability_schedule, 'System Availability Schedule Name')
self._write_to_idf_format(file, 50, 'Maximum Heating Supply Air Temperature')
self._write_to_idf_format(file, 13, 'Minimum Cooling Supply Air Temperature')
self._write_to_idf_format(file, 0.0156, 'Maximum Heating Supply Air Humidity Ratio')
self._write_to_idf_format(file, 0.0077, 'Minimum Cooling Supply Air Humidity Ratio')
self._write_to_idf_format(file, 'NoLimit', 'Heating Limit')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Heating Air Flow Rate')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Sensible Heating Capacity')
self._write_to_idf_format(file, 'NoLimit', 'Cooling Limit')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Cooling Air Flow Rate')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Total Cooling Capacity')
self._write_to_idf_format(file, availability_schedule, 'Heating Availability Schedule Name')
self._write_to_idf_format(file, availability_schedule, 'Cooling Availability Schedule Name')
self._write_to_idf_format(file, 'ConstantSensibleHeatRatio', 'Dehumidification Control Type')
self._write_to_idf_format(file, 0.7, 'Cooling Sensible Heat Ratio')
self._write_to_idf_format(file, 60, 'Dehumidification Setpoint')
self._write_to_idf_format(file, 'None', 'Humidification Control Type')
self._write_to_idf_format(file, 30, 'Humidification Setpoint')
self._write_to_idf_format(file, 'None', 'Outdoor Air Method')
self._write_to_idf_format(file, 0.00944, 'Outdoor Air Flow Rate per Person')
self._write_to_idf_format(file, 0.0, 'Outdoor Air Flow Rate per Zone Floor Area')
self._write_to_idf_format(file, 0, 'Outdoor Air Flow Rate per Zone')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Specification Outdoor Air Object Name')
self._write_to_idf_format(file, 'None', 'Demand Controlled Ventilation Type')
self._write_to_idf_format(file, 'NoEconomizer', 'Outdoor Air Economizer Type')
self._write_to_idf_format(file, 'None', 'Heat Recovery Type')
self._write_to_idf_format(file, 0.70, 'Sensible Heat Recovery Effectiveness')
self._write_to_idf_format(file, 0.65, 'Latent Heat Recovery Effectiveness', ';')

View File

@ -1,32 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
import hub.helpers.constants as cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfInfiltration(IdfBase):
@staticmethod
def add(self, thermal_zone, zone_name):
IdfInfiltration._add_infiltration(self, thermal_zone, zone_name, 'AirChanges/Hour', cte.HOUR_TO_SECONDS)
@staticmethod
def add_surface(self, thermal_zone, zone_name):
IdfInfiltration._add_infiltration(self, thermal_zone, zone_name, 'Flow/ExteriorWallArea', cte.INFILTRATION_75PA_TO_4PA)
@staticmethod
def _add_infiltration(self, thermal_zone, zone_name, calculation_method, multiplier):
schedule_name = f'Infiltration schedules {thermal_zone.usage_name}'
infiltration = thermal_zone.infiltration_rate_system_off * multiplier
file = self._files['infiltration']
self._write_to_idf_format(file, idf_cte.INFILTRATION)
self._write_to_idf_format(file, zone_name, 'Name')
self._write_to_idf_format(file, zone_name, 'Zone or ZoneList or Space or SpaceList Name')
self._write_to_idf_format(file, schedule_name, 'Schedule Name')
self._write_to_idf_format(file, calculation_method, 'Design Flow Rate Calculation Method')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Flow Rate')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Floor Area')
self._write_to_idf_format(file, infiltration, 'Flow Rate per Exterior Surface Area')
self._write_to_idf_format(file, infiltration, 'Air Changes per Hour')
self._write_to_idf_format(file, 1, 'Constant Term Coefficient')
self._write_to_idf_format(file, 0, 'Temperature Term Coefficient')
self._write_to_idf_format(file, 0, 'Velocity Term Coefficient')
self._write_to_idf_format(file, 0, 'Velocity Squared Term Coefficient', ';')

View File

@ -1,28 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfLighting(IdfBase):
@staticmethod
def add(self, thermal_zone, zone_name):
storeys_number = int(thermal_zone.total_floor_area / thermal_zone.footprint_area)
watts_per_zone_floor_area = thermal_zone.lighting.density * storeys_number
subcategory = f'ELECTRIC EQUIPMENT#{zone_name}#GeneralLights'
schedule_name = f'Lighting schedules {thermal_zone.usage_name}'
file = self._files['lighting']
self._write_to_idf_format(file, idf_cte.LIGHTS)
self._write_to_idf_format(file, f'{zone_name}_lights', 'Name')
self._write_to_idf_format(file, zone_name, 'Zone or ZoneList or Space or SpaceList Name')
self._write_to_idf_format(file, schedule_name, 'Schedule Name')
self._write_to_idf_format(file, 'Watts/Area', 'Design Level Calculation Method')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Lighting Level')
self._write_to_idf_format(file, watts_per_zone_floor_area, 'Watts per Zone Floor Area')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Watts per Person')
self._write_to_idf_format(file, 0, 'Return Air Fraction')
self._write_to_idf_format(file, thermal_zone.lighting.radiative_fraction, 'Fraction Radiant')
self._write_to_idf_format(file, 0, 'Fraction Visible')
self._write_to_idf_format(file, 1, 'Fraction Replaceable')
self._write_to_idf_format(file, subcategory, 'EndUse Subcategory')
self._write_to_idf_format(file, 'No', 'Return Air Fraction Calculated from Plenum Temperature')
self._write_to_idf_format(file, 0, 'Return Air Fraction Function of Plenum Temperature Coefficient 1')
self._write_to_idf_format(file, 0, 'Return Air Fraction Function of Plenum Temperature Coefficient 2', ';')

View File

@ -1,39 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfMaterial(IdfBase):
@staticmethod
def _add_solid_material(self, layer):
file = self._files['solid_materials']
self._write_to_idf_format(file, idf_cte.SOLID_MATERIAL)
self._write_to_idf_format(file, layer.material_name, 'Name')
self._write_to_idf_format(file, idf_cte.ROUGHNESS, 'Roughness')
self._write_to_idf_format(file, layer.thickness, 'Thickness')
self._write_to_idf_format(file, layer.conductivity, 'Conductivity')
self._write_to_idf_format(file, layer.density, 'Density')
self._write_to_idf_format(file, layer.specific_heat, 'Specific Heat')
self._write_to_idf_format(file, layer.thermal_absorptance, 'Thermal Absorptance')
self._write_to_idf_format(file, layer.solar_absorptance, 'Solar Absorptance')
self._write_to_idf_format(file, layer.visible_absorptance, 'Visible Absorptance', ';')
@staticmethod
def _add_nomass_material(self, layer):
file = self._files['nomass_materials']
self._write_to_idf_format(file, idf_cte.NOMASS_MATERIAL)
self._write_to_idf_format(file, layer.material_name, 'Name')
self._write_to_idf_format(file, idf_cte.ROUGHNESS, 'Roughness')
self._write_to_idf_format(file, layer.thermal_resistance, 'Thermal Resistance')
self._write_to_idf_format(file, 0.9, 'Thermal Absorptance')
self._write_to_idf_format(file, 0.7, 'Solar Absorptance')
self._write_to_idf_format(file, 0.7, 'Visible Absorptance', ';')
@staticmethod
def add(self, thermal_boundary):
for layer in thermal_boundary.layers:
if layer.material_name not in self._materials_added_to_idf:
self._materials_added_to_idf[layer.material_name] = True
if layer.no_mass:
IdfMaterial._add_nomass_material(self, layer)
else:
IdfMaterial._add_solid_material(self, layer)

View File

@ -1,47 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfOccupancy(IdfBase):
@staticmethod
def add(self, thermal_zone, zone_name):
number_of_people = thermal_zone.occupancy.occupancy_density * thermal_zone.total_floor_area
fraction_radiant = 0
total_sensible = (
thermal_zone.occupancy.sensible_radiative_internal_gain + thermal_zone.occupancy.sensible_convective_internal_gain
)
if total_sensible != 0:
fraction_radiant = thermal_zone.occupancy.sensible_radiative_internal_gain / total_sensible
occupancy_schedule = f'Occupancy schedules {thermal_zone.usage_name}'
activity_level_schedule = f'Activity Level schedules {thermal_zone.usage_name}'
file = self._files['occupancy']
self._write_to_idf_format(file, idf_cte.PEOPLE)
self._write_to_idf_format(file, f'{zone_name}_occupancy', 'Name')
self._write_to_idf_format(file, zone_name, 'Zone or ZoneList or Space or SpaceList Name')
self._write_to_idf_format(file, occupancy_schedule, 'Number of People Schedule Name')
self._write_to_idf_format(file, 'People', 'Number of People Calculation Method')
self._write_to_idf_format(file, number_of_people, 'Number of People')
self._write_to_idf_format(file, idf_cte.EMPTY, 'People per Floor Area')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Floor Area per Person')
self._write_to_idf_format(file, fraction_radiant, 'Fraction Radiant')
self._write_to_idf_format(file, idf_cte.AUTOCALCULATE, 'Sensible Heat Fraction')
self._write_to_idf_format(file, activity_level_schedule, 'Activity Level Schedule Name')
self._write_to_idf_format(file, '3.82e-08', 'Carbon Dioxide Generation Rate')
self._write_to_idf_format(file, 'No', 'Enable ASHRAE 55 Comfort Warnings')
self._write_to_idf_format(file, 'EnclosureAveraged', 'Mean Radiant Temperature Calculation Type')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Surface NameAngle Factor List Name')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Work Efficiency Schedule Name')
self._write_to_idf_format(file, 'ClothingInsulationSchedule', 'Clothing Insulation Calculation Method')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Clothing Insulation Calculation Method Schedule Name')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Clothing Insulation Schedule Name')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Air Velocity Schedule Name')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Thermal Comfort Model 1 Type')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Thermal Comfort Model 2 Type')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Thermal Comfort Model 3 Type')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Thermal Comfort Model 4 Type')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Thermal Comfort Model 5 Type')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Thermal Comfort Model 6 Type')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Thermal Comfort Model 7 Type')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Ankle Level Air Velocity Schedule Name')
self._write_to_idf_format(file, '15.56', 'Cold Stress Temperature Threshold')
self._write_to_idf_format(file, '30', 'Heat Stress Temperature Threshold', ';')

View File

@ -1,30 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfSchedule(IdfBase):
@staticmethod
def add(self, usage, schedule_type, schedules):
if len(schedules) < 1:
return
schedule_name = f'{schedule_type} schedules {usage}'
if schedule_name not in self._schedules_added_to_idf:
self._schedules_added_to_idf[schedule_name] = True
file = self._files['schedules']
self._write_to_idf_format(file, idf_cte.COMPACT_SCHEDULE)
self._write_to_idf_format(file, schedule_name, 'Name')
self._write_to_idf_format(file, idf_cte.idf_type_limits[schedules[0].data_type], 'Schedule Type Limits Name')
self._write_to_idf_format(file, 'Through: 12/31', 'Field 1')
counter = 1
for j, schedule in enumerate(schedules):
_val = schedule.values
_new_field = ''
for day_type in schedule.day_types:
_new_field += f' {idf_cte.idf_day_types[day_type]}'
self._write_to_idf_format(file, f'For:{_new_field}', f'Field {j * 25 + 2}')
counter += 1
for i, _ in enumerate(_val):
self._write_to_idf_format(file, f'Until: {i + 1:02d}:00,{_val[i]}', f'Field {j * 25 + 3 + i}')
counter += 1
self._write_to_idf_format(file, 'For AllOtherDays', f'Field {counter + 1}')
self._write_to_idf_format(file, 'Until: 24:00,0.0', f'Field {counter + 2}', ';')

View File

@ -1,25 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfShading(IdfBase):
@staticmethod
def add(self, building):
name = building.name
file = self._files['shading']
for s, surface in enumerate(building.surfaces):
self._write_to_idf_format(file, idf_cte.SHADING)
self._write_to_idf_format(file, f'{name}_{s}', 'Name')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Transmittance Schedule Name')
self._write_to_idf_format(file, idf_cte.AUTOCALCULATE, 'Number of Vertices')
eol = ','
coordinates = self._matrix_to_list(surface.solid_polygon.coordinates, self._city.lower_corner)
coordinates_length = len(coordinates)
for i, coordinate in enumerate(coordinates):
vertex = i + 1
if vertex == coordinates_length:
eol = ';'
self._write_to_idf_format(file, coordinate[0], f'Vertex {vertex} Xcoordinate')
self._write_to_idf_format(file, coordinate[1], f'Vertex {vertex} Ycoordinate')
self._write_to_idf_format(file, coordinate[2], f'Vertex {vertex} Zcoordinate', eol)

View File

@ -1,52 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
import hub.helpers.constants as cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfSurfaces(IdfBase):
@staticmethod
def add(self, building, zone_name):
zone_name = f'{zone_name}'
file = self._files['surfaces']
for thermal_zone in building.thermal_zones_from_internal_zones:
for index, boundary in enumerate(thermal_zone.thermal_boundaries):
surface_type = idf_cte.idf_surfaces_dictionary[boundary.parent_surface.type]
outside_boundary_condition = idf_cte.OUTDOORS
sun_exposure = idf_cte.SUN_EXPOSED
wind_exposure = idf_cte.WIND_EXPOSED
outside_boundary_condition_object = idf_cte.EMPTY
name = f'Building_{building.name}_surface_{index}'
construction_name = f'{boundary.construction_name} {boundary.parent_surface.type}'
space_name = idf_cte.EMPTY
if boundary.parent_surface.type == cte.GROUND:
outside_boundary_condition = idf_cte.GROUND
sun_exposure = idf_cte.NON_SUN_EXPOSED
wind_exposure = idf_cte.NON_WIND_EXPOSED
if boundary.parent_surface.percentage_shared is not None and boundary.parent_surface.percentage_shared > 0.5:
outside_boundary_condition_object = f'Building_{building.name}_surface_{index}'
outside_boundary_condition = idf_cte.SURFACE
sun_exposure = idf_cte.NON_SUN_EXPOSED
wind_exposure = idf_cte.NON_WIND_EXPOSED
self._write_to_idf_format(file, idf_cte.BUILDING_SURFACE)
self._write_to_idf_format(file, name, 'Name')
self._write_to_idf_format(file, surface_type, 'Surface Type')
self._write_to_idf_format(file, construction_name, 'Construction Name')
self._write_to_idf_format(file, zone_name, 'Zone Name')
self._write_to_idf_format(file, space_name, 'Space Name')
self._write_to_idf_format(file, outside_boundary_condition, 'Outside Boundary Condition')
self._write_to_idf_format(file, outside_boundary_condition_object, 'Outside Boundary Condition Object')
self._write_to_idf_format(file, sun_exposure, 'Sun Exposure')
self._write_to_idf_format(file, wind_exposure, 'Wind Exposure')
self._write_to_idf_format(file, idf_cte.AUTOCALCULATE, 'View Factor to Ground')
self._write_to_idf_format(file, idf_cte.AUTOCALCULATE, 'Number of Vertices')
coordinates = self._matrix_to_list(boundary.parent_surface.solid_polygon.coordinates,
self._city.lower_corner)
eol = ','
coordinates_length = len(coordinates)
for i, coordinate in enumerate(coordinates):
vertex = i + 1
if vertex == coordinates_length:
eol = ';'
self._write_to_idf_format(file, coordinate[0], f'Vertex {vertex} Xcoordinate')
self._write_to_idf_format(file, coordinate[1], f'Vertex {vertex} Ycoordinate')
self._write_to_idf_format(file, coordinate[2], f'Vertex {vertex} Zcoordinate', eol)

View File

@ -1,18 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfThermostat(IdfBase):
@staticmethod
def add(self, thermal_zone):
thermostat_name = f'Thermostat {thermal_zone.usage_name}'
heating_schedule = f'Heating thermostat schedules {thermal_zone.usage_name}'
cooling_schedule = f'Cooling thermostat schedules {thermal_zone.usage_name}'
if thermostat_name not in self._thermostat_added_to_idf:
self._thermostat_added_to_idf[thermostat_name] = True
file = self._files['thermostat']
self._write_to_idf_format(file, idf_cte.THERMOSTAT)
self._write_to_idf_format(file, thermostat_name, 'Name')
self._write_to_idf_format(file, heating_schedule, 'Heating Setpoint Schedule Name')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Constant Heating Setpoint')
self._write_to_idf_format(file, cooling_schedule, 'Cooling Setpoint Schedule Name', ';')

View File

@ -1,38 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
import hub.helpers.constants as cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfVentilation(IdfBase):
@staticmethod
def add(self, thermal_zone, zone_name):
schedule_name = f'Ventilation schedules {thermal_zone.usage_name}'
air_change = thermal_zone.mechanical_air_change * cte.HOUR_TO_SECONDS
file = self._files['ventilation']
self._write_to_idf_format(file, idf_cte.VENTILATION)
self._write_to_idf_format(file, f'{zone_name}_ventilation', 'Name')
self._write_to_idf_format(file, zone_name, 'Zone or ZoneList or Space or SpaceList Name')
self._write_to_idf_format(file, schedule_name, 'Schedule Name')
self._write_to_idf_format(file, 'AirChanges/Hour', 'Design Flow Rate Calculation Method')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Design Flow Rate')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Floor Area')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Flow Rate per Person')
self._write_to_idf_format(file, air_change, 'Air Changes per Hour')
self._write_to_idf_format(file, 'Natural', 'Ventilation Type')
self._write_to_idf_format(file, 0, 'Fan Pressure Rise')
self._write_to_idf_format(file, 1, 'Fan Total Efficiency')
self._write_to_idf_format(file, 1, 'Constant Term Coefficient')
self._write_to_idf_format(file, 0, 'Temperature Term Coefficient')
self._write_to_idf_format(file, 0, 'Velocity Term Coefficient')
self._write_to_idf_format(file, 0, 'Velocity Squared Term Coefficient')
self._write_to_idf_format(file, -100, 'Minimum Indoor Temperature')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Minimum Indoor Temperature Schedule Name')
self._write_to_idf_format(file, 100, 'Maximum Indoor Temperature')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Indoor Temperature Schedule Name')
self._write_to_idf_format(file, -100, 'Delta Temperature')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Delta Temperature Schedule Name')
self._write_to_idf_format(file, -100, 'Minimum Outdoor Temperature')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Minimum Outdoor Temperature Schedule Name')
self._write_to_idf_format(file, 100, 'Maximum Outdoor Temperature')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Maximum Outdoor Temperature Schedule Name')
self._write_to_idf_format(file, 40, 'Maximum Wind Speed', ';')

View File

@ -1,64 +0,0 @@
import logging
import hub.exports.building_energy.idf_helper as idf_cte
import hub.helpers.constants as cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfWindow(IdfBase):
@staticmethod
def _to_window_surface(self, surface):
window_ratio = surface.associated_thermal_boundaries[0].window_ratio
x = 0
y = 1
z = 2
coordinates = self._matrix_to_list(surface.solid_polygon.coordinates, self._city.lower_corner)
min_z = surface.lower_corner[z]
max_z = surface.upper_corner[z]
middle = (max_z - min_z) / 2
distance = (max_z - min_z) * window_ratio
new_max_z = middle + distance / 2
new_min_z = middle - distance / 2
for index, coordinate in enumerate(coordinates):
if coordinate[z] == max_z:
coordinates[index] = (coordinate[x], coordinate[y], new_max_z)
elif coordinate[z] == min_z:
coordinates[index] = (coordinate[x], coordinate[y], new_min_z)
else:
logging.warning('Z coordinate not in top or bottom during window creation')
return coordinates
@staticmethod
def add(self, building):
file = self._files['fenestration']
for thermal_zone in building.thermal_zones_from_internal_zones:
for index, boundary in enumerate(thermal_zone.thermal_boundaries):
building_surface_name = f'Building_{building.name}_surface_{index}'
is_exposed = boundary.parent_surface.type == cte.WALL
if boundary.parent_surface.percentage_shared is not None and boundary.parent_surface.percentage_shared > 0.5 or boundary.window_ratio == 0:
is_exposed = False
if not is_exposed:
continue
name = f'Building_{building.name}_window_{index}'
construction_name = f'{boundary.construction_name}_window_construction'
self._write_to_idf_format(file, idf_cte.WINDOW_SURFACE)
self._write_to_idf_format(file, name, 'Name')
self._write_to_idf_format(file, 'Window', 'Surface Type')
self._write_to_idf_format(file, construction_name, 'Construction Name')
self._write_to_idf_format(file, building_surface_name, 'Building Surface Name')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Outside Boundary Condition Object')
self._write_to_idf_format(file, idf_cte.AUTOCALCULATE, 'View Factor to Ground')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Frame and Divider Name')
self._write_to_idf_format(file, '1.0', 'Multiplier')
self._write_to_idf_format(file, idf_cte.AUTOCALCULATE, 'Number of Vertices')
coordinates = IdfWindow._to_window_surface(self, boundary.parent_surface)
eol = ','
coordinates_length = len(coordinates)
for i, coordinate in enumerate(coordinates):
vertex = i + 1
if vertex == coordinates_length:
eol = ';'
self._write_to_idf_format(file, coordinate[0], f'Vertex {vertex} Xcoordinate')
self._write_to_idf_format(file, coordinate[1], f'Vertex {vertex} Ycoordinate')
self._write_to_idf_format(file, coordinate[2], f'Vertex {vertex} Zcoordinate', eol)

View File

@ -1,17 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfWindowsConstructions(IdfBase):
@staticmethod
def add(self, thermal_boundary):
name = f'{thermal_boundary.construction_name}_window'
if name not in self._windows_added_to_idf:
return # Material not added or already assigned to construction
construction_name = f'{thermal_boundary.construction_name}_window_construction'
if construction_name not in self._constructions_added_to_idf:
self._constructions_added_to_idf[construction_name] = True
file = self._files['constructions']
self._write_to_idf_format(file, idf_cte.CONSTRUCTION)
self._write_to_idf_format(file, construction_name, 'Name')
self._write_to_idf_format(file, name, 'Outside Layer', ';')

View File

@ -1,15 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfWindowsMaterial(IdfBase):
@staticmethod
def add(self, thermal_boundary, thermal_opening):
name = f'{thermal_boundary.construction_name}_window'
if name not in self._windows_added_to_idf:
self._windows_added_to_idf[name] = True
file = self._files['window_materials']
self._write_to_idf_format(file, idf_cte.WINDOW_MATERIAL)
self._write_to_idf_format(file, name, 'Name')
self._write_to_idf_format(file, thermal_opening.overall_u_value, 'UFactor')
self._write_to_idf_format(file, thermal_opening.g_value, 'Solar Heat Gain Coefficient', ';')

View File

@ -1,22 +0,0 @@
import hub.exports.building_energy.idf_helper as idf_cte
from hub.exports.building_energy.idf_helper.idf_base import IdfBase
class IdfZone(IdfBase):
@staticmethod
def add(self, thermal_zone, zone_name):
file = self._files['zones']
self._write_to_idf_format(file, idf_cte.ZONE)
self._write_to_idf_format(file, zone_name, 'Name')
self._write_to_idf_format(file, 0, 'Direction of Relative North')
self._write_to_idf_format(file, 0, 'X Origin')
self._write_to_idf_format(file, 0, 'Y Origin')
self._write_to_idf_format(file, 0, 'Z Origin')
self._write_to_idf_format(file, 1, 'Type')
self._write_to_idf_format(file, 1, 'Multiplier')
self._write_to_idf_format(file, idf_cte.AUTOCALCULATE, 'Ceiling Height')
self._write_to_idf_format(file, thermal_zone.volume, 'Volume')
self._write_to_idf_format(file, idf_cte.AUTOCALCULATE, 'Floor Area')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Zone Inside Convection Algorithm')
self._write_to_idf_format(file, idf_cte.EMPTY, 'Zone Outside Convection Algorithm')
self._write_to_idf_format(file, 'Yes', 'Part of Total Floor Area', ';')

View File

@ -168,18 +168,60 @@ class InselMonthlyEnergyBalance:
parameters.append(f'{usage.hours_day} % BP(16) #6 Usage hours per day zone {i + 1}')
parameters.append(f'{usage.days_year} % BP(17) #7 Usage days per year zone {i + 1}')
# Changed location to have the value of wall area
for thermal_boundary in thermal_zone.thermal_boundaries:
type_code = _CONSTRUCTION_CODE[thermal_boundary.type]
wall_area = thermal_boundary.opaque_area * (1 + thermal_boundary.window_ratio)
if thermal_boundary.type == cte.WALL:
if thermal_boundary.parent_surface.percentage_shared is not None:
wall_area = wall_area * (1 - thermal_boundary.parent_surface.percentage_shared)
window_area = wall_area * thermal_boundary.window_ratio
parameters.append(type_code)
if thermal_boundary.type != cte.GROUND:
parameters.append(wall_area)
parameters.append('0.0')
else:
parameters.append('0.0')
parameters.append(wall_area)
parameters.append(thermal_boundary.u_value)
parameters.append(window_area)
if window_area <= 0.001:
parameters.append(0.0)
parameters.append(0.0)
parameters.append(0.0)
else:
thermal_opening = thermal_boundary.thermal_openings[0]
parameters.append(thermal_opening.frame_ratio)
parameters.append(thermal_opening.overall_u_value)
parameters.append(thermal_opening.g_value)
if thermal_boundary.type is not cte.GROUND:
parameters.append(thermal_boundary.external_surface.short_wave_reflectance)
else:
parameters.append(0.0)
# Changed location to have the value of wall area
ventilation = 0
infiltration = 0
for schedule in usage.thermal_control.hvac_availability_schedules:
ventilation_day = 0
infiltration_day = 0
new_infiltration = (internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_area_system_off * \
wall_area * 0.15) / (internal_zone.thermal_zones_from_internal_zones[0].total_floor_area *
building.average_storey_height)
for value in schedule.values:
if value == 0:
infiltration_day += internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_system_off / 24 * cte.HOUR_TO_SECONDS
#infiltration_day += internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_system_off / 24 * cte.HOUR_TO_SECONDS
infiltration_day = new_infiltration/ 24
ventilation_day += 0
else:
ventilation_value = usage.mechanical_air_change * value * cte.HOUR_TO_SECONDS
infiltration_value = internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_system_off * value * cte.HOUR_TO_SECONDS
#todo: changefactor from 0.15 to (4/50)^0.65, change of units from 50 Pa to 4 Pa.
infiltration_value = new_infiltration
#infiltration_value = internal_zone.thermal_zones_from_internal_zones[0].infiltration_rate_system_off * value * cte.HOUR_TO_SECONDS
if ventilation_value >= infiltration_value:
ventilation_day += ventilation_value / 24
infiltration_day += 0
@ -270,7 +312,7 @@ class InselMonthlyEnergyBalance:
global_irradiance = surface.global_irradiance[cte.MONTH]
for j in range(0, len(global_irradiance)):
parameters.append(f'{j + 1} '
f'{global_irradiance[j] / 24 / _NUMBER_DAYS_PER_MONTH[j]}')
f'{global_irradiance[j] * cte.WATTS_HOUR_TO_JULES / 24 / _NUMBER_DAYS_PER_MONTH[j]}')
else:
for j in range(0, 12):
parameters.append(f'{j + 1} 0.0')

View File

@ -11,7 +11,6 @@ import requests
from hub.exports.building_energy.energy_ade import EnergyAde
from hub.exports.building_energy.idf import Idf
from hub.exports.building_energy.cerc_idf import CercIdf
from hub.exports.building_energy.insel.insel_monthly_energy_balance import InselMonthlyEnergyBalance
from hub.helpers.utils import validate_import_export_type
from hub.imports.weather.helpers.weather import Weather as wh
@ -21,11 +20,9 @@ class EnergyBuildingsExportsFactory:
"""
Energy Buildings exports factory class
"""
def __init__(self, handler, city, path, custom_insel_block='d18599', target_buildings=None, weather_file=None):
def __init__(self, handler, city, path, custom_insel_block='d18599', target_buildings=None):
self._city = city
self._export_type = '_' + handler.lower()
self._weather_file = weather_file
validate_import_export_type(EnergyBuildingsExportsFactory, handler)
if isinstance(path, str):
path = Path(path)
@ -54,25 +51,13 @@ class EnergyBuildingsExportsFactory:
:return: None
"""
idf_data_path = (Path(__file__).parent / './building_energy/idf_files/').resolve()
url = wh().epw_file(self._city.region_code)
if self._weather_file is None:
self._weather_file = (Path(__file__).parent.parent / f'data/weather/epw/{url.rsplit("/", 1)[1]}').resolve()
if not self._weather_file.exists():
with open(self._weather_file, 'wb') as epw_file:
epw_file.write(requests.get(url, allow_redirects=True).content)
return Idf(self._city, self._path, (idf_data_path / 'Minimal.idf'), (idf_data_path / 'Energy+.idd'),
self._weather_file, target_buildings=self._target_buildings)
@property
def _cerc_idf(self):
idf_data_path = (Path(__file__).parent / './building_energy/idf_files/').resolve()
url = wh().epw_file(self._city.region_code)
weather_path = (Path(__file__).parent.parent / f'data/weather/epw/{url.rsplit("/", 1)[1]}').resolve()
if not weather_path.exists():
with open(weather_path, 'wb') as epw_file:
epw_file.write(requests.get(url, allow_redirects=True).content)
return CercIdf(self._city, self._path, (idf_data_path / 'base.idf'), (idf_data_path / 'Energy+.idd'), weather_path,
return Idf(self._city, self._path, (idf_data_path / 'Minimal.idf'), (idf_data_path / 'Energy+.idd'), weather_path,
target_buildings=self._target_buildings)
@property

View File

@ -77,8 +77,8 @@ class CesiumjsTileset:
'function': {
'type': 'STRING'
},
'usages': {
'type': 'LIST'
'usages_percentage': {
'type': 'STRING'
}
}
}
@ -146,7 +146,7 @@ class CesiumjsTileset:
'max_height': building.max_height,
'year_of_construction': building.year_of_construction,
'function': building.function,
'usages': building.usages
'usages_percentage': building.usages_percentage
}
},
'content': {

View File

@ -66,8 +66,8 @@ class SimplifiedRadiosityAlgorithm:
else:
i = (total_days + day - 1) * 24 + hour - 1
representative_building = self._city.buildings[0]
_global = representative_building.diffuse[cte.HOUR][i]
_beam = representative_building.direct_normal[cte.HOUR][i]
_global = representative_building.global_horizontal[cte.HOUR][i] * cte.WATTS_HOUR_TO_JULES
_beam = representative_building.beam[cte.HOUR][i] * cte.WATTS_HOUR_TO_JULES
content += f'{day} {month} {hour} {_global} {_beam}\n'
with open(file, 'w', encoding='utf-8') as file:
file.write(content)

View File

@ -10,11 +10,11 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
KELVIN = 273.15
WATER_DENSITY = 1000 # kg/m3
WATER_HEAT_CAPACITY = 4182 # J/kgK
WATER_THERMAL_CONDUCTIVITY = 0.65 # W/mK
NATURAL_GAS_LHV = 36.6e6 # J/m3
AIR_DENSITY = 1.293 # kg/m3
AIR_HEAT_CAPACITY = 1005.2 # J/kgK
# converters
HOUR_TO_MINUTES = 60
MINUTES_TO_SECONDS = 60
@ -24,7 +24,6 @@ BTU_H_TO_WATTS = 0.29307107
KILO_WATTS_HOUR_TO_JULES = 3600000
WATTS_HOUR_TO_JULES = 3600
GALLONS_TO_QUBIC_METERS = 0.0037854117954011185
INFILTRATION_75PA_TO_4PA = (4 / 75) ** 0.65
# time
SECOND = 'second'
@ -185,19 +184,6 @@ DAYS_A_MONTH = {JANUARY: 31,
NOVEMBER: 30,
DECEMBER: 31}
HOURS_A_MONTH = {JANUARY: 744,
FEBRUARY: 672,
MARCH: 744,
APRIL: 720,
MAY: 744,
JUNE: 720,
JULY: 744,
AUGUST: 744,
SEPTEMBER: 720,
OCTOBER: 744,
NOVEMBER: 720,
DECEMBER: 744}
# data types
ANY_NUMBER = 'any_number'
FRACTION = 'fraction'
@ -306,8 +292,6 @@ WOOD = 'Wood'
GAS = 'Gas'
DIESEL = 'Diesel'
COAL = 'Coal'
BIOMASS = 'Biomass'
BUTANE = 'Butane'
AIR = 'Air'
WATER = 'Water'
GEOTHERMAL = 'Geothermal'
@ -316,19 +300,9 @@ GRID = 'Grid'
ONSITE_ELECTRICITY = 'Onsite Electricity'
PHOTOVOLTAIC = 'Photovoltaic'
BOILER = 'Boiler'
FURNACE = 'Furnace'
HEAT_PUMP = 'Heat Pump'
BASEBOARD = 'Baseboard'
ELECTRICITY_GENERATOR = 'Electricity generator'
CHILLER = 'Chiller'
SPLIT = 'Split'
JOULE = 'Joule'
BUTANE_HEATER = 'Butane Heater'
SENSIBLE = 'sensible'
LATENT = 'Latent'
LITHIUMION = 'Lithium Ion'
NICD = 'NiCd'
LEADACID = 'Lead Acid'
# Geometry
EPSILON = 0.0000001

View File

@ -1,30 +0,0 @@
"""
Dictionaries module for hub function to Palma construction function
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Cecilia Pérez cperez@irec.cat
"""
import hub.helpers.constants as cte
class HubFunctionToPalmaConstructionFunction:
"""
Hub function to Palma construction function class
"""
def __init__(self):
self._dictionary = {
cte.RESIDENTIAL: 'V',
cte.SINGLE_FAMILY_HOUSE: 'Single-family building',
cte.HIGH_RISE_APARTMENT: 'Large multifamily building',
cte.MID_RISE_APARTMENT: 'Medium multifamily building',
cte.MULTI_FAMILY_HOUSE: 'Small multifamily building'
}
@property
def dictionary(self) -> dict:
"""
Get the dictionary
:return: {}
"""
return self._dictionary

View File

@ -1,51 +0,0 @@
"""
Dictionaries module for hub usage to Palma usage
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Cecilia Pérez cperez@irec.cat
"""
"""
Codification of uses from cadastre:
U: store-parking. Residential Use
S: store-parking. Industrial Use
V: Residential
I: Industrial
O: Offices
C: Comercial
K: Sportive center
T: Shows
G: Leisure and Hostelry
Y: Health and charity
E: Culture
R: Religion
M: Urbanization work, gardening and undeveloped land
P: Singular building
B: Farm warehouse
J: Farm Industry
Z: Farm-related
"""
import hub.helpers.constants as cte
class HubUsageToPalmaUsage:
"""
Hub usage to Palma usage class
"""
def __init__(self):
self._dictionary = {
cte.RESIDENTIAL: 'residential',
cte.SINGLE_FAMILY_HOUSE: 'residential',
cte.HIGH_RISE_APARTMENT: 'residential',
cte.MID_RISE_APARTMENT: 'residential',
cte.MULTI_FAMILY_HOUSE: 'residential'
}
@property
def dictionary(self) -> dict:
"""
Get the dictionary
:return: {}
"""
return self._dictionary

View File

@ -12,16 +12,11 @@ class MontrealCustomFuelToHubFuel:
"""
Montreal custom fuel to hub fuel class
"""
def __init__(self):
self._dictionary = {
'gas': cte.GAS,
'natural gas': cte.GAS,
'biomass': cte.BIOMASS,
'electricity': cte.ELECTRICITY,
'renewable': cte.RENEWABLE,
'butane': cte.BUTANE,
'diesel': cte.DIESEL
'renewable': cte.RENEWABLE
}
@property

Some files were not shown because too many files have changed in this diff Show More