diff --git a/hub/catalog_factories/construction/palma_catalog.py b/hub/catalog_factories/construction/palma_catalog.py
new file mode 100644
index 00000000..a40dc665
--- /dev/null
+++ b/hub/catalog_factories/construction/palma_catalog.py
@@ -0,0 +1,242 @@
+"""
+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")
\ No newline at end of file
diff --git a/hub/catalog_factories/construction_catalog_factory.py b/hub/catalog_factories/construction_catalog_factory.py
index b1c8a45b..270cb1b4 100644
--- a/hub/catalog_factories/construction_catalog_factory.py
+++ b/hub/catalog_factories/construction_catalog_factory.py
@@ -11,6 +11,7 @@ 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')
@@ -48,6 +49,13 @@ class ConstructionCatalogFactory:
"""
return EilatCatalog(self._path)
+ @property
+ def _palma(self):
+ """
+ Retrieve Palma catalog
+ """
+ return PalmaCatalog(self._path)
+
@property
def catalog(self) -> Catalog:
"""
diff --git a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py
index 87228afa..68ac1460 100644
--- a/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py
+++ b/hub/catalog_factories/data_models/energy_systems/pv_generation_system.py
@@ -17,8 +17,9 @@ class PvGenerationSystem(GenerationSystem):
def __init__(self, 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, cell_temperature_coefficient=None, width=None, height=None,
- distribution_systems=None, energy_storage_systems=None):
+ standard_test_condition_maximum_power=None, standard_test_condition_radiation=None,
+ cell_temperature_coefficient=None, width=None, height=None, distribution_systems=None,
+ energy_storage_systems=None):
super().__init__(system_id=system_id, name=name, model_name=model_name,
manufacturer=manufacturer, fuel_type='renewable', distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems)
@@ -30,6 +31,7 @@ class PvGenerationSystem(GenerationSystem):
self._nominal_radiation = nominal_radiation
self._standard_test_condition_cell_temperature = standard_test_condition_cell_temperature
self._standard_test_condition_maximum_power = standard_test_condition_maximum_power
+ self._standard_test_condition_radiation = standard_test_condition_radiation
self._cell_temperature_coefficient = cell_temperature_coefficient
self._width = width
self._height = height
@@ -98,6 +100,15 @@ 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):
"""
@@ -143,6 +154,7 @@ class PvGenerationSystem(GenerationSystem):
'nominal radiation [W/m2]': self.nominal_radiation,
'standard test condition cell temperature [Celsius]': self.standard_test_condition_cell_temperature,
'standard test condition maximum power [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,
diff --git a/hub/catalog_factories/energy_systems/montreal_future_system_catalogue.py b/hub/catalog_factories/energy_systems/montreal_future_system_catalogue.py
index a4477ba2..c5036a3e 100644
--- a/hub/catalog_factories/energy_systems/montreal_future_system_catalogue.py
+++ b/hub/catalog_factories/energy_systems/montreal_future_system_catalogue.py
@@ -193,6 +193,7 @@ 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']
@@ -215,6 +216,7 @@ 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,
diff --git a/hub/catalog_factories/energy_systems/palma_system_catalgue.py b/hub/catalog_factories/energy_systems/palma_system_catalgue.py
new file mode 100644
index 00000000..d83c9836
--- /dev/null
+++ b/hub/catalog_factories/energy_systems/palma_system_catalgue.py
@@ -0,0 +1,520 @@
+"""
+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")
diff --git a/hub/catalog_factories/energy_systems_catalog_factory.py b/hub/catalog_factories/energy_systems_catalog_factory.py
index ffd36d10..ecc6004b 100644
--- a/hub/catalog_factories/energy_systems_catalog_factory.py
+++ b/hub/catalog_factories/energy_systems_catalog_factory.py
@@ -10,6 +10,7 @@ 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')
@@ -40,6 +41,13 @@ class EnergySystemsCatalogFactory:
"""
return MontrealFutureSystemCatalogue(self._path)
+ @property
+ def _palma(self):
+ """
+ Retrieve Palma catalog
+ """
+ return PalmaSystemCatalogue(self._path)
+
@property
def catalog(self) -> Catalog:
"""
diff --git a/hub/catalog_factories/usage/palma_catalog.py b/hub/catalog_factories/usage/palma_catalog.py
new file mode 100644
index 00000000..ee8ab4d1
--- /dev/null
+++ b/hub/catalog_factories/usage/palma_catalog.py
@@ -0,0 +1,227 @@
+"""
+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")
\ No newline at end of file
diff --git a/hub/catalog_factories/usage_catalog_factory.py b/hub/catalog_factories/usage_catalog_factory.py
index ce015a35..42df7f4b 100644
--- a/hub/catalog_factories/usage_catalog_factory.py
+++ b/hub/catalog_factories/usage_catalog_factory.py
@@ -11,6 +11,7 @@ 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')
@@ -42,6 +43,13 @@ 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):
"""
diff --git a/hub/city_model_structure/building.py b/hub/city_model_structure/building.py
index 387a4bf9..5e838791 100644
--- a/hub/city_model_structure/building.py
+++ b/hub/city_model_structure/building.py
@@ -292,7 +292,10 @@ 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:
- self._storeys_above_ground = int(self.eave_height / self.average_storey_height)
+ 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
return self._storeys_above_ground
@storeys_above_ground.setter
@@ -736,41 +739,42 @@ class Building(CityObject):
return self._distribution_systems_electrical_consumption
for energy_system in self.energy_systems:
distribution_systems = energy_system.distribution_systems
- for distribution_system in distribution_systems:
- emission_systems = distribution_system.emission_systems
- parasitic_energy_consumption = 0
- if emission_systems is not None:
- for emission_system in emission_systems:
- parasitic_energy_consumption += emission_system.parasitic_energy_consumption
- consumption_variable_flow = distribution_system.distribution_consumption_variable_flow
- for demand_type in energy_system.demand_types:
- if demand_type.lower() == cte.HEATING.lower():
- if _peak_load_type == cte.HEATING.lower():
- _consumption_fix_flow = distribution_system.distribution_consumption_fix_flow
- for heating_demand_key in self.heating_demand:
- _consumption = [0]*len(self.heating_demand[heating_demand_key])
- _demand = self.heating_demand[heating_demand_key]
- for i, _ in enumerate(_consumption):
- _consumption[i] += (parasitic_energy_consumption + consumption_variable_flow) * _demand[i]
- self._distribution_systems_electrical_consumption[heating_demand_key] = _consumption
- if demand_type.lower() == cte.COOLING.lower():
- if _peak_load_type == cte.COOLING.lower():
- _consumption_fix_flow = distribution_system.distribution_consumption_fix_flow
- for demand_key in self.cooling_demand:
- _consumption = self._distribution_systems_electrical_consumption[demand_key]
- _demand = self.cooling_demand[demand_key]
- for i, _ in enumerate(_consumption):
- _consumption[i] += (parasitic_energy_consumption + consumption_variable_flow) * _demand[i]
- self._distribution_systems_electrical_consumption[demand_key] = _consumption
+ if distribution_systems is not None:
+ for distribution_system in distribution_systems:
+ emission_systems = distribution_system.emission_systems
+ parasitic_energy_consumption = 0
+ if emission_systems is not None:
+ for emission_system in emission_systems:
+ parasitic_energy_consumption += emission_system.parasitic_energy_consumption
+ consumption_variable_flow = distribution_system.distribution_consumption_variable_flow
+ for demand_type in energy_system.demand_types:
+ if demand_type.lower() == cte.HEATING.lower():
+ if _peak_load_type == cte.HEATING.lower():
+ _consumption_fix_flow = distribution_system.distribution_consumption_fix_flow
+ for heating_demand_key in self.heating_demand:
+ _consumption = [0]*len(self.heating_demand[heating_demand_key])
+ _demand = self.heating_demand[heating_demand_key]
+ for i, _ in enumerate(_consumption):
+ _consumption[i] += (parasitic_energy_consumption + consumption_variable_flow) * _demand[i]
+ self._distribution_systems_electrical_consumption[heating_demand_key] = _consumption
+ if demand_type.lower() == cte.COOLING.lower():
+ if _peak_load_type == cte.COOLING.lower():
+ _consumption_fix_flow = distribution_system.distribution_consumption_fix_flow
+ for demand_key in self.cooling_demand:
+ _consumption = self._distribution_systems_electrical_consumption[demand_key]
+ _demand = self.cooling_demand[demand_key]
+ for i, _ in enumerate(_consumption):
+ _consumption[i] += (parasitic_energy_consumption + consumption_variable_flow) * _demand[i]
+ self._distribution_systems_electrical_consumption[demand_key] = _consumption
- for key, item in self._distribution_systems_electrical_consumption.items():
- for i in range(0, len(item)):
- _working_hours_value = _working_hours[key]
- if len(item) == 12:
- _working_hours_value = _working_hours[key][i]
- self._distribution_systems_electrical_consumption[key][i] += (
- _peak_load * _consumption_fix_flow * _working_hours_value * cte.WATTS_HOUR_TO_JULES
- )
+ for key, item in self._distribution_systems_electrical_consumption.items():
+ for i in range(0, len(item)):
+ _working_hours_value = _working_hours[key]
+ if len(item) == 12:
+ _working_hours_value = _working_hours[key][i]
+ self._distribution_systems_electrical_consumption[key][i] += (
+ _peak_load * _consumption_fix_flow * _working_hours_value * cte.WATTS_HOUR_TO_JULES
+ )
return self._distribution_systems_electrical_consumption
diff --git a/hub/city_model_structure/building_demand/internal_zone.py b/hub/city_model_structure/building_demand/internal_zone.py
index 77d524a7..b505d593 100644
--- a/hub/city_model_structure/building_demand/internal_zone.py
+++ b/hub/city_model_structure/building_demand/internal_zone.py
@@ -135,6 +135,8 @@ 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]
diff --git a/hub/city_model_structure/energy_systems/pv_generation_system.py b/hub/city_model_structure/energy_systems/pv_generation_system.py
index ddbc847a..f6567c98 100644
--- a/hub/city_model_structure/energy_systems/pv_generation_system.py
+++ b/hub/city_model_structure/energy_systems/pv_generation_system.py
@@ -22,10 +22,11 @@ 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 = None
+ self._electricity_power_output = {}
self._tilt_angle = None
self._surface_azimuth = None
self._solar_altitude_angle = None
@@ -143,6 +144,22 @@ 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):
"""
@@ -192,20 +209,20 @@ class PvGenerationSystem(GenerationSystem):
self._height = value
@property
- def electricity_power(self):
+ def electricity_power_output(self):
"""
Get electricity_power in W
:return: float
"""
- return self._electricity_power
+ return self._electricity_power_output
- @electricity_power.setter
- def electricity_power(self, value):
+ @electricity_power_output.setter
+ def electricity_power_output(self, value):
"""
Set electricity_power in W
:param value: float
"""
- self._electricity_power = value
+ self._electricity_power_output = value
@property
def tilt_angle(self):
diff --git a/hub/data/construction/palma_archetypes.json b/hub/data/construction/palma_archetypes.json
new file mode 100644
index 00000000..8023d726
--- /dev/null
+++ b/hub/data/construction/palma_archetypes.json
@@ -0,0 +1,774 @@
+{
+ "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"
+ }
+ }
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/hub/data/construction/palma_archetypes_modified.json b/hub/data/construction/palma_archetypes_modified.json
new file mode 100644
index 00000000..24c171ad
--- /dev/null
+++ b/hub/data/construction/palma_archetypes_modified.json
@@ -0,0 +1,774 @@
+{
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ },
+ {
+ "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,
+ "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"
+ }
+ },
+ "infiltration_rate_area_for_ventilation_system_on": 0,
+ "infiltration_rate_area_for_ventilation_system_off": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/hub/data/construction/palma_constructions.json b/hub/data/construction/palma_constructions.json
new file mode 100644
index 00000000..4ddeeff2
--- /dev/null
+++ b/hub/data/construction/palma_constructions.json
@@ -0,0 +1,1895 @@
+{
+ "opaque_surfaces": [
+ {
+ "PA1_PA2_1961_1980_FLOOR1": {
+ "period_of_construction": "1961_1980",
+ "climate_zone": "B3",
+ "type": "GroundFloor",
+ "u_value": 0.921,
+ "layers": {
+ "RI01": 0.01,
+ "F02": 0.2,
+ "M01": 0.02,
+ "PT01": 0.03
+ }
+ }
+ },
+ {
+ "PA1_PA2_1961_1980_ROOF1": {
+ "period_of_construction": "1961_1980",
+ "climate_zone": "B3",
+ "type": "OutdoorsRoofCeiling",
+ "u_value": 1.926,
+ "layers": {
+ "IM01": 0.003,
+ "F02": 0.2,
+ "RI01": 0.01
+ }
+ }
+ },
+ {
+ "PA1_PA2_1961_1980_FACEXT1": {
+ "period_of_construction": "1961_1980",
+ "climate_zone": "B3",
+ "type": "OutdoorsWall",
+ "u_value": 2.207,
+ "layers": {
+ "RI05": 0.01,
+ "PH01": 0.2
+ }
+ }
+ },
+ {
+ "PA1_PA2_1961_1980_FLOOR4": {
+ "period_of_construction": "1961_1980",
+ "climate_zone": "B3",
+ "type": "GroundRoofCeiling",
+ "u_value": 2.603,
+ "layers": {
+ "RI05": 0.01,
+ "F02": 0.2,
+ "PT02": 0.03
+ }
+ }
+ },
+ {
+ "PA3_PA4_1901_1940_FLOORGR1": {
+ "period_of_construction": "1800_1980",
+ "climate_zone": "B3",
+ "type": "GroundFloor",
+ "u_value": 1.142,
+ "layers": {
+ "RP01": 0.4,
+ "M01": 0.01,
+ "PC01": 0.01
+ }
+ }
+ },
+ {
+ "PA3_PA4_1901_1940_ROOF1": {
+ "period_of_construction": "1800_1980",
+ "climate_zone": "B3",
+ "type": "OutdoorsRoofCeiling",
+ "u_value": 1.227,
+ "layers": {
+ "ECGX": 0.02,
+ "CA_50": 0,
+ "F03": 0.2,
+ "PC01": 0.06
+ }
+ }
+ },
+ {
+ "PA3_PA4_1901_1940_FACEXT1": {
+ "period_of_construction": "1800_1980",
+ "climate_zone": "B3",
+ "type": "OutdoorsWall",
+ "u_value": 2.703,
+ "layers": {
+ "RI01": 0.01,
+ "MW01": 0.25,
+ "RE01": 0.02
+ }
+ }
+ },
+ {
+ "A_B1900_FACEXT1": {
+ "period_of_construction": "1800_1900",
+ "climate_zone": "B3",
+ "type": "OutdoorsWall",
+ "u_value": 1.65,
+ "layers": {
+ "RI01": 0.02,
+ "PF033": 0.38,
+ "RE01": 0.02
+ }
+ }
+ },
+ {
+ "A_B1900_ROOF1": {
+ "period_of_construction": "1800_1900",
+ "climate_zone": "B3",
+ "type": "OutdoorsRoofCeiling",
+ "u_value": 1.28,
+ "layers": {
+ "ECGX": 0.02,
+ "CA02": 0.2,
+ "F03": 0.2,
+ "CAV20": 0.2,
+ "PC01": 0.06
+ }
+ }
+ },
+ {
+ "A_B1900_FLOORGR1": {
+ "period_of_construction": "1800_1900",
+ "climate_zone": "B3",
+ "type": "GroundFloor",
+ "u_value": 1.39,
+ "layers": {
+ "RP01": 0.4,
+ "M01": 0.04,
+ "PC01": 0.03
+ }
+ }
+ },
+ {
+ "B_1901_1940_FACEXT1": {
+ "period_of_construction": "1901_1940",
+ "climate_zone": "B3",
+ "type": "OutdoorsWall",
+ "u_value": 1.8,
+ "layers": {
+ "RI01": 0.01,
+ "PF033": 0.29,
+ "RE01": 0.02
+ }
+ }
+ },
+ {
+ "B_1901_1940_ROOF1": {
+ "period_of_construction": "1901_1940",
+ "climate_zone": "B3",
+ "type": "OutdoorsRoofCeiling",
+ "u_value": 1.28,
+ "layers": {
+ "ECGX": 0.02,
+ "CA02": 0.2,
+ "F03": 0.2,
+ "CAV20": 0.2,
+ "PC01": 0.06
+ }
+ }
+ },
+ {
+ "B_1901_1940_FLOORGR1": {
+ "period_of_construction": "1901_1940",
+ "climate_zone": "B3",
+ "type": "GroundFloor",
+ "u_value": 1.28,
+ "layers": {
+ "ECGX": 0.02,
+ "CA02": 0.2,
+ "F03": 0.2,
+ "CAV20": 0.2,
+ "PC01": 0.06
+ }
+ }
+ },
+ {
+ "C_1941_1960_FACEXT1": {
+ "period_of_construction": "1941_1960",
+ "climate_zone": "B3",
+ "type": "OutdoorsWall",
+ "u_value": 1.82,
+ "layers": {
+ "RI01": 0.01,
+ "PF012": 0.04,
+ "CA10": 0.1,
+ "PF021": 0.14,
+ "RE01": 0.02
+ }
+ }
+ },
+ {
+ "C_1941_1960_ROOF1": {
+ "period_of_construction": "1941_1960",
+ "climate_zone": "B3",
+ "type": "OutdoorsRoofCeiling",
+ "u_value": 1.4,
+ "layers": {
+ "RI01": 0.01,
+ "F03": 0.2,
+ "CAV16": 0.16,
+ "SC01": 0.05,
+ "M01": 0.04,
+ "PC01": 0.03
+ }
+ }
+ },
+ {
+ "C_1941_1960_FLOORGR1": {
+ "period_of_construction": "1941_1960",
+ "climate_zone": "B3",
+ "type": "GroundFloor",
+ "u_value": 1.47,
+ "layers": {
+ "AI06": 0.2,
+ "M02": 0.2,
+ "M01": 0.04,
+ "PC01": 0.03
+ }
+ }
+ },
+ {
+ "E_1981_2007_FACEXT1": {
+ "period_of_construction": "1981_2007",
+ "climate_zone": "B3",
+ "type": "OutdoorsWall",
+ "u_value": 0.73,
+ "layers": {
+ "RI01": 0.02,
+ "F02": 0.3,
+ "AI02": 0.04,
+ "M02": 0.1,
+ "PC01": 0.04
+ }
+ }
+ },
+ {
+ "E_1981_2007_ROOF1": {
+ "period_of_construction": "1981_2007",
+ "climate_zone": "B3",
+ "type": "OutdoorsRoofCeiling",
+ "u_value": 0.46,
+ "layers": {
+ "RI01": 0.02,
+ "PF022": 0.04,
+ "AI01": 0.02,
+ "CA7": 0.07,
+ "PF021": 0.14,
+ "M01": 0.02
+ }
+ }
+ },
+ {
+ "E_1981_2007_FLOORGR1": {
+ "period_of_construction": "1981_2007",
+ "climate_zone": "B3",
+ "type": "GroundFloor",
+ "u_value": 1.69,
+ "layers": {
+ "F02": 0.25,
+ "M01": 0.025,
+ "PT01": 0.025
+ }
+ }
+ },
+ {
+ "F_2008_2014_FACEXT1": {
+ "period_of_construction": "2008_2014",
+ "climate_zone": "B3",
+ "type": "OutdoorsWall",
+ "u_value": 0.6,
+ "layers": {
+ "RI01": 0.02,
+ "PF022": 0.05,
+ "AI01": 0.03,
+ "CAV16": 0.05,
+ "PF021": 0.14,
+ "RE01": 0.02
+ }
+ }
+ },
+ {
+ "F_2008_2014_ROOF1": {
+ "period_of_construction": "2008_2014",
+ "climate_zone": "B3",
+ "type": "OutdoorsRoofCeiling",
+ "u_value": 0.46,
+ "layers": {
+ "RI01": 0.02,
+ "F02": 0.3,
+ "AI02": 0.07,
+ "M02": 0.1,
+ "M01": 0.01,
+ "PC01": 0.01
+ }
+ }
+ },
+ {
+ "F_2008_2014_FLOORGR1": {
+ "period_of_construction": "2008_2014",
+ "climate_zone": "B3",
+ "type": "GroundFloor",
+ "u_value": 1.59,
+ "layers": {
+ "F02": 0.3,
+ "AI02": 0.05,
+ "M01": 0.025,
+ "PT01": 0.025
+ }
+ }
+ },
+ {
+ "G_2015_2019_FACEXT1": {
+ "period_of_construction": "2015_2019",
+ "climate_zone": "B3",
+ "type": "OutdoorsWall",
+ "u_value": 0.6,
+ "layers": {
+ "RI01": 0.01,
+ "PF022": 0.09,
+ "AI01": 0.04,
+ "CAV16": 0.06,
+ "PF021": 0.14,
+ "M01": 0.02
+ }
+ }
+ },
+ {
+ "G_2015_2019_ROOF1": {
+ "period_of_construction": "2015_2019",
+ "climate_zone": "B3",
+ "type": "OutdoorsRoofCeiling",
+ "u_value": 0.37,
+ "layers": {
+ "RI01": 0.02,
+ "F02": 0.3,
+ "AI02": 0.07,
+ "M02": 0.1,
+ "M01": 0.01,
+ "PC01": 0.01
+ }
+ }
+ },
+ {
+ "G_2015_2019_FLOORGR1": {
+ "period_of_construction": "2015_2019",
+ "climate_zone": "B3",
+ "type": "GroundFloor",
+ "u_value": 0.57,
+ "layers": {
+ "F02": 0.3,
+ "AI02": 0.05,
+ "M01": 0.025,
+ "PT01": 0.025
+ }
+ }
+ },
+ {
+ "PA1_PA2_2021_2050_FLOOR": {
+ "period_of_construction": "2021_2050",
+ "climate_zone": "B3",
+ "type": "GroundFloor",
+ "u_value": 0.75,
+ "layers": {
+ "PT02": 0.03,
+ "CA04": 0,
+ "X01": 0.03,
+ "F04": 0.3,
+ "RI05": 0.01
+ }
+ }
+ },
+ {
+ "PA1_PA2_2021_2050_ROOF": {
+ "period_of_construction": "2021_2050",
+ "climate_zone": "B3",
+ "type": "OutdoorsRoofCeiling",
+ "u_value": 0.44,
+ "layers": {
+ "RI05": 0.01,
+ "F04": 0.3,
+ "CA04": 0,
+ "M04": 0.02,
+ "PC01": 0.04
+ }
+ }
+ },
+ {
+ "PA1_PA2_2021_2050_FACEXT": {
+ "period_of_construction": "2021_2050",
+ "climate_zone": "B3",
+ "type": "OutdoorsWall",
+ "u_value": 0.56,
+ "layers": {
+ "RI05": 0.01,
+ "CA04": 0
+ }
+ }
+ },
+ {
+ "PA1_PA2_2021_2050_FLOORINT": {
+ "period_of_construction": "2021_2050",
+ "climate_zone": "B3",
+ "type": "GroundRoofCeiling",
+ "u_value": 2.207,
+ "layers": {
+ "RI05": 0.01,
+ "F04": 0.3,
+ "IM01": 0.005,
+ "M04": 0.02,
+ "PC01": 0.04
+ }
+ }
+ }
+ ],
+ "transparent_surfaces": [
+ {
+ "PA1_PA2_2021_2050_WIN1": {
+ "period_of_construction": "2021_2050",
+ "climate_zone": "B3",
+ "shgc": 0.65,
+ "type": "Window",
+ "frame_ratio": 0.15,
+ "u_value": 2.3
+ }
+ },
+ {
+ "PA1_PA2_1961_1980_WIN1": {
+ "period_of_construction": "1961_1980",
+ "climate_zone": "B3",
+ "shgc": 0.823,
+ "type": "Window",
+ "frame_ratio": 0.3,
+ "u_value": 5.69
+ }
+ },
+ {
+ "PA3_PA4_1901_1940_WIN1": {
+ "period_of_construction": "1800_1980",
+ "climate_zone": "B3",
+ "shgc": 0.76,
+ "type": "Window",
+ "frame_ratio": 0.3,
+ "u_value": 3.44
+ }
+ },
+ {
+ "A_B1900_WIN2": {
+ "period_of_construction": "1800_1900",
+ "climate_zone": "B3",
+ "shgc": 0.76,
+ "type": "Window",
+ "frame_ratio": 0.3,
+ "u_value": 4.02
+ }
+ },
+ {
+ "B_1901_1940_WIN1": {
+ "period_of_construction": "1901_1940",
+ "climate_zone": "B3",
+ "shgc": 0.76,
+ "type": "Window",
+ "frame_ratio": 0.3,
+ "u_value": 3.44
+ }
+ },
+ {
+ "C_1941_1960_WIN1": {
+ "period_of_construction": "1941_1960",
+ "climate_zone": "B3",
+ "shgc": 0.76,
+ "type": "Window",
+ "frame_ratio": 0.3,
+ "u_value": 3.44
+ }
+ },
+ {
+ "E_1981_2007_WIN1": {
+ "period_of_construction": "1981_2007",
+ "climate_zone": "B3",
+ "shgc": 0.76,
+ "type": "Window",
+ "frame_ratio": 0.3,
+ "u_value": 3.44
+ }
+ },
+ {
+ "F_2008_2014_WIN1": {
+ "period_of_construction": "2008_2014",
+ "climate_zone": "B3",
+ "shgc": 0.76,
+ "type": "Window",
+ "frame_ratio": 0.3,
+ "u_value": 3.44
+ }
+ },
+ {
+ "G_2015_2019_WIN1": {
+ "period_of_construction": "2015_2019",
+ "climate_zone": "B3",
+ "shgc": 0.706,
+ "type": "Window",
+ "frame_ratio": 0.26,
+ "u_value": 3.44
+ }
+ }
+ ],
+ "materials": [
+ {
+ "PUTZ": {
+ "no_mass": false,
+ "conductivity": 2.52,
+ "density": 1400,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "KST": {
+ "no_mass": false,
+ "conductivity": 3.564,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "DAEMA": {
+ "no_mass": false,
+ "conductivity": 0.173,
+ "density": 60,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "GIPS": {
+ "no_mass": false,
+ "conductivity": 0.756,
+ "density": 900,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "HOLZ": {
+ "no_mass": false,
+ "conductivity": 0.468,
+ "density": 600,
+ "specific_heat": 2100.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 2.1
+ }
+ },
+ {
+ "BET": {
+ "no_mass": false,
+ "conductivity": 7.56,
+ "density": 2200,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "TEPP": {
+ "no_mass": false,
+ "conductivity": 0.288,
+ "density": 700,
+ "specific_heat": 1300.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1.3
+ }
+ },
+ {
+ "ESTR": {
+ "no_mass": false,
+ "conductivity": 5.04,
+ "density": 2000,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "MIWO": {
+ "no_mass": false,
+ "conductivity": 0.144,
+ "density": 60,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "DAEMM": {
+ "no_mass": false,
+ "conductivity": 0.144,
+ "density": 60,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "RI01": {
+ "no_mass": false,
+ "conductivity": 1.08,
+ "density": 800,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "X01": {
+ "no_mass": false,
+ "conductivity": 5.884,
+ "density": 2400,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PM01": {
+ "no_mass": false,
+ "conductivity": 5.04,
+ "density": 2000,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "RE01": {
+ "no_mass": false,
+ "conductivity": 3.13,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "ENGUIXAT": {
+ "no_mass": false,
+ "conductivity": 1.083,
+ "density": 800,
+ "specific_heat": 722.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.722
+ }
+ },
+ {
+ "TOTXOMASS": {
+ "no_mass": false,
+ "conductivity": 3.14,
+ "density": 1800,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.83
+ }
+ },
+ {
+ "ARREBOSSAT": {
+ "no_mass": false,
+ "conductivity": 3.14,
+ "density": 1600,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.83
+ }
+ },
+ {
+ "PC01": {
+ "no_mass": false,
+ "conductivity": 3.78,
+ "density": 2000,
+ "specific_heat": 840.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.84
+ }
+ },
+ {
+ "M01": {
+ "no_mass": false,
+ "conductivity": 5.04,
+ "density": 2000,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "RP01": {
+ "no_mass": false,
+ "conductivity": 2.09,
+ "density": 1500,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "EMBLANQUIN": {
+ "no_mass": false,
+ "conductivity": 1.083,
+ "density": 800,
+ "specific_heat": 722.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.722
+ }
+ },
+ {
+ "MAO_CALAT": {
+ "no_mass": false,
+ "conductivity": 2.744,
+ "density": 1600,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.83
+ }
+ },
+ {
+ "ECGX": {
+ "no_mass": false,
+ "conductivity": 0.9,
+ "density": 900,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "CAV20": {
+ "no_mass": true,
+ "thermal_resistance": 0.022,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "CA7": {
+ "no_mass": true,
+ "thermal_resistance": 0.15,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.16
+ }
+ },
+ {
+ "F03": {
+ "no_mass": false,
+ "conductivity": 2.0623,
+ "density": 1290,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "PF021": {
+ "no_mass": false,
+ "conductivity": 2.74,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "PF033": {
+ "no_mass": false,
+ "conductivity": 3.13,
+ "density": 1800,
+ "specific_heat": 1380.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1.38
+ }
+ },
+ {
+ "PF02": {
+ "no_mass": false,
+ "conductivity": 2.74,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "PF032": {
+ "no_mass": false,
+ "conductivity": 3.13,
+ "density": 1800,
+ "specific_heat": 1380.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1.38
+ }
+ },
+ {
+ "FF02": {
+ "no_mass": false,
+ "conductivity": 0.505,
+ "density": 600,
+ "specific_heat": 722.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.722
+ }
+ },
+ {
+ "MARES": {
+ "no_mass": false,
+ "conductivity": 5.4,
+ "density": 2038,
+ "specific_heat": 710.6,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.7106
+ }
+ },
+ {
+ "CA_50": {
+ "no_mass": true,
+ "thermal_resistance": 0.05,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "AI01": {
+ "no_mass": false,
+ "conductivity": 0.13,
+ "density": 15,
+ "specific_heat": 1450.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1.45
+ }
+ },
+ {
+ "MW01": {
+ "no_mass": false,
+ "conductivity": 5.4,
+ "density": 2038,
+ "specific_heat": 710.6,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.7106
+ }
+ },
+ {
+ "POSIDONIA": {
+ "no_mass": false,
+ "conductivity": 0.1548,
+ "density": 185,
+ "specific_heat": 800.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.8
+ }
+ },
+ {
+ "FF01": {
+ "no_mass": false,
+ "conductivity": 0.468,
+ "density": 500,
+ "specific_heat": 1600.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1.6
+ }
+ },
+ {
+ "IM02": {
+ "no_mass": false,
+ "conductivity": 0.36,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "AI09": {
+ "no_mass": false,
+ "conductivity": 0.144,
+ "density": 115,
+ "specific_heat": 1900.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1.9
+ }
+ },
+ {
+ "AI05": {
+ "no_mass": false,
+ "conductivity": 0.14,
+ "density": 30,
+ "specific_heat": 2150.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 2.15
+ }
+ },
+ {
+ "AI08": {
+ "no_mass": false,
+ "conductivity": 0.144,
+ "density": 42.5,
+ "specific_heat": 1340.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1.34
+ }
+ },
+ {
+ "AI10_N": {
+ "no_mass": false,
+ "conductivity": 0.122,
+ "density": 35,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "AI03": {
+ "no_mass": false,
+ "conductivity": 0.16,
+ "density": 28,
+ "specific_heat": 840.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.84
+ }
+ },
+ {
+ "M04": {
+ "no_mass": false,
+ "conductivity": 0.1512,
+ "density": 350,
+ "specific_heat": 1100.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1.1
+ }
+ },
+ {
+ "Y01": {
+ "no_mass": false,
+ "conductivity": 1.08,
+ "density": 800,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "IM01": {
+ "no_mass": false,
+ "conductivity": 0.68,
+ "density": 1100,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "AI02": {
+ "no_mass": false,
+ "conductivity": 0.14,
+ "density": 80,
+ "specific_heat": 1450.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1.45
+ }
+ },
+ {
+ "M03": {
+ "no_mass": false,
+ "conductivity": 0.361,
+ "density": 600,
+ "specific_heat": 722.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.722
+ }
+ },
+ {
+ "M02": {
+ "no_mass": false,
+ "conductivity": 3.14,
+ "density": 1600,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.83
+ }
+ },
+ {
+ "PF022": {
+ "no_mass": false,
+ "conductivity": 2.74,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "IM03": {
+ "no_mass": false,
+ "conductivity": 0.828,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "PAVIMENT_D": {
+ "no_mass": false,
+ "conductivity": 3.791,
+ "density": 2000,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 0.83
+ }
+ },
+ {
+ "CAV16": {
+ "no_mass": true,
+ "thermal_resistance": 0.15,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.1
+ }
+ },
+ {
+ "CEMENT_MOR": {
+ "no_mass": false,
+ "conductivity": 5.04,
+ "density": 2000,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "BAXI_MorteroCem": {
+ "no_mass": false,
+ "conductivity": 1.48,
+ "density": 1125,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "BAXI_LadrilloPerf": {
+ "no_mass": false,
+ "conductivity": 3.57,
+ "density": 2140,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "BAXI_EPS": {
+ "no_mass": false,
+ "conductivity": 0.13,
+ "density": 30,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "BAXI_LadrilloHueco": {
+ "no_mass": false,
+ "conductivity": 1.6,
+ "density": 2140,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6,
+ "capacity": 1
+ }
+ },
+ {
+ "BAXI_Yeso": {
+ "no_mass": false,
+ "conductivity": 2.05,
+ "density": 1150,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PG01": {
+ "no_mass": false,
+ "conductivity": 8.28,
+ "density": 2600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "F01": {
+ "no_mass": false,
+ "conductivity": 4.5,
+ "density": 1500,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RF_INSULATION": {
+ "no_mass": false,
+ "conductivity": 0.072,
+ "density": 25,
+ "specific_heat": 1800.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RF_SLAB": {
+ "no_mass": false,
+ "conductivity": 4.32,
+ "density": 2000,
+ "specific_heat": 1100.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RF_COVERING": {
+ "no_mass": false,
+ "conductivity": 0.72,
+ "density": 800,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RF_PIPES": {
+ "no_mass": false,
+ "pspacing": 0.15,
+ "pdiameter": 0.016,
+ "pwallthickness": 0.002,
+ "conductivity": 1.26,
+ "cpfluid": 4.18,
+ "density": null,
+ "specific_heat": null,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "EF01": {
+ "no_mass": false,
+ "conductivity": 1.76,
+ "density": 1200,
+ "specific_heat": 920.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PF01": {
+ "no_mass": false,
+ "conductivity": 1.76,
+ "density": 1200,
+ "specific_heat": 920.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PF02": {
+ "no_mass": false,
+ "conductivity": 2.74,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "AI01": {
+ "no_mass": false,
+ "conductivity": 0.13,
+ "density": 15,
+ "specific_heat": 1450.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "AI02": {
+ "no_mass": false,
+ "conductivity": 0.14,
+ "density": 80,
+ "specific_heat": 1450.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "CA01": {
+ "no_mass": true,
+ "thermal_resistance": 0.05,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "FC01": {
+ "no_mass": false,
+ "conductivity": 1.19,
+ "density": 1000,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "AI06": {
+ "no_mass": false,
+ "conductivity": 7.2,
+ "density": 2000,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PT01": {
+ "no_mass": false,
+ "conductivity": 5.87,
+ "density": 2400,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "CA02": {
+ "no_mass": true,
+ "thermal_resistance": 0.044,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "CA03": {
+ "no_mass": true,
+ "thermal_resistance": 0.047,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "CA04": {
+ "no_mass": true,
+ "thermal_resistance": 2,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "EF02": {
+ "no_mass": false,
+ "conductivity": 3.13,
+ "density": 1800,
+ "specific_heat": 1380.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RI02": {
+ "no_mass": false,
+ "conductivity": 3.13,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RI03": {
+ "no_mass": false,
+ "conductivity": 0.9,
+ "density": 900,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RI04": {
+ "no_mass": false,
+ "conductivity": 0.72,
+ "density": 800,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "FG01": {
+ "no_mass": false,
+ "conductivity": 4.18,
+ "density": 2000,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "F02": {
+ "no_mass": false,
+ "conductivity": 2.4,
+ "density": 1250,
+ "specific_heat": 900.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PM01": {
+ "no_mass": false,
+ "conductivity": 5.04,
+ "density": 2000,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "TC01": {
+ "no_mass": false,
+ "conductivity": 3.78,
+ "density": 2000,
+ "specific_heat": 800.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "CC01": {
+ "no_mass": false,
+ "conductivity": 3.78,
+ "density": 2000,
+ "specific_heat": 840.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "CF01": {
+ "no_mass": false,
+ "conductivity": 0.5,
+ "density": 600,
+ "specific_heat": 1600.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RC01": {
+ "no_mass": false,
+ "conductivity": 2.09,
+ "density": 1500,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RC02": {
+ "no_mass": false,
+ "conductivity": 2.92,
+ "density": 1700,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "SC01": {
+ "no_mass": false,
+ "conductivity": 1.76,
+ "density": 1200,
+ "specific_heat": 840.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "EPS": {
+ "no_mass": false,
+ "conductivity": 0.13,
+ "density": 30,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "ENGUIXAT": {
+ "no_mass": false,
+ "conductivity": 1.083,
+ "density": 800,
+ "specific_heat": 722.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "TOTXO_FOR": {
+ "no_mass": false,
+ "conductivity": 1.769,
+ "density": 1200,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "ARREBOSSAT": {
+ "no_mass": false,
+ "conductivity": 3.14,
+ "density": 1600,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PTERRATZO": {
+ "no_mass": false,
+ "conductivity": 5.054,
+ "density": 2000,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "MORTER": {
+ "no_mass": false,
+ "conductivity": 4.188,
+ "density": 2000,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "XAPACOMP": {
+ "no_mass": false,
+ "conductivity": 5.884,
+ "density": 2400,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "CASSETONS": {
+ "no_mass": false,
+ "conductivity": 5.7,
+ "density": 1033,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "FORMIGOARM": {
+ "no_mass": false,
+ "conductivity": 5.844,
+ "density": 2400,
+ "specific_heat": 866.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "DEEPCONCR": {
+ "no_mass": false,
+ "conductivity": 5.86,
+ "density": 2400,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "TERRA": {
+ "no_mass": false,
+ "conductivity": 0.68,
+ "density": 1000,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "AI08": {
+ "no_mass": false,
+ "conductivity": 0.144,
+ "density": 42.5,
+ "specific_heat": 1340.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "AI09": {
+ "no_mass": false,
+ "conductivity": 0.144,
+ "density": 115,
+ "specific_heat": 1900.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "FORMPENDEN": {
+ "no_mass": false,
+ "conductivity": 0.361,
+ "density": 600,
+ "specific_heat": 722.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "TELAASFALT": {
+ "no_mass": false,
+ "conductivity": 0.686,
+ "density": 1100,
+ "specific_heat": 1010.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RAJOLACERA": {
+ "no_mass": false,
+ "conductivity": 3.79,
+ "density": 2000,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PH01": {
+ "no_mass": false,
+ "conductivity": 3.3228,
+ "density": 860,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "AI03": {
+ "no_mass": false,
+ "conductivity": 0.16,
+ "density": 28,
+ "specific_heat": 840.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "AI04": {
+ "no_mass": false,
+ "conductivity": 0.12,
+ "density": 22,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "IM02": {
+ "no_mass": false,
+ "conductivity": 0.36,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "IM03": {
+ "no_mass": false,
+ "conductivity": 0.828,
+ "density": 1600,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "RI05": {
+ "no_mass": false,
+ "conductivity": 1.083,
+ "density": 800,
+ "specific_heat": 722.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PF012": {
+ "no_mass": false,
+ "conductivity": 1.769,
+ "density": 1200,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "MAO_MASSIS": {
+ "no_mass": false,
+ "conductivity": 3.141,
+ "density": 1800,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "F04": {
+ "no_mass": false,
+ "conductivity": 5.7,
+ "density": 1033,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "FC02": {
+ "no_mass": false,
+ "conductivity": 5.844,
+ "density": 2400,
+ "specific_heat": 866.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PH02": {
+ "no_mass": false,
+ "conductivity": 5.7,
+ "density": 1033,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PF013": {
+ "no_mass": false,
+ "conductivity": 1.769,
+ "density": 1200,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "PT02": {
+ "no_mass": false,
+ "conductivity": 5.054,
+ "density": 2000,
+ "specific_heat": 830.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "ConceteBl": {
+ "no_mass": false,
+ "conductivity": 1.836,
+ "density": 1400,
+ "specific_heat": 1000,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "FoamInsul": {
+ "no_mass": false,
+ "conductivity": 0.144,
+ "density": 10,
+ "specific_heat": 1400.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ },
+ {
+ "WoodSiding": {
+ "no_mass": false,
+ "conductivity": 0.504,
+ "density": 530,
+ "specific_heat": 900.0,
+ "thermal_emittance": 0.9,
+ "solar_absorptance": 0.6,
+ "visible_absorptance": 0.6
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/hub/data/energy_systems/montreal_future_systems.xml b/hub/data/energy_systems/montreal_future_systems.xml
index b51c9488..5d9b2fb6 100644
--- a/hub/data/energy_systems/montreal_future_systems.xml
+++ b/hub/data/energy_systems/montreal_future_systems.xml
@@ -457,6 +457,7 @@
+
2.01
@@ -1035,6 +1036,7 @@
+
1.0
diff --git a/hub/data/energy_systems/palma_systems.xml b/hub/data/energy_systems/palma_systems.xml
new file mode 100644
index 00000000..1b788dbf
--- /dev/null
+++ b/hub/data/energy_systems/palma_systems.xml
@@ -0,0 +1,809 @@
+
+
+ ./schemas/
+
+
+ 1
+ Water
+
+
+
+
+
+ 981.0
+ 4180.0
+ 0.6
+
+
+
+
+ 1
+ Natural-Gas Boiler
+ boiler
+
+
+
+
+
+ 0.7
+ False
+ natural gas
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+ False
+
+
+ 2
+ Joule
+ joule
+
+
+
+
+
+ 1
+ False
+ electricity
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+ False
+
+
+ 3
+ Heat Pump
+ heat pump
+
+
+
+
+
+ 2
+ True
+ electricity
+ Air
+ Water
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+
+
+ False
+
+
+ 4
+ Butane Heater
+ butane heater
+
+
+
+
+
+ 0.7
+ False
+ butane
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+ False
+
+
+ 5
+ Split
+ split
+
+
+
+
+
+
+ False
+ electricity
+
+
+
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+
+
+ False
+
+
+ 6
+ Domestic Hot Water Heat Pump
+ heat pump
+
+
+
+
+
+ 3
+ False
+ electricity
+ Air
+ Water
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+
+
+
+ 7
+ template Photovoltaic Module
+ Photovoltaic
+
+
+
+ 0.2
+ 20
+ 45
+ 800
+ 25
+ 1000
+ 500
+
+ 2.0
+ 1.0
+
+
+ False
+
+
+ 8
+ Photovoltaic Module
+ Photovoltaic
+ RE400CAA Pure 2
+ REC
+ 305
+ 0.206
+ 20
+ 44
+ 800
+ 25
+ 1000
+ 400
+ 0.24
+ 1.86
+ 1.04
+
+
+ False
+
+
+ 9
+ Photovoltaic Module
+ Photovoltaic
+ RE410CAA Pure 2
+ REC
+ 312
+ 0.211
+ 20
+ 44
+ 800
+ 25
+ 1000
+ 410
+ 0.24
+ 1.86
+ 1.04
+
+
+ False
+
+
+ 10
+ Photovoltaic Module
+ Photovoltaic
+ RE420CAA Pure 2
+ REC
+ 320
+ 0.217
+ 20
+ 44
+ 800
+ 25
+ 1000
+ 420
+ 0.24
+ 1.86
+ 1.04
+
+
+ False
+
+
+ 11
+ Photovoltaic Module
+ Photovoltaic
+ RE430CAA Pure 2
+ REC
+ 327
+ 0.222
+ 20
+ 44
+ 800
+ 25
+ 1000
+ 430
+ 0.24
+ 1.86
+ 1.04
+
+
+ False
+
+
+ 12
+ Photovoltaic Module
+ Photovoltaic
+ REC600AA Pro M
+ REC
+ 457
+ 0.211
+ 20
+ 44
+ 800
+ 25
+ 1000
+ 600
+ 0.24
+ 2.17
+ 1.3
+
+
+ False
+
+
+ 13
+ Photovoltaic Module
+ Photovoltaic
+ REC610AA Pro M
+ REC
+ 464
+ 0.215
+ 20
+ 44
+ 800
+ 25
+ 1000
+ 610
+ 0.24
+ 2.17
+ 1.3
+
+
+ False
+
+
+ 14
+ Photovoltaic Module
+ Photovoltaic
+ REC620AA Pro M
+ REC
+ 472
+ 0.218
+ 20
+ 44
+ 800
+ 25
+ 1000
+ 620
+ 0.24
+ 2.17
+ 1.3
+
+
+ False
+
+
+ 15
+ Photovoltaic Module
+ Photovoltaic
+ REC630AA Pro M
+ REC
+ 480
+ 0.222
+ 20
+ 44
+ 800
+ 25
+ 1000
+ 630
+ 0.24
+ 2.17
+ 1.3
+
+
+ False
+
+
+ 16
+ Photovoltaic Module
+ Photovoltaic
+ REC640AA Pro M
+ REC
+ 487
+ 0.215
+ 20
+ 44
+ 800
+ 25
+ 1000
+ 640
+ 0.24
+ 2.17
+ 1.3
+
+
+ False
+
+
+
+
+ 6
+ template Hot Water Storage Tank
+ thermal
+
+
+ 95.0
+
+ 1
+ 90.0
+
+
+ 2
+ 0
+ 1.5
+ Steel
+
+
+
+ 1
+
+ sensible
+
+
+
+
+
+ 7
+ template Hot Water Storage Tank with Heating Coil
+ thermal
+
+
+ 95.0
+
+ 1
+ 90.0
+
+
+ 2
+ 0
+ 1.5
+ Steel
+
+
+
+ 1
+
+ sensible
+
+
+ 5000
+
+
+
+
+ 1
+ Polyurethane
+
+
+
+
+
+
+
+ 0.028
+
+
+ 2
+ Steel
+
+
+
+
+
+
+
+ 18
+
+
+
+
+
+
+
+
+
+
+ 1
+ Central gas system
+
+
+ heating
+ domestic_hot_water
+
+
+ 1
+
+
+
+ 2
+ Central Joule system
+
+
+ heating
+ domestic_hot_water
+
+
+ 2
+
+
+
+ 3
+ Central butane system
+
+
+ heating
+ domestic_hot_water
+
+
+ 4
+
+
+
+ 4
+ Single zone split system
+
+
+ cooling
+
+
+ 5
+
+
+
+ 5
+ 4 pipe heat pump system
+
+
+ heating
+ cooling
+
+
+ 3
+
+
+
+ 6
+ PV
+
+
+ electricity
+
+
+ 7
+
+
+
+ 7
+ Gas heating
+
+
+ heating
+
+
+ 1
+
+
+
+ 8
+ Electrical heating
+
+
+ heating
+
+
+ 2
+
+
+
+ 9
+ Butane heating
+
+
+ heating
+
+
+ 4
+
+
+
+ 10
+ Gas hot water system
+
+
+ domestic_hot_water
+
+
+ 1
+
+
+
+ 11
+ Electrical hot water system
+
+
+ domestic_hot_water
+
+
+ 2
+
+
+
+ 12
+ Butane hot water system
+
+
+ domestic_hot_water
+
+
+ 4
+
+
+
+ 13
+ Heat Pump hot water system
+
+
+ domestic_hot_water
+
+
+ 6
+
+
+
+
+
+
+ Gas boiler for heating and hot water heater with split cooling
+
+ 1
+ 4
+
+
+
+ Joule heater for heating and hot water heater with split cooling
+
+ 2
+ 4
+
+
+
+ Butane heater for heating and hot water heater with split cooling
+
+ 3
+ 4
+
+
+
+ Gas heating
+
+ 1
+
+
+
+ Electrical joule heating
+
+ 2
+
+
+
+ Butane heating
+
+ 3
+
+
+
+ Heat pump with gas water heater
+
+ 5
+ 7
+
+
+
+ Heat pump with joule water heater
+
+ 5
+ 8
+
+
+
+ Heat pump with butane water heater
+
+ 5
+ 9
+
+
+
+ Heat pump with gas water heater and rooftop PV
+
+ 5
+ 7
+ 6
+
+
+
+ Heat pump with joule water heater and rooftop PV
+
+ 5
+ 8
+ 6
+
+
+
+ Rooftop PV
+
+ 6
+
+
+
+ Joule heater with split cooling and gas hot water
+
+ 4
+ 8
+ 10
+
+
+
+ Joule heater with split cooling and butane hot water
+
+ 4
+ 8
+ 12
+
+
+
+ PV and heat pump
+
+ 5
+ 6
+ 13
+
+
+
+
+
diff --git a/hub/data/usage/palma_schedules.json b/hub/data/usage/palma_schedules.json
new file mode 100644
index 00000000..a16d6e88
--- /dev/null
+++ b/hub/data/usage/palma_schedules.json
@@ -0,0 +1,904 @@
+{
+ "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
+ ]
+ }
+ ]
+ }}}
\ No newline at end of file
diff --git a/hub/data/usage/palma_space_compliance.json b/hub/data/usage/palma_space_compliance.json
new file mode 100644
index 00000000..31ed06b8
--- /dev/null
+++ b/hub/data/usage/palma_space_compliance.json
@@ -0,0 +1,30 @@
+{
+ "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
+ }]
+ }
+ }
+}
\ No newline at end of file
diff --git a/hub/data/usage/palma_space_types.json b/hub/data/usage/palma_space_types.json
new file mode 100644
index 00000000..d12bfb27
--- /dev/null
+++ b/hub/data/usage/palma_space_types.json
@@ -0,0 +1,97 @@
+{
+ "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
+ }
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/hub/exports/building_energy/idf.py b/hub/exports/building_energy/idf.py
index e748d2eb..a6d06d76 100644
--- a/hub/exports/building_energy/idf.py
+++ b/hub/exports/building_energy/idf.py
@@ -332,6 +332,7 @@ 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:
diff --git a/hub/exports/formats/simplified_radiosity_algorithm.py b/hub/exports/formats/simplified_radiosity_algorithm.py
index 25189419..ad622f9b 100644
--- a/hub/exports/formats/simplified_radiosity_algorithm.py
+++ b/hub/exports/formats/simplified_radiosity_algorithm.py
@@ -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] / cte.WATTS_HOUR_TO_JULES
- _beam = representative_building.direct_normal[cte.HOUR][i] / cte.WATTS_HOUR_TO_JULES
+ _global = representative_building.diffuse[cte.HOUR][i]
+ _beam = representative_building.direct_normal[cte.HOUR][i]
content += f'{day} {month} {hour} {_global} {_beam}\n'
with open(file, 'w', encoding='utf-8') as file:
file.write(content)
diff --git a/hub/helpers/constants.py b/hub/helpers/constants.py
index 39586c54..f345b4f0 100644
--- a/hub/helpers/constants.py
+++ b/hub/helpers/constants.py
@@ -24,6 +24,7 @@ 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
@@ -294,6 +295,7 @@ GAS = 'Gas'
DIESEL = 'Diesel'
COAL = 'Coal'
BIOMASS = 'Biomass'
+BUTANE = 'Butane'
AIR = 'Air'
WATER = 'Water'
GEOTHERMAL = 'Geothermal'
@@ -306,6 +308,9 @@ 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'
diff --git a/hub/helpers/data/hub_function_to_palma_construction_function.py b/hub/helpers/data/hub_function_to_palma_construction_function.py
new file mode 100644
index 00000000..8c1c8451
--- /dev/null
+++ b/hub/helpers/data/hub_function_to_palma_construction_function.py
@@ -0,0 +1,30 @@
+"""
+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
\ No newline at end of file
diff --git a/hub/helpers/data/hub_usage_to_palma_usage.py b/hub/helpers/data/hub_usage_to_palma_usage.py
new file mode 100644
index 00000000..834670f7
--- /dev/null
+++ b/hub/helpers/data/hub_usage_to_palma_usage.py
@@ -0,0 +1,51 @@
+"""
+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
diff --git a/hub/helpers/data/montreal_custom_fuel_to_hub_fuel.py b/hub/helpers/data/montreal_custom_fuel_to_hub_fuel.py
index 14fd0fef..be65a012 100644
--- a/hub/helpers/data/montreal_custom_fuel_to_hub_fuel.py
+++ b/hub/helpers/data/montreal_custom_fuel_to_hub_fuel.py
@@ -12,12 +12,16 @@ class MontrealCustomFuelToHubFuel:
"""
Montreal custom fuel to hub fuel class
"""
+
def __init__(self):
self._dictionary = {
- 'gas': cte.GAS,
- 'electricity': cte.ELECTRICITY,
- 'renewable': cte.RENEWABLE
- }
+ 'gas': cte.GAS,
+ 'natural gas': cte.GAS,
+ 'electricity': cte.ELECTRICITY,
+ 'renewable': cte.RENEWABLE,
+ 'butane': cte.BUTANE,
+ 'diesel': cte.DIESEL
+ }
@property
def dictionary(self) -> dict:
diff --git a/hub/helpers/data/montreal_generation_system_to_hub_energy_generation_system.py b/hub/helpers/data/montreal_generation_system_to_hub_energy_generation_system.py
index 7a42c832..be85d7b6 100644
--- a/hub/helpers/data/montreal_generation_system_to_hub_energy_generation_system.py
+++ b/hub/helpers/data/montreal_generation_system_to_hub_energy_generation_system.py
@@ -18,8 +18,12 @@ class MontrealGenerationSystemToHubEnergyGenerationSystem:
'furnace': cte.BASEBOARD,
'cooler': cte.CHILLER,
'electricity generator': cte.ELECTRICITY_GENERATOR,
- 'PV system': cte.PHOTOVOLTAIC,
- 'heat pump': cte.HEAT_PUMP
+ 'Photovoltaic': cte.PHOTOVOLTAIC,
+ 'heat pump': cte.HEAT_PUMP,
+ 'joule': cte.JOULE,
+ 'split': cte.SPLIT,
+ 'butane heater': cte.BUTANE_HEATER
+
}
@property
diff --git a/hub/helpers/data/palma_function_to_hub_function.py b/hub/helpers/data/palma_function_to_hub_function.py
new file mode 100644
index 00000000..5aae2822
--- /dev/null
+++ b/hub/helpers/data/palma_function_to_hub_function.py
@@ -0,0 +1,31 @@
+"""
+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
\ No newline at end of file
diff --git a/hub/helpers/dictionaries.py b/hub/helpers/dictionaries.py
index 107a543a..1775152a 100644
--- a/hub/helpers/dictionaries.py
+++ b/hub/helpers/dictionaries.py
@@ -26,6 +26,9 @@ 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:
@@ -65,6 +68,14 @@ 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:
"""
@@ -88,6 +99,13 @@ 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:
@@ -105,6 +123,14 @@ 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:
"""
diff --git a/hub/imports/construction/helpers/construction_helper.py b/hub/imports/construction/helpers/construction_helper.py
index d75d8424..8eaf758c 100644
--- a/hub/imports/construction/helpers/construction_helper.py
+++ b/hub/imports/construction/helpers/construction_helper.py
@@ -65,6 +65,10 @@ class ConstructionHelper:
'Eilat': 'BWh'
}
+ _reference_city_to_palma_climate_zone ={
+ 'Palma': 'B3'
+ }
+
@staticmethod
def yoc_to_nrel_standard(year_of_construction):
"""
@@ -107,3 +111,13 @@ 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]
+
diff --git a/hub/imports/construction/nrcan_physics_parameters.py b/hub/imports/construction/nrcan_physics_parameters.py
index c65bd2da..35f5382a 100644
--- a/hub/imports/construction/nrcan_physics_parameters.py
+++ b/hub/imports/construction/nrcan_physics_parameters.py
@@ -3,6 +3,7 @@ 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
@@ -32,10 +33,21 @@ class NrcanPhysicsParameters:
city = self._city
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
for building in city.buildings:
- if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
- logging.error('Building %s has an unknown building function %s', building.name, building.function)
+ main_function = None
+ functions = building.function.split('_')
+ if len(functions) > 1:
+ maximum_percentage = 0
+ for function in functions:
+ percentage_and_function = function.split('-')
+ if float(percentage_and_function[0]) > maximum_percentage:
+ maximum_percentage = float(percentage_and_function[0])
+ main_function = percentage_and_function[-1]
+ else:
+ main_function = functions[-1]
+ if main_function not in Dictionaries().hub_function_to_nrcan_construction_function:
+ logging.error('Building %s has an unknown building function %s', building.name, main_function)
continue
- function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
+ function = Dictionaries().hub_function_to_nrcan_construction_function[main_function]
try:
archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone)
diff --git a/hub/imports/construction/palma_physics_parameters.py b/hub/imports/construction/palma_physics_parameters.py
new file mode 100644
index 00000000..cf80a384
--- /dev/null
+++ b/hub/imports/construction/palma_physics_parameters.py
@@ -0,0 +1,107 @@
+"""
+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
diff --git a/hub/imports/construction_factory.py b/hub/imports/construction_factory.py
index dcf8b054..bc97d245 100644
--- a/hub/imports/construction_factory.py
+++ b/hub/imports/construction_factory.py
@@ -10,6 +10,7 @@ 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:
@@ -48,6 +49,15 @@ 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
diff --git a/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py b/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py
index 0a9d589f..710efd00 100644
--- a/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py
+++ b/hub/imports/energy_systems/montreal_custom_energy_system_parameters.py
@@ -85,7 +85,7 @@ class MontrealCustomEnergySystemParameters:
for archetype_generation_system in archetype_system.generation_systems:
if archetype_generation_system.system_type == 'Photovoltaic':
_generation_system = PvGenerationSystem()
- _type = 'PV system'
+ _type = 'Photovoltaic'
_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]
diff --git a/hub/imports/energy_systems/montreal_future_energy_systems_parameters.py b/hub/imports/energy_systems/montreal_future_energy_systems_parameters.py
index ab2b6dda..73484f33 100644
--- a/hub/imports/energy_systems/montreal_future_energy_systems_parameters.py
+++ b/hub/imports/energy_systems/montreal_future_energy_systems_parameters.py
@@ -92,7 +92,7 @@ class MontrealFutureEnergySystemParameters:
_generation_system.name = archetype_generation_system.name
_generation_system.model_name = archetype_generation_system.model_name
_generation_system.manufacturer = archetype_generation_system.manufacturer
- _type = 'PV system'
+ _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
@@ -119,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().north_america_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_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
diff --git a/hub/imports/energy_systems/palma_energy_systems_parameters.py b/hub/imports/energy_systems/palma_energy_systems_parameters.py
new file mode 100644
index 00000000..f61f5ea1
--- /dev/null
+++ b/hub/imports/energy_systems/palma_energy_systems_parameters.py
@@ -0,0 +1,216 @@
+"""
+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
diff --git a/hub/imports/energy_systems_factory.py b/hub/imports/energy_systems_factory.py
index 5a9344b8..ea5ad89b 100644
--- a/hub/imports/energy_systems_factory.py
+++ b/hub/imports/energy_systems_factory.py
@@ -11,6 +11,7 @@ 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:
"""
@@ -52,6 +53,15 @@ 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
diff --git a/hub/imports/geometry/geojson.py b/hub/imports/geometry/geojson.py
index b07a6a7b..998a2298 100644
--- a/hub/imports/geometry/geojson.py
+++ b/hub/imports/geometry/geojson.py
@@ -127,6 +127,27 @@ class Geojson:
function = None
if self._function_field is not None:
function = str(feature['properties'][self._function_field])
+ if function == 'Mixed use' or function == 'mixed use':
+ function_parts = []
+ if 'usages' in feature['properties']:
+ usages = feature['properties']['usages']
+ for usage in usages:
+ if self._function_to_hub is not None and usage['usage'] in self._function_to_hub:
+ function_parts.append(f"{usage['percentage']}-{self._function_to_hub[usage['usage']]}")
+ else:
+ function_parts.append(f"{usage['percentage']}-{usage['usage']}")
+ else:
+ for key, value in feature['properties'].items():
+ if key.startswith("mixed_type_") and not key.endswith("_percentage"):
+ type_key = key
+ percentage_key = f"{key}_percentage"
+ if percentage_key in feature['properties']:
+ if self._function_to_hub is not None and feature['properties'][type_key] in self._function_to_hub:
+ usage_function = self._function_to_hub[feature['properties'][type_key]]
+ function_parts.append(f"{feature['properties'][percentage_key]}-{usage_function}")
+ else:
+ function_parts.append(f"{feature['properties'][percentage_key]}-{feature['properties'][type_key]}")
+ function = "_".join(function_parts)
if self._function_to_hub is not None:
# use the transformation dictionary to retrieve the proper function
if function in self._function_to_hub:
@@ -135,6 +156,8 @@ class Geojson:
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:
diff --git a/hub/imports/usage/comnet_usage_parameters.py b/hub/imports/usage/comnet_usage_parameters.py
index 02f9b77e..a3a6a613 100644
--- a/hub/imports/usage/comnet_usage_parameters.py
+++ b/hub/imports/usage/comnet_usage_parameters.py
@@ -3,6 +3,7 @@ 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
@@ -18,6 +19,8 @@ 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:
@@ -35,29 +38,62 @@ class ComnetUsageParameters:
city = self._city
comnet_catalog = UsageCatalogFactory('comnet').catalog
for building in city.buildings:
- usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
- try:
- archetype_usage = self._search_archetypes(comnet_catalog, usage_name)
- except KeyError:
- logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
- continue
-
- for internal_zone in building.internal_zones:
- if internal_zone.area is None:
- raise TypeError('Internal zone area not defined, ACH cannot be calculated')
- if internal_zone.volume is None:
- raise TypeError('Internal zone volume not defined, ACH cannot be calculated')
- if internal_zone.area <= 0:
- raise TypeError('Internal zone area is zero, ACH cannot be calculated')
- volume_per_area = internal_zone.volume / internal_zone.area
- usage = Usage()
- 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, archetype_usage)
-
- internal_zone.usages = [usage]
+ usages = []
+ comnet_archetype_usages = []
+ building_functions = building.function.split('_')
+ for function in building_functions:
+ usages.append(function.split('-'))
+ for usage in usages:
+ comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]]
+ 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 = []
+ 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][-1])
+ 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][-1])
+ 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][-1])
+ continue
+ volume_per_area += internal_zone.volume / internal_zone.area
+ usage = Usage()
+ usage.name = usages[i][-1]
+ self._assign_values(usage, comnet_archetype_usages[i], 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)
+ storeys_above_ground = self.average_storey_height_calculator(self._city, building)
+ volume_per_area = building.volume / building.floor_area / storeys_above_ground
+ for (j, mixed_usage) in enumerate(usages):
+ usage = Usage()
+ usage.name = mixed_usage[-1]
+ if len(usages) > 1:
+ usage.percentage = float(mixed_usage[0]) / 100
+ else:
+ usage.percentage = 1
+ 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
@staticmethod
def _search_archetypes(comnet_catalog, usage_name):
comnet_archetypes = comnet_catalog.entries('archetypes').usages
@@ -229,3 +265,37 @@ 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
+ main_function = None
+ functions = building.function.split('_')
+ if len(functions) > 1:
+ maximum_percentage = 0
+ for function in functions:
+ percentage_and_function = function.split('-')
+ if float(percentage_and_function[0]) > maximum_percentage:
+ maximum_percentage = float(percentage_and_function[0])
+ main_function = percentage_and_function[-1]
+ else:
+ main_function = functions[-1]
+ if main_function not in Dictionaries().hub_function_to_nrcan_construction_function:
+ logging.error('Building %s has an unknown building function %s', building.name, main_function)
+ function = Dictionaries().hub_function_to_nrcan_construction_function[main_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:
+ 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, climate_zone)
+
+ return average_storey_height
\ No newline at end of file
diff --git a/hub/imports/usage/nrcan_usage_parameters.py b/hub/imports/usage/nrcan_usage_parameters.py
index 9d718d33..854d7051 100644
--- a/hub/imports/usage/nrcan_usage_parameters.py
+++ b/hub/imports/usage/nrcan_usage_parameters.py
@@ -3,11 +3,13 @@ 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
@@ -16,6 +18,7 @@ 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:
@@ -33,53 +36,75 @@ class NrcanUsageParameters:
city = self._city
nrcan_catalog = UsageCatalogFactory('nrcan').catalog
comnet_catalog = UsageCatalogFactory('comnet').catalog
-
for building in city.buildings:
- usage_name = Dictionaries().hub_usage_to_nrcan_usage[building.function]
- try:
- archetype_usage = self._search_archetypes(nrcan_catalog, usage_name)
- except KeyError:
- logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
- continue
+ usages = []
+ nrcan_archetype_usages = []
+ comnet_archetype_usages = []
+ building_functions = building.function.split('_')
+ for function in building_functions:
+ usages.append(function.split('-'))
+ for usage in usages:
+ usage_name = Dictionaries().hub_usage_to_nrcan_usage[usage[-1]]
+ 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[-1]]
+ 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
- comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
- try:
- comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
- except KeyError:
- logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
- continue
-
- for internal_zone in building.internal_zones:
+ for (i, internal_zone) in enumerate(building.internal_zones):
+ internal_zone_usages = []
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, usage_name)
+ building.name, usages[i][-1])
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, usage_name)
+ building.name, usages[i][-1])
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, usage_name)
+ building.name, usages[i][-1])
continue
volume_per_area += internal_zone.volume / internal_zone.area
+ usage = Usage()
+ usage.name = usages[i][-1]
+ 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:
- 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)
+ 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)
+ storeys_above_ground = self.average_storey_height_calculator(self._city, building)
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, mixed_usage) in enumerate(usages):
+ usage = Usage()
+ usage.name = mixed_usage[-1]
+ if len(usages) > 1:
+ usage.percentage = float(mixed_usage[0]) / 100
+ else:
+ usage.percentage = 1
+ 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)
- usage = Usage()
- 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)
-
- internal_zone.usages = [usage]
+ internal_zone.usages = internal_zone_usages
@staticmethod
def _search_archetypes(catalog, usage_name):
@@ -197,3 +222,39 @@ 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
+ main_function = None
+ functions = building.function.split('_')
+ if len(functions) > 1:
+ maximum_percentage = 0
+ for function in functions:
+ percentage_and_function = function.split('-')
+ if float(percentage_and_function[0]) > maximum_percentage:
+ maximum_percentage = float(percentage_and_function[0])
+ main_function = percentage_and_function[-1]
+ else:
+ main_function = functions[-1]
+ if main_function not in Dictionaries().hub_function_to_nrcan_construction_function:
+ logging.error('Building %s has an unknown building function %s', building.name, main_function)
+ function = Dictionaries().hub_function_to_nrcan_construction_function[main_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:
+ 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, climate_zone)
+
+ return average_storey_height
+
+
diff --git a/hub/imports/usage/palma_usage_parameters.py b/hub/imports/usage/palma_usage_parameters.py
new file mode 100644
index 00000000..56cd80f3
--- /dev/null
+++ b/hub/imports/usage/palma_usage_parameters.py
@@ -0,0 +1,174 @@
+"""
+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
diff --git a/hub/imports/usage_factory.py b/hub/imports/usage_factory.py
index 8af57364..feadd5a9 100644
--- a/hub/imports/usage_factory.py
+++ b/hub/imports/usage_factory.py
@@ -10,6 +10,7 @@ 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:
@@ -48,6 +49,15 @@ 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
diff --git a/hub/imports/weather/epw_weather_parameters.py b/hub/imports/weather/epw_weather_parameters.py
index 0c362261..9101d3e7 100644
--- a/hub/imports/weather/epw_weather_parameters.py
+++ b/hub/imports/weather/epw_weather_parameters.py
@@ -110,12 +110,9 @@ 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 * 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.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.beam[cte.HOUR] = [building.global_horizontal[cte.HOUR][i] -
building.diffuse[cte.HOUR][i]
for i in range(len(building.global_horizontal[cte.HOUR]))]
diff --git a/hub/version.py b/hub/version.py
index b0317da1..fb3b3f94 100644
--- a/hub/version.py
+++ b/hub/version.py
@@ -1,4 +1,4 @@
"""
Hub version number
"""
-__version__ = '0.2.0.9'
+__version__ = '0.2.0.13'
diff --git a/requirements.txt b/requirements.txt
index 8a9cecfc..70d2bd71 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -24,4 +24,5 @@ triangle
psycopg2-binary
Pillow
pathlib
-sqlalchemy_utils
\ No newline at end of file
+sqlalchemy_utils
+build
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 8af11db8..7c2df9ca 100644
--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,7 @@ with pathlib.Path('requirements.txt').open() as r:
for requirement
in r.readlines()
]
-install_requires.append('setuptools, build')
+install_requires.append('setuptools')
main_ns = {}
version = convert_path('hub/version.py')
diff --git a/tests/test_construction_catalog.py b/tests/test_construction_catalog.py
index 5c5a0e9d..299fee9d 100644
--- a/tests/test_construction_catalog.py
+++ b/tests/test_construction_catalog.py
@@ -71,3 +71,23 @@ 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')
diff --git a/tests/test_construction_factory.py b/tests/test_construction_factory.py
index 710894bd..0339ce6f 100644
--- a/tests/test_construction_factory.py
+++ b/tests/test_construction_factory.py
@@ -296,6 +296,27 @@ class TestConstructionFactory(TestCase):
function_to_hub=Dictionaries().eilat_function_to_hub_function).city
ConstructionFactory('eilat', 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)
+
+ 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:
diff --git a/tests/test_systems_catalog.py b/tests/test_systems_catalog.py
index 612a8fe6..d31dfb99 100644
--- a/tests/test_systems_catalog.py
+++ b/tests/test_systems_catalog.py
@@ -54,4 +54,23 @@ class TestSystemsCatalog(TestCase):
with self.assertRaises(IndexError):
catalog.get_entry('unknown')
- print(catalog.entries())
+
+ def test_palma_catalog(self):
+ catalog = EnergySystemsCatalogFactory('palma').catalog
+ catalog_categories = catalog.names()
+ archetypes = catalog.names()
+ self.assertEqual(15, len(archetypes['archetypes']))
+ systems = catalog.names('systems')
+ self.assertEqual(13, len(systems['systems']))
+ generation_equipments = catalog.names('generation_equipments')
+ self.assertEqual(16, len(generation_equipments['generation_equipments']))
+ 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')
diff --git a/tests/test_systems_factory.py b/tests/test_systems_factory.py
index a8207a7a..95393fbf 100644
--- a/tests/test_systems_factory.py
+++ b/tests/test_systems_factory.py
@@ -127,6 +127,43 @@ class TestSystemsFactory(TestCase):
_generation_system = cast(NonPvGenerationSystem, energy_system.generation_systems[0])
_generation_system.nominal_cooling_output = building.cooling_peak_load[cte.YEAR][0]
+ for building in self._city.buildings:
+ self.assertLess(0, building.heating_consumption[cte.YEAR][0])
+ self.assertLess(0, building.cooling_consumption[cte.YEAR][0])
+ self.assertLess(0, building.domestic_hot_water_consumption[cte.YEAR][0])
+ self.assertLess(0, building.onsite_electrical_production[cte.YEAR][0])
+
+ def test_palma_system_results(self):
+ """
+ Enrich the city with the construction information and verify it
+ """
+ ConstructionFactory('nrcan', self._city).enrich()
+ UsageFactory('nrcan', self._city).enrich()
+ WeatherFactory('epw', self._city).enrich()
+ ExportsFactory('sra', self._city, self._output_path).export()
+ sra_path = (self._output_path / f'{self._city.name}_sra.xml').resolve()
+ subprocess.run(['sra', str(sra_path)])
+ ResultFactory('sra', self._city, self._output_path).enrich()
+ EnergyBuildingsExportsFactory('insel_monthly_energy_balance', self._city, self._output_path).export()
+ for building in self._city.buildings:
+ insel_path = (self._output_path / f'{building.name}.insel')
+ subprocess.run(['insel', str(insel_path)])
+ ResultFactory('insel_monthly_energy_balance', self._city, self._output_path).enrich()
+
+ for building in self._city.buildings:
+ building.energy_systems_archetype_name = 'PV and heat pump'
+ EnergySystemsFactory('palma', self._city).enrich()
+ # Need to assign energy systems to buildings:
+ for building in self._city.buildings:
+ _building_energy_systems = []
+ for energy_system in building.energy_systems:
+ if cte.HEATING in energy_system.demand_types:
+ _generation_system = cast(NonPvGenerationSystem, energy_system.generation_systems[0])
+ _generation_system.nominal_heat_output = building.heating_peak_load[cte.YEAR][0]
+ if cte.COOLING in energy_system.demand_types:
+ _generation_system = cast(NonPvGenerationSystem, energy_system.generation_systems[0])
+ _generation_system.nominal_cooling_output = building.cooling_peak_load[cte.YEAR][0]
+
for building in self._city.buildings:
self.assertLess(0, building.heating_consumption[cte.YEAR][0])
self.assertLess(0, building.cooling_consumption[cte.YEAR][0])
diff --git a/tests/test_usage_catalog.py b/tests/test_usage_catalog.py
index 2d927372..40fd6eb8 100644
--- a/tests/test_usage_catalog.py
+++ b/tests/test_usage_catalog.py
@@ -21,3 +21,10 @@ class TestConstructionCatalog(TestCase):
self.assertIsNotNone(catalog, 'catalog is none')
content = catalog.entries()
self.assertEqual(34, len(content.usages), 'Wrong number of usages')
+
+ def test_palma_catalog(self):
+ catalog = UsageCatalogFactory('palma').catalog
+ self.assertIsNotNone(catalog, 'catalog is none')
+ content = catalog.entries()
+ #print(catalog.entries())
+ self.assertEqual(1, len(content.usages), 'Wrong number of usages')
diff --git a/tests/test_usage_factory.py b/tests/test_usage_factory.py
index 6b6d821a..22fb3dad 100644
--- a/tests/test_usage_factory.py
+++ b/tests/test_usage_factory.py
@@ -182,3 +182,61 @@ class TestUsageFactory(TestCase):
self.assertIsNotNone(usage.domestic_hot_water.service_temperature,
'domestic hot water service temperature is none')
self.assertIsNotNone(usage.domestic_hot_water.schedules, 'domestic hot water schedules is none')
+
+ def test_import_palma(self):
+ """
+ Enrich the city with the usage information from palma and verify it
+ """
+ file = 'palma_test_file.geojson'
+ file_path = (self._example_path / file).resolve()
+ city = GeometryFactory('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()
+ UsageFactory('palma', city).enrich()
+ self._check_buildings(city)
+ for building in city.buildings:
+ for internal_zone in building.internal_zones:
+ if internal_zone.usages is not None:
+ self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
+ for usage in internal_zone.usages:
+ self._check_usage(usage)
+ self.assertIsNotNone(usage.mechanical_air_change, 'mechanical air change is none')
+ self.assertIsNotNone(usage.thermal_control.heating_set_point_schedules,
+ 'control heating set point schedule is none')
+ self.assertIsNotNone(usage.thermal_control.cooling_set_point_schedules,
+ 'control cooling set point schedule is none')
+ self.assertIsNotNone(usage.occupancy, 'occupancy is none')
+ occupancy = usage.occupancy
+ self.assertIsNotNone(occupancy.occupancy_density, 'occupancy density is none')
+ self.assertIsNotNone(occupancy.latent_internal_gain, 'occupancy latent internal gain is none')
+ self.assertIsNotNone(occupancy.sensible_convective_internal_gain,
+ 'occupancy sensible convective internal gain is none')
+ self.assertIsNotNone(occupancy.sensible_radiative_internal_gain,
+ 'occupancy sensible radiant internal gain is none')
+ self.assertIsNotNone(occupancy.occupancy_schedules, 'occupancy schedule is none')
+ self.assertIsNotNone(usage.lighting, 'lighting is none')
+ lighting = usage.lighting
+ self.assertIsNotNone(lighting.density, 'lighting density is none')
+ self.assertIsNotNone(lighting.latent_fraction, 'lighting latent fraction is none')
+ self.assertIsNotNone(lighting.convective_fraction, 'lighting convective fraction is none')
+ self.assertIsNotNone(lighting.radiative_fraction, 'lighting radiant fraction is none')
+ self.assertIsNotNone(lighting.schedules, 'lighting schedule is none')
+ self.assertIsNotNone(usage.appliances, 'appliances is none')
+ appliances = usage.appliances
+ self.assertIsNotNone(appliances.density, 'appliances density is none')
+ self.assertIsNotNone(appliances.latent_fraction, 'appliances latent fraction is none')
+ self.assertIsNotNone(appliances.convective_fraction, 'appliances convective fraction is none')
+ self.assertIsNotNone(appliances.radiative_fraction, 'appliances radiant fraction is none')
+ self.assertIsNotNone(appliances.schedules, 'appliances schedule is none')
+ self.assertIsNotNone(usage.thermal_control.hvac_availability_schedules,
+ 'control hvac availability is none')
+ self.assertIsNotNone(usage.domestic_hot_water.peak_flow, 'domestic hot water peak flow is none')
+ self.assertIsNotNone(usage.domestic_hot_water.service_temperature,
+ 'domestic hot water service temperature is none')
+ self.assertIsNotNone(usage.domestic_hot_water.schedules, 'domestic hot water schedules is none')
+
diff --git a/tests/tests_data/palma_test_file.geojson b/tests/tests_data/palma_test_file.geojson
new file mode 100644
index 00000000..6127f5c3
--- /dev/null
+++ b/tests/tests_data/palma_test_file.geojson
@@ -0,0 +1,325 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {
+ "gml_id": "1701545DD7810B-7",
+ "name": "Build_1701545DD7810B-7",
+ "usage": "Medium multifamily building",
+ "yearOfConstruction": 1900,
+ "measuredHeight": 1.91,
+ "id": 10000139
+ },
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ 2.670070724294205,
+ 39.56930642367412,
+ 10.59
+ ],
+ [
+ 2.670185785609704,
+ 39.56929891118361,
+ 10.59
+ ],
+ [
+ 2.670190100634483,
+ 39.56934649857977,
+ 8.68
+ ],
+ [
+ 2.670126975953838,
+ 39.569351455373074,
+ 8.68
+ ],
+ [
+ 2.670077594530873,
+ 39.569355279790706,
+ 8.68
+ ],
+ [
+ 2.670070724294205,
+ 39.56930642367412,
+ 10.59
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "gml_id": "1701556DD7810B-0",
+ "name": "Build_1701556DD7810B-0",
+ "usage": "Single-family building",
+ "yearOfConstruction": 1900,
+ "measuredHeight": 2.41,
+ "id": 10000187
+ },
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ 2.670200083996169,
+ 39.569672074284036,
+ 11.45
+ ],
+ [
+ 2.670200346722237,
+ 39.569665767718384,
+ 11.45
+ ],
+ [
+ 2.670198829516351,
+ 39.569641975838955,
+ 11.45
+ ],
+ [
+ 2.670196767769449,
+ 39.56961025322274,
+ 9.04
+ ],
+ [
+ 2.670193356349873,
+ 39.5695685251824,
+ 11.45
+ ],
+ [
+ 2.670277913478355,
+ 39.56956137655187,
+ 9.04
+ ],
+ [
+ 2.670279246946909,
+ 39.56957480589787,
+ 11.45
+ ],
+ [
+ 2.67033655158975,
+ 39.56956965230401,
+ 9.04
+ ],
+ [
+ 2.670344584906827,
+ 39.5696433805295,
+ 11.45
+ ],
+ [
+ 2.670355415974015,
+ 39.56964260031243,
+ 11.45
+ ],
+ [
+ 2.670356972062089,
+ 39.569658192795536,
+ 11.45
+ ],
+ [
+ 2.670325184211198,
+ 39.56965909377396,
+ 11.45
+ ],
+ [
+ 2.670324202558058,
+ 39.569645124800005,
+ 11.45
+ ],
+ [
+ 2.670282742314197,
+ 39.56964798062581,
+ 9.04
+ ],
+ [
+ 2.670220439148762,
+ 39.56965149812889,
+ 11.45
+ ],
+ [
+ 2.670223258772483,
+ 39.56967069837706,
+ 11.45
+ ],
+ [
+ 2.670200083996169,
+ 39.569672074284036,
+ 11.45
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "gml_id": "1701557DD7810B",
+ "name": "Build_1701557DD7810B",
+ "usage": "Single-family building",
+ "yearOfConstruction": 1900,
+ "measuredHeight": 3.14,
+ "id": 10000205
+ },
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ 2.670076001010665,
+ 39.56959324111637,
+ 12.07
+ ],
+ [
+ 2.670075832651971,
+ 39.56957963486689,
+ 8.93
+ ],
+ [
+ 2.670193356349873,
+ 39.5695685251824,
+ 12.07
+ ],
+ [
+ 2.670196767769449,
+ 39.56961025322274,
+ 8.93
+ ],
+ [
+ 2.670198829516351,
+ 39.569641975838955,
+ 8.93
+ ],
+ [
+ 2.670200346722237,
+ 39.569665767718384,
+ 12.07
+ ],
+ [
+ 2.670165875186915,
+ 39.56966792249954,
+ 12.07
+ ],
+ [
+ 2.670163320870091,
+ 39.569641875065045,
+ 12.07
+ ],
+ [
+ 2.670162763096683,
+ 39.56963673752855,
+ 12.07
+ ],
+ [
+ 2.670099057749991,
+ 39.56964133224028,
+ 12.07
+ ],
+ [
+ 2.670097648460491,
+ 39.569619342754734,
+ 12.07
+ ],
+ [
+ 2.670077380826434,
+ 39.56962144772541,
+ 12.07
+ ],
+ [
+ 2.670076001010665,
+ 39.56959324111637,
+ 12.07
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "gml_id": "1701548DD7810B-1",
+ "name": "Build_1701548DD7810B-1",
+ "usage": "Single-family building",
+ "yearOfConstruction": 1903,
+ "measuredHeight": 4.01,
+ "id": 10000230
+ },
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ 2.670232581277104,
+ 39.56952142176154,
+ 12.83
+ ],
+ [
+ 2.670223774973652,
+ 39.56943886109741,
+ 8.82
+ ],
+ [
+ 2.670329525337772,
+ 39.56943078141684,
+ 8.82
+ ],
+ [
+ 2.670338924541374,
+ 39.56951109114386,
+ 8.82
+ ],
+ [
+ 2.670232581277104,
+ 39.56952142176154,
+ 12.83
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {
+ "gml_id": "1701548DD7810B-0",
+ "name": "Build_1701548DD7810B-0",
+ "usage": "Single-family building",
+ "yearOfConstruction": 1903,
+ "measuredHeight": 3.54,
+ "id": 10000246
+ },
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ 2.670221550271632,
+ 39.569416959403185,
+ 12.6
+ ],
+ [
+ 2.670241580303924,
+ 39.56941584488198,
+ 12.6
+ ],
+ [
+ 2.670243380302281,
+ 39.569429095343594,
+ 12.6
+ ],
+ [
+ 2.67022299587959,
+ 39.56943129011285,
+ 12.6
+ ],
+ [
+ 2.670221550271632,
+ 39.569416959403185,
+ 12.6
+ ]
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file