Compare commits

..

1 Commits

Author SHA1 Message Date
ogavalda
1b4fcc3d94 Added thunderbay 2024-08-30 17:46:11 -04:00
107 changed files with 1721 additions and 13897 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

@ -128,12 +128,6 @@ 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_constructions = []
for archetype_construction in archetype['constructions']:
@ -159,6 +153,7 @@ class NrcanCatalog(Catalog):
_window)
archetype_constructions.append(_construction)
break
_catalog_archetypes.append(Archetype(archetype_id,
name,
function,
@ -170,10 +165,7 @@ class NrcanCatalog(Catalog):
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
))
infiltration_rate_for_ventilation_system_on))
return _catalog_archetypes
def names(self, category=None):

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

@ -23,10 +23,7 @@ class Archetype:
extra_loses_due_to_thermal_bridges,
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_for_ventilation_system_on):
self._id = archetype_id
self._name = name
self._function = function
@ -39,8 +36,6 @@ class Archetype:
self._indirect_heated_ratio = indirect_heated_ratio
self._infiltration_rate_for_ventilation_system_off = infiltration_rate_for_ventilation_system_off
self._infiltration_rate_for_ventilation_system_on = infiltration_rate_for_ventilation_system_on
self._infiltration_rate_area_for_ventilation_system_off = infiltration_rate_area_for_ventilation_system_off
self._infiltration_rate_area_for_ventilation_system_on = infiltration_rate_area_for_ventilation_system_on
@property
def id(self):
@ -138,22 +133,6 @@ class Archetype:
"""
return self._infiltration_rate_for_ventilation_system_on
@property
def infiltration_rate_area_for_ventilation_system_off(self):
"""
Get archetype infiltration rate for ventilation system off in m3/sm2
:return: float
"""
return self._infiltration_rate_area_for_ventilation_system_off
@property
def infiltration_rate_area_for_ventilation_system_on(self):
"""
Get archetype infiltration rate for ventilation system on in m3/sm2
:return: float
"""
return self._infiltration_rate_for_ventilation_system_on
def to_dictionary(self):
"""Class content to dictionary"""
_constructions = []
@ -170,8 +149,6 @@ 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,
'constructions': _constructions
}
}

View File

@ -15,20 +15,11 @@ class Archetype:
"""
Archetype class
"""
def __init__(self, name, systems):
def __init__(self, name, systems, archetype_cluster_id=None):
self._cluster_id = archetype_cluster_id
self._name = name
self._systems = systems
@property
def cluster_id(self):
"""
Get id
:return: string
"""
return self._cluster_id
@property
def name(self):
"""
@ -52,7 +43,6 @@ class Archetype:
_systems.append(_system.to_dictionary())
content = {
'Archetype': {
'cluster_id': self.cluster_id,
'name': self.name,
'systems': _systems
}

View File

@ -17,9 +17,8 @@ class PvGenerationSystem(GenerationSystem):
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):
standard_test_condition_maximum_power=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)
@ -31,7 +30,6 @@ class PvGenerationSystem(GenerationSystem):
self._nominal_radiation = nominal_radiation
self._standard_test_condition_cell_temperature = standard_test_condition_cell_temperature
self._standard_test_condition_maximum_power = standard_test_condition_maximum_power
self._standard_test_condition_radiation = standard_test_condition_radiation
self._cell_temperature_coefficient = cell_temperature_coefficient
self._width = width
self._height = height
@ -100,15 +98,6 @@ class PvGenerationSystem(GenerationSystem):
"""
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):
"""
@ -154,7 +143,6 @@ class PvGenerationSystem(GenerationSystem):
'nominal radiation [W/m2]': self.nominal_radiation,
'standard test condition cell temperature [Celsius]': self.standard_test_condition_cell_temperature,
'standard test condition maximum power [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,

View File

@ -119,7 +119,7 @@ class ThermalStorageSystem(EnergyStorageSystem):
'height [m]': self.height,
'layers': _layers,
'maximum operating temperature [Celsius]': self.maximum_operating_temperature,
'storage_medium': _medias,
'storage_medium': self.storage_medium.to_dictionary(),
'heating coil capacity [W]': self.heating_coil_capacity
}
}

View File

@ -69,10 +69,10 @@ class MontrealCustomCatalog(Catalog):
storage_system = ThermalStorageSystem(equipment_id)
storage_systems = [storage_system]
if model_name == 'PV system':
system_type = 'photovoltaic'
system_type = 'Photovoltaic'
generation_system = PvGenerationSystem(equipment_id,
name=None,
system_type=system_type,
system_type= system_type,
model_name=model_name,
electricity_efficiency=electricity_efficiency,
energy_storage_systems=storage_systems

View File

@ -30,8 +30,7 @@ class MontrealFutureSystemCatalogue(Catalog):
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'])
force_list=['pv_generation_component', 'templateStorages', 'demand'])
self._storage_components = self._load_storage_components()
self._generation_components = self._load_generation_components()
@ -50,7 +49,7 @@ class MontrealFutureSystemCatalogue(Catalog):
'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']
system_id = non_pv['system_id']
name = non_pv['name']
system_type = non_pv['system_type']
model_name = non_pv['model_name']
@ -182,7 +181,7 @@ class MontrealFutureSystemCatalogue(Catalog):
'pv_generation_component']
if pv_generation_components is not None:
for pv in pv_generation_components:
system_id = pv['generation_system_id']
system_id = pv['system_id']
name = pv['name']
system_type = pv['system_type']
model_name = pv['model_name']
@ -194,7 +193,6 @@ class MontrealFutureSystemCatalogue(Catalog):
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']
@ -217,7 +215,6 @@ class MontrealFutureSystemCatalogue(Catalog):
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,
@ -382,7 +379,6 @@ class MontrealFutureSystemCatalogue(Catalog):
_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]
@ -390,7 +386,7 @@ class MontrealFutureSystemCatalogue(Catalog):
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))
_system_archetypes.append(Archetype(name=name, systems=_systems))
return _system_archetypes
def _load_materials(self):

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

@ -10,7 +10,6 @@ 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')
@ -41,13 +40,6 @@ class EnergySystemsCatalogFactory:
"""
return MontrealFutureSystemCatalogue(self._path)
@property
def _palma(self):
"""
Retrieve Palma catalog
"""
return PalmaSystemCatalogue(self._path)
@property
def catalog(self) -> Catalog:
"""

View File

@ -98,7 +98,7 @@ class NrcanCatalog(Catalog):
domestic_hot_water_peak_flow = (
space_type['service_water_heating_peak_flow_per_area'] *
cte.GALLONS_TO_QUBIC_METERS / cte.HOUR_TO_SECONDS
)
) #m3/(s m2)
space_types_dictionary[usage_type] = {'occupancy_per_area': occupancy_density,
'lighting_per_area': lighting_density,
'electric_equipment_per_area': appliances_density,

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
@ -93,7 +92,6 @@ class Building(CityObject):
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 = {}
@property
@ -258,17 +256,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 +292,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
@ -605,6 +590,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]]:
"""
@ -738,7 +736,6 @@ class Building(CityObject):
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
parasitic_energy_consumption = 0
@ -866,10 +863,9 @@ class Building(CityObject):
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}}
fuel_breakdown = {cte.ELECTRICITY: {cte.LIGHTING: self.lighting_electrical_demand[cte.YEAR][0],
cte.APPLIANCES: self.appliances_electrical_demand[cte.YEAR][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
@ -885,8 +881,7 @@ class Building(CityObject):
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]
fuel_breakdown[cte.ELECTRICITY][f'{demand_type}'] += storage_system.heating_coil_energy_consumption[cte.YEAR][0]
#TODO: When simulation models of all energy system archetypes are created, this part can be removed
heating_fuels = []
dhw_fuels = []
@ -901,52 +896,20 @@ class Building(CityObject):
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 generation_system in energy_system.generation_systems:
fuel_breakdown[generation_system.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 generation_system in energy_system.generation_systems:
fuel_breakdown[generation_system.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]
for generation_system in energy_system.generation_systems:
fuel_breakdown[generation_system.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

@ -135,8 +135,6 @@ class InternalZone:
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

@ -157,7 +157,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 +180,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 +188,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
@ -391,7 +390,7 @@ class Surface:
@property
def global_irradiance_tilted(self) -> dict:
"""
Get global irradiance on a tilted surface in W/m2
Get global irradiance on a tilted surface in J/m2
:return: dict
"""
return self._global_irradiance_tilted
@ -399,7 +398,7 @@ class Surface:
@global_irradiance_tilted.setter
def global_irradiance_tilted(self, value):
"""
Set global irradiance on a tilted surface in W/m2
Set global irradiance on a tilted surface in J/m2
:param value: dict
"""
self._global_irradiance_tilted = value

View File

@ -20,8 +20,6 @@ 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
@property
def constructions(self) -> [Construction]:
@ -134,35 +132,3 @@ class ThermalArchetype:
:param value: float
"""
self._infiltration_rate_for_ventilation_system_on = value
@property
def infiltration_rate_area_for_ventilation_system_off(self):
"""
Get infiltration rate for ventilation system off in l/s/m2
:return: float
"""
return self._infiltration_rate_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
:param value: float
"""
self._infiltration_rate_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
:return: float
"""
return self._infiltration_rate_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
:param value: float
"""
self._infiltration_rate_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
@ -44,13 +44,15 @@ class ThermalZone:
self._indirectly_heated_area_ratio = None
self._infiltration_rate_system_on = None
self._infiltration_rate_system_off = None
self._infiltration_rate_area_system_on = None
self._infiltration_rate_area_system_off = None
self._volume = volume
self._ordinate_number = None
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 +62,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 +75,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
@ -156,24 +166,6 @@ class ThermalZone:
self._infiltration_rate_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_for_ventilation_system_off
return self._infiltration_rate_system_off
@property
def infiltration_rate_area_system_on(self):
"""
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
@property
def infiltration_rate_area_system_off(self):
"""
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
@property
def volume(self):
"""

View File

@ -22,13 +22,14 @@ class PvGenerationSystem(GenerationSystem):
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._electricity_power = None
self._tilt_angle = None
self._installed_capacity = None
self._surface_azimuth = None
self._solar_altitude_angle = None
self._solar_azimuth_angle = None
@property
def nominal_electricity_output(self):
@ -142,22 +143,6 @@ class PvGenerationSystem(GenerationSystem):
"""
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):
"""
@ -207,33 +192,49 @@ class PvGenerationSystem(GenerationSystem):
self._height = value
@property
def electricity_power_output(self):
def electricity_power(self):
"""
Get electricity_power in W
:return: float
"""
return self._electricity_power_output
return self._electricity_power
@electricity_power_output.setter
def electricity_power_output(self, value):
@electricity_power.setter
def electricity_power(self, value):
"""
Set electricity_power in W
:param value: float
"""
self._electricity_power_output = value
self._electricity_power = value
@property
def installed_capacity(self):
def tilt_angle(self):
"""
Get the total installed nominal capacity in W
Get tilt angle of PV system in degrees
:return: float
"""
return self._installed_capacity
return self._tilt_angle
@installed_capacity.setter
def installed_capacity(self, value):
@tilt_angle.setter
def tilt_angle(self, value):
"""
Set the total installed nominal capacity in W
Set PV system tilt angle in degrees
:param value: float
"""
self._installed_capacity = value
self._tilt_angle = value
@property
def surface_azimuth(self):
"""
Get surface azimuth angle of PV system in degrees. 0 is North
:return: float
"""
return self._surface_azimuth
@surface_azimuth.setter
def surface_azimuth(self, value):
"""
Set PV system tilt angle in degrees
:param value: float
"""
self._surface_azimuth = value

View File

@ -0,0 +1,18 @@
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
_path_constructions = (Path(__file__).parent / 'nrcan_constructions.json').resolve()
with open(_path_constructions, 'r', encoding='utf-8') as file:
_constructions = json.load(file)
for surface in _constructions['opaque_surfaces']:
print(surface.name)

File diff suppressed because it is too large Load Diff

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

@ -198,7 +198,7 @@
<equipments>
<generation_id>3</generation_id>
<distribution_id>8</distribution_id>
</equipments>
g </equipments>
</system>
<system id="5">
<name>Single zone packaged rooftop unit with electrical resistance furnace and baseboards and fuel boiler for acs</name>
@ -240,7 +240,7 @@
<demand>domestic_hot_water</demand>
</demands>
<equipments>
<generation_id>1</generation_id>
<generation_id>2</generation_id>
<distribution_id>3</distribution_id>
</equipments>
</system>
@ -302,7 +302,7 @@
</demands>
<equipments>
<generation_id>5</generation_id>
<distribution_id>4</distribution_id>
<distribution_id>6</distribution_id>
</equipments>
</system>
<system id="15">

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>

View File

@ -8378,6 +8378,7 @@ CA.10.08 Abitibi-Témiscamingue Abitibi-Temiscamingue 5881941
CA.04.1306 Albert County Albert County 5883098
CA.03.5883398 Alexander Alexander 5883398
CA.08.3557 Algoma Algoma 5883638
CA.08.3558 Thunder Bay Thunder Bay
CA.03.5884145 Alonsa Alonsa 5884145
CA.07.1205 Annapolis County Annapolis County 5885415
CA.07.1214 Antigonish County Antigonish County 5886183

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

@ -8,12 +8,10 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
"""
import copy
import datetime
import shutil
import subprocess
import glob
import os
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
@ -109,7 +107,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()
@ -334,7 +331,6 @@ class Idf:
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:
@ -396,9 +392,9 @@ class Idf:
thermostat = self._add_thermostat(thermal_zone)
self._idf.newidfobject(self._IDEAL_LOAD_AIR_SYSTEM,
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}',
System_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
Heating_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
Cooling_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
Template_Thermostat_Name=thermostat.Name)
def _add_occupancy(self, thermal_zone, zone_name):
@ -447,7 +443,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 +454,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 +464,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
@ -504,7 +489,7 @@ class Idf:
)
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,12 +516,11 @@ 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)
self._target_buildings.remoidf_surface_typeve(building.name)
is_target = False
continue
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
@ -565,12 +549,9 @@ class Idf:
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)
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,7 +562,7 @@ 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_infiltration(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)
@ -590,7 +571,9 @@ class Idf:
if self._export_type == "Surfaces":
if is_target:
if building.thermal_zones_from_internal_zones is not None:
start = datetime.datetime.now()
self._add_surfaces(building, building.name)
print(f'add surfaces {datetime.datetime.now() - start}')
else:
self._add_pure_geometry(building, building.name)
else:
@ -628,18 +611,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]:
@ -653,26 +624,14 @@ class Idf:
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 +700,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:
@ -775,11 +731,13 @@ class Idf:
else:
construction_name = f'{boundary.construction_name} {boundary.parent_surface.type}'
_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 +749,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,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

@ -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.diffuse[cte.HOUR][i] / cte.WATTS_HOUR_TO_JULES
_beam = representative_building.direct_normal[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

@ -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'
@ -307,7 +293,6 @@ GAS = 'Gas'
DIESEL = 'Diesel'
COAL = 'Coal'
BIOMASS = 'Biomass'
BUTANE = 'Butane'
AIR = 'Air'
WATER = 'Water'
GEOTHERMAL = 'Geothermal'
@ -316,14 +301,10 @@ 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'

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

View File

@ -15,15 +15,11 @@ class MontrealGenerationSystemToHubEnergyGenerationSystem:
def __init__(self):
self._dictionary = {
'boiler': cte.BOILER,
'furnace': cte.FURNACE,
'furnace': cte.BASEBOARD,
'cooler': cte.CHILLER,
'electricity generator': cte.ELECTRICITY_GENERATOR,
'photovoltaic': cte.PHOTOVOLTAIC,
'heat pump': cte.HEAT_PUMP,
'joule': cte.JOULE,
'split': cte.SPLIT,
'butane heater': cte.BUTANE_HEATER
'PV system': cte.PHOTOVOLTAIC,
'heat pump': cte.HEAT_PUMP
}
@property

View File

@ -1,31 +0,0 @@
"""
Dictionaries module for Palma function to hub 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 PalmaFunctionToHubFunction:
"""
Palma function to hub function class
"""
def __init__(self):
self._dictionary = {'Residential': cte.RESIDENTIAL,
'Single-family building': cte.SINGLE_FAMILY_HOUSE,
'Large multifamily building': cte.HIGH_RISE_APARTMENT,
'Medium multifamily building': cte.MID_RISE_APARTMENT,
'Small multifamily building': cte.MULTI_FAMILY_HOUSE,
'V': cte.RESIDENTIAL
}
@property
def dictionary(self) -> dict:
"""
Get the dictionary
:return: {}
"""
return self._dictionary

View File

@ -26,9 +26,6 @@ from hub.helpers.data.north_america_demand_type_to_hub_energy_demand_type import
from hub.helpers.data.north_america_system_to_hub_energy_generation_system import NorthAmericaSystemToHubEnergyGenerationSystem
from hub.helpers.data.north_america_custom_fuel_to_hub_fuel import NorthAmericaCustomFuelToHubFuel
from hub.helpers.data.north_america_storage_system_to_hub_storage import NorthAmericaStorageSystemToHubEnergyStorage
from hub.helpers.data.palma_function_to_hub_function import PalmaFunctionToHubFunction
from hub.helpers.data.hub_usage_to_palma_usage import HubUsageToPalmaUsage
from hub.helpers.data.hub_function_to_palma_construction_function import HubFunctionToPalmaConstructionFunction
class Dictionaries:
@ -68,14 +65,6 @@ class Dictionaries:
"""
return HubUsageToEilatUsage().dictionary
@property
def hub_usage_to_palma_usage(self) -> dict:
"""
Hub usage to Palma usage, transformation dictionary
:return: dict
"""
return HubUsageToPalmaUsage().dictionary
@property
def hub_function_to_nrcan_construction_function(self) -> dict:
"""
@ -99,13 +88,6 @@ class Dictionaries:
:return: dict
"""
return HubFunctionToNrelConstructionFunction().dictionary
@property
def hub_function_to_palma_construction_function(self) -> dict:
"""
Get hub function to Palma construction function, transformation dictionary
:return: dict
"""
return HubFunctionToPalmaConstructionFunction().dictionary
@property
def pluto_function_to_hub_function(self) -> dict:
@ -123,14 +105,6 @@ class Dictionaries:
"""
return HftFunctionToHubFunction().dictionary
@property
def palma_function_to_hub_function(self) -> dict:
"""
Get Palma function to hub function, transformation dictionary
:return: dict
"""
return PalmaFunctionToHubFunction().dictionary
@property
def montreal_function_to_hub_function(self) -> dict:
"""

View File

@ -1,31 +0,0 @@
class ListUsageToHub:
"""
Eilat function to hub function class
"""
def __init__(self, function_dictionary=None):
self._function_dictionary = function_dictionary
def _apply_function_dictionary(self, usages):
function_dictionary = self._function_dictionary
if function_dictionary is not None:
for usage in usages:
if usage['usage'] in function_dictionary:
usage['usage'] = function_dictionary[usage['usage']]
return usages
def parse(self, usages) -> list[dict]:
"""
Get the dictionary
:return: {}
"""
usages = [{"usage": str(i["usage"]), "ratio": float(i["ratio"])} for i in usages]
usages = self._apply_function_dictionary(usages)
return usages

View File

@ -1,19 +0,0 @@
class StringUsageToHub:
"""
Eilat function to hub function class
"""
def parse(self, usages) -> list[dict]:
"""
Parse usage string in form residential-80_commercial-20
:usages: str
:return: {}
"""
parsed_usages = []
for usage in usages.split('_'):
usage_dict = {"usage": str(usage.split('-')[0]), "ratio": float(usage.split('-')[1])/100}
parsed_usages.append(usage_dict)
return parsed_usages

View File

@ -1,31 +0,0 @@
"""
Dictionaries module saves all transformations of functions and usages to access the catalogs
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.helpers.parsers.list_usage_to_hub import ListUsageToHub
from hub.helpers.parsers.string_usage_to_hub import StringUsageToHub
class UsageParsers:
"""
Dictionaries class
"""
@staticmethod
def string_usage_to_hub() -> object:
"""
Hub usage to HfT usage, transformation dictionary
:return: dict
"""
return StringUsageToHub().parse
@staticmethod
def list_usage_to_hub(function_dictionary=None) -> object:
"""
Hub usage to HfT usage, transformation dictionary
:return: dict
"""
return ListUsageToHub(function_dictionary).parse

View File

@ -58,17 +58,14 @@ class ConstructionHelper:
'Boucherville': '6',
'Mascouche': '6',
'Saint-Leonard': '6',
'La Prairie': '6'
'La Prairie': '6',
'Thunder Bay': '7B'
}
_reference_city_to_israel_climate_zone = {
'Eilat': 'BWh'
}
_reference_city_to_palma_climate_zone ={
'Palma': 'B3'
}
@staticmethod
def yoc_to_nrel_standard(year_of_construction):
"""
@ -111,13 +108,3 @@ class ConstructionHelper:
:return: str
"""
return ConstructionHelper._reference_city_to_israel_climate_zone[reference_city]
@staticmethod
def city_to_palma_climate_zone(reference_city):
"""
City name to Palma climate zone
:param reference_city: str
:return: str
"""
return ConstructionHelper._reference_city_to_palma_climate_zone[reference_city]

View File

@ -3,7 +3,6 @@ NrcanPhysicsParameters import the construction and material information defined
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Project Collaborator Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import logging
@ -68,8 +67,6 @@ class NrcanPhysicsParameters:
thermal_archetype.indirect_heated_ratio = 0
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
thermal_archetype.infiltration_rate_area_for_ventilation_system_on = catalog_archetype.infiltration_rate_area_for_ventilation_system_on
thermal_archetype.infiltration_rate_area_for_ventilation_system_off = catalog_archetype.infiltration_rate_area_for_ventilation_system_off
_constructions = []
for catalog_construction in catalog_archetype.constructions:
construction = Construction()

View File

@ -1,107 +0,0 @@
"""
PalmaPhysicsParameters import the construction and material information defined by Palma
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Cecilia Pérez Pérez cperez@irec.cat
"""
import logging
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
from hub.city_model_structure.building_demand.thermal_archetype import ThermalArchetype
from hub.city_model_structure.building_demand.construction import Construction
from hub.city_model_structure.building_demand.layer import Layer
from hub.helpers.dictionaries import Dictionaries
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
class PalmaPhysicsParameters:
"""
PalmaPhysicsParameters class
"""
def __init__(self, city, divide_in_storeys=False):
self._city = city
self._divide_in_storeys = divide_in_storeys
self._climate_zone = ConstructionHelper.city_to_palma_climate_zone(city.climate_reference_city)
def enrich_buildings(self):
"""
Returns the city with the construction parameters assigned to the buildings
"""
city = self._city
palma_catalog = ConstructionCatalogFactory('palma').catalog
for building in city.buildings:
if building.function not in Dictionaries().hub_function_to_palma_construction_function:
logging.error('Building %s has an unknown building function %s', building.name, building.function)
continue
function = Dictionaries().hub_function_to_palma_construction_function[building.function]
try:
archetype = self._search_archetype(palma_catalog, function, building.year_of_construction, self._climate_zone)
except KeyError:
logging.error('Building %s has unknown construction archetype for building function: %s '
'[%s], building year of construction: %s and climate zone %s', building.name, function,
building.function, building.year_of_construction, self._climate_zone)
continue
thermal_archetype = ThermalArchetype()
self._assign_values(thermal_archetype, archetype)
for internal_zone in building.internal_zones:
internal_zone.thermal_archetype = thermal_archetype
@staticmethod
def _search_archetype(nrcan_catalog, function, year_of_construction, climate_zone):
nrcan_archetypes = nrcan_catalog.entries('archetypes')
for building_archetype in nrcan_archetypes:
construction_period_limits = building_archetype.construction_period.split('_')
if int(construction_period_limits[0]) <= int(year_of_construction) <= int(construction_period_limits[1]):
if str(function) == str(building_archetype.function) and climate_zone == str(building_archetype.climate_zone):
return building_archetype
raise KeyError('archetype not found')
@staticmethod
def _assign_values(thermal_archetype, catalog_archetype):
thermal_archetype.average_storey_height = catalog_archetype.average_storey_height
thermal_archetype.extra_loses_due_to_thermal_bridges = catalog_archetype.extra_loses_due_to_thermal_bridges
thermal_archetype.thermal_capacity = catalog_archetype.thermal_capacity
thermal_archetype.indirect_heated_ratio = 0
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
thermal_archetype.infiltration_rate_area_for_ventilation_system_on = catalog_archetype.infiltration_rate_area_for_ventilation_system_on
thermal_archetype.infiltration_rate_area_for_ventilation_system_off = catalog_archetype.infiltration_rate_area_for_ventilation_system_off
_constructions = []
for catalog_construction in catalog_archetype.constructions:
construction = Construction()
construction.type = catalog_construction.type
construction.name = catalog_construction.name
if catalog_construction.window_ratio is not None:
for _orientation in catalog_construction.window_ratio:
if catalog_construction.window_ratio[_orientation] is None:
catalog_construction.window_ratio[_orientation] = 0
construction.window_ratio = catalog_construction.window_ratio
_layers = []
for layer_archetype in catalog_construction.layers:
layer = Layer()
layer.thickness = layer_archetype.thickness
archetype_material = layer_archetype.material
layer.material_name = archetype_material.name
layer.no_mass = archetype_material.no_mass
if archetype_material.no_mass:
layer.thermal_resistance = archetype_material.thermal_resistance
else:
layer.density = archetype_material.density
layer.conductivity = archetype_material.conductivity
layer.specific_heat = archetype_material.specific_heat
layer.solar_absorptance = archetype_material.solar_absorptance
layer.thermal_absorptance = archetype_material.thermal_absorptance
layer.visible_absorptance = archetype_material.visible_absorptance
_layers.append(layer)
construction.layers = _layers
if catalog_construction.window is not None:
window_archetype = catalog_construction.window
construction.window_type = window_archetype.name
construction.window_frame_ratio = window_archetype.frame_ratio
construction.window_g_value = window_archetype.g_value
construction.window_overall_u_value = window_archetype.overall_u_value
_constructions.append(construction)
thermal_archetype.constructions = _constructions

View File

@ -10,7 +10,6 @@ from hub.helpers.utils import validate_import_export_type
from hub.imports.construction.nrcan_physics_parameters import NrcanPhysicsParameters
from hub.imports.construction.nrel_physics_parameters import NrelPhysicsParameters
from hub.imports.construction.eilat_physics_parameters import EilatPhysicsParameters
from hub.imports.construction.palma_physics_parameters import PalmaPhysicsParameters
class ConstructionFactory:
@ -49,15 +48,6 @@ class ConstructionFactory:
for building in self._city.buildings:
building.level_of_detail.construction = 2
def _palma(self):
"""
Enrich the city by using Palma information
"""
PalmaPhysicsParameters(self._city).enrich_buildings()
self._city.level_of_detail.construction = 2
for building in self._city.buildings:
building.level_of_detail.construction = 2
def enrich(self):
"""
Enrich the city given to the class using the class given handler

View File

@ -3,7 +3,6 @@ Montreal custom energy system importer
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Project Contributor Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import logging
@ -84,9 +83,9 @@ class MontrealCustomEnergySystemParameters:
def _create_generation_systems(archetype_system):
_generation_systems = []
for archetype_generation_system in archetype_system.generation_systems:
if archetype_generation_system.system_type == 'photovoltaic':
if archetype_generation_system.system_type == 'Photovoltaic':
_generation_system = PvGenerationSystem()
_type = archetype_generation_system.system_type
_type = 'PV system'
_generation_system.system_type = Dictionaries().montreal_generation_system_to_hub_energy_generation_system[
_type]
_fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type]
@ -137,13 +136,13 @@ class MontrealCustomEnergySystemParameters:
_distribution_system.distribution_consumption_variable_flow = \
archetype_distribution_system.distribution_consumption_variable_flow
_distribution_system.heat_losses = archetype_distribution_system.heat_losses
_generic_emission_system = None
_emission_system = None
if archetype_distribution_system.emission_systems is not None:
_emission_systems = []
for emission_system in archetype_distribution_system.emission_systems:
_generic_emission_system = EmissionSystem()
_generic_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_generic_emission_system)
_emission_system = EmissionSystem()
_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_emission_system)
_distribution_system.emission_systems = _emission_systems
_distribution_systems.append(_distribution_system)
return _distribution_systems

View File

@ -43,7 +43,6 @@ class MontrealFutureEnergySystemParameters:
archetype_name = building.energy_systems_archetype_name
try:
archetype = self._search_archetypes(montreal_custom_catalog, archetype_name)
building.energy_systems_archetype_cluster_id = archetype.cluster_id
except KeyError:
logging.error('Building %s has unknown energy system archetype for system name %s', building.name,
archetype_name)
@ -88,12 +87,12 @@ class MontrealFutureEnergySystemParameters:
archetype_generation_systems = archetype_system.generation_systems
if archetype_generation_systems is not None:
for archetype_generation_system in archetype_system.generation_systems:
if archetype_generation_system.system_type == 'photovoltaic':
if archetype_generation_system.system_type == 'Photovoltaic':
_generation_system = PvGenerationSystem()
_generation_system.name = archetype_generation_system.name
_generation_system.model_name = archetype_generation_system.model_name
_generation_system.manufacturer = archetype_generation_system.manufacturer
_type = archetype_generation_system.system_type
_type = 'PV system'
_generation_system.system_type = Dictionaries().montreal_generation_system_to_hub_energy_generation_system[_type]
_fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type]
_generation_system.fuel_type = _fuel_type
@ -104,21 +103,15 @@ class MontrealFutureEnergySystemParameters:
_generation_system.nominal_radiation = archetype_generation_system.nominal_radiation
_generation_system.standard_test_condition_cell_temperature = archetype_generation_system.standard_test_condition_cell_temperature
_generation_system.standard_test_condition_maximum_power = archetype_generation_system.standard_test_condition_maximum_power
_generation_system.standard_test_condition_radiation = archetype_generation_system.standard_test_condition_radiation
_generation_system.cell_temperature_coefficient = archetype_generation_system.cell_temperature_coefficient
_generation_system.width = archetype_generation_system.width
_generation_system.height = archetype_generation_system.height
_generation_system.tilt_angle = self._city.latitude
_generic_storage_system = None
if archetype_generation_system.energy_storage_systems is not None:
_storage_systems = []
for storage_system in archetype_generation_system.energy_storage_systems:
if storage_system.type_energy_stored == 'electrical':
_generic_storage_system = ElectricalStorageSystem()
_generic_storage_system.type_energy_stored = 'electrical'
_storage_systems.append(_generic_storage_system)
_generation_system.energy_storage_systems = _storage_systems
_generation_system.energy_storage_systems = [_generic_storage_system]
else:
_generation_system = NonPvGenerationSystem()
_generation_system.name = archetype_generation_system.name
@ -126,7 +119,7 @@ class MontrealFutureEnergySystemParameters:
_generation_system.manufacturer = archetype_generation_system.manufacturer
_type = archetype_generation_system.system_type
_generation_system.system_type = Dictionaries().montreal_generation_system_to_hub_energy_generation_system[_type]
_fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type]
_fuel_type = Dictionaries().north_america_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type]
_generation_system.fuel_type = _fuel_type
_generation_system.nominal_heat_output = archetype_generation_system.nominal_heat_output
_generation_system.nominal_cooling_output = archetype_generation_system.nominal_cooling_output
@ -192,13 +185,13 @@ class MontrealFutureEnergySystemParameters:
_distribution_system.distribution_consumption_variable_flow = \
archetype_distribution_system.distribution_consumption_variable_flow
_distribution_system.heat_losses = archetype_distribution_system.heat_losses
_generic_emission_system = None
_emission_system = None
if archetype_distribution_system.emission_systems is not None:
_emission_systems = []
for emission_system in archetype_distribution_system.emission_systems:
_generic_emission_system = EmissionSystem()
_generic_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_generic_emission_system)
_emission_system = EmissionSystem()
_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_emission_system)
_distribution_system.emission_systems = _emission_systems
_distribution_systems.append(_distribution_system)
return _distribution_systems

View File

@ -1,216 +0,0 @@
"""
Montreal future system importer
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import logging
import copy
from hub.catalog_factories.energy_systems_catalog_factory import EnergySystemsCatalogFactory
from hub.city_model_structure.energy_systems.energy_system import EnergySystem
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.electrical_storage_system import ElectricalStorageSystem
from hub.city_model_structure.energy_systems.thermal_storage_system import ThermalStorageSystem
from hub.city_model_structure.energy_systems.emission_system import EmissionSystem
from hub.helpers.dictionaries import Dictionaries
class PalmaEnergySystemParameters:
"""
MontrealCustomEnergySystemParameters class
"""
def __init__(self, city):
self._city = city
def enrich_buildings(self):
"""
Returns the city with the system parameters assigned to the buildings
:return:
"""
city = self._city
montreal_custom_catalog = EnergySystemsCatalogFactory('palma').catalog
if city.generic_energy_systems is None:
_generic_energy_systems = {}
else:
_generic_energy_systems = city.generic_energy_systems
for building in city.buildings:
archetype_name = building.energy_systems_archetype_name
try:
archetype = self._search_archetypes(montreal_custom_catalog, archetype_name)
except KeyError:
logging.error('Building %s has unknown energy system archetype for system name %s', building.name,
archetype_name)
continue
if archetype.name not in _generic_energy_systems:
_generic_energy_systems = self._create_generic_systems_list(archetype, _generic_energy_systems)
city.generic_energy_systems = _generic_energy_systems
self._assign_energy_systems_to_buildings(city)
@staticmethod
def _search_archetypes(catalog, name):
archetypes = catalog.entries('archetypes')
for building_archetype in archetypes:
if str(name) == str(building_archetype.name):
return building_archetype
raise KeyError('archetype not found')
def _create_generic_systems_list(self, archetype, _generic_energy_systems):
building_systems = []
for archetype_system in archetype.systems:
energy_system = EnergySystem()
_hub_demand_types = []
for demand_type in archetype_system.demand_types:
_hub_demand_types.append(Dictionaries().montreal_demand_type_to_hub_energy_demand_type[demand_type])
energy_system.name = archetype_system.name
energy_system.demand_types = _hub_demand_types
energy_system.configuration_schema = archetype_system.configuration_schema
energy_system.generation_systems = self._create_generation_systems(archetype_system)
if energy_system.distribution_systems is not None:
energy_system.distribution_systems = self._create_distribution_systems(archetype_system)
building_systems.append(energy_system)
_generic_energy_systems[archetype.name] = building_systems
return _generic_energy_systems
def _create_generation_systems(self, archetype_system):
_generation_systems = []
archetype_generation_systems = archetype_system.generation_systems
if archetype_generation_systems is not None:
for archetype_generation_system in archetype_system.generation_systems:
if archetype_generation_system.system_type == 'photovoltaic':
_generation_system = PvGenerationSystem()
_generation_system.name = archetype_generation_system.name
_generation_system.model_name = archetype_generation_system.model_name
_generation_system.manufacturer = archetype_generation_system.manufacturer
_type = archetype_generation_system.system_type
_generation_system.system_type = Dictionaries().montreal_generation_system_to_hub_energy_generation_system[_type]
_fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type]
_generation_system.fuel_type = _fuel_type
_generation_system.electricity_efficiency = archetype_generation_system.electricity_efficiency
_generation_system.nominal_electricity_output = archetype_generation_system.nominal_electricity_output
_generation_system.nominal_ambient_temperature = archetype_generation_system.nominal_ambient_temperature
_generation_system.nominal_cell_temperature = archetype_generation_system.nominal_cell_temperature
_generation_system.nominal_radiation = archetype_generation_system.nominal_radiation
_generation_system.standard_test_condition_cell_temperature = archetype_generation_system.standard_test_condition_cell_temperature
_generation_system.standard_test_condition_maximum_power = archetype_generation_system.standard_test_condition_maximum_power
_generation_system.standard_test_condition_radiation = archetype_generation_system.standard_test_condition_radiation
_generation_system.cell_temperature_coefficient = archetype_generation_system.cell_temperature_coefficient
_generation_system.width = archetype_generation_system.width
_generation_system.height = archetype_generation_system.height
_generation_system.tilt_angle = self._city.latitude
_generic_storage_system = None
if archetype_generation_system.energy_storage_systems is not None:
_storage_systems = []
for storage_system in archetype_generation_system.energy_storage_systems:
if storage_system.type_energy_stored == 'electrical':
_generic_storage_system = ElectricalStorageSystem()
_generic_storage_system.type_energy_stored = 'electrical'
_storage_systems.append(_generic_storage_system)
_generation_system.energy_storage_systems = _storage_systems
else:
_generation_system = NonPvGenerationSystem()
_generation_system.name = archetype_generation_system.name
_generation_system.model_name = archetype_generation_system.model_name
_generation_system.manufacturer = archetype_generation_system.manufacturer
_type = archetype_generation_system.system_type
_generation_system.system_type = Dictionaries().montreal_generation_system_to_hub_energy_generation_system[_type]
_fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type]
_generation_system.fuel_type = _fuel_type
_generation_system.nominal_heat_output = archetype_generation_system.nominal_heat_output
_generation_system.nominal_cooling_output = archetype_generation_system.nominal_cooling_output
_generation_system.maximum_heat_output = archetype_generation_system.maximum_heat_output
_generation_system.minimum_heat_output = archetype_generation_system.minimum_heat_output
_generation_system.maximum_cooling_output = archetype_generation_system.maximum_cooling_output
_generation_system.minimum_cooling_output = archetype_generation_system.minimum_cooling_output
_generation_system.source_temperature = archetype_generation_system.source_temperature
_generation_system.source_mass_flow = archetype_generation_system.source_mass_flow
_generation_system.supply_medium = archetype_generation_system.supply_medium
_generation_system.maximum_heat_supply_temperature = archetype_generation_system.maximum_heat_supply_temperature
_generation_system.maximum_cooling_supply_temperature = archetype_generation_system.maximum_cooling_supply_temperature
_generation_system.minimum_heat_supply_temperature = archetype_generation_system.minimum_heat_supply_temperature
_generation_system.minimum_cooling_supply_temperature = archetype_generation_system.minimum_cooling_supply_temperature
_generation_system.heat_output_curve = archetype_generation_system.heat_output_curve
_generation_system.heat_fuel_consumption_curve = archetype_generation_system.heat_fuel_consumption_curve
_generation_system.heat_efficiency_curve = archetype_generation_system.heat_efficiency_curve
_generation_system.cooling_output_curve = archetype_generation_system.cooling_output_curve
_generation_system.cooling_fuel_consumption_curve = archetype_generation_system.cooling_fuel_consumption_curve
_generation_system.cooling_efficiency_curve = archetype_generation_system.cooling_efficiency_curve
_generation_system.domestic_hot_water = archetype_generation_system.domestic_hot_water
_generation_system.nominal_electricity_output = archetype_generation_system.nominal_electricity_output
_generation_system.source_medium = archetype_generation_system.source_medium
_generation_system.heat_efficiency = archetype_generation_system.heat_efficiency
_generation_system.cooling_efficiency = archetype_generation_system.cooling_efficiency
_generation_system.electricity_efficiency = archetype_generation_system.electricity_efficiency
_generation_system.reversibility = archetype_generation_system.reversibility
_generic_storage_system = None
if archetype_generation_system.energy_storage_systems is not None:
_storage_systems = []
for storage_system in archetype_generation_system.energy_storage_systems:
if storage_system.type_energy_stored == 'electrical':
_generic_storage_system = ElectricalStorageSystem()
_generic_storage_system.type_energy_stored = 'electrical'
else:
_generic_storage_system = ThermalStorageSystem()
_generic_storage_system.type_energy_stored = storage_system.type_energy_stored
_generic_storage_system.height = storage_system.height
_generic_storage_system.layers = storage_system.layers
_generic_storage_system.storage_medium = storage_system.storage_medium
_generic_storage_system.heating_coil_capacity = storage_system.heating_coil_capacity
_storage_systems.append(_generic_storage_system)
_generation_system.energy_storage_systems = _storage_systems
if archetype_generation_system.domestic_hot_water:
_generation_system.domestic_hot_water = True
if archetype_generation_system.reversibility:
_generation_system.reversibility = True
if archetype_generation_system.simultaneous_heat_cold:
_generation_system.simultaneous_heat_cold = True
_generation_systems.append(_generation_system)
return _generation_systems
@staticmethod
def _create_distribution_systems(archetype_system):
_distribution_systems = []
archetype_distribution_systems = archetype_system.distribution_systems
if archetype_distribution_systems is not None:
for archetype_distribution_system in archetype_system.distribution_systems:
_distribution_system = DistributionSystem()
_distribution_system.type = archetype_distribution_system.type
_distribution_system.distribution_consumption_fix_flow = \
archetype_distribution_system.distribution_consumption_fix_flow
_distribution_system.distribution_consumption_variable_flow = \
archetype_distribution_system.distribution_consumption_variable_flow
_distribution_system.heat_losses = archetype_distribution_system.heat_losses
_generic_emission_system = None
if archetype_distribution_system.emission_systems is not None:
_emission_systems = []
for emission_system in archetype_distribution_system.emission_systems:
_generic_emission_system = EmissionSystem()
_generic_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_generic_emission_system)
_distribution_system.emission_systems = _emission_systems
_distribution_systems.append(_distribution_system)
return _distribution_systems
@staticmethod
def _assign_energy_systems_to_buildings(city):
for building in city.buildings:
_building_energy_systems = []
energy_systems_cluster_name = building.energy_systems_archetype_name
if str(energy_systems_cluster_name) == 'nan':
break
_generic_building_energy_systems = city.generic_energy_systems[energy_systems_cluster_name]
for _generic_building_energy_system in _generic_building_energy_systems:
_building_energy_systems.append(copy.deepcopy(_generic_building_energy_system))
building.energy_systems = _building_energy_systems

View File

@ -11,7 +11,6 @@ from hub.helpers.utils import validate_import_export_type
from hub.imports.energy_systems.montreal_custom_energy_system_parameters import MontrealCustomEnergySystemParameters
from hub.imports.energy_systems.north_america_custom_energy_system_parameters import NorthAmericaCustomEnergySystemParameters
from hub.imports.energy_systems.montreal_future_energy_systems_parameters import MontrealFutureEnergySystemParameters
from hub.imports.energy_systems.palma_energy_systems_parameters import PalmaEnergySystemParameters
class EnergySystemsFactory:
"""
@ -53,15 +52,6 @@ class EnergySystemsFactory:
for building in self._city.buildings:
building.level_of_detail.energy_systems = 2
def _palma(self):
"""
Enrich the city by using north america custom energy systems catalog information
"""
PalmaEnergySystemParameters(self._city).enrich_buildings()
self._city.level_of_detail.energy_systems = 2
for building in self._city.buildings:
building.level_of_detail.energy_systems = 2
def enrich(self):
"""
Enrich the city given to the class using the class given handler

View File

@ -35,8 +35,6 @@ class Geojson:
year_of_construction_field=None,
function_field=None,
function_to_hub=None,
usages_field=None,
usages_to_hub=None,
hub_crs=None
):
self._hub_crs = hub_crs
@ -54,8 +52,6 @@ class Geojson:
self._year_of_construction_field = year_of_construction_field
self._function_field = function_field
self._function_to_hub = function_to_hub
self._usages_field = usages_field
self._usages_to_hub = usages_to_hub
with open(path, 'r', encoding='utf8') as json_file:
self._geojson = json.loads(json_file.read())
@ -121,36 +117,24 @@ class Geojson:
lod = 0
for feature in self._geojson['features']:
extrusion_height = 0
if self._extrusion_height_field is not None:
extrusion_height = float(feature['properties'][self._extrusion_height_field])
lod = 1
self._max_z = max(self._max_z, extrusion_height)
year_of_construction = None
if self._year_of_construction_field is not None:
year_of_construction = int(feature['properties'][self._year_of_construction_field])
function = None
if self._function_field is not None:
function = str(feature['properties'][self._function_field])
if self._function_to_hub is not None:
# use the transformation dictionary to retrieve the proper function
if function in self._function_to_hub:
function = self._function_to_hub[function]
usages = None
if self._usages_field is not None:
if self._usages_field in feature['properties']:
usages = feature['properties'][self._usages_field]
if self._usages_to_hub is not None:
usages = self._usages_to_hub(usages)
geometry = feature['geometry']
building_aliases = []
if 'id' in feature:
building_name = feature['id']
elif 'id' in feature['properties']:
building_name = feature['properties']['id']
else:
building_name = uuid.uuid4()
if self._aliases_field is not None:
@ -163,7 +147,6 @@ class Geojson:
building_name,
building_aliases,
function,
usages,
year_of_construction,
extrusion_height))
@ -172,7 +155,6 @@ class Geojson:
building_name,
building_aliases,
function,
usages,
year_of_construction,
extrusion_height))
else:
@ -198,7 +180,7 @@ class Geojson:
transformed_coordinates = f'{transformed_coordinates} {transformed[self._X]} {transformed[self._Y]} 0.0'
return transformed_coordinates.lstrip(' ')
def _parse_polygon(self, coordinates, building_name, building_aliases, function, usages, year_of_construction, extrusion_height):
def _parse_polygon(self, coordinates, building_name, building_aliases, function, year_of_construction, extrusion_height):
surfaces = []
for polygon_coordinates in coordinates:
points = igh.points_from_string(
@ -231,7 +213,7 @@ class Geojson:
polygon = Polygon(coordinates)
polygon.area = igh.ground_area(coordinates)
surfaces[-1] = Surface(polygon, polygon)
building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
building = Building(f'{building_name}', surfaces, year_of_construction, function)
for alias in building_aliases:
building.add_alias(alias)
if extrusion_height == 0:
@ -266,13 +248,13 @@ class Geojson:
polygon = Polygon(wall_coordinates)
wall = Surface(polygon, polygon)
surfaces.append(wall)
building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
building = Building(f'{building_name}', surfaces, year_of_construction, function)
for alias in building_aliases:
building.add_alias(alias)
building.volume = volume
return building
def _parse_multi_polygon(self, polygons_coordinates, building_name, building_aliases, function, usages, year_of_construction, extrusion_height):
def _parse_multi_polygon(self, polygons_coordinates, building_name, building_aliases, function, year_of_construction, extrusion_height):
surfaces = []
for coordinates in polygons_coordinates:
for polygon_coordinates in coordinates:
@ -305,7 +287,7 @@ class Geojson:
polygon = Polygon(coordinates)
polygon.area = igh.ground_area(coordinates)
surfaces[-1] = Surface(polygon, polygon)
building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
building = Building(f'{building_name}', surfaces, year_of_construction, function)
for alias in building_aliases:
building.add_alias(alias)
if extrusion_height == 0:
@ -340,7 +322,7 @@ class Geojson:
polygon = Polygon(wall_coordinates)
wall = Surface(polygon, polygon)
surfaces.append(wall)
building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
building = Building(f'{building_name}', surfaces, year_of_construction, function)
for alias in building_aliases:
building.add_alias(alias)
building.volume = volume

View File

@ -23,8 +23,6 @@ class GeometryFactory:
year_of_construction_field=None,
function_field=None,
function_to_hub=None,
usages_field=None,
usages_to_hub=None,
hub_crs=None):
self._file_type = '_' + file_type.lower()
validate_import_export_type(GeometryFactory, file_type)
@ -34,8 +32,6 @@ class GeometryFactory:
self._year_of_construction_field = year_of_construction_field
self._function_field = function_field
self._function_to_hub = function_to_hub
self._usages_field = usages_field
self._usages_to_hub = usages_to_hub
self._hub_crs = hub_crs
@property
@ -70,8 +66,6 @@ class GeometryFactory:
self._year_of_construction_field,
self._function_field,
self._function_to_hub,
self._usages_field,
self._usages_to_hub,
self._hub_crs).city
@property

View File

@ -1,12 +1,14 @@
"""
Cerc Idf result import
Insel monthly energy balance
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Guillermo.GutierrezMorote@concordia.ca
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
Project collaborator Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from pathlib import Path
import csv
from hub.helpers.monthly_values import MonthlyValues
import hub.helpers.constants as cte
@ -14,33 +16,62 @@ class EnergyPlus:
"""
Energy plus class
"""
def _extract_fields_from_headers(self, headers):
for header in headers:
header_parts = header.split(':')
building_name = header_parts[0]
variable = ':'.join(header_parts[1:]).strip() # concat the rest and ensure that : it's reintroduced just in case
if variable == '':
continue
if building_name not in self._summary_variables:
self._building_energy_demands[variable] = [] # initialize the list of variables
else:
self._building_energy_demands[header] = []
def __init__(self, city, file_path):
def __init__(self, city, base_path):
self._city = city
self._building_energy_demands = {}
self._lines = []
self._summary_variables = ['DistrictCooling:Facility [J](Hourly)',
'InteriorEquipment:Electricity [J](Hourly)',
'InteriorLights:Electricity [J](Hourly) ']
self._base_path = base_path
with open(file_path, 'r', encoding='utf8') as csv_file:
@staticmethod
def _building_energy_demands(energy_plus_output_file_path):
with open(Path(energy_plus_output_file_path).resolve(), 'r', encoding='utf8') as csv_file:
csv_output = csv.reader(csv_file)
self._headers = next(csv_output)
self._extract_fields_from_headers(self._headers)
headers = next(csv_output)
building_energy_demands = {
'Heating (J)': [],
'Cooling (J)': [],
'DHW (J)': [],
'Appliances (J)': [],
'Lighting (J)': []
}
heating_column_index = []
cooling_column_index = []
dhw_column_index = []
appliance_column_index = []
lighting_column_index = []
for index, header in enumerate(headers):
if "Total Heating" in header:
heating_column_index.append(index)
elif "Total Cooling" in header:
cooling_column_index.append(index)
elif "DHW" in header:
dhw_column_index.append(index)
elif "InteriorEquipment" in header:
appliance_column_index.append(index)
elif "InteriorLights" in header:
lighting_column_index.append(index)
for line in csv_output:
self._lines.append(line)
total_heating_demand = 0
total_cooling_demand = 0
total_dhw_demand = 0
total_appliance_demand = 0
total_lighting_demand = 0
for heating_index in heating_column_index:
total_heating_demand += float(line[heating_index])
building_energy_demands['Heating (J)'].append(total_heating_demand)
for cooling_index in cooling_column_index:
total_cooling_demand += float(line[cooling_index])
building_energy_demands['Cooling (J)'].append(total_cooling_demand)
for dhw_index in dhw_column_index:
total_dhw_demand += float(line[dhw_index]) * 3600
building_energy_demands['DHW (J)'].append(total_dhw_demand)
for appliance_index in appliance_column_index:
total_appliance_demand += float(line[appliance_index])
building_energy_demands['Appliances (J)'].append(total_appliance_demand)
for lighting_index in lighting_column_index:
total_lighting_demand += float(line[lighting_index])
building_energy_demands['Lighting (J)'].append(total_lighting_demand)
return building_energy_demands
def enrich(self):
"""
@ -48,58 +79,27 @@ class EnergyPlus:
:return: None
"""
for building in self._city.buildings:
_energy_demands = {}
for header in self._building_energy_demands:
print(header)
if header == 'Zone Ideal Loads Supply Air Total Heating Energy [J](Hourly)':
field_name = f'{building.name} IDEAL LOADS AIR SYSTEM:{header}'
elif header == 'Zone Ideal Loads Supply Air Total Cooling Energy [J](Hourly)':
field_name = f'{building.name} IDEAL LOADS AIR SYSTEM:{header}'
else:
field_name = f'{building.name}:{header}'
position = -1
if field_name in self._headers:
position = self._headers.index(field_name)
if position == -1:
continue
for line in self._lines:
if header not in _energy_demands.keys():
_energy_demands[header] = []
_energy_demands[header].append(line[position])
# print(building_energy_demands['Zone Ideal Loads Supply Air Total Heating Energy [J](Hourly)'])
EnergyPlus._set_building_demands(building, _energy_demands)
@staticmethod
def _set_building_demands(building, energy_demands):
print(energy_demands.keys())
heating = [float(x) for x in energy_demands['Zone Ideal Loads Supply Air Total Heating Energy [J](Hourly)']]
cooling = [float(x) for x in energy_demands['Zone Ideal Loads Supply Air Total Cooling Energy [J](Hourly)']]
dhw = [float(x) * cte.WATTS_HOUR_TO_JULES for x in energy_demands['Water Use Equipment Heating Rate [W](Hourly)']]
appliances = [float(x) * cte.WATTS_HOUR_TO_JULES for x in energy_demands['Other Equipment Electricity Rate [W](Hourly)']]
lighting = [float(x) * cte.WATTS_HOUR_TO_JULES for x in energy_demands['Zone Lights Electricity Rate [W](Hourly)']]
building.heating_demand[cte.HOUR] = heating
building.cooling_demand[cte.HOUR] = cooling
building.domestic_hot_water_heat_demand[cte.HOUR] = dhw
building.appliances_electrical_demand[cte.HOUR] = appliances
building.lighting_electrical_demand[cte.HOUR] = lighting
building.heating_demand[cte.MONTH] = []
building.cooling_demand[cte.MONTH] = []
building.domestic_hot_water_heat_demand[cte.MONTH] = []
building.appliances_electrical_demand[cte.MONTH] = []
building.lighting_electrical_demand[cte.MONTH] = []
start = 0
for hours in cte.HOURS_A_MONTH.values():
end = hours + start
building.heating_demand[cte.MONTH].append(sum(building.heating_demand[cte.HOUR][start: end]))
building.cooling_demand[cte.MONTH].append(sum(building.cooling_demand[cte.HOUR][start: end]))
building.domestic_hot_water_heat_demand[cte.MONTH].append(sum(dhw[start: end]))
building.appliances_electrical_demand[cte.MONTH].append(sum(appliances[start: end]))
building.lighting_electrical_demand[cte.MONTH].append(sum(lighting[start: end]))
start = end
building.heating_demand[cte.YEAR] = [sum(building.heating_demand[cte.HOUR])]
building.cooling_demand[cte.YEAR] = [sum(building.cooling_demand[cte.HOUR])]
building.domestic_hot_water_heat_demand[cte.YEAR] = [sum(building.domestic_hot_water_heat_demand[cte.HOUR])]
building.appliances_electrical_demand[cte.YEAR] = [sum(building.appliances_electrical_demand[cte.HOUR])]
building.lighting_electrical_demand[cte.YEAR] = [sum(building.lighting_electrical_demand[cte.HOUR])]
file_name = f'{building.name}_out.csv'
energy_plus_output_file_path = Path(self._base_path / file_name).resolve()
if energy_plus_output_file_path.is_file():
building_energy_demands = self._building_energy_demands(energy_plus_output_file_path)
building.heating_demand[cte.HOUR] = building_energy_demands['Heating (J)']
building.cooling_demand[cte.HOUR] = building_energy_demands['Cooling (J)']
building.domestic_hot_water_heat_demand[cte.HOUR] = building_energy_demands['DHW (J)']
building.appliances_electrical_demand[cte.HOUR] = building_energy_demands['Appliances (J)']
building.lighting_electrical_demand[cte.HOUR] = building_energy_demands['Lighting (J)']
# todo: @Saeed, this a list of ONE value with the total energy of the year, exactly the same as cte.YEAR.
# You have to use the method to add hourly values from helpers/monthly_values
building.heating_demand[cte.MONTH] = MonthlyValues.get_total_month(building.heating_demand[cte.HOUR])
building.cooling_demand[cte.MONTH] = MonthlyValues.get_total_month(building.cooling_demand[cte.HOUR])
building.domestic_hot_water_heat_demand[cte.MONTH] = (
MonthlyValues.get_total_month(building.domestic_hot_water_heat_demand[cte.HOUR]))
building.appliances_electrical_demand[cte.MONTH] = (
MonthlyValues.get_total_month(building.appliances_electrical_demand[cte.HOUR]))
building.lighting_electrical_demand[cte.MONTH] = (
MonthlyValues.get_total_month(building.lighting_electrical_demand[cte.HOUR]))
building.heating_demand[cte.YEAR] = [sum(building.heating_demand[cte.MONTH])]
building.cooling_demand[cte.YEAR] = [sum(building.cooling_demand[cte.MONTH])]
building.domestic_hot_water_heat_demand[cte.YEAR] = [sum(building.domestic_hot_water_heat_demand[cte.MONTH])]
building.appliances_electrical_demand[cte.YEAR] = [sum(building.appliances_electrical_demand[cte.MONTH])]
building.lighting_electrical_demand[cte.YEAR] = [sum(building.lighting_electrical_demand[cte.MONTH])]

View File

@ -22,11 +22,9 @@ class EnergyPlusMultipleBuildings:
with open(Path(energy_plus_output_file_path).resolve(), 'r', encoding='utf8') as csv_file:
csv_output = list(csv.DictReader(csv_file))
print(csv_output)
return
for building in self._city.buildings:
building_name = building.name.upper()
for building in self._city.buildings:
building_name = building.name
buildings_energy_demands[f'Building {building_name} Heating Demand (J)'] = [
float(
row[f"{building_name} IDEAL LOADS AIR SYSTEM:Zone Ideal Loads Supply Air Total Heating Energy [J](Hourly)"])
@ -38,7 +36,7 @@ class EnergyPlusMultipleBuildings:
for row in csv_output
]
buildings_energy_demands[f'Building {building_name} DHW Demand (W)'] = [
float(row[f"DHW {building_name}:Water Use Equipment Heating Rate [W](Hourly)"])
float(row[f"DHW {building.name}:Water Use Equipment Heating Rate [W](Hourly)"])
for row in csv_output
]
buildings_energy_demands[f'Building {building_name} Appliances (W)'] = [
@ -60,15 +58,14 @@ class EnergyPlusMultipleBuildings:
if energy_plus_output_file_path.is_file():
building_energy_demands = self._building_energy_demands(energy_plus_output_file_path)
for building in self._city.buildings:
building_name = building.name.upper()
building.heating_demand[cte.HOUR] = building_energy_demands[f'Building {building_name} Heating Demand (J)']
building.cooling_demand[cte.HOUR] = building_energy_demands[f'Building {building_name} Cooling Demand (J)']
building.heating_demand[cte.HOUR] = building_energy_demands[f'Building {building.name} Heating Demand (J)']
building.cooling_demand[cte.HOUR] = building_energy_demands[f'Building {building.name} Cooling Demand (J)']
building.domestic_hot_water_heat_demand[cte.HOUR] = \
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building_name} DHW Demand (W)']]
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building.name} DHW Demand (W)']]
building.appliances_electrical_demand[cte.HOUR] = \
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building_name} Appliances (W)']]
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building.name} Appliances (W)']]
building.lighting_electrical_demand[cte.HOUR] = \
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building_name} Lighting (W)']]
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building.name} Lighting (W)']]
building.heating_demand[cte.MONTH] = MonthlyValues.get_total_month(building.heating_demand[cte.HOUR])
building.cooling_demand[cte.MONTH] = MonthlyValues.get_total_month(building.cooling_demand[cte.HOUR])
building.domestic_hot_water_heat_demand[cte.MONTH] = (

View File

@ -34,7 +34,7 @@ class SimplifiedRadiosityAlgorithm:
for key in self._results:
_irradiance = {}
header_name = key.split(':')
result = [x for x in self._results[key]]
result = [x * cte.WATTS_HOUR_TO_JULES for x in self._results[key]]
city_object_name = header_name[1]
building = self._city.city_object(city_object_name)
surface_id = header_name[2]

View File

@ -8,7 +8,6 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
from pathlib import Path
from hub.helpers.utils import validate_import_export_type
from hub.imports.results.energy_plus import EnergyPlus
from hub.imports.results.insel_monthly_energry_balance import InselMonthlyEnergyBalance
from hub.imports.results.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm
@ -61,9 +60,6 @@ class ResultFactory:
"""
EnergyPlusMultipleBuildings(self._city, self._base_path).enrich()
def _cerc_idf(self):
EnergyPlus(self._city, self._base_path).enrich()
def enrich(self):
"""
Enrich the city given to the class using the usage factory given handler

View File

@ -3,7 +3,6 @@ ComnetUsageParameters extracts the usage properties from Comnet catalog and assi
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Project Collaborator Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import copy
import logging
@ -19,8 +18,6 @@ from hub.city_model_structure.building_demand.domestic_hot_water import Domestic
from hub.city_model_structure.attributes.schedule import Schedule
from hub.city_model_structure.building_demand.internal_gain import InternalGain
from hub.catalog_factories.usage_catalog_factory import UsageCatalogFactory
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
class ComnetUsageParameters:
@ -38,63 +35,28 @@ class ComnetUsageParameters:
city = self._city
comnet_catalog = UsageCatalogFactory('comnet').catalog
for building in city.buildings:
comnet_archetype_usages = []
usages = building.usages
for usage in usages:
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage['usage']]
usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
try:
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
comnet_archetype_usages.append(comnet_archetype_usage)
archetype_usage = self._search_archetypes(comnet_catalog, usage_name)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
continue
for (i, internal_zone) in enumerate(building.internal_zones):
internal_zone_usages = []
if len(building.internal_zones) > 1:
volume_per_area = 0
for internal_zone in building.internal_zones:
if internal_zone.area is None:
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
building.name, usages[i]['usage'])
continue
raise TypeError('Internal zone area not defined, ACH cannot be calculated')
if internal_zone.volume is None:
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
building.name, usages[i]['usage'])
continue
raise TypeError('Internal zone volume not defined, ACH cannot be calculated')
if internal_zone.area <= 0:
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
building.name, usages[i]['usage'])
continue
volume_per_area += internal_zone.volume / internal_zone.area
raise TypeError('Internal zone area is zero, ACH cannot be calculated')
volume_per_area = internal_zone.volume / internal_zone.area
usage = Usage()
usage.name = usages[i]['usage']
self._assign_values(usage, comnet_archetype_usages[i], volume_per_area, building.cold_water_temperature)
usage.name = usage_name
self._assign_values(usage, archetype_usage, volume_per_area, building.cold_water_temperature)
usage.percentage = 1
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[i])
internal_zone_usages.append(usage)
else:
storeys_above_ground = building.storeys_above_ground
if storeys_above_ground is None:
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s. '
'NRCAN construction data for the year %s is used to calculated number of storeys above '
'ground', building.name, usages, building.year_of_construction)
try:
storeys_above_ground = self.average_storey_height_calculator(self._city, building)
except ValueError as e:
logging.error(e)
continue
self._calculate_reduced_values_from_extended_library(usage, archetype_usage)
volume_per_area = building.volume / building.floor_area / storeys_above_ground
for j, usage_type in enumerate(usages):
usage = Usage()
usage.name = usage_type['usage']
usage.percentage = float(usage_type['ratio'])
self._assign_values(usage, comnet_archetype_usages[j], volume_per_area, building.cold_water_temperature)
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[j])
internal_zone_usages.append(usage)
internal_zone.usages = internal_zone_usages
internal_zone.usages = [usage]
@staticmethod
def _search_archetypes(comnet_catalog, usage_name):
@ -267,28 +229,3 @@ class ComnetUsageParameters:
_mean_internal_gain.schedules = _schedules
return [_mean_internal_gain]
@staticmethod
def average_storey_height_calculator(city, building):
climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
raise ValueError('Building %s has an unknown building function %s', building.name, building.function)
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
construction_archetype = None
average_storey_height = None
nrcan_archetypes = nrcan_catalog.entries('archetypes')
for building_archetype in nrcan_archetypes:
construction_period_limits = building_archetype.construction_period.split('_')
if int(construction_period_limits[0]) <= int(building.year_of_construction) <= int(construction_period_limits[1]):
if str(function) == str(building_archetype.function) and climate_zone == str(building_archetype.climate_zone):
construction_archetype = building_archetype
average_storey_height = building_archetype.average_storey_height
if construction_archetype is None:
raise ValueError('Building %s has unknown construction archetype for building function: %s '
'[%s], building year of construction: %s and climate zone %s', building.name, function,
building.function, building.year_of_construction, climate_zone)
return average_storey_height

View File

@ -3,13 +3,11 @@ NrcanUsageParameters extracts the usage properties from NRCAN catalog and assign
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Project Collaborator Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import logging
import hub.helpers.constants as cte
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
from hub.helpers.dictionaries import Dictionaries
from hub.city_model_structure.building_demand.usage import Usage
from hub.city_model_structure.building_demand.lighting import Lighting
@ -18,7 +16,6 @@ from hub.city_model_structure.building_demand.appliances import Appliances
from hub.city_model_structure.building_demand.thermal_control import ThermalControl
from hub.city_model_structure.building_demand.domestic_hot_water import DomesticHotWater
from hub.catalog_factories.usage_catalog_factory import UsageCatalogFactory
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
class NrcanUsageParameters:
@ -36,74 +33,53 @@ class NrcanUsageParameters:
city = self._city
nrcan_catalog = UsageCatalogFactory('nrcan').catalog
comnet_catalog = UsageCatalogFactory('comnet').catalog
for building in city.buildings:
nrcan_archetype_usages = []
comnet_archetype_usages = []
usages = building.usages
for usage in usages:
usage_name = Dictionaries().hub_usage_to_nrcan_usage[usage['usage']]
usage_name = Dictionaries().hub_usage_to_nrcan_usage[building.function]
try:
archetype_usage = self._search_archetypes(nrcan_catalog, usage_name)
nrcan_archetype_usages.append(archetype_usage)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
continue
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage['usage']]
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
try:
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
comnet_archetype_usages.append(comnet_archetype_usage)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
continue
for (i, internal_zone) in enumerate(building.internal_zones):
internal_zone_usages = []
for internal_zone in building.internal_zones:
if len(building.internal_zones) > 1:
volume_per_area = 0
if internal_zone.area is None:
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
building.name, usages[i]['usage'])
building.name, usage_name)
continue
if internal_zone.volume is None:
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
building.name, usages[i]['usage'])
building.name, usage_name)
continue
if internal_zone.area <= 0:
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
building.name, usages[i]['usage'])
building.name, usage_name)
continue
volume_per_area += internal_zone.volume / internal_zone.area
usage = Usage()
usage.name = usages[i]['usage']
self._assign_values(usage, nrcan_archetype_usages[i], volume_per_area, building.cold_water_temperature)
self._assign_comnet_extra_values(usage, comnet_archetype_usages[i], nrcan_archetype_usages[i].occupancy.occupancy_density)
usage.percentage = 1
self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[i])
internal_zone_usages.append(usage)
else:
storeys_above_ground = building.storeys_above_ground
if storeys_above_ground is None:
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for function %s. '
'NRCAN construction data for the year %s is used to calculated number of storeys above '
'ground', building.name, building.function, building.year_of_construction)
try:
storeys_above_ground = self.average_storey_height_calculator(self._city, building)
except ValueError as e:
logging.error(e)
if building.storeys_above_ground is None:
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s',
building.name, usage_name)
continue
volume_per_area = building.volume / building.floor_area / building.storeys_above_ground
volume_per_area = building.volume / building.floor_area / storeys_above_ground
for j, usage_type in enumerate(usages):
usage = Usage()
usage.name = usage_type['usage']
usage.percentage = float(usage_type['ratio'])
usage.name = usage_name
self._assign_values(usage, archetype_usage, volume_per_area, building.cold_water_temperature)
self._assign_comnet_extra_values(usage, comnet_archetype_usage, archetype_usage.occupancy.occupancy_density)
usage.percentage = 1
self._calculate_reduced_values_from_extended_library(usage, archetype_usage)
self._assign_values(usage, nrcan_archetype_usages[j], volume_per_area, building.cold_water_temperature)
self._assign_comnet_extra_values(usage, comnet_archetype_usages[j], nrcan_archetype_usages[j].occupancy.occupancy_density)
self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[j])
internal_zone_usages.append(usage)
internal_zone.usages = internal_zone_usages
internal_zone.usages = [usage]
@staticmethod
def _search_archetypes(catalog, usage_name):
@ -221,30 +197,3 @@ class NrcanUsageParameters:
usage.thermal_control.mean_heating_set_point = max_heating_setpoint
usage.thermal_control.heating_set_back = min_heating_setpoint
usage.thermal_control.mean_cooling_set_point = min_cooling_setpoint
@staticmethod
def average_storey_height_calculator(city, building):
climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
raise ValueError('Building %s has an unknown building function %s', building.name, building.function)
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
construction_archetype = None
average_storey_height = None
nrcan_archetypes = nrcan_catalog.entries('archetypes')
for building_archetype in nrcan_archetypes:
construction_period_limits = building_archetype.construction_period.split('_')
if int(construction_period_limits[0]) <= int(building.year_of_construction) <= int(construction_period_limits[1]):
if str(function) == str(building_archetype.function) and climate_zone == str(building_archetype.climate_zone):
construction_archetype = building_archetype
average_storey_height = building_archetype.average_storey_height
if construction_archetype is None:
raise ValueError('Building %s has unknown construction archetype for building function: %s '
'[%s], building year of construction: %s and climate zone %s', building.name, function,
building.function, building.year_of_construction, climate_zone)
return average_storey_height

View File

@ -1,174 +0,0 @@
"""
PalmaUsageParameters extracts the usage properties from Palma catalog and assigns to each building
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Cecilia Pérez cperez@irec.cat
"""
import logging
import hub.helpers.constants as cte
from hub.helpers.dictionaries import Dictionaries
from hub.city_model_structure.building_demand.usage import Usage
from hub.city_model_structure.building_demand.lighting import Lighting
from hub.city_model_structure.building_demand.occupancy import Occupancy
from hub.city_model_structure.building_demand.appliances import Appliances
from hub.city_model_structure.building_demand.thermal_control import ThermalControl
from hub.city_model_structure.building_demand.domestic_hot_water import DomesticHotWater
from hub.catalog_factories.usage_catalog_factory import UsageCatalogFactory
class PalmaUsageParameters:
"""
PalmaUsageParameters class
"""
def __init__(self, city):
self._city = city
def enrich_buildings(self):
"""
Returns the city with the usage parameters assigned to the buildings
:return:
"""
city = self._city
palma_catalog = UsageCatalogFactory('palma').catalog
for building in city.buildings:
palma_usage_name = Dictionaries().hub_usage_to_palma_usage[building.function]
try:
archetype_usage = self._search_archetypes(palma_catalog, palma_usage_name)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, palma_usage_name)
continue
for internal_zone in building.internal_zones:
if len(building.internal_zones) > 1:
volume_per_area = 0
if internal_zone.area is None:
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
building.name, palma_usage_name)
continue
if internal_zone.volume is None:
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
building.name, palma_usage_name)
continue
if internal_zone.area <= 0:
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
building.name, palma_usage_name)
continue
volume_per_area += internal_zone.volume / internal_zone.area
else:
if building.storeys_above_ground is None:
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s',
building.name, palma_usage_name)
continue
volume_per_area = building.volume / building.floor_area / building.storeys_above_ground
usage = Usage()
usage.name = palma_usage_name
self._assign_values(usage, archetype_usage, volume_per_area, building.cold_water_temperature)
usage.percentage = 1
self._calculate_reduced_values_from_extended_library(usage, archetype_usage)
internal_zone.usages = [usage]
@staticmethod
def _search_archetypes(palma_catalog, usage_name):
archetypes = palma_catalog.entries('archetypes').usages
for building_archetype in archetypes:
if str(usage_name) == str(building_archetype.name):
return building_archetype
raise KeyError('archetype not found')
@staticmethod
def _assign_values(usage, archetype, volume_per_area, cold_water_temperature):
if archetype.mechanical_air_change > 0:
# 1/s
usage.mechanical_air_change = archetype.mechanical_air_change
elif archetype.ventilation_rate > 0:
# m3/m2.s to 1/s
usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area
else:
usage.mechanical_air_change = 0
_occupancy = Occupancy()
_occupancy.occupancy_density = archetype.occupancy.occupancy_density
_occupancy.sensible_radiative_internal_gain = archetype.occupancy.sensible_radiative_internal_gain
_occupancy.latent_internal_gain = archetype.occupancy.latent_internal_gain
_occupancy.sensible_convective_internal_gain = archetype.occupancy.sensible_convective_internal_gain
_occupancy.occupancy_schedules = archetype.occupancy.schedules
usage.occupancy = _occupancy
_lighting = Lighting()
_lighting.density = archetype.lighting.density
_lighting.convective_fraction = archetype.lighting.convective_fraction
_lighting.radiative_fraction = archetype.lighting.radiative_fraction
_lighting.latent_fraction = archetype.lighting.latent_fraction
_lighting.schedules = archetype.lighting.schedules
usage.lighting = _lighting
_appliances = Appliances()
_appliances.density = archetype.appliances.density
_appliances.convective_fraction = archetype.appliances.convective_fraction
_appliances.radiative_fraction = archetype.appliances.radiative_fraction
_appliances.latent_fraction = archetype.appliances.latent_fraction
_appliances.schedules = archetype.appliances.schedules
usage.appliances = _appliances
_control = ThermalControl()
_control.cooling_set_point_schedules = archetype.thermal_control.cooling_set_point_schedules
_control.heating_set_point_schedules = archetype.thermal_control.heating_set_point_schedules
_control.hvac_availability_schedules = archetype.thermal_control.hvac_availability_schedules
usage.thermal_control = _control
_domestic_hot_water = DomesticHotWater()
_domestic_hot_water.peak_flow = archetype.domestic_hot_water.peak_flow
_domestic_hot_water.service_temperature = archetype.domestic_hot_water.service_temperature
density = None
if len(cold_water_temperature) > 0:
cold_temperature = cold_water_temperature[cte.YEAR][0]
density = (
archetype.domestic_hot_water.peak_flow * cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY *
(archetype.domestic_hot_water.service_temperature - cold_temperature)
)
_domestic_hot_water.density = density
_domestic_hot_water.schedules = archetype.domestic_hot_water.schedules
usage.domestic_hot_water = _domestic_hot_water
@staticmethod
def _calculate_reduced_values_from_extended_library(usage, archetype):
number_of_days_per_type = {'WD': 251, 'Sat': 52, 'Sun': 62}
total = 0
for schedule in archetype.thermal_control.hvac_availability_schedules:
if schedule.day_types[0] == cte.SATURDAY:
for value in schedule.values:
total += value * number_of_days_per_type['Sat']
elif schedule.day_types[0] == cte.SUNDAY:
for value in schedule.values:
total += value * number_of_days_per_type['Sun']
else:
for value in schedule.values:
total += value * number_of_days_per_type['WD']
usage.hours_day = total / 365
usage.days_year = 365
max_heating_setpoint = cte.MIN_FLOAT
min_heating_setpoint = cte.MAX_FLOAT
for schedule in archetype.thermal_control.heating_set_point_schedules:
if schedule.values is None:
max_heating_setpoint = None
min_heating_setpoint = None
break
if max(schedule.values) > max_heating_setpoint:
max_heating_setpoint = max(schedule.values)
if min(schedule.values) < min_heating_setpoint:
min_heating_setpoint = min(schedule.values)
min_cooling_setpoint = cte.MAX_FLOAT
for schedule in archetype.thermal_control.cooling_set_point_schedules:
if schedule.values is None:
min_cooling_setpoint = None
break
if min(schedule.values) < min_cooling_setpoint:
min_cooling_setpoint = min(schedule.values)
usage.thermal_control.mean_heating_set_point = max_heating_setpoint
usage.thermal_control.heating_set_back = min_heating_setpoint
usage.thermal_control.mean_cooling_set_point = min_cooling_setpoint

View File

@ -10,7 +10,6 @@ from hub.helpers.utils import validate_import_export_type
from hub.imports.usage.comnet_usage_parameters import ComnetUsageParameters
from hub.imports.usage.nrcan_usage_parameters import NrcanUsageParameters
from hub.imports.usage.eilat_usage_parameters import EilatUsageParameters
from hub.imports.usage.palma_usage_parameters import PalmaUsageParameters
class UsageFactory:
@ -49,15 +48,6 @@ class UsageFactory:
for building in self._city.buildings:
building.level_of_detail.usage = 2
def _palma(self):
"""
Enrich the city with Palma usage library
"""
PalmaUsageParameters(self._city).enrich_buildings()
self._city.level_of_detail.usage = 2
for building in self._city.buildings:
building.level_of_detail.usage = 2
def enrich(self):
"""
Enrich the city given to the class using the usage factory given handler

View File

@ -110,9 +110,12 @@ class EpwWeatherParameters:
# new_value = pd.DataFrame(self._weather_values[['dry_bulb_temperature_c']].to_numpy(), columns=['epw'])
# number_invalid_records = new_value[new_value.epw == 99.9].count().epw
building.external_temperature[cte.HOUR] = self._weather_values['dry_bulb_temperature_c']
building.global_horizontal[cte.HOUR] = [x for x in self._weather_values['global_horizontal_radiation_wh_m2']]
building.diffuse[cte.HOUR] = [x for x in self._weather_values['diffuse_horizontal_radiation_wh_m2']]
building.direct_normal[cte.HOUR] = [x for x in self._weather_values['direct_normal_radiation_wh_m2']]
building.global_horizontal[cte.HOUR] = [x * cte.WATTS_HOUR_TO_JULES
for x in self._weather_values['global_horizontal_radiation_wh_m2']]
building.diffuse[cte.HOUR] = [x * cte.WATTS_HOUR_TO_JULES
for x in self._weather_values['diffuse_horizontal_radiation_wh_m2']]
building.direct_normal[cte.HOUR] = [x * cte.WATTS_HOUR_TO_JULES
for x in self._weather_values['direct_normal_radiation_wh_m2']]
building.beam[cte.HOUR] = [building.global_horizontal[cte.HOUR][i] -
building.diffuse[cte.HOUR][i]
for i in range(len(building.global_horizontal[cte.HOUR]))]

View File

@ -25,7 +25,8 @@ class Weather:
'US.NY.047': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/USA/NY/USA_NY_New.York.City-Central.Park.94728_TMY/USA_NY_New.York.City-Central.Park.94728_TMY.epw',
'CA.10.12': 'https://energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/CAN/PQ/CAN_PQ_Quebec.717140_CWEC/CAN_PQ_Quebec.717140_CWEC.epw',
'IL.01.': 'https://energyplus-weather.s3.amazonaws.com/europe_wmo_region_6/ISR/ISR_Eilat.401990_MSI/ISR_Eilat.401990_MSI.epw',
'ES.07.PM': 'https://energyplus-weather.s3.amazonaws.com/europe_wmo_region_6/ESP/ESP_Palma.083060_SWEC/ESP_Palma.083060_SWEC.epw'
'ES.07.PM': 'https://energyplus-weather.s3.amazonaws.com/europe_wmo_region_6/ESP/ESP_Palma.083060_SWEC/ESP_Palma.083060_SWEC.epw',
'CA.10.17': 'https: //energyplus-weather.s3.amazonaws.com/north_and_central_america_wmo_region_4/CAN/ON/CAN_ON_Thunder.Bay.717490_CWEC.epw'
}
# todo: this dictionary need to be completed, a data science student task?

View File

@ -9,7 +9,6 @@ import datetime
import logging
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey, Float
from sqlalchemy.dialects.postgresql import JSON
from sqlalchemy import DateTime
from hub.city_model_structure.building import Building
@ -28,7 +27,7 @@ class CityObject(Models):
type = Column(String, nullable=False)
year_of_construction = Column(Integer, nullable=True)
function = Column(String, nullable=True)
usage = Column(JSON, nullable=True)
usage = Column(String, nullable=True)
volume = Column(Float, nullable=False)
area = Column(Float, nullable=False)
total_heating_area = Column(Float, nullable=False)
@ -47,7 +46,7 @@ class CityObject(Models):
self.type = building.type
self.year_of_construction = building.year_of_construction
self.function = building.function
self.usage = building.usages
self.usage = building.usages_percentage
self.volume = building.volume
self.area = building.floor_area
self.roof_area = sum(roof.solid_polygon.area for roof in building.roofs)

View File

@ -1,4 +1,4 @@
"""
Hub version number
"""
__version__ = '0.3.0.5'
__version__ = '0.2.0.8'

View File

@ -25,4 +25,3 @@ psycopg2-binary
Pillow
pathlib
sqlalchemy_utils
build

View File

@ -59,14 +59,12 @@ setup(
'hub.exports',
'hub.exports.building_energy',
'hub.exports.building_energy.idf_files',
'hub.exports.building_energy.idf_helper',
'hub.exports.building_energy.insel',
'hub.exports.energy_systems',
'hub.exports.formats',
'hub.helpers',
'hub.helpers.peak_calculation',
'hub.helpers.data',
'hub.helpers.parsers',
'hub.imports',
'hub.imports.construction',
'hub.imports.construction.helpers',

View File

@ -71,23 +71,3 @@ class TestConstructionCatalog(TestCase):
with self.assertRaises(IndexError):
catalog.get_entry('unknown')
def test_palma_catalog(self):
catalog = ConstructionCatalogFactory('palma').catalog
catalog_categories = catalog.names()
constructions = catalog.names('constructions')
windows = catalog.names('windows')
materials = catalog.names('materials')
self.assertEqual(29, len(constructions['constructions']))
self.assertEqual(9, len(windows['windows']))
self.assertEqual(122, len(materials['materials']))
with self.assertRaises(ValueError):
catalog.names('unknown')
# retrieving all the entries should not raise any exceptions
for category in catalog_categories:
for value in catalog_categories[category]:
catalog.get_entry(value)
with self.assertRaises(IndexError):
catalog.get_entry('unknown')

View File

@ -306,24 +306,3 @@ class TestConstructionFactory(TestCase):
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
self._check_thermal_openings(thermal_boundary)
self._check_surfaces(thermal_boundary)
def test_palma_construction_factory(self):
file = 'palma_test_file.geojson'
file_path = (self._example_path / file).resolve()
city = GeometryFactory(file_type='geojson',
path=file_path,
height_field='measuredHeight',
year_of_construction_field='yearOfConstruction',
function_field='usage',
function_to_hub=Dictionaries().palma_function_to_hub_function).city
ConstructionFactory('palma', city).enrich()
self._check_buildings(city)
for building in city.buildings:
for internal_zone in building.internal_zones:
self._check_thermal_zones(internal_zone)
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
self._check_thermal_boundaries(thermal_zone)
for thermal_boundary in thermal_zone.thermal_boundaries:
self.assertIsNotNone(thermal_boundary.layers, 'layers is none')
self._check_thermal_openings(thermal_boundary)
self._check_surfaces(thermal_boundary)

View File

@ -17,7 +17,6 @@ from hub.exports.exports_factory import ExportsFactory
from hub.helpers.dictionaries import Dictionaries
from hub.imports.construction_factory import ConstructionFactory
from hub.imports.geometry_factory import GeometryFactory
from hub.imports.results_factory import ResultFactory
from hub.imports.usage_factory import UsageFactory
from hub.imports.weather_factory import WeatherFactory
@ -137,49 +136,14 @@ class TestExports(TestCase):
year_of_construction_field='ANNEE_CONS',
function_field='CODE_UTILI',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
self.assertIsNotNone(city, 'city is none')
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
ConstructionFactory('nrcan', city).enrich()
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
UsageFactory('nrcan', city).enrich()
WeatherFactory('epw', city).enrich()
try:
_idf = EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
_idf.run()
except Exception:
self.fail("Idf ExportsFactory raised ExceptionType unexpectedly!")
def test_cerc_idf_export(self):
"""
export to IDF
"""
file = 'test.geojson'
file_path = (self._example_path / file).resolve()
city = GeometryFactory('geojson',
path=file_path,
height_field='citygml_me',
year_of_construction_field='ANNEE_CONS',
function_field='CODE_UTILI',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
self.assertIsNotNone(city, 'city is none')
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
ConstructionFactory('nrcan', city).enrich()
EnergyBuildingsExportsFactory('idf', city, self._output_path).export()
UsageFactory('nrcan', city).enrich()
WeatherFactory('epw', city).enrich()
try:
idf = EnergyBuildingsExportsFactory('cerc_idf', city, self._output_path).export()
idf.run()
csv_output_path = (self._output_path / f'{city.name}_out.csv').resolve()
ResultFactory('cerc_idf', city, csv_output_path).enrich()
self.assertTrue(csv_output_path.is_file())
for building in city.buildings:
self.assertIsNotNone(building.heating_demand)
self.assertIsNotNone(building.cooling_demand)
self.assertIsNotNone(building.domestic_hot_water_heat_demand)
self.assertIsNotNone(building.lighting_electrical_demand)
self.assertIsNotNone(building.appliances_electrical_demand)
total_demand = sum(building.heating_demand[cte.HOUR])
total_demand_month = sum(building.heating_demand[cte.MONTH])
self.assertAlmostEqual(total_demand, building.heating_demand[cte.YEAR][0], 2)
self.assertAlmostEqual(total_demand_month, building.heating_demand[cte.YEAR][0], 2)
EnergyBuildingsExportsFactory('idf', city, self._output_path, target_buildings=[1]).export()
except Exception:
self.fail("Idf ExportsFactory raised ExceptionType unexpectedly!")

View File

@ -92,3 +92,42 @@ class TestResultsImport(TestCase):
building.cooling_demand[cte.HOUR] = values
self.assertIsNotNone(building.heating_peak_load)
self.assertIsNotNone(building.cooling_peak_load)
def test_energy_plus_results_import(self):
ResultFactory('energy_plus_single_building', self._city, self._example_path).enrich()
for building in self._city.buildings:
csv_output_name = f'{building.name}_out.csv'
csv_output_path = (self._example_path / csv_output_name).resolve()
if csv_output_path.is_file():
self.assertEqual(building.name, '12')
self.assertIsNotNone(building.heating_demand)
self.assertIsNotNone(building.cooling_demand)
self.assertIsNotNone(building.domestic_hot_water_heat_demand)
self.assertIsNotNone(building.lighting_electrical_demand)
self.assertIsNotNone(building.appliances_electrical_demand)
total_demand = sum(building.heating_demand[cte.HOUR])
self.assertAlmostEqual(total_demand, building.heating_demand[cte.YEAR][0], 3)
total_demand = sum(building.heating_demand[cte.MONTH])
self.assertEqual(total_demand, building.heating_demand[cte.YEAR][0], 3)
if building.name != '12':
self.assertDictEqual(building.heating_demand, {})
self.assertDictEqual(building.cooling_demand, {})
self.assertDictEqual(building.domestic_hot_water_heat_demand, {})
self.assertDictEqual(building.lighting_electrical_demand, {})
self.assertDictEqual(building.appliances_electrical_demand, {})
def test_energy_plus_multiple_buildings_results_import(self):
ResultFactory('energy_plus_multiple_buildings', self._city, self._example_path).enrich()
csv_output_name = f'{self._city.name}_out.csv'
csv_output_path = (self._example_path / csv_output_name).resolve()
if csv_output_path.is_file():
for building in self._city.buildings:
self.assertIsNotNone(building.heating_demand)
self.assertIsNotNone(building.cooling_demand)
self.assertIsNotNone(building.domestic_hot_water_heat_demand)
self.assertIsNotNone(building.lighting_electrical_demand)
self.assertIsNotNone(building.appliances_electrical_demand)
total_demand = sum(building.heating_demand[cte.HOUR])
self.assertAlmostEqual(total_demand, building.heating_demand[cte.YEAR][0], 2)
total_demand = sum(building.heating_demand[cte.MONTH])
self.assertEqual(total_demand, building.heating_demand[cte.YEAR][0], 2)

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