From 164ffbf9c8cdbd57211bc16fd0ccd48feb573fae Mon Sep 17 00:00:00 2001 From: s_ranjbar Date: Mon, 21 Oct 2024 23:30:10 +0200 Subject: [PATCH] feat: all the catalogues, importers, data and tests of palma are added --- .../construction/palma_catalog.py | 236 ++ .../construction_catalog_factory.py | 8 + .../energy_systems/pv_generation_system.py | 16 +- .../energy_systems/palma_system_catalgue.py | 520 +++++ .../energy_systems_catalog_factory.py | 8 + hub/catalog_factories/usage/palma_catalog.py | 227 ++ .../usage_catalog_factory.py | 8 + hub/data/construction/palma_archetypes.json | 664 ++++++ .../construction/palma_constructions.json | 1895 +++++++++++++++++ hub/data/energy_systems/palma_systems.xml | 809 +++++++ hub/data/usage/palma_schedules.json | 904 ++++++++ hub/data/usage/palma_space_compliance.json | 30 + hub/data/usage/palma_space_types.json | 97 + hub/helpers/constants.py | 5 +- ...function_to_palma_construction_function.py | 30 + hub/helpers/data/hub_usage_to_palma_usage.py | 51 + .../data/montreal_custom_fuel_to_hub_fuel.py | 12 +- ..._system_to_hub_energy_generation_system.py | 8 +- .../data/palma_function_to_hub_function.py | 31 + hub/helpers/dictionaries.py | 26 + .../helpers/construction_helper.py | 14 + .../construction/palma_physics_parameters.py | 104 + hub/imports/construction_factory.py | 10 + .../palma_energy_systems_parameters.py | 216 ++ hub/imports/energy_systems_factory.py | 10 + hub/imports/usage/palma_usage_parameters.py | 174 ++ hub/imports/usage_factory.py | 10 + tests/test_construction_catalog.py | 20 + tests/test_construction_factory.py | 28 +- tests/test_systems_catalog.py | 21 + tests/test_systems_factory.py | 39 + tests/test_usage_catalog.py | 8 + tests/test_usage_factory.py | 58 + tests/tests_data/palma_test.geojson | 48 + 34 files changed, 6335 insertions(+), 10 deletions(-) create mode 100644 hub/catalog_factories/construction/palma_catalog.py create mode 100644 hub/catalog_factories/energy_systems/palma_system_catalgue.py create mode 100644 hub/catalog_factories/usage/palma_catalog.py create mode 100644 hub/data/construction/palma_archetypes.json create mode 100644 hub/data/construction/palma_constructions.json create mode 100644 hub/data/energy_systems/palma_systems.xml create mode 100644 hub/data/usage/palma_schedules.json create mode 100644 hub/data/usage/palma_space_compliance.json create mode 100644 hub/data/usage/palma_space_types.json create mode 100644 hub/helpers/data/hub_function_to_palma_construction_function.py create mode 100644 hub/helpers/data/hub_usage_to_palma_usage.py create mode 100644 hub/helpers/data/palma_function_to_hub_function.py create mode 100644 hub/imports/construction/palma_physics_parameters.py create mode 100644 hub/imports/energy_systems/palma_energy_systems_parameters.py create mode 100644 hub/imports/usage/palma_usage_parameters.py create mode 100644 tests/tests_data/palma_test.geojson diff --git a/hub/catalog_factories/construction/palma_catalog.py b/hub/catalog_factories/construction/palma_catalog.py new file mode 100644 index 00000000..3a0d3809 --- /dev/null +++ b/hub/catalog_factories/construction/palma_catalog.py @@ -0,0 +1,236 @@ +""" +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 + + 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, + None, + None)) + 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/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..b5412bd2 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') @@ -49,6 +50,13 @@ class UsageCatalogFactory: """ return EilatCatalog(self._path) + @property + def _palma(self): + """ + Retrieve Palma catalog + """ + return PalmaCatalog(self._path) + @property def catalog(self) -> Catalog: """ diff --git a/hub/data/construction/palma_archetypes.json b/hub/data/construction/palma_archetypes.json new file mode 100644 index 00000000..5781ceaa --- /dev/null +++ b/hub/data/construction/palma_archetypes.json @@ -0,0 +1,664 @@ +{ + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + }, + { + "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" + } + } + } + ] + } \ 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/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/helpers/constants.py b/hub/helpers/constants.py index 39586c54..e06aec79 100644 --- a/hub/helpers/constants.py +++ b/hub/helpers/constants.py @@ -25,7 +25,6 @@ KILO_WATTS_HOUR_TO_JULES = 3600000 WATTS_HOUR_TO_JULES = 3600 GALLONS_TO_QUBIC_METERS = 0.0037854117954011185 - # time SECOND = 'second' MINUTE = 'minute' @@ -294,6 +293,7 @@ GAS = 'Gas' DIESEL = 'Diesel' COAL = 'Coal' BIOMASS = 'Biomass' +BUTANE = 'Butane' AIR = 'Air' WATER = 'Water' GEOTHERMAL = 'Geothermal' @@ -306,6 +306,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..13b07925 --- /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..bd8e731b 100644 --- a/hub/imports/construction/helpers/construction_helper.py +++ b/hub/imports/construction/helpers/construction_helper.py @@ -65,6 +65,11 @@ class ConstructionHelper: 'Eilat': 'BWh' } + _reference_city_to_palma_climate_zone = { + 'Palma': 'B3' + } + + @staticmethod def yoc_to_nrel_standard(year_of_construction): """ @@ -107,3 +112,12 @@ 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/palma_physics_parameters.py b/hub/imports/construction/palma_physics_parameters.py new file mode 100644 index 00000000..7f874b68 --- /dev/null +++ b/hub/imports/construction/palma_physics_parameters.py @@ -0,0 +1,104 @@ +""" +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 + _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_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/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/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/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..fad046f1 100644 --- a/tests/test_construction_factory.py +++ b/tests/test_construction_factory.py @@ -305,4 +305,30 @@ class TestConstructionFactory(TestCase): 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) \ No newline at end of file + self._check_surfaces(thermal_boundary) + + def test_palma_construction_factory(self): + """ + Enrich the city with the construction information from palma and verify it + """ + file = 'palma_test.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() + + 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) diff --git a/tests/test_systems_catalog.py b/tests/test_systems_catalog.py index 612a8fe6..9086cafd 100644 --- a/tests/test_systems_catalog.py +++ b/tests/test_systems_catalog.py @@ -55,3 +55,24 @@ 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..37f69de9 100644 --- a/tests/test_systems_factory.py +++ b/tests/test_systems_factory.py @@ -127,6 +127,45 @@ 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] + + print('test') + 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..8149578a 100644 --- a/tests/test_usage_catalog.py +++ b/tests/test_usage_catalog.py @@ -20,4 +20,12 @@ class TestConstructionCatalog(TestCase): catalog = UsageCatalogFactory('nrcan').catalog self.assertIsNotNone(catalog, 'catalog is none') content = catalog.entries() + print(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 5c180f09..f64f3ae6 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.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.geojson b/tests/tests_data/palma_test.geojson new file mode 100644 index 00000000..b4a0d6a7 --- /dev/null +++ b/tests/tests_data/palma_test.geojson @@ -0,0 +1,48 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "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 + ] + ] + ] + } + } + ] +} \ No newline at end of file