Compare commits
2 Commits
main
...
feature/ad
Author | SHA1 | Date | |
---|---|---|---|
b00fb69d9c | |||
1592dd2802 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -22,7 +22,6 @@ class EilatCatalog(Catalog):
|
|||
"""
|
||||
Eilat catalog class
|
||||
"""
|
||||
|
||||
def __init__(self, path):
|
||||
_path_archetypes = Path(path / 'eilat_archetypes.json').resolve()
|
||||
_path_constructions = (path / 'eilat_constructions.json').resolve()
|
||||
|
@ -122,10 +121,8 @@ class EilatCatalog(Catalog):
|
|||
construction_period = archetype['period_of_construction']
|
||||
average_storey_height = archetype['average_storey_height']
|
||||
extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges']
|
||||
infiltration_rate_for_ventilation_system_off = archetype[
|
||||
'infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
|
||||
infiltration_rate_for_ventilation_system_on = archetype[
|
||||
'infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
|
||||
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
|
||||
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
|
||||
|
||||
archetype_constructions = []
|
||||
for archetype_construction in archetype['constructions']:
|
||||
|
@ -163,9 +160,7 @@ class EilatCatalog(Catalog):
|
|||
extra_loses_due_to_thermal_bridges,
|
||||
None,
|
||||
infiltration_rate_for_ventilation_system_off,
|
||||
infiltration_rate_for_ventilation_system_on,
|
||||
0,
|
||||
0))
|
||||
infiltration_rate_for_ventilation_system_on))
|
||||
return _catalog_archetypes
|
||||
|
||||
def names(self, category=None):
|
||||
|
|
|
@ -128,12 +128,6 @@ class NrcanCatalog(Catalog):
|
|||
infiltration_rate_for_ventilation_system_on = (
|
||||
archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
|
||||
)
|
||||
infiltration_rate_area_for_ventilation_system_off = (
|
||||
archetype['infiltration_rate_area_for_ventilation_system_off'] * 1
|
||||
)
|
||||
infiltration_rate_area_for_ventilation_system_on = (
|
||||
archetype['infiltration_rate_area_for_ventilation_system_on'] * 1
|
||||
)
|
||||
|
||||
archetype_constructions = []
|
||||
for archetype_construction in archetype['constructions']:
|
||||
|
@ -159,6 +153,7 @@ class NrcanCatalog(Catalog):
|
|||
_window)
|
||||
archetype_constructions.append(_construction)
|
||||
break
|
||||
|
||||
_catalog_archetypes.append(Archetype(archetype_id,
|
||||
name,
|
||||
function,
|
||||
|
@ -170,10 +165,7 @@ class NrcanCatalog(Catalog):
|
|||
extra_loses_due_to_thermal_bridges,
|
||||
None,
|
||||
infiltration_rate_for_ventilation_system_off,
|
||||
infiltration_rate_for_ventilation_system_on,
|
||||
infiltration_rate_area_for_ventilation_system_off,
|
||||
infiltration_rate_area_for_ventilation_system_on
|
||||
))
|
||||
infiltration_rate_for_ventilation_system_on))
|
||||
return _catalog_archetypes
|
||||
|
||||
def names(self, category=None):
|
||||
|
|
|
@ -162,9 +162,7 @@ class NrelCatalog(Catalog):
|
|||
extra_loses_due_to_thermal_bridges,
|
||||
indirect_heated_ratio,
|
||||
infiltration_rate_for_ventilation_system_off,
|
||||
infiltration_rate_for_ventilation_system_on,
|
||||
0,
|
||||
0))
|
||||
infiltration_rate_for_ventilation_system_on))
|
||||
return _catalog_archetypes
|
||||
|
||||
def names(self, category=None):
|
||||
|
|
|
@ -1,242 +0,0 @@
|
|||
"""
|
||||
Palma construction catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2023 Concordia CERC group
|
||||
Project Coder Cecilia Pérez Pérez cperez@irec.cat
|
||||
"""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from hub.catalog_factories.catalog import Catalog
|
||||
from hub.catalog_factories.data_models.construction.content import Content
|
||||
from hub.catalog_factories.construction.construction_helper import ConstructionHelper
|
||||
from hub.catalog_factories.data_models.construction.construction import Construction
|
||||
from hub.catalog_factories.data_models.construction.archetype import Archetype
|
||||
from hub.catalog_factories.data_models.construction.window import Window
|
||||
from hub.catalog_factories.data_models.construction.material import Material
|
||||
from hub.catalog_factories.data_models.construction.layer import Layer
|
||||
import hub.helpers.constants as cte
|
||||
|
||||
|
||||
class PalmaCatalog(Catalog):
|
||||
"""
|
||||
Palma catalog class
|
||||
"""
|
||||
def __init__(self, path):
|
||||
_path_archetypes = Path(path / 'palma_archetypes.json').resolve()
|
||||
_path_constructions = (path / 'palma_constructions.json').resolve()
|
||||
with open(_path_archetypes, 'r', encoding='utf-8') as file:
|
||||
self._archetypes = json.load(file)
|
||||
with open(_path_constructions, 'r', encoding='utf-8') as file:
|
||||
self._constructions = json.load(file)
|
||||
|
||||
self._catalog_windows = self._load_windows()
|
||||
self._catalog_materials = self._load_materials()
|
||||
self._catalog_constructions = self._load_constructions()
|
||||
self._catalog_archetypes = self._load_archetypes()
|
||||
|
||||
# store the full catalog data model in self._content
|
||||
self._content = Content(self._catalog_archetypes,
|
||||
self._catalog_constructions,
|
||||
self._catalog_materials,
|
||||
self._catalog_windows)
|
||||
|
||||
def _load_windows(self):
|
||||
_catalog_windows = []
|
||||
windows = self._constructions['transparent_surfaces']
|
||||
for window in windows:
|
||||
name = list(window.keys())[0]
|
||||
window_id = name
|
||||
g_value = window[name]['shgc']
|
||||
window_type = window[name]['type']
|
||||
frame_ratio = window[name]['frame_ratio']
|
||||
overall_u_value = window[name]['u_value']
|
||||
_catalog_windows.append(Window(window_id, frame_ratio, g_value, overall_u_value, name, window_type))
|
||||
return _catalog_windows
|
||||
|
||||
def _load_materials(self):
|
||||
_catalog_materials = []
|
||||
materials = self._constructions['materials']
|
||||
for material in materials:
|
||||
name = list(material.keys())[0]
|
||||
material_id = name
|
||||
no_mass = material[name]['no_mass']
|
||||
thermal_resistance = None
|
||||
conductivity = None
|
||||
density = None
|
||||
specific_heat = None
|
||||
solar_absorptance = None
|
||||
thermal_absorptance = None
|
||||
visible_absorptance = None
|
||||
if no_mass:
|
||||
thermal_resistance = material[name]['thermal_resistance']
|
||||
else:
|
||||
solar_absorptance = material[name]['solar_absorptance']
|
||||
thermal_absorptance = str(1 - float(material[name]['thermal_emittance']))
|
||||
visible_absorptance = material[name]['visible_absorptance']
|
||||
conductivity = material[name]['conductivity']
|
||||
density = material[name]['density']
|
||||
specific_heat = material[name]['specific_heat']
|
||||
_material = Material(material_id,
|
||||
name,
|
||||
solar_absorptance,
|
||||
thermal_absorptance,
|
||||
visible_absorptance,
|
||||
no_mass,
|
||||
thermal_resistance,
|
||||
conductivity,
|
||||
density,
|
||||
specific_heat)
|
||||
_catalog_materials.append(_material)
|
||||
return _catalog_materials
|
||||
|
||||
def _load_constructions(self):
|
||||
_catalog_constructions = []
|
||||
constructions = self._constructions['opaque_surfaces']
|
||||
for construction in constructions:
|
||||
name = list(construction.keys())[0]
|
||||
construction_id = name
|
||||
construction_type = ConstructionHelper().nrcan_surfaces_types_to_hub_types[construction[name]['type']]
|
||||
layers = []
|
||||
for layer in construction[name]['layers']:
|
||||
layer_id = layer
|
||||
layer_name = layer
|
||||
material_id = layer
|
||||
thickness = construction[name]['layers'][layer]
|
||||
for material in self._catalog_materials:
|
||||
if str(material_id) == str(material.id):
|
||||
layers.append(Layer(layer_id, layer_name, material, thickness))
|
||||
break
|
||||
_catalog_constructions.append(Construction(construction_id, construction_type, name, layers))
|
||||
return _catalog_constructions
|
||||
|
||||
def _load_archetypes(self):
|
||||
_catalog_archetypes = []
|
||||
archetypes = self._archetypes['archetypes']
|
||||
for archetype in archetypes:
|
||||
archetype_id = f'{archetype["function"]}_{archetype["period_of_construction"]}_{archetype["climate_zone"]}'
|
||||
function = archetype['function']
|
||||
name = archetype_id
|
||||
climate_zone = archetype['climate_zone']
|
||||
construction_period = archetype['period_of_construction']
|
||||
average_storey_height = archetype['average_storey_height']
|
||||
thermal_capacity = float(archetype['thermal_capacity']) * 1000
|
||||
extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges']
|
||||
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
|
||||
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
|
||||
infiltration_rate_area_for_ventilation_system_off = (
|
||||
archetype['infiltration_rate_area_for_ventilation_system_off'] * 1
|
||||
)
|
||||
infiltration_rate_area_for_ventilation_system_on = (
|
||||
archetype['infiltration_rate_area_for_ventilation_system_on'] * 1
|
||||
)
|
||||
|
||||
archetype_constructions = []
|
||||
for archetype_construction in archetype['constructions']:
|
||||
archetype_construction_type = ConstructionHelper().nrcan_surfaces_types_to_hub_types[archetype_construction]
|
||||
archetype_construction_name = archetype['constructions'][archetype_construction]['opaque_surface_name']
|
||||
for construction in self._catalog_constructions:
|
||||
if archetype_construction_type == construction.type and construction.name == archetype_construction_name:
|
||||
_construction = None
|
||||
_window = None
|
||||
_window_ratio = None
|
||||
if 'transparent_surface_name' in archetype['constructions'][archetype_construction].keys():
|
||||
_window_ratio = archetype['constructions'][archetype_construction]['transparent_ratio']
|
||||
_window_id = archetype['constructions'][archetype_construction]['transparent_surface_name']
|
||||
for window in self._catalog_windows:
|
||||
if _window_id == window.id:
|
||||
_window = window
|
||||
break
|
||||
_construction = Construction(construction.id,
|
||||
construction.type,
|
||||
construction.name,
|
||||
construction.layers,
|
||||
_window_ratio,
|
||||
_window)
|
||||
archetype_constructions.append(_construction)
|
||||
break
|
||||
|
||||
_catalog_archetypes.append(Archetype(archetype_id,
|
||||
name,
|
||||
function,
|
||||
climate_zone,
|
||||
construction_period,
|
||||
archetype_constructions,
|
||||
average_storey_height,
|
||||
thermal_capacity,
|
||||
extra_loses_due_to_thermal_bridges,
|
||||
None,
|
||||
infiltration_rate_for_ventilation_system_off,
|
||||
infiltration_rate_for_ventilation_system_on,
|
||||
infiltration_rate_area_for_ventilation_system_off,
|
||||
infiltration_rate_area_for_ventilation_system_on))
|
||||
return _catalog_archetypes
|
||||
|
||||
def names(self, category=None):
|
||||
"""
|
||||
Get the catalog elements names
|
||||
:parm: optional category filter
|
||||
"""
|
||||
if category is None:
|
||||
_names = {'archetypes': [], 'constructions': [], 'materials': [], 'windows': []}
|
||||
for archetype in self._content.archetypes:
|
||||
_names['archetypes'].append(archetype.name)
|
||||
for construction in self._content.constructions:
|
||||
_names['constructions'].append(construction.name)
|
||||
for material in self._content.materials:
|
||||
_names['materials'].append(material.name)
|
||||
for window in self._content.windows:
|
||||
_names['windows'].append(window.name)
|
||||
else:
|
||||
_names = {category: []}
|
||||
if category.lower() == 'archetypes':
|
||||
for archetype in self._content.archetypes:
|
||||
_names[category].append(archetype.name)
|
||||
elif category.lower() == 'constructions':
|
||||
for construction in self._content.constructions:
|
||||
_names[category].append(construction.name)
|
||||
elif category.lower() == 'materials':
|
||||
for material in self._content.materials:
|
||||
_names[category].append(material.name)
|
||||
elif category.lower() == 'windows':
|
||||
for window in self._content.windows:
|
||||
_names[category].append(window.name)
|
||||
else:
|
||||
raise ValueError(f'Unknown category [{category}]')
|
||||
return _names
|
||||
|
||||
def entries(self, category=None):
|
||||
"""
|
||||
Get the catalog elements
|
||||
:parm: optional category filter
|
||||
"""
|
||||
if category is None:
|
||||
return self._content
|
||||
if category.lower() == 'archetypes':
|
||||
return self._content.archetypes
|
||||
if category.lower() == 'constructions':
|
||||
return self._content.constructions
|
||||
if category.lower() == 'materials':
|
||||
return self._content.materials
|
||||
if category.lower() == 'windows':
|
||||
return self._content.windows
|
||||
raise ValueError(f'Unknown category [{category}]')
|
||||
|
||||
def get_entry(self, name):
|
||||
"""
|
||||
Get one catalog element by names
|
||||
:parm: entry name
|
||||
"""
|
||||
for entry in self._content.archetypes:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.constructions:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.materials:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.windows:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
raise IndexError(f"{name} doesn't exists in the catalog")
|
|
@ -11,7 +11,6 @@ from typing import TypeVar
|
|||
from hub.catalog_factories.construction.nrcan_catalog import NrcanCatalog
|
||||
from hub.catalog_factories.construction.nrel_catalog import NrelCatalog
|
||||
from hub.catalog_factories.construction.eilat_catalog import EilatCatalog
|
||||
from hub.catalog_factories.construction.palma_catalog import PalmaCatalog
|
||||
from hub.helpers.utils import validate_import_export_type
|
||||
|
||||
Catalog = TypeVar('Catalog')
|
||||
|
@ -49,13 +48,6 @@ class ConstructionCatalogFactory:
|
|||
"""
|
||||
return EilatCatalog(self._path)
|
||||
|
||||
@property
|
||||
def _palma(self):
|
||||
"""
|
||||
Retrieve Palma catalog
|
||||
"""
|
||||
return PalmaCatalog(self._path)
|
||||
|
||||
@property
|
||||
def catalog(self) -> Catalog:
|
||||
"""
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -23,10 +23,7 @@ class Archetype:
|
|||
extra_loses_due_to_thermal_bridges,
|
||||
indirect_heated_ratio,
|
||||
infiltration_rate_for_ventilation_system_off,
|
||||
infiltration_rate_for_ventilation_system_on,
|
||||
infiltration_rate_area_for_ventilation_system_off,
|
||||
infiltration_rate_area_for_ventilation_system_on
|
||||
):
|
||||
infiltration_rate_for_ventilation_system_on):
|
||||
self._id = archetype_id
|
||||
self._name = name
|
||||
self._function = function
|
||||
|
@ -39,8 +36,6 @@ class Archetype:
|
|||
self._indirect_heated_ratio = indirect_heated_ratio
|
||||
self._infiltration_rate_for_ventilation_system_off = infiltration_rate_for_ventilation_system_off
|
||||
self._infiltration_rate_for_ventilation_system_on = infiltration_rate_for_ventilation_system_on
|
||||
self._infiltration_rate_area_for_ventilation_system_off = infiltration_rate_area_for_ventilation_system_off
|
||||
self._infiltration_rate_area_for_ventilation_system_on = infiltration_rate_area_for_ventilation_system_on
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -138,22 +133,6 @@ class Archetype:
|
|||
"""
|
||||
return self._infiltration_rate_for_ventilation_system_on
|
||||
|
||||
@property
|
||||
def infiltration_rate_area_for_ventilation_system_off(self):
|
||||
"""
|
||||
Get archetype infiltration rate for ventilation system off in m3/sm2
|
||||
:return: float
|
||||
"""
|
||||
return self._infiltration_rate_area_for_ventilation_system_off
|
||||
|
||||
@property
|
||||
def infiltration_rate_area_for_ventilation_system_on(self):
|
||||
"""
|
||||
Get archetype infiltration rate for ventilation system on in m3/sm2
|
||||
:return: float
|
||||
"""
|
||||
return self._infiltration_rate_for_ventilation_system_on
|
||||
|
||||
def to_dictionary(self):
|
||||
"""Class content to dictionary"""
|
||||
_constructions = []
|
||||
|
@ -170,8 +149,6 @@ class Archetype:
|
|||
'indirect heated ratio': self.indirect_heated_ratio,
|
||||
'infiltration rate for ventilation off [1/s]': self.infiltration_rate_for_ventilation_system_off,
|
||||
'infiltration rate for ventilation on [1/s]': self.infiltration_rate_for_ventilation_system_on,
|
||||
'infiltration rate area for ventilation off [m3/sm2]': self.infiltration_rate_area_for_ventilation_system_off,
|
||||
'infiltration rate area for ventilation on [m3/sm2]': self.infiltration_rate_area_for_ventilation_system_on,
|
||||
'constructions': _constructions
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -25,11 +25,9 @@ class NonPvGenerationSystem(GenerationSystem):
|
|||
maximum_cooling_supply_temperature=None, minimum_cooling_supply_temperature=None, heat_output_curve=None,
|
||||
heat_fuel_consumption_curve=None, heat_efficiency_curve=None, cooling_output_curve=None,
|
||||
cooling_fuel_consumption_curve=None, cooling_efficiency_curve=None,
|
||||
distribution_systems=None, energy_storage_systems=None, domestic_hot_water=False,
|
||||
reversible=None, simultaneous_heat_cold=None):
|
||||
super().__init__(system_id=system_id, name=name, model_name=model_name, manufacturer=manufacturer,
|
||||
fuel_type=fuel_type, distribution_systems=distribution_systems,
|
||||
energy_storage_systems=energy_storage_systems)
|
||||
distribution_systems=None, energy_storage_systems=None, dual_supply_capability=False):
|
||||
super().__init__(system_id=system_id, name=name, model_name=model_name, manufacturer=manufacturer, fuel_type=fuel_type,
|
||||
distribution_systems=distribution_systems, energy_storage_systems=energy_storage_systems)
|
||||
self._system_type = system_type
|
||||
self._nominal_heat_output = nominal_heat_output
|
||||
self._maximum_heat_output = maximum_heat_output
|
||||
|
@ -55,9 +53,7 @@ class NonPvGenerationSystem(GenerationSystem):
|
|||
self._cooling_output_curve = cooling_output_curve
|
||||
self._cooling_fuel_consumption_curve = cooling_fuel_consumption_curve
|
||||
self._cooling_efficiency_curve = cooling_efficiency_curve
|
||||
self._domestic_hot_water = domestic_hot_water
|
||||
self._reversible = reversible
|
||||
self._simultaneous_heat_cold = simultaneous_heat_cold
|
||||
self._dual_supply_capability = dual_supply_capability
|
||||
|
||||
@property
|
||||
def system_type(self):
|
||||
|
@ -260,28 +256,12 @@ class NonPvGenerationSystem(GenerationSystem):
|
|||
return self._cooling_efficiency_curve
|
||||
|
||||
@property
|
||||
def domestic_hot_water(self):
|
||||
def dual_supply_capability(self):
|
||||
"""
|
||||
Get the ability to produce domestic hot water
|
||||
Get dual supply capability
|
||||
:return: bool
|
||||
"""
|
||||
return self._domestic_hot_water
|
||||
|
||||
@property
|
||||
def reversibility(self):
|
||||
"""
|
||||
Get the ability to produce heating and cooling
|
||||
:return: bool
|
||||
"""
|
||||
return self._reversible
|
||||
|
||||
@property
|
||||
def simultaneous_heat_cold(self):
|
||||
"""
|
||||
Get the ability to produce heating and cooling at the same time
|
||||
:return: bool
|
||||
"""
|
||||
return self._simultaneous_heat_cold
|
||||
return self._dual_supply_capability
|
||||
|
||||
def to_dictionary(self):
|
||||
"""Class content to dictionary"""
|
||||
|
@ -289,18 +269,6 @@ class NonPvGenerationSystem(GenerationSystem):
|
|||
self.distribution_systems] if self.distribution_systems is not None else None
|
||||
_energy_storage_systems = [_energy_storage_system.to_dictionary() for _energy_storage_system in
|
||||
self.energy_storage_systems] if self.energy_storage_systems is not None else None
|
||||
_heat_output_curve = self.heat_output_curve.to_dictionary() if (
|
||||
self.heat_output_curve is not None) else None
|
||||
_heat_fuel_consumption_curve = self.heat_fuel_consumption_curve.to_dictionary() if (
|
||||
self.heat_fuel_consumption_curve is not None) else None
|
||||
_heat_efficiency_curve = self.heat_efficiency_curve.to_dictionary() if (
|
||||
self.heat_efficiency_curve is not None) else None
|
||||
_cooling_output_curve = self.cooling_output_curve.to_dictionary() if (
|
||||
self.cooling_output_curve is not None) else None
|
||||
_cooling_fuel_consumption_curve = self.cooling_fuel_consumption_curve.to_dictionary() if (
|
||||
self.cooling_fuel_consumption_curve is not None) else None
|
||||
_cooling_efficiency_curve = self.cooling_efficiency_curve.to_dictionary() if (
|
||||
self.cooling_efficiency_curve is not None) else None
|
||||
|
||||
content = {
|
||||
'Energy Generation component':
|
||||
|
@ -330,15 +298,13 @@ class NonPvGenerationSystem(GenerationSystem):
|
|||
'minimum cooling supply temperature [Celsius]': self.minimum_cooling_supply_temperature,
|
||||
'heat output curve': self.heat_output_curve,
|
||||
'heat fuel consumption curve': self.heat_fuel_consumption_curve,
|
||||
'heat efficiency curve': _heat_efficiency_curve,
|
||||
'heat efficiency curve': self.heat_efficiency_curve,
|
||||
'cooling output curve': self.cooling_output_curve,
|
||||
'cooling fuel consumption curve': self.cooling_fuel_consumption_curve,
|
||||
'cooling efficiency curve': self.cooling_efficiency_curve,
|
||||
'distribution systems connected': _distribution_systems,
|
||||
'storage systems connected': _energy_storage_systems,
|
||||
'domestic hot water production capability': self.domestic_hot_water,
|
||||
'reversible cycle': self.reversibility,
|
||||
'simultaneous heat and cooling production': self.simultaneous_heat_cold
|
||||
'dual supply capability': self.dual_supply_capability
|
||||
}
|
||||
}
|
||||
return content
|
||||
|
|
|
@ -24,13 +24,13 @@ class PerformanceCurves:
|
|||
def curve_type(self):
|
||||
"""
|
||||
The type of the fit function from the following
|
||||
Linear =>>> y = a + b*x
|
||||
Linear =>>> y = a*x + b
|
||||
Exponential =>>> y = a*(b**x)
|
||||
Second degree polynomial =>>> y = a + b*x + c*(x**2)
|
||||
Polynomial =>>> y = a*(x**2) + b*x + c
|
||||
Power =>>> y = a*(x**b)
|
||||
Bi-Quadratic =>>> y = a + b*x + c*(x**2) + d*z + e*(z**2) + f*x*z
|
||||
Second degree multivariable =>>> y = a*(x**2) + b*x + c*x*z + d*z + e*(z**2) + f
|
||||
|
||||
Get the type of function from ['linear', 'exponential', 'second degree polynomial', 'power', 'bi-quadratic']
|
||||
Get the type of function from ['linear', 'exponential', 'polynomial', 'power', 'second degree multivariable']
|
||||
:return: string
|
||||
"""
|
||||
return self._curve_type
|
||||
|
|
|
@ -17,9 +17,8 @@ class PvGenerationSystem(GenerationSystem):
|
|||
def __init__(self, system_id, name, system_type, model_name=None, manufacturer=None, electricity_efficiency=None,
|
||||
nominal_electricity_output=None, nominal_ambient_temperature=None, nominal_cell_temperature=None,
|
||||
nominal_radiation=None, standard_test_condition_cell_temperature=None,
|
||||
standard_test_condition_maximum_power=None, standard_test_condition_radiation=None,
|
||||
cell_temperature_coefficient=None, width=None, height=None, distribution_systems=None,
|
||||
energy_storage_systems=None):
|
||||
standard_test_condition_maximum_power=None, cell_temperature_coefficient=None, width=None, height=None,
|
||||
distribution_systems=None, energy_storage_systems=None):
|
||||
super().__init__(system_id=system_id, name=name, model_name=model_name,
|
||||
manufacturer=manufacturer, fuel_type='renewable', distribution_systems=distribution_systems,
|
||||
energy_storage_systems=energy_storage_systems)
|
||||
|
@ -31,7 +30,6 @@ class PvGenerationSystem(GenerationSystem):
|
|||
self._nominal_radiation = nominal_radiation
|
||||
self._standard_test_condition_cell_temperature = standard_test_condition_cell_temperature
|
||||
self._standard_test_condition_maximum_power = standard_test_condition_maximum_power
|
||||
self._standard_test_condition_radiation = standard_test_condition_radiation
|
||||
self._cell_temperature_coefficient = cell_temperature_coefficient
|
||||
self._width = width
|
||||
self._height = height
|
||||
|
@ -100,15 +98,6 @@ class PvGenerationSystem(GenerationSystem):
|
|||
"""
|
||||
return self._standard_test_condition_maximum_power
|
||||
|
||||
@property
|
||||
def standard_test_condition_radiation(self):
|
||||
"""
|
||||
Get standard test condition cell temperature of PV panels in W/m2
|
||||
:return: float
|
||||
"""
|
||||
return self._standard_test_condition_radiation
|
||||
|
||||
|
||||
@property
|
||||
def cell_temperature_coefficient(self):
|
||||
"""
|
||||
|
@ -154,7 +143,6 @@ class PvGenerationSystem(GenerationSystem):
|
|||
'nominal radiation [W/m2]': self.nominal_radiation,
|
||||
'standard test condition cell temperature [Celsius]': self.standard_test_condition_cell_temperature,
|
||||
'standard test condition maximum power [W]': self.standard_test_condition_maximum_power,
|
||||
'standard test condition radiation [W/m2]': self.standard_test_condition_radiation,
|
||||
'cell temperature coefficient': self.cell_temperature_coefficient,
|
||||
'width': self.width,
|
||||
'height': self.height,
|
||||
|
|
|
@ -17,7 +17,7 @@ class ThermalStorageSystem(EnergyStorageSystem):
|
|||
|
||||
def __init__(self, storage_id, type_energy_stored=None, model_name=None, manufacturer=None, storage_type=None,
|
||||
nominal_capacity=None, losses_ratio=None, volume=None, height=None, layers=None,
|
||||
maximum_operating_temperature=None, storage_medium=None, heating_coil_capacity=None):
|
||||
maximum_operating_temperature=None, storage_medium=None):
|
||||
|
||||
super().__init__(storage_id, model_name, manufacturer, nominal_capacity, losses_ratio)
|
||||
self._type_energy_stored = type_energy_stored
|
||||
|
@ -27,7 +27,6 @@ class ThermalStorageSystem(EnergyStorageSystem):
|
|||
self._layers = layers
|
||||
self._maximum_operating_temperature = maximum_operating_temperature
|
||||
self._storage_medium = storage_medium
|
||||
self._heating_coil_capacity = heating_coil_capacity
|
||||
|
||||
@property
|
||||
def type_energy_stored(self):
|
||||
|
@ -85,14 +84,6 @@ class ThermalStorageSystem(EnergyStorageSystem):
|
|||
"""
|
||||
return self._storage_medium
|
||||
|
||||
@property
|
||||
def heating_coil_capacity(self):
|
||||
"""
|
||||
Get heating coil capacity in Watts
|
||||
:return: [material
|
||||
"""
|
||||
return self._heating_coil_capacity
|
||||
|
||||
def to_dictionary(self):
|
||||
"""Class content to dictionary"""
|
||||
_layers = None
|
||||
|
@ -119,8 +110,7 @@ class ThermalStorageSystem(EnergyStorageSystem):
|
|||
'height [m]': self.height,
|
||||
'layers': _layers,
|
||||
'maximum operating temperature [Celsius]': self.maximum_operating_temperature,
|
||||
'storage_medium': self.storage_medium.to_dictionary(),
|
||||
'heating coil capacity [W]': self.heating_coil_capacity
|
||||
'storage_medium': self.storage_medium.to_dictionary()
|
||||
}
|
||||
}
|
||||
return content
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -87,7 +87,7 @@ class MontrealCustomCatalog(Catalog):
|
|||
cooling_efficiency=cooling_efficiency,
|
||||
electricity_efficiency=electricity_efficiency,
|
||||
energy_storage_systems=storage_systems,
|
||||
domestic_hot_water=False
|
||||
dual_supply_capability=False
|
||||
)
|
||||
_equipments.append(generation_system)
|
||||
|
||||
|
@ -111,7 +111,10 @@ class MontrealCustomCatalog(Catalog):
|
|||
distribution_consumption_variable_flow = float(
|
||||
equipment['distribution_consumption_variable_flow']['#text']) / 100
|
||||
|
||||
emission_equipment = -1
|
||||
if 'dissipation_id' in equipment:
|
||||
emission_equipment = equipment['dissipation_id']
|
||||
|
||||
_emission_equipments = None
|
||||
for equipment_archetype in self._catalog_emission_equipments:
|
||||
if int(equipment_archetype.id) == int(emission_equipment):
|
||||
|
|
|
@ -121,26 +121,13 @@ class MontrealFutureSystemCatalogue(Catalog):
|
|||
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
|
||||
dual_supply_capability = None
|
||||
if non_pv['dual_supply_capability'] is not None:
|
||||
if non_pv['dual_supply_capability'] == 'True':
|
||||
dual_supply_capability = True
|
||||
else:
|
||||
dhw = False
|
||||
dual_supply_capability = 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,
|
||||
|
@ -173,9 +160,7 @@ class MontrealFutureSystemCatalogue(Catalog):
|
|||
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)
|
||||
dual_supply_capability=dual_supply_capability)
|
||||
generation_components.append(non_pv_component)
|
||||
pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][
|
||||
'pv_generation_component']
|
||||
|
@ -193,7 +178,6 @@ class MontrealFutureSystemCatalogue(Catalog):
|
|||
nominal_radiation = pv['nominal_radiation']
|
||||
standard_test_condition_cell_temperature = pv['standard_test_condition_cell_temperature']
|
||||
standard_test_condition_maximum_power = pv['standard_test_condition_maximum_power']
|
||||
standard_test_condition_radiation = pv['standard_test_condition_radiation']
|
||||
cell_temperature_coefficient = pv['cell_temperature_coefficient']
|
||||
width = pv['width']
|
||||
height = pv['height']
|
||||
|
@ -203,6 +187,7 @@ class MontrealFutureSystemCatalogue(Catalog):
|
|||
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,
|
||||
|
@ -216,7 +201,6 @@ class MontrealFutureSystemCatalogue(Catalog):
|
|||
standard_test_condition_cell_temperature=
|
||||
standard_test_condition_cell_temperature,
|
||||
standard_test_condition_maximum_power=standard_test_condition_maximum_power,
|
||||
standard_test_condition_radiation=standard_test_condition_radiation,
|
||||
cell_temperature_coefficient=cell_temperature_coefficient,
|
||||
width=width,
|
||||
height=height,
|
||||
|
@ -300,7 +284,6 @@ class MontrealFutureSystemCatalogue(Catalog):
|
|||
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,
|
||||
|
@ -312,8 +295,7 @@ class MontrealFutureSystemCatalogue(Catalog):
|
|||
height=height,
|
||||
layers=layers,
|
||||
maximum_operating_temperature=maximum_operating_temperature,
|
||||
storage_medium=medium,
|
||||
heating_coil_capacity=heating_coil_capacity)
|
||||
storage_medium=medium)
|
||||
storage_components.append(storage_component)
|
||||
|
||||
for template in template_storages:
|
||||
|
@ -321,7 +303,7 @@ class MontrealFutureSystemCatalogue(Catalog):
|
|||
storage_type = template['storage_type']
|
||||
type_energy_stored = template['type_energy_stored']
|
||||
maximum_operating_temperature = template['maximum_operating_temperature']
|
||||
height = float(template['physical_characteristics']['height'])
|
||||
height = template['physical_characteristics']['height']
|
||||
materials = self._load_materials()
|
||||
insulation_material_id = template['insulation']['material_id']
|
||||
insulation_material = self._search_material(materials, insulation_material_id)
|
||||
|
@ -340,7 +322,6 @@ class MontrealFutureSystemCatalogue(Catalog):
|
|||
nominal_capacity = template['nominal_capacity']
|
||||
losses_ratio = template['losses_ratio']
|
||||
volume = template['physical_characteristics']['volume']
|
||||
heating_coil_capacity = template['heating_coil_capacity']
|
||||
storage_component = ThermalStorageSystem(storage_id=storage_id,
|
||||
model_name=model_name,
|
||||
type_energy_stored=type_energy_stored,
|
||||
|
@ -352,8 +333,7 @@ class MontrealFutureSystemCatalogue(Catalog):
|
|||
height=height,
|
||||
layers=layers,
|
||||
maximum_operating_temperature=maximum_operating_temperature,
|
||||
storage_medium=medium,
|
||||
heating_coil_capacity=heating_coil_capacity)
|
||||
storage_medium=medium)
|
||||
storage_components.append(storage_component)
|
||||
return storage_components
|
||||
|
||||
|
|
|
@ -1,520 +0,0 @@
|
|||
"""
|
||||
Palma energy system catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
|
||||
"""
|
||||
|
||||
import xmltodict
|
||||
from pathlib import Path
|
||||
from hub.catalog_factories.catalog import Catalog
|
||||
from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.system import System
|
||||
from hub.catalog_factories.data_models.energy_systems.content import Content
|
||||
from hub.catalog_factories.data_models.energy_systems.non_pv_generation_system import NonPvGenerationSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.pv_generation_system import PvGenerationSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.thermal_storage_system import ThermalStorageSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves
|
||||
from hub.catalog_factories.data_models.energy_systems.archetype import Archetype
|
||||
from hub.catalog_factories.data_models.construction.material import Material
|
||||
from hub.catalog_factories.data_models.construction.layer import Layer
|
||||
|
||||
|
||||
class PalmaSystemCatalogue(Catalog):
|
||||
"""
|
||||
North america energy system catalog class
|
||||
"""
|
||||
|
||||
def __init__(self, path):
|
||||
path = str(path / 'palma_systems.xml')
|
||||
with open(path, 'r', encoding='utf-8') as xml:
|
||||
self._archetypes = xmltodict.parse(xml.read(),
|
||||
force_list=['pv_generation_component', 'demand'])
|
||||
|
||||
self._storage_components = self._load_storage_components()
|
||||
self._generation_components = self._load_generation_components()
|
||||
self._energy_emission_components = self._load_emission_equipments()
|
||||
self._distribution_components = self._load_distribution_equipments()
|
||||
self._systems = self._load_systems()
|
||||
self._system_archetypes = self._load_archetypes()
|
||||
self._content = Content(self._system_archetypes,
|
||||
self._systems,
|
||||
generations=self._generation_components,
|
||||
distributions=self._distribution_components)
|
||||
|
||||
def _load_generation_components(self):
|
||||
generation_components = []
|
||||
non_pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][
|
||||
'non_pv_generation_component']
|
||||
if non_pv_generation_components is not None:
|
||||
for non_pv in non_pv_generation_components:
|
||||
system_id = non_pv['system_id']
|
||||
name = non_pv['name']
|
||||
system_type = non_pv['system_type']
|
||||
model_name = non_pv['model_name']
|
||||
manufacturer = non_pv['manufacturer']
|
||||
fuel_type = non_pv['fuel_type']
|
||||
distribution_systems = non_pv['distribution_systems']
|
||||
energy_storage_systems = None
|
||||
if non_pv['energy_storage_systems'] is not None:
|
||||
storage_component = non_pv['energy_storage_systems']['storage_id']
|
||||
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component)
|
||||
energy_storage_systems = storage_systems
|
||||
nominal_heat_output = non_pv['nominal_heat_output']
|
||||
maximum_heat_output = non_pv['maximum_heat_output']
|
||||
minimum_heat_output = non_pv['minimum_heat_output']
|
||||
source_medium = non_pv['source_medium']
|
||||
supply_medium = non_pv['supply_medium']
|
||||
heat_efficiency = non_pv['heat_efficiency']
|
||||
nominal_cooling_output = non_pv['nominal_cooling_output']
|
||||
maximum_cooling_output = non_pv['maximum_cooling_output']
|
||||
minimum_cooling_output = non_pv['minimum_cooling_output']
|
||||
cooling_efficiency = non_pv['cooling_efficiency']
|
||||
electricity_efficiency = non_pv['electricity_efficiency']
|
||||
source_temperature = non_pv['source_temperature']
|
||||
source_mass_flow = non_pv['source_mass_flow']
|
||||
nominal_electricity_output = non_pv['nominal_electricity_output']
|
||||
maximum_heat_supply_temperature = non_pv['maximum_heat_supply_temperature']
|
||||
minimum_heat_supply_temperature = non_pv['minimum_heat_supply_temperature']
|
||||
maximum_cooling_supply_temperature = non_pv['maximum_cooling_supply_temperature']
|
||||
minimum_cooling_supply_temperature = non_pv['minimum_cooling_supply_temperature']
|
||||
heat_output_curve = None
|
||||
heat_fuel_consumption_curve = None
|
||||
heat_efficiency_curve = None
|
||||
cooling_output_curve = None
|
||||
cooling_fuel_consumption_curve = None
|
||||
cooling_efficiency_curve = None
|
||||
if non_pv['heat_output_curve'] is not None:
|
||||
curve_type = non_pv['heat_output_curve']['curve_type']
|
||||
dependant_variable = non_pv['heat_output_curve']['dependant_variable']
|
||||
parameters = non_pv['heat_output_curve']['parameters']
|
||||
coefficients = list(non_pv['heat_output_curve']['coefficients'].values())
|
||||
heat_output_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
if non_pv['heat_fuel_consumption_curve'] is not None:
|
||||
curve_type = non_pv['heat_fuel_consumption_curve']['curve_type']
|
||||
dependant_variable = non_pv['heat_fuel_consumption_curve']['dependant_variable']
|
||||
parameters = non_pv['heat_fuel_consumption_curve']['parameters']
|
||||
coefficients = list(non_pv['heat_fuel_consumption_curve']['coefficients'].values())
|
||||
heat_fuel_consumption_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
if non_pv['heat_efficiency_curve'] is not None:
|
||||
curve_type = non_pv['heat_efficiency_curve']['curve_type']
|
||||
dependant_variable = non_pv['heat_efficiency_curve']['dependant_variable']
|
||||
parameters = non_pv['heat_efficiency_curve']['parameters']
|
||||
coefficients = list(non_pv['heat_efficiency_curve']['coefficients'].values())
|
||||
heat_efficiency_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
if non_pv['cooling_output_curve'] is not None:
|
||||
curve_type = non_pv['cooling_output_curve']['curve_type']
|
||||
dependant_variable = non_pv['cooling_output_curve']['dependant_variable']
|
||||
parameters = non_pv['cooling_output_curve']['parameters']
|
||||
coefficients = list(non_pv['cooling_output_curve']['coefficients'].values())
|
||||
cooling_output_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
if non_pv['cooling_fuel_consumption_curve'] is not None:
|
||||
curve_type = non_pv['cooling_fuel_consumption_curve']['curve_type']
|
||||
dependant_variable = non_pv['cooling_fuel_consumption_curve']['dependant_variable']
|
||||
parameters = non_pv['cooling_fuel_consumption_curve']['parameters']
|
||||
coefficients = list(non_pv['cooling_fuel_consumption_curve']['coefficients'].values())
|
||||
cooling_fuel_consumption_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
if non_pv['cooling_efficiency_curve'] is not None:
|
||||
curve_type = non_pv['cooling_efficiency_curve']['curve_type']
|
||||
dependant_variable = non_pv['cooling_efficiency_curve']['dependant_variable']
|
||||
parameters = non_pv['cooling_efficiency_curve']['parameters']
|
||||
coefficients = list(non_pv['cooling_efficiency_curve']['coefficients'].values())
|
||||
cooling_efficiency_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
dhw = None
|
||||
if non_pv['domestic_hot_water'] is not None:
|
||||
if non_pv['domestic_hot_water'] == 'True':
|
||||
dhw = True
|
||||
else:
|
||||
dhw = False
|
||||
|
||||
reversible = None
|
||||
if non_pv['reversible'] is not None:
|
||||
if non_pv['reversible'] == 'True':
|
||||
reversible = True
|
||||
else:
|
||||
reversible = False
|
||||
|
||||
dual_supply = None
|
||||
if non_pv['simultaneous_heat_cold'] is not None:
|
||||
if non_pv['simultaneous_heat_cold'] == 'True':
|
||||
dual_supply = True
|
||||
else:
|
||||
dual_supply = False
|
||||
non_pv_component = NonPvGenerationSystem(system_id=system_id,
|
||||
name=name,
|
||||
system_type=system_type,
|
||||
model_name=model_name,
|
||||
manufacturer=manufacturer,
|
||||
fuel_type=fuel_type,
|
||||
nominal_heat_output=nominal_heat_output,
|
||||
maximum_heat_output=maximum_heat_output,
|
||||
minimum_heat_output=minimum_heat_output,
|
||||
source_medium=source_medium,
|
||||
supply_medium=supply_medium,
|
||||
heat_efficiency=heat_efficiency,
|
||||
nominal_cooling_output=nominal_cooling_output,
|
||||
maximum_cooling_output=maximum_cooling_output,
|
||||
minimum_cooling_output=minimum_cooling_output,
|
||||
cooling_efficiency=cooling_efficiency,
|
||||
electricity_efficiency=electricity_efficiency,
|
||||
source_temperature=source_temperature,
|
||||
source_mass_flow=source_mass_flow,
|
||||
nominal_electricity_output=nominal_electricity_output,
|
||||
maximum_heat_supply_temperature=maximum_heat_supply_temperature,
|
||||
minimum_heat_supply_temperature=minimum_heat_supply_temperature,
|
||||
maximum_cooling_supply_temperature=maximum_cooling_supply_temperature,
|
||||
minimum_cooling_supply_temperature=minimum_cooling_supply_temperature,
|
||||
heat_output_curve=heat_output_curve,
|
||||
heat_fuel_consumption_curve=heat_fuel_consumption_curve,
|
||||
heat_efficiency_curve=heat_efficiency_curve,
|
||||
cooling_output_curve=cooling_output_curve,
|
||||
cooling_fuel_consumption_curve=cooling_fuel_consumption_curve,
|
||||
cooling_efficiency_curve=cooling_efficiency_curve,
|
||||
distribution_systems=distribution_systems,
|
||||
energy_storage_systems=energy_storage_systems,
|
||||
domestic_hot_water=dhw,
|
||||
reversible=reversible,
|
||||
simultaneous_heat_cold=dual_supply)
|
||||
generation_components.append(non_pv_component)
|
||||
pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][
|
||||
'pv_generation_component']
|
||||
if pv_generation_components is not None:
|
||||
for pv in pv_generation_components:
|
||||
system_id = pv['system_id']
|
||||
name = pv['name']
|
||||
system_type = pv['system_type']
|
||||
model_name = pv['model_name']
|
||||
manufacturer = pv['manufacturer']
|
||||
electricity_efficiency = pv['electricity_efficiency']
|
||||
nominal_electricity_output = pv['nominal_electricity_output']
|
||||
nominal_ambient_temperature = pv['nominal_ambient_temperature']
|
||||
nominal_cell_temperature = pv['nominal_cell_temperature']
|
||||
nominal_radiation = pv['nominal_radiation']
|
||||
standard_test_condition_cell_temperature = pv['standard_test_condition_cell_temperature']
|
||||
standard_test_condition_maximum_power = pv['standard_test_condition_maximum_power']
|
||||
standard_test_condition_radiation = pv['standard_test_condition_radiation']
|
||||
cell_temperature_coefficient = pv['cell_temperature_coefficient']
|
||||
width = pv['width']
|
||||
height = pv['height']
|
||||
distribution_systems = pv['distribution_systems']
|
||||
energy_storage_systems = None
|
||||
if pv['energy_storage_systems'] is not None:
|
||||
storage_component = pv['energy_storage_systems']['storage_id']
|
||||
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component)
|
||||
energy_storage_systems = storage_systems
|
||||
pv_component = PvGenerationSystem(system_id=system_id,
|
||||
name=name,
|
||||
system_type=system_type,
|
||||
model_name=model_name,
|
||||
manufacturer=manufacturer,
|
||||
electricity_efficiency=electricity_efficiency,
|
||||
nominal_electricity_output=nominal_electricity_output,
|
||||
nominal_ambient_temperature=nominal_ambient_temperature,
|
||||
nominal_cell_temperature=nominal_cell_temperature,
|
||||
nominal_radiation=nominal_radiation,
|
||||
standard_test_condition_cell_temperature=
|
||||
standard_test_condition_cell_temperature,
|
||||
standard_test_condition_maximum_power=standard_test_condition_maximum_power,
|
||||
standard_test_condition_radiation=standard_test_condition_radiation,
|
||||
cell_temperature_coefficient=cell_temperature_coefficient,
|
||||
width=width,
|
||||
height=height,
|
||||
distribution_systems=distribution_systems,
|
||||
energy_storage_systems=energy_storage_systems)
|
||||
generation_components.append(pv_component)
|
||||
|
||||
return generation_components
|
||||
|
||||
def _load_distribution_equipments(self):
|
||||
_equipments = []
|
||||
distribution_systems = self._archetypes['EnergySystemCatalog']['distribution_systems']['distribution_system']
|
||||
if distribution_systems is not None:
|
||||
for distribution_system in distribution_systems:
|
||||
system_id = None
|
||||
model_name = None
|
||||
system_type = None
|
||||
supply_temperature = None
|
||||
distribution_consumption_fix_flow = None
|
||||
distribution_consumption_variable_flow = None
|
||||
heat_losses = None
|
||||
generation_systems = None
|
||||
energy_storage_systems = None
|
||||
emission_systems = None
|
||||
distribution_equipment = DistributionSystem(system_id=system_id,
|
||||
model_name=model_name,
|
||||
system_type=system_type,
|
||||
supply_temperature=supply_temperature,
|
||||
distribution_consumption_fix_flow=distribution_consumption_fix_flow,
|
||||
distribution_consumption_variable_flow=
|
||||
distribution_consumption_variable_flow,
|
||||
heat_losses=heat_losses,
|
||||
generation_systems=generation_systems,
|
||||
energy_storage_systems=energy_storage_systems,
|
||||
emission_systems=emission_systems
|
||||
)
|
||||
_equipments.append(distribution_equipment)
|
||||
return _equipments
|
||||
|
||||
def _load_emission_equipments(self):
|
||||
_equipments = []
|
||||
dissipation_systems = self._archetypes['EnergySystemCatalog']['dissipation_systems']['dissipation_system']
|
||||
if dissipation_systems is not None:
|
||||
for dissipation_system in dissipation_systems:
|
||||
system_id = None
|
||||
model_name = None
|
||||
system_type = None
|
||||
parasitic_energy_consumption = 0
|
||||
emission_system = EmissionSystem(system_id=system_id,
|
||||
model_name=model_name,
|
||||
system_type=system_type,
|
||||
parasitic_energy_consumption=parasitic_energy_consumption)
|
||||
_equipments.append(emission_system)
|
||||
return _equipments
|
||||
|
||||
def _load_storage_components(self):
|
||||
storage_components = []
|
||||
thermal_storages = self._archetypes['EnergySystemCatalog']['energy_storage_components']['thermalStorages']
|
||||
for tes in thermal_storages:
|
||||
storage_id = tes['storage_id']
|
||||
type_energy_stored = tes['type_energy_stored']
|
||||
model_name = tes['model_name']
|
||||
manufacturer = tes['manufacturer']
|
||||
storage_type = tes['storage_type']
|
||||
volume = tes['physical_characteristics']['volume']
|
||||
height = tes['physical_characteristics']['height']
|
||||
maximum_operating_temperature = tes['maximum_operating_temperature']
|
||||
materials = self._load_materials()
|
||||
insulation_material_id = tes['insulation']['material_id']
|
||||
insulation_material = self._search_material(materials, insulation_material_id)
|
||||
material_id = tes['physical_characteristics']['material_id']
|
||||
tank_material = self._search_material(materials, material_id)
|
||||
thickness = float(tes['insulation']['insulationThickness']) / 100 # from cm to m
|
||||
insulation_layer = Layer(None, 'insulation', insulation_material, thickness)
|
||||
thickness = float(tes['physical_characteristics']['tankThickness']) / 100 # from cm to m
|
||||
tank_layer = Layer(None, 'tank', tank_material, thickness)
|
||||
media = self._load_media()
|
||||
media_id = tes['storage_medium']['medium_id']
|
||||
medium = self._search_media(media, media_id)
|
||||
layers = [insulation_layer, tank_layer]
|
||||
nominal_capacity = tes['nominal_capacity']
|
||||
losses_ratio = tes['losses_ratio']
|
||||
heating_coil_capacity = tes['heating_coil_capacity']
|
||||
storage_component = ThermalStorageSystem(storage_id=storage_id,
|
||||
model_name=model_name,
|
||||
type_energy_stored=type_energy_stored,
|
||||
manufacturer=manufacturer,
|
||||
storage_type=storage_type,
|
||||
nominal_capacity=nominal_capacity,
|
||||
losses_ratio=losses_ratio,
|
||||
volume=volume,
|
||||
height=height,
|
||||
layers=layers,
|
||||
maximum_operating_temperature=maximum_operating_temperature,
|
||||
storage_medium=medium,
|
||||
heating_coil_capacity=heating_coil_capacity)
|
||||
storage_components.append(storage_component)
|
||||
return storage_components
|
||||
|
||||
def _load_systems(self):
|
||||
base_path = Path(Path(__file__).parent.parent.parent / 'data/energy_systems')
|
||||
_catalog_systems = []
|
||||
systems = self._archetypes['EnergySystemCatalog']['systems']['system']
|
||||
for system in systems:
|
||||
system_id = system['id']
|
||||
name = system['name']
|
||||
demands = system['demands']['demand']
|
||||
generation_components = system['components']['generation_id']
|
||||
generation_systems = self._search_generation_equipment(self._load_generation_components(), generation_components)
|
||||
configuration_schema = None
|
||||
if system['schema'] is not None:
|
||||
configuration_schema = Path(base_path / system['schema'])
|
||||
energy_system = System(system_id=system_id,
|
||||
name=name,
|
||||
demand_types=demands,
|
||||
generation_systems=generation_systems,
|
||||
distribution_systems=None,
|
||||
configuration_schema=configuration_schema)
|
||||
_catalog_systems.append(energy_system)
|
||||
return _catalog_systems
|
||||
|
||||
def _load_archetypes(self):
|
||||
_system_archetypes = []
|
||||
system_clusters = self._archetypes['EnergySystemCatalog']['system_archetypes']['system_archetype']
|
||||
for system_cluster in system_clusters:
|
||||
name = system_cluster['name']
|
||||
systems = system_cluster['systems']['system_id']
|
||||
integer_system_ids = [int(item) for item in systems]
|
||||
_systems = []
|
||||
for system_archetype in self._systems:
|
||||
if int(system_archetype.id) in integer_system_ids:
|
||||
_systems.append(system_archetype)
|
||||
_system_archetypes.append(Archetype(name=name, systems=_systems))
|
||||
return _system_archetypes
|
||||
|
||||
def _load_materials(self):
|
||||
materials = []
|
||||
_materials = self._archetypes['EnergySystemCatalog']['materials']['material']
|
||||
for _material in _materials:
|
||||
material_id = _material['material_id']
|
||||
name = _material['name']
|
||||
conductivity = _material['conductivity']
|
||||
solar_absorptance = _material['solar_absorptance']
|
||||
thermal_absorptance = _material['thermal_absorptance']
|
||||
density = _material['density']
|
||||
specific_heat = _material['specific_heat']
|
||||
no_mass = _material['no_mass']
|
||||
visible_absorptance = _material['visible_absorptance']
|
||||
thermal_resistance = _material['thermal_resistance']
|
||||
|
||||
material = Material(material_id,
|
||||
name,
|
||||
solar_absorptance=solar_absorptance,
|
||||
thermal_absorptance=thermal_absorptance,
|
||||
density=density,
|
||||
conductivity=conductivity,
|
||||
thermal_resistance=thermal_resistance,
|
||||
visible_absorptance=visible_absorptance,
|
||||
no_mass=no_mass,
|
||||
specific_heat=specific_heat)
|
||||
materials.append(material)
|
||||
return materials
|
||||
|
||||
@staticmethod
|
||||
def _search_material(materials, material_id):
|
||||
_material = None
|
||||
for material in materials:
|
||||
if int(material.id) == int(material_id):
|
||||
_material = material
|
||||
break
|
||||
if _material is None:
|
||||
raise ValueError(f'Material with the id = [{material_id}] not found in catalog ')
|
||||
return _material
|
||||
|
||||
def _load_media(self):
|
||||
media = []
|
||||
_media = [self._archetypes['EnergySystemCatalog']['media']['medium']]
|
||||
for _medium in _media:
|
||||
medium_id = _medium['medium_id']
|
||||
density = _medium['density']
|
||||
name = _medium['name']
|
||||
conductivity = _medium['conductivity']
|
||||
solar_absorptance = _medium['solar_absorptance']
|
||||
thermal_absorptance = _medium['thermal_absorptance']
|
||||
specific_heat = _medium['specific_heat']
|
||||
no_mass = _medium['no_mass']
|
||||
visible_absorptance = _medium['visible_absorptance']
|
||||
thermal_resistance = _medium['thermal_resistance']
|
||||
medium = Material(material_id=medium_id,
|
||||
name=name,
|
||||
solar_absorptance=solar_absorptance,
|
||||
thermal_absorptance=thermal_absorptance,
|
||||
visible_absorptance=visible_absorptance,
|
||||
no_mass=no_mass,
|
||||
thermal_resistance=thermal_resistance,
|
||||
conductivity=conductivity,
|
||||
density=density,
|
||||
specific_heat=specific_heat)
|
||||
media.append(medium)
|
||||
return media
|
||||
|
||||
@staticmethod
|
||||
def _search_media(media, medium_id):
|
||||
_medium = None
|
||||
for medium in media:
|
||||
if int(medium.id) == int(medium_id):
|
||||
_medium = medium
|
||||
break
|
||||
if _medium is None:
|
||||
raise ValueError(f'media with the id = [{medium_id}] not found in catalog ')
|
||||
return _medium
|
||||
|
||||
@staticmethod
|
||||
def _search_generation_equipment(generation_systems, generation_id):
|
||||
_generation_systems = []
|
||||
|
||||
if isinstance(generation_id, list):
|
||||
integer_ids = [int(item) for item in generation_id]
|
||||
for generation in generation_systems:
|
||||
if int(generation.id) in integer_ids:
|
||||
_generation_systems.append(generation)
|
||||
else:
|
||||
integer_id = int(generation_id)
|
||||
for generation in generation_systems:
|
||||
if int(generation.id) == integer_id:
|
||||
_generation_systems.append(generation)
|
||||
|
||||
if len(_generation_systems) == 0:
|
||||
_generation_systems = None
|
||||
raise ValueError(f'The system with the following id is not found in catalog [{generation_id}]')
|
||||
return _generation_systems
|
||||
|
||||
@staticmethod
|
||||
def _search_storage_equipment(storage_systems, storage_id):
|
||||
_storage_systems = []
|
||||
for storage in storage_systems:
|
||||
if storage.id in storage_id:
|
||||
_storage_systems.append(storage)
|
||||
if len(_storage_systems) == 0:
|
||||
_storage_systems = None
|
||||
raise ValueError(f'The system with the following id is not found in catalog [{storage_id}]')
|
||||
return _storage_systems
|
||||
|
||||
def names(self, category=None):
|
||||
"""
|
||||
Get the catalog elements names
|
||||
:parm: optional category filter
|
||||
"""
|
||||
if category is None:
|
||||
_names = {'archetypes': [], 'systems': [], 'generation_equipments': [], 'storage_equipments': []}
|
||||
for archetype in self._content.archetypes:
|
||||
_names['archetypes'].append(archetype.name)
|
||||
for system in self._content.systems:
|
||||
_names['systems'].append(system.name)
|
||||
for equipment in self._content.generation_equipments:
|
||||
_names['generation_equipments'].append(equipment.name)
|
||||
else:
|
||||
_names = {category: []}
|
||||
if category.lower() == 'archetypes':
|
||||
for archetype in self._content.archetypes:
|
||||
_names[category].append(archetype.name)
|
||||
elif category.lower() == 'systems':
|
||||
for system in self._content.systems:
|
||||
_names[category].append(system.name)
|
||||
elif category.lower() == 'generation_equipments':
|
||||
for system in self._content.generation_equipments:
|
||||
_names[category].append(system.name)
|
||||
else:
|
||||
raise ValueError(f'Unknown category [{category}]')
|
||||
return _names
|
||||
|
||||
def entries(self, category=None):
|
||||
"""
|
||||
Get the catalog elements
|
||||
:parm: optional category filter
|
||||
"""
|
||||
if category is None:
|
||||
return self._content
|
||||
if category.lower() == 'archetypes':
|
||||
return self._content.archetypes
|
||||
if category.lower() == 'systems':
|
||||
return self._content.systems
|
||||
if category.lower() == 'generation_equipments':
|
||||
return self._content.generation_equipments
|
||||
raise ValueError(f'Unknown category [{category}]')
|
||||
|
||||
def get_entry(self, name):
|
||||
"""
|
||||
Get one catalog element by names
|
||||
:parm: entry name
|
||||
"""
|
||||
for entry in self._content.archetypes:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.systems:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.generation_equipments:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
raise IndexError(f"{name} doesn't exists in the catalog")
|
|
@ -10,7 +10,6 @@ from typing import TypeVar
|
|||
|
||||
from hub.catalog_factories.energy_systems.montreal_custom_catalog import MontrealCustomCatalog
|
||||
from hub.catalog_factories.energy_systems.montreal_future_system_catalogue import MontrealFutureSystemCatalogue
|
||||
from hub.catalog_factories.energy_systems.palma_system_catalgue import PalmaSystemCatalogue
|
||||
from hub.helpers.utils import validate_import_export_type
|
||||
|
||||
Catalog = TypeVar('Catalog')
|
||||
|
@ -41,13 +40,6 @@ class EnergySystemsCatalogFactory:
|
|||
"""
|
||||
return MontrealFutureSystemCatalogue(self._path)
|
||||
|
||||
@property
|
||||
def _palma(self):
|
||||
"""
|
||||
Retrieve Palma catalog
|
||||
"""
|
||||
return PalmaSystemCatalogue(self._path)
|
||||
|
||||
@property
|
||||
def catalog(self) -> Catalog:
|
||||
"""
|
||||
|
|
BIN
hub/catalog_factories/usage/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
hub/catalog_factories/usage/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,227 +0,0 @@
|
|||
"""
|
||||
Palma usage catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Cecilia Pérez cperez@irec.cat
|
||||
"""
|
||||
|
||||
import json
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
import xmltodict
|
||||
|
||||
import hub.helpers.constants as cte
|
||||
from hub.catalog_factories.catalog import Catalog
|
||||
from hub.catalog_factories.data_models.usages.appliances import Appliances
|
||||
from hub.catalog_factories.data_models.usages.content import Content
|
||||
from hub.catalog_factories.data_models.usages.lighting import Lighting
|
||||
from hub.catalog_factories.data_models.usages.occupancy import Occupancy
|
||||
from hub.catalog_factories.data_models.usages.domestic_hot_water import DomesticHotWater
|
||||
from hub.catalog_factories.data_models.usages.schedule import Schedule
|
||||
from hub.catalog_factories.data_models.usages.thermal_control import ThermalControl
|
||||
from hub.catalog_factories.data_models.usages.usage import Usage
|
||||
from hub.catalog_factories.usage.usage_helper import UsageHelper
|
||||
|
||||
|
||||
class PalmaCatalog(Catalog):
|
||||
"""
|
||||
Palma catalog class
|
||||
"""
|
||||
def __init__(self, path):
|
||||
self._schedules_path = Path(path / 'palma_schedules.json').resolve()
|
||||
self._space_types_path = Path(path / 'palma_space_types.json').resolve()
|
||||
self._space_compliance_path = Path(path / 'palma_space_compliance.json').resolve()
|
||||
self._content = None
|
||||
self._schedules = {}
|
||||
self._load_schedules()
|
||||
self._content = Content(self._load_archetypes())
|
||||
|
||||
@staticmethod
|
||||
def _extract_schedule(raw):
|
||||
nrcan_schedule_type = raw['category']
|
||||
if 'Heating' in raw['name'] and 'Water' not in raw['name']:
|
||||
nrcan_schedule_type = f'{nrcan_schedule_type} Heating'
|
||||
elif 'Cooling' in raw['name']:
|
||||
nrcan_schedule_type = f'{nrcan_schedule_type} Cooling'
|
||||
if nrcan_schedule_type not in UsageHelper().nrcan_schedule_type_to_hub_schedule_type:
|
||||
return None
|
||||
hub_type = UsageHelper().nrcan_schedule_type_to_hub_schedule_type[nrcan_schedule_type]
|
||||
data_type = UsageHelper().nrcan_data_type_to_hub_data_type[raw['units']]
|
||||
time_step = UsageHelper().nrcan_time_to_hub_time[raw['type']]
|
||||
# nrcan only uses daily range for the schedules
|
||||
time_range = cte.DAY
|
||||
day_types = UsageHelper().nrcan_day_type_to_hub_days[raw['day_types']]
|
||||
return Schedule(hub_type, raw['values'], data_type, time_step, time_range, day_types)
|
||||
|
||||
def _load_schedules(self):
|
||||
_schedule_types = []
|
||||
with open(self._schedules_path, 'r') as f:
|
||||
schedules_type = json.load(f)
|
||||
for schedule_type in schedules_type['tables']['schedules']['table']:
|
||||
schedule = PalmaCatalog._extract_schedule(schedule_type)
|
||||
if schedule_type['name'] not in _schedule_types:
|
||||
_schedule_types.append(schedule_type['name'])
|
||||
if schedule is not None:
|
||||
self._schedules[schedule_type['name']] = [schedule]
|
||||
else:
|
||||
if schedule is not None:
|
||||
_schedules = self._schedules[schedule_type['name']]
|
||||
_schedules.append(schedule)
|
||||
self._schedules[schedule_type['name']] = _schedules
|
||||
|
||||
def _get_schedules(self, name):
|
||||
schedule = None
|
||||
if name in self._schedules:
|
||||
schedule = self._schedules[name]
|
||||
return schedule
|
||||
|
||||
def _load_archetypes(self):
|
||||
usages = []
|
||||
with open(self._space_types_path, 'r') as f:
|
||||
space_types = json.load(f)['tables']['space_types']['table']
|
||||
space_types = [st for st in space_types if st['space_type'] == 'WholeBuilding']
|
||||
with open(self._space_compliance_path, 'r') as f:
|
||||
space_types_compliance = json.load(f)['tables']['space_compliance']['table']
|
||||
space_types_compliance = [st for st in space_types_compliance if st['space_type'] == 'WholeBuilding']
|
||||
space_types_dictionary = {}
|
||||
for space_type in space_types_compliance:
|
||||
usage_type = space_type['building_type']
|
||||
# people/m2
|
||||
occupancy_density = space_type['occupancy_per_area_people_per_m2']
|
||||
# W/m2
|
||||
lighting_density = space_type['lighting_per_area_w_per_m2']
|
||||
# W/m2
|
||||
appliances_density = space_type['electric_equipment_per_area_w_per_m2']
|
||||
# peak flow in gallons/h/m2
|
||||
domestic_hot_water_peak_flow = (
|
||||
space_type['service_water_heating_peak_flow_per_area'] *
|
||||
cte.GALLONS_TO_QUBIC_METERS / cte.HOUR_TO_SECONDS
|
||||
)
|
||||
space_types_dictionary[usage_type] = {'occupancy_per_area': occupancy_density,
|
||||
'lighting_per_area': lighting_density,
|
||||
'electric_equipment_per_area': appliances_density,
|
||||
'service_water_heating_peak_flow_per_area': domestic_hot_water_peak_flow
|
||||
}
|
||||
|
||||
for space_type in space_types:
|
||||
usage_type = space_type['building_type']
|
||||
space_type_compliance = space_types_dictionary[usage_type]
|
||||
occupancy_density = space_type_compliance['occupancy_per_area']
|
||||
sensible_convective_internal_gain = space_type['sensible_convective_internal_gain']
|
||||
sensible_radiative_internal_gain = space_type['sensible_radiative_internal_gain']
|
||||
latent_internal_gain = space_type['latent_internal_gain']
|
||||
lighting_density = space_type_compliance['lighting_per_area']
|
||||
appliances_density = space_type_compliance['electric_equipment_per_area']
|
||||
domestic_hot_water_peak_flow = space_type_compliance['service_water_heating_peak_flow_per_area']
|
||||
|
||||
occupancy_schedule_name = space_type['occupancy_schedule']
|
||||
lighting_schedule_name = space_type['lighting_schedule']
|
||||
appliance_schedule_name = space_type['electric_equipment_schedule']
|
||||
hvac_schedule_name = space_type['exhaust_schedule']
|
||||
if hvac_schedule_name and 'FAN' in hvac_schedule_name:
|
||||
hvac_schedule_name = hvac_schedule_name.replace('FAN', 'Fan')
|
||||
if not hvac_schedule_name:
|
||||
hvac_schedule_name = 'default_HVAC_schedule'
|
||||
heating_setpoint_schedule_name = space_type['heating_setpoint_schedule']
|
||||
cooling_setpoint_schedule_name = space_type['cooling_setpoint_schedule']
|
||||
domestic_hot_water_schedule_name = space_type['service_water_heating_schedule']
|
||||
occupancy_schedule = self._get_schedules(occupancy_schedule_name)
|
||||
lighting_schedule = self._get_schedules(lighting_schedule_name)
|
||||
appliance_schedule = self._get_schedules(appliance_schedule_name)
|
||||
heating_schedule = self._get_schedules(heating_setpoint_schedule_name)
|
||||
cooling_schedule = self._get_schedules(cooling_setpoint_schedule_name)
|
||||
hvac_availability = self._get_schedules(hvac_schedule_name)
|
||||
domestic_hot_water_load_schedule = self._get_schedules(domestic_hot_water_schedule_name)
|
||||
|
||||
# ACH -> 1/s
|
||||
mechanical_air_change = space_type['ventilation_air_changes'] / cte.HOUR_TO_SECONDS
|
||||
# cfm/ft2 to m3/m2.s
|
||||
ventilation_rate = space_type['ventilation_per_area'] / (cte.METERS_TO_FEET * cte.MINUTES_TO_SECONDS)
|
||||
# cfm/person to m3/m2.s
|
||||
ventilation_rate += space_type['ventilation_per_person'] / (
|
||||
pow(cte.METERS_TO_FEET, 3) * cte.MINUTES_TO_SECONDS
|
||||
) * occupancy_density
|
||||
|
||||
lighting_radiative_fraction = space_type['lighting_fraction_radiant']
|
||||
lighting_convective_fraction = 0
|
||||
if lighting_radiative_fraction is not None:
|
||||
lighting_convective_fraction = 1 - lighting_radiative_fraction
|
||||
lighting_latent_fraction = 0
|
||||
appliances_radiative_fraction = space_type['electric_equipment_fraction_radiant']
|
||||
appliances_latent_fraction = space_type['electric_equipment_fraction_latent']
|
||||
appliances_convective_fraction = 0
|
||||
if appliances_radiative_fraction is not None and appliances_latent_fraction is not None:
|
||||
appliances_convective_fraction = 1 - appliances_radiative_fraction - appliances_latent_fraction
|
||||
|
||||
domestic_hot_water_service_temperature = space_type['service_water_heating_target_temperature']
|
||||
|
||||
occupancy = Occupancy(occupancy_density,
|
||||
sensible_convective_internal_gain,
|
||||
sensible_radiative_internal_gain,
|
||||
latent_internal_gain,
|
||||
occupancy_schedule)
|
||||
lighting = Lighting(lighting_density,
|
||||
lighting_convective_fraction,
|
||||
lighting_radiative_fraction,
|
||||
lighting_latent_fraction,
|
||||
lighting_schedule)
|
||||
appliances = Appliances(appliances_density,
|
||||
appliances_convective_fraction,
|
||||
appliances_radiative_fraction,
|
||||
appliances_latent_fraction,
|
||||
appliance_schedule)
|
||||
thermal_control = ThermalControl(None,
|
||||
None,
|
||||
None,
|
||||
hvac_availability,
|
||||
heating_schedule,
|
||||
cooling_schedule)
|
||||
domestic_hot_water = DomesticHotWater(None,
|
||||
domestic_hot_water_peak_flow,
|
||||
domestic_hot_water_service_temperature,
|
||||
domestic_hot_water_load_schedule)
|
||||
|
||||
hours_day = None
|
||||
days_year = None
|
||||
|
||||
usages.append(Usage(usage_type,
|
||||
hours_day,
|
||||
days_year,
|
||||
mechanical_air_change,
|
||||
ventilation_rate,
|
||||
occupancy,
|
||||
lighting,
|
||||
appliances,
|
||||
thermal_control,
|
||||
domestic_hot_water))
|
||||
|
||||
|
||||
return usages
|
||||
|
||||
def names(self, category=None):
|
||||
"""
|
||||
Get the catalog elements names
|
||||
:parm: for usage catalog category filter does nothing as there is only one category (usages)
|
||||
"""
|
||||
_names = {'usages': []}
|
||||
for usage in self._content.usages:
|
||||
_names['usages'].append(usage.name)
|
||||
return _names
|
||||
|
||||
def entries(self, category=None):
|
||||
"""
|
||||
Get the catalog elements
|
||||
:parm: for usage catalog category filter does nothing as there is only one category (usages)
|
||||
"""
|
||||
return self._content
|
||||
|
||||
def get_entry(self, name):
|
||||
"""
|
||||
Get one catalog element by names
|
||||
:parm: entry name
|
||||
"""
|
||||
for usage in self._content.usages:
|
||||
if usage.name.lower() == name.lower():
|
||||
return usage
|
||||
raise IndexError(f"{name} doesn't exists in the catalog")
|
|
@ -11,7 +11,6 @@ from typing import TypeVar
|
|||
from hub.catalog_factories.usage.comnet_catalog import ComnetCatalog
|
||||
from hub.catalog_factories.usage.nrcan_catalog import NrcanCatalog
|
||||
from hub.catalog_factories.usage.eilat_catalog import EilatCatalog
|
||||
from hub.catalog_factories.usage.palma_catalog import PalmaCatalog
|
||||
from hub.helpers.utils import validate_import_export_type
|
||||
|
||||
Catalog = TypeVar('Catalog')
|
||||
|
@ -43,13 +42,6 @@ class UsageCatalogFactory:
|
|||
# nrcan retrieves the data directly from github
|
||||
return NrcanCatalog(self._path)
|
||||
|
||||
@property
|
||||
def _palma(self):
|
||||
"""
|
||||
Retrieve Palma catalog
|
||||
"""
|
||||
return PalmaCatalog(self._path)
|
||||
|
||||
@property
|
||||
def _eilat(self):
|
||||
"""
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -90,9 +90,7 @@ class Building(CityObject):
|
|||
self._interior_slabs.append(surface)
|
||||
else:
|
||||
logging.error('Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type)
|
||||
self._domestic_hot_water_peak_load = None
|
||||
self._fuel_consumption_breakdown = {}
|
||||
self._pv_generation = {}
|
||||
self._heating_consumption_disaggregated = {}
|
||||
|
||||
@property
|
||||
def shell(self) -> Polyhedron:
|
||||
|
@ -292,10 +290,7 @@ class Building(CityObject):
|
|||
"""
|
||||
if self._storeys_above_ground is None:
|
||||
if self.eave_height is not None and self.average_storey_height is not None:
|
||||
storeys_above_ground = int(self.eave_height / self.average_storey_height)
|
||||
if storeys_above_ground == 0:
|
||||
storeys_above_ground += 1
|
||||
self._storeys_above_ground = storeys_above_ground
|
||||
self._storeys_above_ground = int(self.eave_height / self.average_storey_height)
|
||||
return self._storeys_above_ground
|
||||
|
||||
@storeys_above_ground.setter
|
||||
|
@ -454,8 +449,8 @@ class Building(CityObject):
|
|||
monthly_values = PeakLoads(self).heating_peak_loads_from_methodology
|
||||
if monthly_values is None:
|
||||
return None
|
||||
results[cte.MONTH] = [x / cte.WATTS_HOUR_TO_JULES for x in monthly_values]
|
||||
results[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES]
|
||||
results[cte.MONTH] = monthly_values
|
||||
results[cte.YEAR] = [max(monthly_values)]
|
||||
return results
|
||||
|
||||
@property
|
||||
|
@ -471,24 +466,8 @@ class Building(CityObject):
|
|||
monthly_values = PeakLoads(self).cooling_peak_loads_from_methodology
|
||||
if monthly_values is None:
|
||||
return None
|
||||
results[cte.MONTH] = [x / cte.WATTS_HOUR_TO_JULES for x in monthly_values]
|
||||
results[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES]
|
||||
return results
|
||||
|
||||
@property
|
||||
def domestic_hot_water_peak_load(self) -> Union[None, dict]:
|
||||
"""
|
||||
Get cooling peak load in W
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
results = {}
|
||||
monthly_values = None
|
||||
if cte.HOUR in self.domestic_hot_water_heat_demand:
|
||||
monthly_values = PeakLoads().peak_loads_from_hourly(self.domestic_hot_water_heat_demand[cte.HOUR])
|
||||
if monthly_values is None:
|
||||
return None
|
||||
results[cte.MONTH] = [x / cte.WATTS_HOUR_TO_JULES for x in monthly_values]
|
||||
results[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES]
|
||||
results[cte.MONTH] = [x * cte.WATTS_HOUR_TO_JULES for x in monthly_values]
|
||||
results[cte.YEAR] = [max(monthly_values)]
|
||||
return results
|
||||
|
||||
@property
|
||||
|
@ -739,7 +718,6 @@ class Building(CityObject):
|
|||
return self._distribution_systems_electrical_consumption
|
||||
for energy_system in self.energy_systems:
|
||||
distribution_systems = energy_system.distribution_systems
|
||||
if distribution_systems is not None:
|
||||
for distribution_system in distribution_systems:
|
||||
emission_systems = distribution_system.emission_systems
|
||||
parasitic_energy_consumption = 0
|
||||
|
@ -847,6 +825,23 @@ class Building(CityObject):
|
|||
self._onsite_electrical_production[_key] = _results
|
||||
return self._onsite_electrical_production
|
||||
|
||||
@property
|
||||
def heating_consumption_disaggregated(self) -> dict:
|
||||
"""
|
||||
Get energy consumed for heating from different fuels in J
|
||||
return: dict
|
||||
"""
|
||||
return self._heating_consumption_disaggregated
|
||||
|
||||
@heating_consumption_disaggregated.setter
|
||||
def heating_consumption_disaggregated(self, value):
|
||||
"""
|
||||
Get energy consumed for heating from different fuels in J
|
||||
return: dict
|
||||
"""
|
||||
self._heating_consumption_disaggregated = value
|
||||
|
||||
|
||||
@property
|
||||
def lower_corner(self):
|
||||
"""
|
||||
|
@ -860,60 +855,3 @@ class Building(CityObject):
|
|||
Get building upper corner.
|
||||
"""
|
||||
return [self._max_x, self._max_y, self._max_z]
|
||||
|
||||
@property
|
||||
def energy_consumption_breakdown(self) -> dict:
|
||||
"""
|
||||
Get energy consumption of different sectors
|
||||
return: dict
|
||||
"""
|
||||
fuel_breakdown = {cte.ELECTRICITY: {cte.LIGHTING: self.lighting_electrical_demand[cte.YEAR][0],
|
||||
cte.APPLIANCES: self.appliances_electrical_demand[cte.YEAR][0]}}
|
||||
energy_systems = self.energy_systems
|
||||
for energy_system in energy_systems:
|
||||
demand_types = energy_system.demand_types
|
||||
generation_systems = energy_system.generation_systems
|
||||
for demand_type in demand_types:
|
||||
for generation_system in generation_systems:
|
||||
if generation_system.system_type != cte.PHOTOVOLTAIC:
|
||||
if generation_system.fuel_type not in fuel_breakdown:
|
||||
fuel_breakdown[generation_system.fuel_type] = {}
|
||||
if demand_type in generation_system.energy_consumption:
|
||||
fuel_breakdown[f'{generation_system.fuel_type}'][f'{demand_type}'] = (
|
||||
generation_system.energy_consumption)[f'{demand_type}'][cte.YEAR][0]
|
||||
storage_systems = generation_system.energy_storage_systems
|
||||
if storage_systems:
|
||||
for storage_system in storage_systems:
|
||||
if storage_system.type_energy_stored == 'thermal' and storage_system.heating_coil_energy_consumption:
|
||||
fuel_breakdown[cte.ELECTRICITY][f'{demand_type}'] += storage_system.heating_coil_energy_consumption[cte.YEAR][0]
|
||||
#TODO: When simulation models of all energy system archetypes are created, this part can be removed
|
||||
heating_fuels = []
|
||||
dhw_fuels = []
|
||||
for energy_system in self.energy_systems:
|
||||
if cte.HEATING in energy_system.demand_types:
|
||||
for generation_system in energy_system.generation_systems:
|
||||
heating_fuels.append(generation_system.fuel_type)
|
||||
if cte.DOMESTIC_HOT_WATER in energy_system.demand_types:
|
||||
for generation_system in energy_system.generation_systems:
|
||||
dhw_fuels.append(generation_system.fuel_type)
|
||||
for key in fuel_breakdown:
|
||||
if key == cte.ELECTRICITY and cte.COOLING not in fuel_breakdown[key]:
|
||||
for energy_system in energy_systems:
|
||||
if cte.COOLING in energy_system.demand_types and cte.COOLING not in fuel_breakdown[key]:
|
||||
for generation_system in energy_system.generation_systems:
|
||||
fuel_breakdown[generation_system.fuel_type][cte.COOLING] = self.cooling_consumption[cte.YEAR][0]
|
||||
for fuel in heating_fuels:
|
||||
if cte.HEATING not in fuel_breakdown[fuel]:
|
||||
for energy_system in energy_systems:
|
||||
if cte.HEATING in energy_system.demand_types:
|
||||
for generation_system in energy_system.generation_systems:
|
||||
fuel_breakdown[generation_system.fuel_type][cte.HEATING] = self.heating_consumption[cte.YEAR][0]
|
||||
for fuel in dhw_fuels:
|
||||
if cte.DOMESTIC_HOT_WATER not in fuel_breakdown[fuel]:
|
||||
for energy_system in energy_systems:
|
||||
if cte.DOMESTIC_HOT_WATER in energy_system.demand_types:
|
||||
for generation_system in energy_system.generation_systems:
|
||||
fuel_breakdown[generation_system.fuel_type][cte.DOMESTIC_HOT_WATER] = self.domestic_hot_water_consumption[cte.YEAR][0]
|
||||
self._fuel_consumption_breakdown = fuel_breakdown
|
||||
return self._fuel_consumption_breakdown
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -132,11 +132,7 @@ class InternalZone:
|
|||
_thermal_boundary = ThermalBoundary(surface, surface.solid_polygon.area, windows_areas)
|
||||
surface.associated_thermal_boundaries = [_thermal_boundary]
|
||||
_thermal_boundaries.append(_thermal_boundary)
|
||||
if self.thermal_archetype is None:
|
||||
return None # there are no archetype
|
||||
_number_of_storeys = int(self.volume / self.area / self.thermal_archetype.average_storey_height)
|
||||
if _number_of_storeys == 0:
|
||||
_number_of_storeys = 1
|
||||
_thermal_zone = ThermalZone(_thermal_boundaries, self, self.volume, self.area, _number_of_storeys)
|
||||
for thermal_boundary in _thermal_zone.thermal_boundaries:
|
||||
thermal_boundary.thermal_zones = [_thermal_zone]
|
||||
|
|
|
@ -42,12 +42,10 @@ class Surface:
|
|||
self._short_wave_reflectance = None
|
||||
self._long_wave_emittance = None
|
||||
self._inverse = None
|
||||
self._associated_thermal_boundaries = None
|
||||
self._associated_thermal_boundaries = []
|
||||
self._vegetation = None
|
||||
self._percentage_shared = None
|
||||
self._solar_collectors_area_reduction_factor = None
|
||||
self._global_irradiance_tilted = {}
|
||||
self._installed_solar_collector_area = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -180,7 +178,7 @@ class Surface:
|
|||
@property
|
||||
def global_irradiance(self) -> dict:
|
||||
"""
|
||||
Get global irradiance on surface in W/m2
|
||||
Get global irradiance on surface in J/m2
|
||||
:return: dict
|
||||
"""
|
||||
return self._global_irradiance
|
||||
|
@ -188,7 +186,7 @@ class Surface:
|
|||
@global_irradiance.setter
|
||||
def global_irradiance(self, value):
|
||||
"""
|
||||
Set global irradiance on surface in W/m2
|
||||
Set global irradiance on surface in J/m2
|
||||
:param value: dict
|
||||
"""
|
||||
self._global_irradiance = value
|
||||
|
@ -386,35 +384,3 @@ class Surface:
|
|||
:param value: float
|
||||
"""
|
||||
self._solar_collectors_area_reduction_factor = value
|
||||
|
||||
@property
|
||||
def global_irradiance_tilted(self) -> dict:
|
||||
"""
|
||||
Get global irradiance on a tilted surface in W/m2
|
||||
:return: dict
|
||||
"""
|
||||
return self._global_irradiance_tilted
|
||||
|
||||
@global_irradiance_tilted.setter
|
||||
def global_irradiance_tilted(self, value):
|
||||
"""
|
||||
Set global irradiance on a tilted surface in W/m2
|
||||
:param value: dict
|
||||
"""
|
||||
self._global_irradiance_tilted = value
|
||||
|
||||
@property
|
||||
def installed_solar_collector_area(self):
|
||||
"""
|
||||
Get installed solar collector area in m2
|
||||
:return: dict
|
||||
"""
|
||||
return self._installed_solar_collector_area
|
||||
|
||||
@installed_solar_collector_area.setter
|
||||
def installed_solar_collector_area(self, value):
|
||||
"""
|
||||
Set installed solar collector area in m2
|
||||
:return: dict
|
||||
"""
|
||||
self._installed_solar_collector_area = value
|
|
@ -20,8 +20,6 @@ class ThermalArchetype:
|
|||
self._indirect_heated_ratio = None
|
||||
self._infiltration_rate_for_ventilation_system_off = None
|
||||
self._infiltration_rate_for_ventilation_system_on = None
|
||||
self._infiltration_rate_area_for_ventilation_system_off=None
|
||||
self._infiltration_rate_area_for_ventilation_system_on=None
|
||||
|
||||
@property
|
||||
def constructions(self) -> [Construction]:
|
||||
|
@ -134,35 +132,3 @@ class ThermalArchetype:
|
|||
:param value: float
|
||||
"""
|
||||
self._infiltration_rate_for_ventilation_system_on = value
|
||||
|
||||
@property
|
||||
def infiltration_rate_area_for_ventilation_system_off(self):
|
||||
"""
|
||||
Get infiltration rate for ventilation system off in l/s/m2
|
||||
:return: float
|
||||
"""
|
||||
return self._infiltration_rate_for_ventilation_system_off
|
||||
|
||||
@infiltration_rate_area_for_ventilation_system_off.setter
|
||||
def infiltration_rate_area_for_ventilation_system_off(self, value):
|
||||
"""
|
||||
Set infiltration rate for ventilation system off in l/s/m2
|
||||
:param value: float
|
||||
"""
|
||||
self._infiltration_rate_for_ventilation_system_off = value
|
||||
|
||||
@property
|
||||
def infiltration_rate_area_for_ventilation_system_on(self):
|
||||
"""
|
||||
Get infiltration rate for ventilation system on in l/s/m2
|
||||
:return: float
|
||||
"""
|
||||
return self._infiltration_rate_for_ventilation_system_on
|
||||
|
||||
@infiltration_rate_area_for_ventilation_system_on.setter
|
||||
def infiltration_rate_area_for_ventilation_system_on(self, value):
|
||||
"""
|
||||
Set infiltration rate for ventilation system on in l/s/m2
|
||||
:param value: float
|
||||
"""
|
||||
self._infiltration_rate_for_ventilation_system_on = value
|
||||
|
|
|
@ -44,8 +44,6 @@ class ThermalZone:
|
|||
self._indirectly_heated_area_ratio = None
|
||||
self._infiltration_rate_system_on = None
|
||||
self._infiltration_rate_system_off = None
|
||||
self._infiltration_rate_area_system_on = None
|
||||
self._infiltration_rate_area_system_off = None
|
||||
self._volume = volume
|
||||
self._ordinate_number = None
|
||||
self._view_factors_matrix = None
|
||||
|
@ -168,24 +166,6 @@ class ThermalZone:
|
|||
self._infiltration_rate_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_for_ventilation_system_off
|
||||
return self._infiltration_rate_system_off
|
||||
|
||||
@property
|
||||
def infiltration_rate_area_system_on(self):
|
||||
"""
|
||||
Get thermal zone infiltration rate system on in air changes per second (1/s)
|
||||
:return: None or float
|
||||
"""
|
||||
self._infiltration_rate_area_system_on = self._parent_internal_zone.thermal_archetype.infiltration_rate_area_for_ventilation_system_on
|
||||
return self._infiltration_rate_area_system_on
|
||||
|
||||
@property
|
||||
def infiltration_rate_area_system_off(self):
|
||||
"""
|
||||
Get thermal zone infiltration rate system off in air changes per second (1/s)
|
||||
:return: None or float
|
||||
"""
|
||||
self._infiltration_rate_area_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_area_for_ventilation_system_off
|
||||
return self._infiltration_rate_area_system_off
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
"""
|
||||
|
|
|
@ -41,10 +41,9 @@ class CityObject:
|
|||
self._ground_temperature = {}
|
||||
self._global_horizontal = {}
|
||||
self._diffuse = {}
|
||||
self._direct_normal = {}
|
||||
self._beam = {}
|
||||
self._sensors = []
|
||||
self._neighbours = None
|
||||
self._beam = {}
|
||||
|
||||
@property
|
||||
def level_of_detail(self) -> LevelOfDetail:
|
||||
|
@ -239,20 +238,20 @@ class CityObject:
|
|||
self._diffuse = value
|
||||
|
||||
@property
|
||||
def direct_normal(self) -> dict:
|
||||
def beam(self) -> dict:
|
||||
"""
|
||||
Get beam radiation surrounding the city object in J/m2
|
||||
:return: dict{dict{[float]}}
|
||||
"""
|
||||
return self._direct_normal
|
||||
return self._beam
|
||||
|
||||
@direct_normal.setter
|
||||
def direct_normal(self, value):
|
||||
@beam.setter
|
||||
def beam(self, value):
|
||||
"""
|
||||
Set beam radiation surrounding the city object in J/m2
|
||||
:param value: dict{dict{[float]}}
|
||||
"""
|
||||
self._direct_normal = value
|
||||
self._beam = value
|
||||
|
||||
@property
|
||||
def lower_corner(self):
|
||||
|
@ -303,19 +302,3 @@ class CityObject:
|
|||
Set the list of neighbour_objects and their properties associated to the current city_object
|
||||
"""
|
||||
self._neighbours = value
|
||||
|
||||
@property
|
||||
def beam(self) -> dict:
|
||||
"""
|
||||
Get beam radiation surrounding the city object in J/m2
|
||||
:return: dict{dict{[float]}}
|
||||
"""
|
||||
return self._beam
|
||||
|
||||
@beam.setter
|
||||
def beam(self, value):
|
||||
"""
|
||||
Set beam radiation surrounding the city object in J/m2
|
||||
:param value: dict{dict{[float]}}
|
||||
"""
|
||||
self._beam = value
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user