Compare commits

..

2 Commits

171 changed files with 4873 additions and 79271 deletions

13
.gitignore vendored
View File

@ -1,12 +1 @@
!.gitignore
**/venv/
.idea/
/development_tests/
/data/energy_systems/heat_pumps/*.csv
/data/energy_systems/heat_pumps/*.insel
.DS_Store
**/.env
**/hub/logs/
**/__pycache__/
**/.idea/
cerc_hub.egg-info
.idea

3
cerc_hub.egg-info/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Except this file
*
!.gitignore

View File

@ -1,50 +0,0 @@
# LINUX_INSTALL
## Prepare your environment
### Install Miniconda
1. Get the link for the latest version of Miniconda from https://docs.conda.io/en/latest/miniconda.html
2. Download the installer using wget
````
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
````
3. Make the installer executable
````
chmod +x ./Miniconda3-latest-Linux-x86_64.sh
````
4. Run the installer
````
./Miniconda3-latest-Linux-x86_64.sh
````
5. Holder enter until you are prompted to accept the license terms. Enter yes.
6. Initialize the conda environment
````
conda init bash
````
7. Source .bashrc
````
source ~/.bashrc
````
8. Create a conda environment for the hub
````
conda create --name hub python=3.9.16
````
### Setup SRA
1. Get the sra binary and libshortwave.so library from Guille or Koa
2. Place the binary and the library into your directory of choice
3. Make a symlink for the binary and place it into /usr/local/bin/sra
````
sudo ln -s ~/sra /usr/local/bin/sra
````
4. Make a symlink for the library and place it into /usr/local/lib/libshortwave.so
````
sudo ln -s ~/libshortwave.so /usr/local/lib/libshortwave.so
````
### Setup INSEL
1. TBD
### Get a Python editor
You are welcome to use the Python editor of your preference. The CERC team generally uses PyCharm to develop the hub.
The latest version of PyCharm can be downloaded from [JetBrains website](https://www.jetbrains.com/pycharm/promo/?source=google&medium=cpc&campaign=14127625109&term=pycharm&content=536947779504&gad=1&gclid=CjwKCAjw0ZiiBhBKEiwA4PT9z2AxPfy39x_RcBqlYxJ6sm_s55T9qvA_sZ8ZfkhIVX6FOD-ySbmzARoCcpQQAvD_BwE).
For setup and installation instructions, please view the "Get a Python Editor"
from the [WINDOWS_INSTALL](https://nextgenerations-cities.encs.concordia.ca/gitea/CERC/hub/src/branch/main/hub/WINDOWS_INSTALL.md)
documentation.

View File

@ -2,16 +2,16 @@
This is an installation guide for Windows, covering all the steps needed to begin developing code for the Urban
Simulation Platform 'Hub'. At the end of this process you will have installed and configured all the necessary applications,
set up your own project on CERC's Gitea and created your first python file.
set up your own project on CERC's Gitlab and created your first python file.
## Prepare your environment
g
To develop any new code for the Urban Simulation Platform you must have the right software applications installed and configured.
The Platform is written in python and so the applications you need are:
* Miniconda
* SRA Files
* Python Editor
You also need to register a user account with the CERC's code repository on Gitea and have the necessary permissions for
You also need to register a user account with the CERC's code repository on Gitlab and have the necessary permissions for
creating new code. For that purpose, please, contact Guillermo (guillermo.gutierrezmorote@concordia.ca) or
Koa (kekoa.wells@concordia.ca) as soon as possible.
@ -47,29 +47,6 @@ _The term '...' is not recognized as the name of a cmdlet, function,..._
To solve it, type 'Set-ExecutionPolicy Unrestricted' as shown in the image.
### Setup SRA
1. Get the SRA executable and dll files from Guille or Koa
2. Create a folder in "C:\Program Files\" called "sra"
![create_sra](docs/img_windows_install/img_34.png)
3. Copy shortwave_integer.exe and pthreadGC2.dll into the sra folder.
![create_sra](docs/img_windows_install/img_35.png)
4. Add the newly created sra folder to the Path, similar to step 2 from the Miniconda setup above.
![create_sra](docs/img_windows_install/img_36.png)
### Install and setup INSEL
1. Get the INSEL installer from Guille or Koa
2. Run the installer to completion using the default installation path
3. Add the INSEL installation folder to the Path
![create_sra](docs/img_windows_install/img_41.png)
### Get a Python editor
1. You will need a python editor in order to import the existing Hub source code and to write your own python code.
@ -78,7 +55,7 @@ an excellent open-source python editor.
2. Run the installer, and follow the installation instructions for PyCharm, you may change a few options,
but the default ones should be fine.
**NOTE:** If PyCharm asks you to create a Virtual Environment, click **Cancel**. You will do it later using Conda instead.
**NOTE:** If Pycharm asks you to create a Virtual Environment, click **Cancel**. You will do it later using Conda instead.
![creating_virtual_environment](docs/img_windows_install/img_31.png)
@ -93,12 +70,14 @@ You can find it also at **Git->Clone...**
![pycharm get from version control](docs/img_windows_install/img_6.png)
3. Select **Git** as the **Version control**. Open the [hub repository](https://nextgenerations-cities.encs.concordia.ca/gitea/CERC/hub)
on Gitea and copy the URL from your browser to use as the URL inside PyCharm.
3. Select **Git** as the **Version control**. For the URL use the link to the Hub repository, as seen below.
![pycharm get from version control screen](docs/img_windows_install/img_1.png)
![gitea get https](docs/img_windows_install/img_39.png)
(You can also copy this URL by going to the Hub repository in [Gitlab](https://rs-loy-gitlab.concordia.ca/Guille/hub.git)
and clicking on the **Copy URL** button, next to **Clone with HTTPS**)
![gitlab get https](docs/img_windows_install/img_17.png)
The Directory to store the Hub source code locally is automatically created for you. Edit this if you prefer it to be stored somewhere else.
@ -173,7 +152,7 @@ _lca_classes_,... And, click on the **Create** button.
3. Click on the **Git** button in the bottom-left corner to pop-up the window showing the Git information.
See your new branch has been created under _Local_.
4. Now we need to let the CERC Gitea repository know about this new branch. You do this by right-clicking on
4. Now we need to let the CERC Gitlab repository know about this new branch. You do this by right-clicking on
your branch and selecting **Push...** from the drop-down menu.
5. Then click on the **Push** button at the bottom-right of the **Push Commits** window.
@ -201,35 +180,33 @@ See the picture below.
![pycharm configuration screen](docs/img_windows_install/img_5.png)
## Set up a new project on Gitea
You will need an account before you can access the Gitea. Please contact Guillermo (guillermo.gutierrezmorote@concordia.ca) or
Koa (kekoa.wells@concordia.ca) to request an account.
## Set up a new project on Gitlab
1. Open a browser and go to the [CERC Gitea](https://nextgenerations-cities.encs.concordia.ca/). Click on the **+** in the top right
and select "New Repository" or press the **+** below the Organization tab.
1. Open a browser and to the [CERC Git](https://rs-loy-gitlab.concordia.ca/). Click on the blue **New project** button.
![git new project screen](docs/img_windows_install/img_37.png)
![git new project screen](docs/img_windows_install/img_14.png)
2. Choose the **Create blank project** option from the three options seen below.
3. Type in a name that describes your project: _hp_workflow_, _bus_system_optimization_...
(remember to follow the CERC naming conventions described in the [Coding Style](PYGUIDE.md)).
Ideally, uncheck the option **Make Repository Private**, and check the **Initialize Repository**
Check the option **Initialize repository with a README**, and ideally, check the **Visibility Level** to be **Public**.
Then click on the **Create project** button.
![git give a name](docs/img_windows_install/img_38.png)
![git give a name](docs/img_windows_install/img_15.png)
You should then see a confirmation screen with all the information about your new project.
## Get your project into Pycharm
1. Now you can make a clone of this project, within PyCharm. First, go to the page of your repository on the Gitea and copy the URL.
1. Now you can make a clone of this project, within PyCharm. First, copy the URL by clicking on the blue **Clone** button
and then click on the **Copy URL** button, next to the **Clone with HTTPS** link.
2. Switch back to PyCharm and close the Hub project by choosing **File->Close Project**. You will then see the
**Welcome To PyCharm** window again.
3. Clone a copy of your Project into PyCharm, following the steps 2-6 of the _GET THE CERC HUB SOURCE CODE_
section above, but using the URL link that you just copied for your Gitea project.
section above, but using the URL link that you just copied for your gitlab project.
4. Select **File->Settings** to open the **Settings** window. From the panel on the left click on
**Project:<project name> -> Project Structure**.
@ -265,5 +242,5 @@ city = GeometryFactory('citygml', path='myfile.gml').city
9. Always remember to push your own project changes as the last thing you do before ending your working day!
First, commit your changes by clicking on the green check in the top-right corner of Pycharm. Add a comment that explains briefly your changes.
Then, pull by clicking on the blue arrow to be sure that there are no conflicts between your version (local) and the remote one (Gitea).
Then, pull by clicking on the blue arrow to be sure that there are no conflicts between your version (local) and the remote one (gitlab).
Once the conflicts are solved and the merge in local is done, push the changes by clicking on the green arrow.

View File

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

View File

@ -128,12 +128,6 @@ class NrcanCatalog(Catalog):
infiltration_rate_for_ventilation_system_on = (
archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
)
infiltration_rate_area_for_ventilation_system_off = (
archetype['infiltration_rate_area_for_ventilation_system_off'] * 1
)
infiltration_rate_area_for_ventilation_system_on = (
archetype['infiltration_rate_area_for_ventilation_system_on'] * 1
)
archetype_constructions = []
for archetype_construction in archetype['constructions']:
@ -159,6 +153,7 @@ class NrcanCatalog(Catalog):
_window)
archetype_constructions.append(_construction)
break
_catalog_archetypes.append(Archetype(archetype_id,
name,
function,
@ -170,10 +165,7 @@ class NrcanCatalog(Catalog):
extra_loses_due_to_thermal_bridges,
None,
infiltration_rate_for_ventilation_system_off,
infiltration_rate_for_ventilation_system_on,
infiltration_rate_area_for_ventilation_system_off,
infiltration_rate_area_for_ventilation_system_on
))
infiltration_rate_for_ventilation_system_on))
return _catalog_archetypes
def names(self, category=None):

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
"""
Energy System catalog archetype, understood as a cluster of energy systems
Energy System catalog archetype
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
@ -15,11 +15,20 @@ class Archetype:
"""
Archetype class
"""
def __init__(self, name, systems):
def __init__(self, lod, name, systems):
self._lod = lod
self._name = name
self._systems = systems
@property
def lod(self):
"""
Get level of detail of the catalog
:return: string
"""
return self._lod
@property
def name(self):
"""
@ -41,10 +50,11 @@ class Archetype:
_systems = []
for _system in self.systems:
_systems.append(_system.to_dictionary())
content = {
'Archetype': {
'name': self.name,
'systems': _systems
}
}
content = {'Archetype': {'name': self.name,
'level of detail': self.lod,
'systems': _systems
}
}
return content

View File

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

View File

@ -6,32 +6,21 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
from typing import Union, List, TypeVar
from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem
from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem
GenerationSystem = TypeVar('GenerationSystem')
class DistributionSystem:
"""
Distribution system class
"""
def __init__(self, system_id, model_name=None, system_type=None, supply_temperature=None,
distribution_consumption_fix_flow=None, distribution_consumption_variable_flow=None, heat_losses=None,
generation_systems=None, energy_storage_systems=None, emission_systems=None):
def __init__(self, system_id, name, system_type, supply_temperature, distribution_consumption_fix_flow,
distribution_consumption_variable_flow, heat_losses):
self._system_id = system_id
self._model_name = model_name
self._name = name
self._type = system_type
self._supply_temperature = supply_temperature
self._distribution_consumption_fix_flow = distribution_consumption_fix_flow
self._distribution_consumption_variable_flow = distribution_consumption_variable_flow
self._heat_losses = heat_losses
self._generation_systems = generation_systems
self._energy_storage_systems = energy_storage_systems
self._emission_systems = emission_systems
@property
def id(self):
@ -42,12 +31,12 @@ class DistributionSystem:
return self._system_id
@property
def model_name(self):
def name(self):
"""
Get model name
Get name
:return: string
"""
return self._model_name
return self._name
@property
def type(self):
@ -90,51 +79,17 @@ class DistributionSystem:
"""
return self._heat_losses
@property
def generation_systems(self) -> Union[None, List[GenerationSystem]]:
"""
Get generation systems connected to the distribution system
:return: [GenerationSystem]
"""
return self._generation_systems
@property
def energy_storage_systems(self) -> Union[None, List[EnergyStorageSystem]]:
"""
Get energy storage systems connected to this distribution system
:return: [EnergyStorageSystem]
"""
return self._energy_storage_systems
@property
def emission_systems(self) -> Union[None, List[EmissionSystem]]:
"""
Get energy emission systems connected to this distribution system
:return: [EmissionSystem]
"""
return self._emission_systems
def to_dictionary(self):
"""Class content to dictionary"""
_generation_systems = [_generation_system.to_dictionary() for _generation_system in
self.generation_systems] if self.generation_systems is not None else None
_energy_storage_systems = [_energy_storage_system.to_dictionary() for _energy_storage_system in
self.energy_storage_systems] if self.energy_storage_systems is not None else None
_emission_systems = [_emission_system.to_dictionary() for _emission_system in
self.emission_systems] if self.emission_systems is not None else None
content = {
'Layer': {
'id': self.id,
'model name': self.model_name,
'name': self.name,
'type': self.type,
'supply temperature [Celsius]': self.supply_temperature,
'distribution consumption if fix flow over peak power [W/W]': self.distribution_consumption_fix_flow,
'distribution consumption if variable flow over peak power [J/J]': self.distribution_consumption_variable_flow,
'heat losses per energy produced [J/J]': self.heat_losses,
'generation systems connected': _generation_systems,
'energy storage systems connected': _energy_storage_systems,
'emission systems connected': _emission_systems
'heat losses per energy produced [J/J]': self.heat_losses
}
}
return content

View File

@ -14,12 +14,10 @@ class ElectricalStorageSystem(EnergyStorageSystem):
Energy Storage System Class
"""
def __init__(self, storage_id, type_energy_stored=None, model_name=None, manufacturer=None, storage_type=None,
nominal_capacity=None, losses_ratio=None, rated_output_power=None, nominal_efficiency=None,
battery_voltage=None, depth_of_discharge=None, self_discharge_rate=None):
def __init__(self, storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio,
rated_output_power, nominal_efficiency, battery_voltage, depth_of_discharge, self_discharge_rate):
super().__init__(storage_id, model_name, manufacturer, nominal_capacity, losses_ratio)
self._type_energy_stored = type_energy_stored
super().__init__(storage_id, name, model_name, manufacturer, nominal_capacity, losses_ratio)
self._storage_type = storage_type
self._rated_output_power = rated_output_power
self._nominal_efficiency = nominal_efficiency
@ -27,18 +25,10 @@ class ElectricalStorageSystem(EnergyStorageSystem):
self._depth_of_discharge = depth_of_discharge
self._self_discharge_rate = self_discharge_rate
@property
def type_energy_stored(self):
"""
Get type of energy stored from ['electrical', 'thermal']
:return: string
"""
return self._type_energy_stored
@property
def storage_type(self):
"""
Get storage type from ['lithium_ion', 'lead_acid', 'NiCd']
Get storage type from ['electrical', 'lithium_ion', 'lead_acid', 'NiCd']
:return: string
"""
return self._storage_type
@ -54,7 +44,7 @@ class ElectricalStorageSystem(EnergyStorageSystem):
@property
def nominal_efficiency(self):
"""
Get the nominal efficiency of the storage system
Get the nominal efficiency of the storage system
:return: float
"""
return self._nominal_efficiency
@ -87,7 +77,7 @@ class ElectricalStorageSystem(EnergyStorageSystem):
"""Class content to dictionary"""
content = {'Storage component': {
'storage id': self.id,
'type of energy stored': self.type_energy_stored,
'name': self.name,
'model name': self.model_name,
'manufacturer': self.manufacturer,
'storage type': self.storage_type,

View File

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

View File

@ -14,9 +14,9 @@ class EnergyStorageSystem(ABC):
Energy Storage System Abstract Class
"""
def __init__(self, storage_id, model_name=None, manufacturer=None,
nominal_capacity=None, losses_ratio=None):
def __init__(self, storage_id, name, model_name, manufacturer, nominal_capacity, losses_ratio):
self._storage_id = storage_id
self._name = name
self._model_name = model_name
self._manufacturer = manufacturer
self._nominal_capacity = nominal_capacity
@ -31,18 +31,18 @@ class EnergyStorageSystem(ABC):
return self._storage_id
@property
def type_energy_stored(self):
def name(self):
"""
Get type of energy stored from ['electrical', 'thermal']
Get storage name
:return: string
"""
raise NotImplementedError
return self._name
@property
def model_name(self):
"""
Get system model
:return: string
:return: float
"""
return self._model_name

View File

@ -6,28 +6,53 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
from __future__ import annotations
from abc import ABC
from typing import List, Union
from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem
from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem
from typing import Union
from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves
class GenerationSystem(ABC):
class GenerationSystem:
"""
Heat Generation system class
"""
def __init__(self, system_id, name, model_name=None, manufacturer=None, fuel_type=None,
distribution_systems=None, energy_storage_systems=None):
def __init__(self, system_id, name, model_name, manufacturer, system_type, fuel_type, nominal_thermal_output,
maximum_heat_output, minimum_heat_output, source_medium, supply_medium, heat_efficiency,
nominal_cooling_output, maximum_cooling_output, minimum_cooling_output, cooling_efficiency,
electricity_efficiency, source_temperature, source_mass_flow, nominal_electricity_output,
maximum_heat_supply_temperature, minimum_heat_supply_temperature,
maximum_cooling_supply_temperature, minimum_cooling_supply_temperature, heat_output_curve,
heat_fuel_consumption_curve, heat_efficiency_curve, cooling_output_curve, cooling_fuel_consumption_curve,
cooling_efficiency_curve):
self._system_id = system_id
self._name = name
self._model_name = model_name
self._manufacturer = manufacturer
self._system_type = system_type
self._fuel_type = fuel_type
self._distribution_systems = distribution_systems
self._energy_storage_systems = energy_storage_systems
self._nominal_thermal_output = nominal_thermal_output
self._maximum_heat_output = maximum_heat_output
self._minimum_heat_output = minimum_heat_output
self._heat_efficiency = heat_efficiency
self._nominal_cooling_output = nominal_cooling_output
self._maximum_cooling_output = maximum_cooling_output
self._minimum_cooling_output = minimum_cooling_output
self._cooling_efficiency = cooling_efficiency
self._electricity_efficiency = electricity_efficiency
self._nominal_electricity_output = nominal_electricity_output
self._source_medium = source_medium
self._source_temperature = source_temperature
self._source_mass_flow = source_mass_flow
self._supply_medium = supply_medium
self._maximum_heat_supply_temperature = maximum_heat_supply_temperature
self._minimum_heat_supply_temperature = minimum_heat_supply_temperature
self._maximum_cooling_supply_temperature = maximum_cooling_supply_temperature
self._minimum_cooling_supply_temperature = minimum_cooling_supply_temperature
self._heat_output_curve = heat_output_curve
self._heat_fuel_consumption_curve = heat_fuel_consumption_curve
self._heat_efficiency_curve = heat_efficiency_curve
self._cooling_output_curve = cooling_output_curve
self._cooling_fuel_consumption_curve = cooling_fuel_consumption_curve
self._cooling_efficiency_curve = cooling_efficiency_curve
@property
def id(self):
@ -40,19 +65,11 @@ class GenerationSystem(ABC):
@property
def name(self):
"""
Get system name
Get name
:return: string
"""
return self._name
@property
def system_type(self):
"""
Get type
:return: string
"""
raise NotImplementedError
@property
def model_name(self):
"""
@ -69,6 +86,14 @@ class GenerationSystem(ABC):
"""
return self._manufacturer
@property
def system_type(self):
"""
Get type
:return: string
"""
return self._system_type
@property
def fuel_type(self):
"""
@ -78,21 +103,230 @@ class GenerationSystem(ABC):
return self._fuel_type
@property
def distribution_systems(self) -> Union[None, List[DistributionSystem]]:
def nominal_thermal_output(self):
"""
Get distributions systems connected to this generation system
:return: [DistributionSystem]
Get nominal_thermal_output of heat generation devices in kW
:return: float
"""
return self._distribution_systems
return self._nominal_thermal_output
@property
def energy_storage_systems(self) -> Union[None, List[EnergyStorageSystem]]:
def maximum_heat_output(self):
"""
Get energy storage systems connected to this generation system
:return: [EnergyStorageSystem]
Get maximum heat output of heat generation devices in W
:return: float
"""
return self._energy_storage_systems
return self._maximum_heat_output
@property
def minimum_heat_output(self):
"""
Get minimum heat output of heat generation devices in W
:return: float
"""
return self._minimum_heat_output
@property
def source_medium(self):
"""
Get source_type from [air, water, ground, district_heating, grid, on_site_electricity]
:return: [string]
"""
return self._source_medium
@property
def supply_medium(self):
"""
Get the supply medium from ['air', 'water']
:return: string
"""
return self._supply_medium
@property
def heat_efficiency(self):
"""
Get heat_efficiency
:return: float
"""
return self._heat_efficiency
@property
def nominal_cooling_output(self):
"""
Get nominal_thermal_output of heat generation devices in kW
:return: float
"""
return self._nominal_cooling_output
@property
def maximum_cooling_output(self):
"""
Get maximum heat output of heat generation devices in W
:return: float
"""
return self._maximum_cooling_output
@property
def minimum_cooling_output(self):
"""
Get minimum heat output of heat generation devices in W
:return: float
"""
return self._minimum_cooling_output
@property
def cooling_efficiency(self):
"""
Get cooling_efficiency
:return: float
"""
return self._cooling_efficiency
@property
def electricity_efficiency(self):
"""
Get electricity_efficiency
:return: float
"""
return self._electricity_efficiency
@property
def source_temperature(self):
"""
Get source_temperature in degree Celsius
:return: float
"""
return self._source_temperature
@property
def source_mass_flow(self):
"""
Get source_mass_flow in kg/s
:return: float
"""
return self._source_mass_flow
@property
def nominal_electricity_output(self):
"""
Get nominal_power_output of electricity generation devices or inverters in kW
:return: float
"""
return self._nominal_electricity_output
@property
def maximum_heat_supply_temperature(self):
"""
Get the maximum heat supply temperature in degree Celsius
:return: float
"""
return self._minimum_heat_supply_temperature
@property
def minimum_heat_supply_temperature(self):
"""
Get the minimum heat supply temperature in degree Celsius
:return: float
"""
return self._minimum_heat_supply_temperature
@property
def maximum_cooling_supply_temperature(self):
"""
Get the maximum cooling supply temperature in degree Celsius
:return: float
"""
return self._maximum_cooling_supply_temperature
@property
def minimum_cooling_supply_temperature(self):
"""
Get the minimum cooling supply temperature in degree Celsius
:return: float
"""
return self._minimum_cooling_supply_temperature
@property
def heat_output_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heat output curve of the heat generation device
:return: PerformanceCurve
"""
return self._heat_output_curve
@property
def heat_fuel_consumption_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heating fuel consumption curve of the heat generation device
:return: PerformanceCurve
"""
return self._heat_fuel_consumption_curve
@property
def heat_efficiency_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heating efficiency curve of the heat generation device
:return: PerformanceCurve
"""
return self._heat_efficiency_curve
@property
def cooling_output_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heat output curve of the heat generation device
:return: PerformanceCurve
"""
return self._cooling_output_curve
@property
def cooling_fuel_consumption_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heating fuel consumption curve of the heat generation device
:return: PerformanceCurve
"""
return self._cooling_fuel_consumption_curve
@property
def cooling_efficiency_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heating efficiency curve of the heat generation device
:return: PerformanceCurve
"""
return self._cooling_efficiency_curve
def to_dictionary(self):
"""Class content to dictionary"""
raise NotImplementedError
content = {'Energy Generation component': {
'id': self.id,
'name': self.name,
'model name': self.model_name,
'manufacturer': self.manufacturer,
'type': self.system_type,
'fuel type': self.fuel_type,
'nominal thermal output [W]': self.nominal_thermal_output,
'maximum heat output [W]': self.maximum_heat_output,
'minimum heat output [W]': self.minimum_heat_output,
'source medium': self.source_medium,
'supply medium': self.supply_medium,
'source temperature [Celsius]': self.source_temperature,
'source mass flow [kg/s]': self.source_mass_flow,
'heat efficiency': self.heat_efficiency,
'nominal cooling output [W]': self.nominal_cooling_output,
'maximum cooling output [W]': self.maximum_cooling_output,
'minimum cooling output [W]': self.minimum_cooling_output,
'cooling efficiency': self.cooling_efficiency,
'electricity efficiency': self.electricity_efficiency,
'nominal power output [W]': self.nominal_electricity_output,
'maximum heating supply temperature [Celsius]': self.maximum_heat_supply_temperature,
'minimum heating supply temperature [Celsius]': self.minimum_heat_supply_temperature,
'maximum cooling supply temperature [Celsius]': self.maximum_cooling_supply_temperature,
'minimum cooling supply temperature [Celsius]': self.minimum_cooling_supply_temperature,
'heat output curve': self.heat_output_curve,
'heat fuel consumption curve': self.heat_fuel_consumption_curve,
'heat efficiency curve': 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
}
}
return content

View File

@ -1,344 +0,0 @@
"""
Energy System catalog non PV generation system
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
from typing import Union
from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves
from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem
class NonPvGenerationSystem(GenerationSystem):
"""
Non PV Generation system class
"""
def __init__(self, system_id, name, system_type, model_name=None, manufacturer=None, fuel_type=None,
nominal_heat_output=None, maximum_heat_output=None, minimum_heat_output=None, source_medium=None,
supply_medium=None, heat_efficiency=None, nominal_cooling_output=None, maximum_cooling_output=None,
minimum_cooling_output=None, cooling_efficiency=None, electricity_efficiency=None,
source_temperature=None, source_mass_flow=None, nominal_electricity_output=None,
maximum_heat_supply_temperature=None, minimum_heat_supply_temperature=None,
maximum_cooling_supply_temperature=None, minimum_cooling_supply_temperature=None, heat_output_curve=None,
heat_fuel_consumption_curve=None, heat_efficiency_curve=None, cooling_output_curve=None,
cooling_fuel_consumption_curve=None, cooling_efficiency_curve=None,
distribution_systems=None, energy_storage_systems=None, domestic_hot_water=False,
reversible=None, simultaneous_heat_cold=None):
super().__init__(system_id=system_id, name=name, model_name=model_name, manufacturer=manufacturer,
fuel_type=fuel_type, distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems)
self._system_type = system_type
self._nominal_heat_output = nominal_heat_output
self._maximum_heat_output = maximum_heat_output
self._minimum_heat_output = minimum_heat_output
self._heat_efficiency = heat_efficiency
self._nominal_cooling_output = nominal_cooling_output
self._maximum_cooling_output = maximum_cooling_output
self._minimum_cooling_output = minimum_cooling_output
self._cooling_efficiency = cooling_efficiency
self._electricity_efficiency = electricity_efficiency
self._nominal_electricity_output = nominal_electricity_output
self._source_medium = source_medium
self._source_temperature = source_temperature
self._source_mass_flow = source_mass_flow
self._supply_medium = supply_medium
self._maximum_heat_supply_temperature = maximum_heat_supply_temperature
self._minimum_heat_supply_temperature = minimum_heat_supply_temperature
self._maximum_cooling_supply_temperature = maximum_cooling_supply_temperature
self._minimum_cooling_supply_temperature = minimum_cooling_supply_temperature
self._heat_output_curve = heat_output_curve
self._heat_fuel_consumption_curve = heat_fuel_consumption_curve
self._heat_efficiency_curve = heat_efficiency_curve
self._cooling_output_curve = cooling_output_curve
self._cooling_fuel_consumption_curve = cooling_fuel_consumption_curve
self._cooling_efficiency_curve = cooling_efficiency_curve
self._domestic_hot_water = domestic_hot_water
self._reversible = reversible
self._simultaneous_heat_cold = simultaneous_heat_cold
@property
def system_type(self):
"""
Get type
:return: string
"""
return self._system_type
@property
def nominal_heat_output(self):
"""
Get nominal heat output of heat generation devices in W
:return: float
"""
return self._nominal_heat_output
@property
def maximum_heat_output(self):
"""
Get maximum heat output of heat generation devices in W
:return: float
"""
return self._maximum_heat_output
@property
def minimum_heat_output(self):
"""
Get minimum heat output of heat generation devices in W
:return: float
"""
return self._minimum_heat_output
@property
def source_medium(self):
"""
Get source_type from [air, water, ground, district_heating, grid, on_site_electricity]
:return: string
"""
return self._source_medium
@property
def supply_medium(self):
"""
Get the supply medium from ['air', 'water']
:return: string
"""
return self._supply_medium
@property
def heat_efficiency(self):
"""
Get heat_efficiency
:return: float
"""
return self._heat_efficiency
@property
def nominal_cooling_output(self):
"""
Get nominal cooling output of heat generation devices in W
:return: float
"""
return self._nominal_cooling_output
@property
def maximum_cooling_output(self):
"""
Get maximum heat output of heat generation devices in W
:return: float
"""
return self._maximum_cooling_output
@property
def minimum_cooling_output(self):
"""
Get minimum heat output of heat generation devices in W
:return: float
"""
return self._minimum_cooling_output
@property
def cooling_efficiency(self):
"""
Get cooling_efficiency
:return: float
"""
return self._cooling_efficiency
@property
def electricity_efficiency(self):
"""
Get electricity_efficiency
:return: float
"""
return self._electricity_efficiency
@property
def source_temperature(self):
"""
Get source_temperature in degree Celsius
:return: float
"""
return self._source_temperature
@property
def source_mass_flow(self):
"""
Get source_mass_flow in kg/s
:return: float
"""
return self._source_mass_flow
@property
def nominal_electricity_output(self):
"""
Get nominal_power_output of electricity generation devices or inverters in W
:return: float
"""
return self._nominal_electricity_output
@property
def maximum_heat_supply_temperature(self):
"""
Get the maximum heat supply temperature in degree Celsius
:return: float
"""
return self._minimum_heat_supply_temperature
@property
def minimum_heat_supply_temperature(self):
"""
Get the minimum heat supply temperature in degree Celsius
:return: float
"""
return self._minimum_heat_supply_temperature
@property
def maximum_cooling_supply_temperature(self):
"""
Get the maximum cooling supply temperature in degree Celsius
:return: float
"""
return self._maximum_cooling_supply_temperature
@property
def minimum_cooling_supply_temperature(self):
"""
Get the minimum cooling supply temperature in degree Celsius
:return: float
"""
return self._minimum_cooling_supply_temperature
@property
def heat_output_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heat output curve of the heat generation device
:return: PerformanceCurve
"""
return self._heat_output_curve
@property
def heat_fuel_consumption_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heating fuel consumption curve of the heat generation device
:return: PerformanceCurve
"""
return self._heat_fuel_consumption_curve
@property
def heat_efficiency_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heating efficiency curve of the heat generation device
:return: PerformanceCurve
"""
return self._heat_efficiency_curve
@property
def cooling_output_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heat output curve of the heat generation device
:return: PerformanceCurve
"""
return self._cooling_output_curve
@property
def cooling_fuel_consumption_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heating fuel consumption curve of the heat generation device
:return: PerformanceCurve
"""
return self._cooling_fuel_consumption_curve
@property
def cooling_efficiency_curve(self) -> Union[None, PerformanceCurves]:
"""
Get the heating efficiency curve of the heat generation device
:return: PerformanceCurve
"""
return self._cooling_efficiency_curve
@property
def domestic_hot_water(self):
"""
Get the ability to produce domestic hot water
:return: bool
"""
return self._domestic_hot_water
@property
def reversibility(self):
"""
Get the ability to produce heating and cooling
:return: bool
"""
return self._reversible
@property
def simultaneous_heat_cold(self):
"""
Get the ability to produce heating and cooling at the same time
:return: bool
"""
return self._simultaneous_heat_cold
def to_dictionary(self):
"""Class content to dictionary"""
_distribution_systems = [_distribution_system.to_dictionary() for _distribution_system in
self.distribution_systems] if self.distribution_systems is not None else None
_energy_storage_systems = [_energy_storage_system.to_dictionary() for _energy_storage_system in
self.energy_storage_systems] if self.energy_storage_systems is not None else None
_heat_output_curve = self.heat_output_curve.to_dictionary() if (
self.heat_output_curve is not None) else None
_heat_fuel_consumption_curve = self.heat_fuel_consumption_curve.to_dictionary() if (
self.heat_fuel_consumption_curve is not None) else None
_heat_efficiency_curve = self.heat_efficiency_curve.to_dictionary() if (
self.heat_efficiency_curve is not None) else None
_cooling_output_curve = self.cooling_output_curve.to_dictionary() if (
self.cooling_output_curve is not None) else None
_cooling_fuel_consumption_curve = self.cooling_fuel_consumption_curve.to_dictionary() if (
self.cooling_fuel_consumption_curve is not None) else None
_cooling_efficiency_curve = self.cooling_efficiency_curve.to_dictionary() if (
self.cooling_efficiency_curve is not None) else None
content = {
'Energy Generation component':
{
'id': self.id,
'model name': self.model_name,
'manufacturer': self.manufacturer,
'type': self.system_type,
'fuel type': self.fuel_type,
'nominal heat output [W]': self.nominal_heat_output,
'maximum heat output [W]': self.maximum_heat_output,
'minimum heat output [W]': self.minimum_heat_output,
'source medium': self.source_medium,
'supply medium': self.supply_medium,
'source temperature [Celsius]': self.source_temperature,
'source mass flow [kg/s]': self.source_mass_flow,
'heat efficiency': self.heat_efficiency,
'nominal cooling output [W]': self.nominal_cooling_output,
'maximum cooling output [W]': self.maximum_cooling_output,
'minimum cooling output [W]': self.minimum_cooling_output,
'cooling efficiency': self.cooling_efficiency,
'electricity efficiency': self.electricity_efficiency,
'nominal power output [W]': self.nominal_electricity_output,
'maximum heating supply temperature [Celsius]': self.maximum_heat_supply_temperature,
'minimum heating supply temperature [Celsius]': self.minimum_heat_supply_temperature,
'maximum cooling supply temperature [Celsius]': self.maximum_cooling_supply_temperature,
'minimum cooling supply temperature [Celsius]': self.minimum_cooling_supply_temperature,
'heat output curve': self.heat_output_curve,
'heat fuel consumption curve': self.heat_fuel_consumption_curve,
'heat efficiency curve': _heat_efficiency_curve,
'cooling output curve': self.cooling_output_curve,
'cooling fuel consumption curve': self.cooling_fuel_consumption_curve,
'cooling efficiency curve': self.cooling_efficiency_curve,
'distribution systems connected': _distribution_systems,
'storage systems connected': _energy_storage_systems,
'domestic hot water production capability': self.domestic_hot_water,
'reversible cycle': self.reversibility,
'simultaneous heat and cooling production': self.simultaneous_heat_cold
}
}
return content

View File

@ -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

View File

@ -14,52 +14,35 @@ class PvGenerationSystem(GenerationSystem):
Electricity Generation system class
"""
def __init__(self, system_id, name, system_type, model_name=None, manufacturer=None, electricity_efficiency=None,
nominal_electricity_output=None, nominal_ambient_temperature=None, nominal_cell_temperature=None,
nominal_radiation=None, standard_test_condition_cell_temperature=None,
standard_test_condition_maximum_power=None, standard_test_condition_radiation=None,
cell_temperature_coefficient=None, width=None, height=None, distribution_systems=None,
energy_storage_systems=None):
def __init__(self, system_id, name, model_name, manufacturer, electricity_efficiency,
nominal_electricity_output, nominal_ambient_temperature, nominal_cell_temperature,
nominal_radiation, standard_test_condition_cell_temperature, standard_test_condition_maximum_power,
cell_temperature_coefficient, width, height):
super().__init__(system_id=system_id, name=name, model_name=model_name,
manufacturer=manufacturer, fuel_type='renewable', distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems)
self._system_type = system_type
self._electricity_efficiency = electricity_efficiency
self._nominal_electricity_output = nominal_electricity_output
manufacturer=manufacturer, system_type='pv', fuel_type='renewable',
nominal_thermal_output=None, maximum_heat_output=None,
minimum_heat_output=None, source_medium=None,
supply_medium=None, heat_efficiency=None, nominal_cooling_output=None,
maximum_cooling_output=None, minimum_cooling_output=None,
cooling_efficiency=None, electricity_efficiency=electricity_efficiency,
source_temperature=None, source_mass_flow=None,
nominal_electricity_output=nominal_electricity_output,
maximum_heat_supply_temperature=None,
minimum_heat_supply_temperature=None,
maximum_cooling_supply_temperature=None,
minimum_cooling_supply_temperature=None, heat_output_curve=None,
heat_fuel_consumption_curve=None, heat_efficiency_curve=None,
cooling_output_curve=None, cooling_fuel_consumption_curve=None,
cooling_efficiency_curve=None)
self._nominal_ambient_temperature = nominal_ambient_temperature
self._nominal_cell_temperature = nominal_cell_temperature
self._nominal_radiation = nominal_radiation
self._standard_test_condition_cell_temperature = standard_test_condition_cell_temperature
self._standard_test_condition_maximum_power = standard_test_condition_maximum_power
self._standard_test_condition_radiation = standard_test_condition_radiation
self._cell_temperature_coefficient = cell_temperature_coefficient
self._width = width
self._height = height
@property
def system_type(self):
"""
Get type
:return: string
"""
return self._system_type
@property
def nominal_electricity_output(self):
"""
Get nominal_power_output of electricity generation devices or inverters in W
:return: float
"""
return self._nominal_electricity_output
@property
def electricity_efficiency(self):
"""
Get electricity_efficiency
:return: float
"""
return self._electricity_efficiency
@property
def nominal_ambient_temperature(self):
"""
@ -95,20 +78,11 @@ class PvGenerationSystem(GenerationSystem):
@property
def standard_test_condition_maximum_power(self):
"""
Get standard test condition maximum power of PV panels in W
Get standard test condition maximum power of PV panels in kW
:return: float
"""
return self._standard_test_condition_maximum_power
@property
def standard_test_condition_radiation(self):
"""
Get standard test condition cell temperature of PV panels in W/m2
:return: float
"""
return self._standard_test_condition_radiation
@property
def cell_temperature_coefficient(self):
"""
@ -135,31 +109,23 @@ class PvGenerationSystem(GenerationSystem):
def to_dictionary(self):
"""Class content to dictionary"""
_distribution_systems = [_distribution_system.to_dictionary() for _distribution_system in
self.distribution_systems] if self.distribution_systems is not None else None
_energy_storage_systems = [_energy_storage_system.to_dictionary() for _energy_storage_system in
self.energy_storage_systems] if self.energy_storage_systems is not None else None
content = {
'Energy Generation component':
{
'id': self.id,
'model name': self.model_name,
'manufacturer': self.manufacturer,
'type': self.system_type,
'fuel type': self.fuel_type,
'electricity efficiency': self.electricity_efficiency,
'nominal power output [W]': self.nominal_electricity_output,
'nominal ambient temperature [Celsius]': self.nominal_ambient_temperature,
'nominal cell temperature [Celsius]': self.nominal_cell_temperature,
'nominal radiation [W/m2]': self.nominal_radiation,
'standard test condition cell temperature [Celsius]': self.standard_test_condition_cell_temperature,
'standard test condition maximum power [W]': self.standard_test_condition_maximum_power,
'standard test condition radiation [W/m2]': self.standard_test_condition_radiation,
'cell temperature coefficient': self.cell_temperature_coefficient,
'width': self.width,
'height': self.height,
'distribution systems connected': _distribution_systems,
'storage systems connected': _energy_storage_systems
}
content = {'Energy Generation component': {
'id': self.id,
'name': self.name,
'model name': self.model_name,
'manufacturer': self.manufacturer,
'type': self.system_type,
'fuel type': self.fuel_type,
'electricity efficiency': self.electricity_efficiency,
'nominal power output [kW]': self.nominal_electricity_output,
'nominal ambient temperature [Celsius]': self.nominal_ambient_temperature,
'nominal cell temperature [Celsius]': self.nominal_cell_temperature,
'nominal radiation [W/m2]': self.nominal_radiation,
'standard test condition cell temperature [Celsius]': self.standard_test_condition_cell_temperature,
'standard test condition maximum power [kW]': self.standard_test_condition_maximum_power,
'cell temperature coefficient': self.cell_temperature_coefficient,
'width': self.width,
'height': self.height,
}
}
return content

View File

@ -1,5 +1,5 @@
"""
Energy Systems catalog System
Energy System catalog heat generation system
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
@ -7,10 +7,12 @@ Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
from typing import Union, List
from pathlib import Path
from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem
from hub.catalog_factories.data_models.energy_systems.thermal_storage_system import ThermalStorageSystem
from hub.catalog_factories.data_models.energy_systems.electrical_storage_system import ElectricalStorageSystem
from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem
from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem
class System:
@ -19,18 +21,31 @@ class System:
"""
def __init__(self,
lod,
system_id,
name,
demand_types,
name=None,
generation_systems=None,
distribution_systems=None,
configuration_schema=None):
generation_systems,
distribution_systems,
emission_systems,
energy_storage_systems):
self._lod = lod
self._system_id = system_id
self._name = name
self._demand_types = demand_types
self._generation_systems = generation_systems
self._distribution_systems = distribution_systems
self._configuration_schema = configuration_schema
self._emission_systems = emission_systems
self._generation_systems = generation_systems
self._energy_storage_systems = energy_storage_systems
# self._configuration = configuration
@property
def lod(self):
"""
Get level of detail of the catalog
:return: string
"""
return self._lod
@property
def id(self):
@ -57,7 +72,7 @@ class System:
return self._demand_types
@property
def generation_systems(self) -> Union[None, List[GenerationSystem]]:
def generation_systems(self) -> List[GenerationSystem]:
"""
Get generation systems
:return: [GenerationSystem]
@ -73,12 +88,20 @@ class System:
return self._distribution_systems
@property
def configuration_schema(self) -> Path:
def emission_systems(self) -> Union[None, List[EmissionSystem]]:
"""
Get system configuration schema
:return: Path
Get emission systems
:return: [EmissionSystem]
"""
return self._configuration_schema
return self._emission_systems
@property
def energy_storage_systems(self) -> Union[None, List[ThermalStorageSystem], List[ElectricalStorageSystem]]:
"""
Get energy storage systems
:return: [EnergyStorageSystem]
"""
return self._energy_storage_systems
def to_dictionary(self):
"""Class content to dictionary"""
@ -87,13 +110,19 @@ class System:
_generation_systems.append(_generation.to_dictionary())
_distribution_systems = [_distribution.to_dictionary() for _distribution in
self.distribution_systems] if self.distribution_systems is not None else None
_emission_systems = [_emission.to_dictionary() for _emission in
self.emission_systems] if self.emission_systems is not None else None
_storage_systems = [_storage.to_dictionary() for _storage in
self.energy_storage_systems] if self.energy_storage_systems is not None else None
content = {'system': {'id': self.id,
'name': self.name,
'level of detail': self.lod,
'demand types': self.demand_types,
'generation system(s)': _generation_systems,
'distribution system(s)': _distribution_systems,
'configuration schema path': self.configuration_schema
'emission system(s)': _emission_systems,
'energy storage system(s)': _storage_systems,
}
}
return content

View File

@ -8,34 +8,22 @@ Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
from hub.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem
from hub.catalog_factories.data_models.construction.layer import Layer
from hub.catalog_factories.data_models.construction.material import Material
class ThermalStorageSystem(EnergyStorageSystem):
""""
Energy Storage System Class
"""
def __init__(self, storage_id, type_energy_stored=None, model_name=None, manufacturer=None, storage_type=None,
nominal_capacity=None, losses_ratio=None, volume=None, height=None, layers=None,
maximum_operating_temperature=None, storage_medium=None, heating_coil_capacity=None):
def __init__(self, storage_id, name, model_name, manufacturer, storage_type, nominal_capacity, losses_ratio,
volume, height, layers, maximum_operating_temperature):
super().__init__(storage_id, model_name, manufacturer, nominal_capacity, losses_ratio)
self._type_energy_stored = type_energy_stored
super().__init__(storage_id, name, model_name, manufacturer, nominal_capacity, losses_ratio)
self._storage_type = storage_type
self._volume = volume
self._height = height
self._layers = layers
self._maximum_operating_temperature = maximum_operating_temperature
self._storage_medium = storage_medium
self._heating_coil_capacity = heating_coil_capacity
@property
def type_energy_stored(self):
"""
Get type of energy stored from ['electrical', 'thermal']
:return: string
"""
return self._type_energy_stored
@property
def storage_type(self):
@ -77,50 +65,25 @@ class ThermalStorageSystem(EnergyStorageSystem):
"""
return self._maximum_operating_temperature
@property
def storage_medium(self) -> Material:
"""
Get thermodynamic characteristics of the storage medium
:return: [material
"""
return self._storage_medium
@property
def heating_coil_capacity(self):
"""
Get heating coil capacity in Watts
:return: [material
"""
return self._heating_coil_capacity
def to_dictionary(self):
"""Class content to dictionary"""
_layers = None
_medias = None
if self.layers is not None:
_layers = []
for _layer in self.layers:
_layers.append(_layer.to_dictionary())
if self.storage_medium is not None:
_medias = self.storage_medium.to_dictionary()
content = {
'Storage component':
{
'storage id': self.id,
'type of energy stored': self.type_energy_stored,
'model name': self.model_name,
'manufacturer': self.manufacturer,
'storage type': self.storage_type,
'nominal capacity [J]': self.nominal_capacity,
'losses-ratio [J/J]': self.losses_ratio,
'volume [m3]': self.volume,
'height [m]': self.height,
'layers': _layers,
'maximum operating temperature [Celsius]': self.maximum_operating_temperature,
'storage_medium': self.storage_medium.to_dictionary(),
'heating coil capacity [W]': self.heating_coil_capacity
}
content = {'Storage component': {
'storage id': self.id,
'name': self.name,
'model name': self.model_name,
'manufacturer': self.manufacturer,
'storage type': self.storage_type,
'nominal capacity [J]': self.nominal_capacity,
'losses-ratio [J/J]': self.losses_ratio,
'volume [m3]': self.volume,
'height [m]': self.height,
'layers': _layers,
'maximum operating temperature [Celsius]': self.maximum_operating_temperature
}
}
return content

View File

@ -10,8 +10,7 @@ import xmltodict
from hub.catalog_factories.catalog import Catalog
from hub.catalog_factories.data_models.energy_systems.system import System
from hub.catalog_factories.data_models.energy_systems.content import Content
from hub.catalog_factories.data_models.energy_systems.non_pv_generation_system import NonPvGenerationSystem
from hub.catalog_factories.data_models.energy_systems.pv_generation_system import PvGenerationSystem
from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem
from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem
from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem
from hub.catalog_factories.data_models.energy_systems.archetype import Archetype
@ -30,18 +29,23 @@ class MontrealCustomCatalog(Catalog):
self._archetypes = xmltodict.parse(xml.read(), force_list=('system', 'system_cluster', 'equipment',
'demand', 'system_id'))
self._catalog_generation_equipments = self._load_generation_equipments()
self._catalog_emission_equipments = self._load_emission_equipments()
self._lod = float(self._archetypes['catalog']['@lod'])
self._catalog_generation_equipments, self._catalog_storage_equipments = \
self._load_generation_and_storage_equipments()
self._catalog_distribution_equipments = self._load_distribution_equipments()
self._catalog_emission_equipments = self._load_emission_equipments()
self._catalog_systems = self._load_systems()
self._catalog_archetypes = self._load_archetypes()
# store the full catalog data model in self._content
self._content = Content(self._catalog_archetypes,
self._catalog_systems,
self._catalog_generation_equipments,
self._catalog_distribution_equipments)
self._catalog_distribution_equipments,
self._catalog_emission_equipments,
None)
def _load_generation_equipments(self):
def _load_generation_and_storage_equipments(self):
_equipments = []
_storages = []
equipments = self._archetypes['catalog']['generation_equipments']['equipment']
@ -49,7 +53,7 @@ class MontrealCustomCatalog(Catalog):
equipment_id = float(equipment['@id'])
equipment_type = equipment['@type']
fuel_type = equipment['@fuel_type']
model_name = equipment['name']
name = equipment['name']
heating_efficiency = None
if 'heating_efficiency' in equipment:
heating_efficiency = float(equipment['heating_efficiency'])
@ -59,39 +63,48 @@ class MontrealCustomCatalog(Catalog):
electricity_efficiency = None
if 'electrical_efficiency' in equipment:
electricity_efficiency = float(equipment['electrical_efficiency'])
storage_systems = None
generation_system = GenerationSystem(equipment_id,
name,
None,
None,
equipment_type,
fuel_type,
None,
None,
None,
None,
None,
heating_efficiency,
None,
None,
None,
cooling_efficiency,
electricity_efficiency,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None)
_equipments.append(generation_system)
storage = literal_eval(equipment['storage'].capitalize())
if storage:
if equipment_type == 'electricity generator':
storage_system = ElectricalStorageSystem(equipment_id)
storage_system = ElectricalStorageSystem(equipment_id, None, None, None, 'electrical', None, None, None, None,
None, None, None)
else:
storage_system = ThermalStorageSystem(equipment_id)
storage_systems = [storage_system]
if model_name == 'PV system':
system_type = 'Photovoltaic'
generation_system = PvGenerationSystem(equipment_id,
name=None,
system_type= system_type,
model_name=model_name,
electricity_efficiency=electricity_efficiency,
energy_storage_systems=storage_systems
)
else:
generation_system = NonPvGenerationSystem(equipment_id,
name=None,
model_name=model_name,
system_type=equipment_type,
fuel_type=fuel_type,
heat_efficiency=heating_efficiency,
cooling_efficiency=cooling_efficiency,
electricity_efficiency=electricity_efficiency,
energy_storage_systems=storage_systems,
domestic_hot_water=False
)
_equipments.append(generation_system)
storage_system = ThermalStorageSystem(equipment_id, None, None, None, 'thermal', None, None, None, None, None,
None)
_storages.append(storage_system)
return _equipments
return _equipments, _storages
def _load_distribution_equipments(self):
_equipments = []
@ -99,7 +112,7 @@ class MontrealCustomCatalog(Catalog):
for equipment in equipments:
equipment_id = float(equipment['@id'])
equipment_type = equipment['@type']
model_name = equipment['name']
name = equipment['name']
distribution_heat_losses = None
if 'distribution_heat_losses' in equipment:
distribution_heat_losses = float(equipment['distribution_heat_losses']['#text']) / 100
@ -111,19 +124,13 @@ class MontrealCustomCatalog(Catalog):
distribution_consumption_variable_flow = float(
equipment['distribution_consumption_variable_flow']['#text']) / 100
emission_equipment = equipment['dissipation_id']
_emission_equipments = None
for equipment_archetype in self._catalog_emission_equipments:
if int(equipment_archetype.id) == int(emission_equipment):
_emission_equipments = [equipment_archetype]
distribution_system = DistributionSystem(equipment_id,
model_name=model_name,
system_type=equipment_type,
distribution_consumption_fix_flow=distribution_consumption_fix_flow,
distribution_consumption_variable_flow=distribution_consumption_variable_flow,
heat_losses=distribution_heat_losses,
emission_systems=_emission_equipments)
name,
equipment_type,
None,
distribution_consumption_fix_flow,
distribution_consumption_variable_flow,
distribution_heat_losses)
_equipments.append(distribution_system)
return _equipments
@ -134,15 +141,15 @@ class MontrealCustomCatalog(Catalog):
for equipment in equipments:
equipment_id = float(equipment['@id'])
equipment_type = equipment['@type']
model_name = equipment['name']
parasitic_consumption = 0
name = equipment['name']
parasitic_consumption = None
if 'parasitic_consumption' in equipment:
parasitic_consumption = float(equipment['parasitic_consumption']['#text']) / 100
emission_system = EmissionSystem(equipment_id,
model_name=model_name,
system_type=equipment_type,
parasitic_energy_consumption=parasitic_consumption)
name,
equipment_type,
parasitic_consumption)
_equipments.append(emission_system)
return _equipments
@ -159,17 +166,29 @@ class MontrealCustomCatalog(Catalog):
for equipment_archetype in self._catalog_generation_equipments:
if int(equipment_archetype.id) == int(generation_equipment):
_generation_equipments = [equipment_archetype]
_storage_equipments = None
for equipment_archetype in self._catalog_storage_equipments:
if int(equipment_archetype.id) == int(generation_equipment):
_storage_equipments = [equipment_archetype]
distribution_equipment = system['equipments']['distribution_id']
_distribution_equipments = None
for equipment_archetype in self._catalog_distribution_equipments:
if int(equipment_archetype.id) == int(distribution_equipment):
_distribution_equipments = [equipment_archetype]
emission_equipment = system['equipments']['dissipation_id']
_emission_equipments = None
for equipment_archetype in self._catalog_emission_equipments:
if int(equipment_archetype.id) == int(emission_equipment):
_emission_equipments = [equipment_archetype]
_catalog_systems.append(System(system_id,
_catalog_systems.append(System(self._lod,
system_id,
name,
demands,
name=name,
generation_systems=_generation_equipments,
distribution_systems=_distribution_equipments))
_generation_equipments,
_distribution_equipments,
_emission_equipments,
_storage_equipments))
return _catalog_systems
def _load_archetypes(self):
@ -183,7 +202,7 @@ class MontrealCustomCatalog(Catalog):
for system_archetype in self._catalog_systems:
if int(system_archetype.id) == int(system):
_systems.append(system_archetype)
_catalog_archetypes.append(Archetype(name, _systems))
_catalog_archetypes.append(Archetype(self._lod, name, _systems))
return _catalog_archetypes
def names(self, category=None):
@ -199,9 +218,11 @@ class MontrealCustomCatalog(Catalog):
for system in self._content.systems:
_names['systems'].append(system.name)
for equipment in self._content.generation_equipments:
_names['generation_equipments'].append(equipment.model_name)
_names['generation_equipments'].append(equipment.name)
for equipment in self._content.distribution_equipments:
_names['distribution_equipments'].append(equipment.model_name)
_names['distribution_equipments'].append(equipment.name)
for equipment in self._content.emission_equipments:
_names['emission_equipments'].append(equipment.name)
else:
_names = {category: []}
if category.lower() == 'archetypes':
@ -212,10 +233,13 @@ class MontrealCustomCatalog(Catalog):
_names[category].append(system.name)
elif category.lower() == 'generation_equipments':
for system in self._content.generation_equipments:
_names[category].append(system.model_name)
_names[category].append(system.name)
elif category.lower() == 'distribution_equipments':
for system in self._content.distribution_equipments:
_names[category].append(system.model_name)
_names[category].append(system.name)
elif category.lower() == 'emission_equipments':
for system in self._content.emission_equipments:
_names[category].append(system.name)
else:
raise ValueError(f'Unknown category [{category}]')
return _names
@ -235,6 +259,9 @@ class MontrealCustomCatalog(Catalog):
return self._content.generation_equipments
if category.lower() == 'distribution_equipments':
return self._content.distribution_equipments
if category.lower() == 'emission_equipments':
return self._content.emission_equipments
raise ValueError(f'Unknown category [{category}]')
def get_entry(self, name):
"""
@ -248,9 +275,12 @@ class MontrealCustomCatalog(Catalog):
if entry.name.lower() == name.lower():
return entry
for entry in self._content.generation_equipments:
if entry.model_name.lower() == name.lower():
if entry.name.lower() == name.lower():
return entry
for entry in self._content.distribution_equipments:
if entry.model_name.lower() == name.lower():
if entry.name.lower() == name.lower():
return entry
raise IndexError(f"{name} doesn't exists in the catalog")
for entry in self._content.emission_equipments:
if entry.name.lower() == name.lower():
return entry
raise IndexError(f"{name} doesn't exists in the catalog")

View File

@ -1,559 +0,0 @@
"""
Montreal future energy system catalog
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import xmltodict
from pathlib import Path
from hub.catalog_factories.catalog import Catalog
from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem
from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem
from hub.catalog_factories.data_models.energy_systems.system import System
from hub.catalog_factories.data_models.energy_systems.content import Content
from hub.catalog_factories.data_models.energy_systems.non_pv_generation_system import NonPvGenerationSystem
from hub.catalog_factories.data_models.energy_systems.pv_generation_system import PvGenerationSystem
from hub.catalog_factories.data_models.energy_systems.thermal_storage_system import ThermalStorageSystem
from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves
from hub.catalog_factories.data_models.energy_systems.archetype import Archetype
from hub.catalog_factories.data_models.construction.material import Material
from hub.catalog_factories.data_models.construction.layer import Layer
class MontrealFutureSystemCatalogue(Catalog):
"""
North america energy system catalog class
"""
def __init__(self, path):
path = str(path / 'montreal_future_systems.xml')
with open(path, 'r', encoding='utf-8') as xml:
self._archetypes = xmltodict.parse(xml.read(),
force_list=['pv_generation_component', 'templateStorages', 'demand'])
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']
template_storages = self._archetypes['EnergySystemCatalog']['energy_storage_components']['templateStorages']
for tes in thermal_storages:
storage_id = tes['storage_id']
type_energy_stored = tes['type_energy_stored']
model_name = tes['model_name']
manufacturer = tes['manufacturer']
storage_type = tes['storage_type']
volume = tes['physical_characteristics']['volume']
height = tes['physical_characteristics']['height']
maximum_operating_temperature = tes['maximum_operating_temperature']
materials = self._load_materials()
insulation_material_id = tes['insulation']['material_id']
insulation_material = self._search_material(materials, insulation_material_id)
material_id = tes['physical_characteristics']['material_id']
tank_material = self._search_material(materials, material_id)
thickness = float(tes['insulation']['insulationThickness']) / 100 # from cm to m
insulation_layer = Layer(None, 'insulation', insulation_material, thickness)
thickness = float(tes['physical_characteristics']['tankThickness']) / 100 # from cm to m
tank_layer = Layer(None, 'tank', tank_material, thickness)
media = self._load_media()
media_id = tes['storage_medium']['medium_id']
medium = self._search_media(media, media_id)
layers = [insulation_layer, tank_layer]
nominal_capacity = tes['nominal_capacity']
losses_ratio = tes['losses_ratio']
heating_coil_capacity = tes['heating_coil_capacity']
storage_component = ThermalStorageSystem(storage_id=storage_id,
model_name=model_name,
type_energy_stored=type_energy_stored,
manufacturer=manufacturer,
storage_type=storage_type,
nominal_capacity=nominal_capacity,
losses_ratio=losses_ratio,
volume=volume,
height=height,
layers=layers,
maximum_operating_temperature=maximum_operating_temperature,
storage_medium=medium,
heating_coil_capacity=heating_coil_capacity)
storage_components.append(storage_component)
for template in template_storages:
storage_id = template['storage_id']
storage_type = template['storage_type']
type_energy_stored = template['type_energy_stored']
maximum_operating_temperature = template['maximum_operating_temperature']
height = float(template['physical_characteristics']['height'])
materials = self._load_materials()
insulation_material_id = template['insulation']['material_id']
insulation_material = self._search_material(materials, insulation_material_id)
material_id = template['physical_characteristics']['material_id']
tank_material = self._search_material(materials, material_id)
thickness = float(template['insulation']['insulationThickness']) / 100 # from cm to m
insulation_layer = Layer(None, 'insulation', insulation_material, thickness)
thickness = float(template['physical_characteristics']['tankThickness']) / 100 # from cm to m
tank_layer = Layer(None, 'tank', tank_material, thickness)
layers = [insulation_layer, tank_layer]
media = self._load_media()
media_id = template['storage_medium']['medium_id']
medium = self._search_media(media, media_id)
model_name = template['model_name']
manufacturer = template['manufacturer']
nominal_capacity = template['nominal_capacity']
losses_ratio = template['losses_ratio']
volume = template['physical_characteristics']['volume']
heating_coil_capacity = template['heating_coil_capacity']
storage_component = ThermalStorageSystem(storage_id=storage_id,
model_name=model_name,
type_energy_stored=type_energy_stored,
manufacturer=manufacturer,
storage_type=storage_type,
nominal_capacity=nominal_capacity,
losses_ratio=losses_ratio,
volume=volume,
height=height,
layers=layers,
maximum_operating_temperature=maximum_operating_temperature,
storage_medium=medium,
heating_coil_capacity=heating_coil_capacity)
storage_components.append(storage_component)
return storage_components
def _load_systems(self):
base_path = Path(Path(__file__).parent.parent.parent / 'data/energy_systems')
_catalog_systems = []
systems = self._archetypes['EnergySystemCatalog']['systems']['system']
for system in systems:
system_id = system['id']
name = system['name']
demands = system['demands']['demand']
generation_components = system['components']['generation_id']
generation_systems = self._search_generation_equipment(self._load_generation_components(), generation_components)
configuration_schema = Path(base_path / system['schema'])
energy_system = System(system_id=system_id,
name=name,
demand_types=demands,
generation_systems=generation_systems,
distribution_systems=None,
configuration_schema=configuration_schema)
_catalog_systems.append(energy_system)
return _catalog_systems
def _load_archetypes(self):
_system_archetypes = []
system_clusters = self._archetypes['EnergySystemCatalog']['system_archetypes']['system_archetype']
for system_cluster in system_clusters:
name = system_cluster['name']
systems = system_cluster['systems']['system_id']
integer_system_ids = [int(item) for item in systems]
_systems = []
for system_archetype in self._systems:
if int(system_archetype.id) in integer_system_ids:
_systems.append(system_archetype)
_system_archetypes.append(Archetype(name=name, systems=_systems))
return _system_archetypes
def _load_materials(self):
materials = []
_materials = self._archetypes['EnergySystemCatalog']['materials']['material']
for _material in _materials:
material_id = _material['material_id']
name = _material['name']
conductivity = _material['conductivity']
solar_absorptance = _material['solar_absorptance']
thermal_absorptance = _material['thermal_absorptance']
density = _material['density']
specific_heat = _material['specific_heat']
no_mass = _material['no_mass']
visible_absorptance = _material['visible_absorptance']
thermal_resistance = _material['thermal_resistance']
material = Material(material_id,
name,
solar_absorptance=solar_absorptance,
thermal_absorptance=thermal_absorptance,
density=density,
conductivity=conductivity,
thermal_resistance=thermal_resistance,
visible_absorptance=visible_absorptance,
no_mass=no_mass,
specific_heat=specific_heat)
materials.append(material)
return materials
@staticmethod
def _search_material(materials, material_id):
_material = None
for material in materials:
if int(material.id) == int(material_id):
_material = material
break
if _material is None:
raise ValueError(f'Material with the id = [{material_id}] not found in catalog ')
return _material
def _load_media(self):
media = []
_media = [self._archetypes['EnergySystemCatalog']['media']['medium']]
for _medium in _media:
medium_id = _medium['medium_id']
density = _medium['density']
name = _medium['name']
conductivity = _medium['conductivity']
solar_absorptance = _medium['solar_absorptance']
thermal_absorptance = _medium['thermal_absorptance']
specific_heat = _medium['specific_heat']
no_mass = _medium['no_mass']
visible_absorptance = _medium['visible_absorptance']
thermal_resistance = _medium['thermal_resistance']
medium = Material(material_id=medium_id,
name=name,
solar_absorptance=solar_absorptance,
thermal_absorptance=thermal_absorptance,
visible_absorptance=visible_absorptance,
no_mass=no_mass,
thermal_resistance=thermal_resistance,
conductivity=conductivity,
density=density,
specific_heat=specific_heat)
media.append(medium)
return media
@staticmethod
def _search_media(media, medium_id):
_medium = None
for medium in media:
if int(medium.id) == int(medium_id):
_medium = medium
break
if _medium is None:
raise ValueError(f'media with the id = [{medium_id}] not found in catalog ')
return _medium
@staticmethod
def _search_generation_equipment(generation_systems, generation_id):
_generation_systems = []
if isinstance(generation_id, list):
integer_ids = [int(item) for item in generation_id]
for generation in generation_systems:
if int(generation.id) in integer_ids:
_generation_systems.append(generation)
else:
integer_id = int(generation_id)
for generation in generation_systems:
if int(generation.id) == integer_id:
_generation_systems.append(generation)
if len(_generation_systems) == 0:
_generation_systems = None
raise ValueError(f'The system with the following id is not found in catalog [{generation_id}]')
return _generation_systems
@staticmethod
def _search_storage_equipment(storage_systems, storage_id):
_storage_systems = []
for storage in storage_systems:
if storage.id in storage_id:
_storage_systems.append(storage)
if len(_storage_systems) == 0:
_storage_systems = None
raise ValueError(f'The system with the following id is not found in catalog [{storage_id}]')
return _storage_systems
def names(self, category=None):
"""
Get the catalog elements names
:parm: optional category filter
"""
if category is None:
_names = {'archetypes': [], 'systems': [], 'generation_equipments': [], 'storage_equipments': []}
for archetype in self._content.archetypes:
_names['archetypes'].append(archetype.name)
for system in self._content.systems:
_names['systems'].append(system.name)
for equipment in self._content.generation_equipments:
_names['generation_equipments'].append(equipment.name)
else:
_names = {category: []}
if category.lower() == 'archetypes':
for archetype in self._content.archetypes:
_names[category].append(archetype.name)
elif category.lower() == 'systems':
for system in self._content.systems:
_names[category].append(system.name)
elif category.lower() == 'generation_equipments':
for system in self._content.generation_equipments:
_names[category].append(system.name)
else:
raise ValueError(f'Unknown category [{category}]')
return _names
def entries(self, category=None):
"""
Get the catalog elements
:parm: optional category filter
"""
if category is None:
return self._content
if category.lower() == 'archetypes':
return self._content.archetypes
if category.lower() == 'systems':
return self._content.systems
if category.lower() == 'generation_equipments':
return self._content.generation_equipments
raise ValueError(f'Unknown category [{category}]')
def get_entry(self, name):
"""
Get one catalog element by names
:parm: entry name
"""
for entry in self._content.archetypes:
if entry.name.lower() == name.lower():
return entry
for entry in self._content.systems:
if entry.name.lower() == name.lower():
return entry
for entry in self._content.generation_equipments:
if entry.name.lower() == name.lower():
return entry
raise IndexError(f"{name} doesn't exists in the catalog")

View File

@ -0,0 +1,510 @@
"""
North america energy system catalog
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import xmltodict
from hub.catalog_factories.catalog import Catalog
from hub.catalog_factories.data_models.energy_systems.system import System
from hub.catalog_factories.data_models.energy_systems.content import Content
from hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem
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 NorthAmericaEnergySystemCatalog(Catalog):
"""
North america energy system catalog class
"""
def __init__(self, path):
path = str(path / 'north_america_systems.xml')
with open(path, 'r', encoding='utf-8') as xml:
self._archetypes = xmltodict.parse(xml.read(), force_list=['photovoltaicModules', 'templateStorages'])
self._generation_components = self._load_generation_components()
self._storage_components = self._load_storage_components()
self._systems = self._load_systems()
self._system_archetypes = self._load_archetypes()
self._content = Content(self._system_archetypes,
self._systems,
self._generation_components,
None,
None,
self._storage_components)
def _load_generation_components(self):
generation_components = []
boilers = self._archetypes['EnergySystemCatalog']['energy_generation_components']['boilers']
heat_pumps = self._archetypes['EnergySystemCatalog']['energy_generation_components']['heatPumps']
photovoltaics = self._archetypes['EnergySystemCatalog']['energy_generation_components']['photovoltaicModules']
templates = self._archetypes['EnergySystemCatalog']['energy_generation_components']['templateGenerationEquipments']
for boiler in boilers:
boiler_id = boiler['@generation_id']
boiler_name = boiler['@name']
boiler_model_name = boiler['@modelName']
boiler_manufacturer = boiler['@manufacturer']
system_type = 'boiler'
boiler_fuel_type = boiler['@fuel']
boiler_nominal_thermal_output = float(boiler['@installedThermalPower'])
boiler_maximum_heat_output = float(boiler['@maximumHeatOutput'])
boiler_minimum_heat_output = float(boiler['@minimumHeatOutput'])
boiler_heat_efficiency = float(boiler['@nominalEfficiency'])
boiler_component = GenerationSystem(boiler_id,
boiler_name,
boiler_model_name,
boiler_manufacturer,
system_type,
boiler_fuel_type,
boiler_nominal_thermal_output,
boiler_maximum_heat_output,
boiler_minimum_heat_output,
None,
None,
boiler_heat_efficiency,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None)
generation_components.append(boiler_component)
for heat_pump in heat_pumps:
heat_pump_id = heat_pump['@generation_id']
heat_pump_name = heat_pump['@name']
heat_pump_model_name = heat_pump['@modelName']
heat_pump_manufacturer = heat_pump['@manufacturer']
system_type = 'heat pump'
heat_pump_fuel_type = heat_pump['@fuel']
heat_pump_nominal_thermal_output = float(heat_pump['@installedThermalPower'])
heat_pump_maximum_heat_output = float(heat_pump['@maximumHeatOutput'])
heat_pump_minimum_heat_output = float(heat_pump['@minimumHeatOutput'])
heat_pump_source_medium = heat_pump['@heatSource']
heat_pump_supply_medium = heat_pump['@supply_medium']
heat_pump_nominal_cop = float(heat_pump['@nominalCOP'])
heat_pump_maximum_heat_supply_temperature = float(heat_pump['@maxHeatingSupTemperature'])
heat_pump_minimum_heat_supply_temperature = float(heat_pump['@minHeatingSupTemperature'])
heat_pump_maximum_cooling_supply_temperature = float(heat_pump['@maxCoolingSupTemperature'])
heat_pump_minimum_cooling_supply_temperature = float(heat_pump['@minCoolingSupTemperature'])
cop_curve_type = heat_pump['performance_curve']['@curve_type']
dependant_variable = heat_pump['performance_curve']['dependant_variable']
parameters = heat_pump['performance_curve']['parameters']
coefficients = list(heat_pump['performance_curve']['coefficients'].values())
cop_curve = PerformanceCurves(cop_curve_type, dependant_variable, parameters, coefficients)
heat_pump_component = GenerationSystem(heat_pump_id,
heat_pump_name,
heat_pump_model_name,
heat_pump_manufacturer,
system_type,
heat_pump_fuel_type,
heat_pump_nominal_thermal_output,
heat_pump_maximum_heat_output,
heat_pump_minimum_heat_output,
heat_pump_source_medium,
heat_pump_supply_medium,
heat_pump_nominal_cop,
None,
None,
None,
None,
None,
None,
None,
None,
heat_pump_maximum_heat_supply_temperature,
heat_pump_minimum_heat_supply_temperature,
heat_pump_maximum_cooling_supply_temperature,
heat_pump_minimum_cooling_supply_temperature,
None,
None,
cop_curve,
None,
None,
None)
generation_components.append(heat_pump_component)
for pv in photovoltaics:
pv_id = pv['@generation_id']
pv_name = pv['@name']
pv_model_name = pv['@modelName']
pv_manufacturer = pv['@manufacturer']
pv_electricity_efficiency = pv['@nominalEfficiency']
pv_nominal_electricity_output = pv['@nominalPower']
nominal_ambient_temperature = float(pv['@nominalAmbientTemperature'])
nominal_cell_temperature = float(pv['@nominalCellTemperature'])
nominal_radiation = float(pv['@nominalRadiation'])
standard_test_condition_cell_temperature = float(pv['@STCCellTemperature'])
standard_test_condition_maximum_power = float(pv['@STCMaxPower'])
cell_temperature_coefficient = float(pv['@CellTemperatureCoefficient'])
width = float(pv['@width'])
height = float(pv['@height'])
pv_component = PvGenerationSystem(pv_id,
pv_name,
pv_model_name,
pv_manufacturer,
pv_electricity_efficiency,
pv_nominal_electricity_output,
nominal_ambient_temperature,
nominal_cell_temperature,
nominal_radiation,
standard_test_condition_cell_temperature,
standard_test_condition_maximum_power,
cell_temperature_coefficient,
width,
height)
generation_components.append(pv_component)
for template in templates:
system_id = template['@generation_id']
system_name = template['@name']
if "Boiler" in system_name:
system_type = 'boiler'
fuel_type = template['@fuel']
heat_efficiency = float(template['@nominalEfficiency'])
source_medium = None
supply_medium = None
boiler_template = GenerationSystem(system_id,
system_name,
None,
None,
system_type,
fuel_type,
None,
None,
None,
source_medium,
supply_medium,
heat_efficiency,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None)
generation_components.append(boiler_template)
elif "Heat Pump" in system_name:
system_type = 'heat pump'
fuel_type = template['@fuel']
heat_efficiency = template['@nominalCOP']
source_medium = template['@heatSource']
supply_medium = template['@supply_medium']
heat_pump_template = GenerationSystem(system_id,
system_name,
None,
None,
system_type,
fuel_type,
None,
None,
None,
source_medium,
supply_medium,
heat_efficiency,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None,
None)
generation_components.append(heat_pump_template)
else:
electricity_efficiency = float(template['@nominalEfficiency'])
height = float(template['@height'])
width = float(template['@width'])
pv_template = PvGenerationSystem(system_id,
system_name,
None,
None,
electricity_efficiency,
None,
None,
None,
None,
None,
None,
None,
width,
height)
generation_components.append(pv_template)
return generation_components
def _load_storage_components(self):
storage_components = []
thermal_storages = self._archetypes['EnergySystemCatalog']['energy_storage_components']['thermalStorages']
template_storages = self._archetypes['EnergySystemCatalog']['energy_storage_components']['templateStorages']
for tes in thermal_storages:
storage_id = tes['@storage_id']
name = tes['@name']
model_name = tes['@modelName']
manufacturer = tes['@manufacturer']
storage_type = 'sensible'
volume = tes['physical_characteristics']['@volume']
height = tes['physical_characteristics']['@height']
maximum_operating_temperature = tes['@maxTemp']
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)
# the convention is from outside to inside
layers = [insulation_layer, tank_layer]
storage_component = ThermalStorageSystem(storage_id,
name,
model_name,
manufacturer,
storage_type,
None,
None,
volume,
height,
layers,
maximum_operating_temperature)
storage_components.append(storage_component)
for template in template_storages:
storage_id = template['@storage_id']
name = template['@name']
storage_type = 'sensible'
maximum_temperature = template['@maxTemp']
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)
material_id = template['physical_characteristics']['@material_id']
tank_material = self._search_material(materials, material_id)
thickness = float(template['insulation']['@insulationThickness']) / 100 # from cm to m
insulation_layer = Layer(None, 'insulation', insulation_material, thickness)
thickness = float(template['physical_characteristics']['@tankThickness']) / 100 # from cm to m
tank_layer = Layer(None, 'tank', tank_material, thickness)
# the convention is from outside to inside
layers = [insulation_layer, tank_layer]
storage_component = ThermalStorageSystem(storage_id,
name,
None,
None,
storage_type,
None,
None,
None,
height,
layers,
maximum_temperature)
storage_components.append(storage_component)
return storage_components
def _load_systems(self):
_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)
if 'storage_id' in system['components'].keys():
storage_components = system['components']['storage_id']
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_components)
else:
storage_systems = None
energy_system = System(None,
system_id,
name,
demands,
generation_systems,
None,
None,
storage_systems)
_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(None, name, _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']
thermal_conductivity = _material['@thermalConductivity']
material = Material(material_id,
name,
None,
None,
None,
False,
None,
thermal_conductivity,
None,
None)
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
return _material
if _material is None:
raise ValueError(f'Material with the id = [{material_id}] not found in catalog ')
@staticmethod
def _search_generation_equipment(generation_systems, generation_id):
_generation_systems = []
if type(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_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)
for equipment in self._content.storage_equipments:
_names['storage_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)
elif category.lower() == 'storage_equipments':
for system in self._content.storage_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
if category.lower() == 'storage_equipments':
return self._content.storage_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
for entry in self._content.storage_equipments:
if entry.name.lower() == name.lower():
return entry
raise IndexError(f"{name} doesn't exists in the catalog")

View File

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

View File

@ -9,8 +9,7 @@ from pathlib import Path
from typing import TypeVar
from hub.catalog_factories.energy_systems.montreal_custom_catalog import MontrealCustomCatalog
from hub.catalog_factories.energy_systems.montreal_future_system_catalogue import MontrealFutureSystemCatalogue
from hub.catalog_factories.energy_systems.palma_system_catalgue import PalmaSystemCatalogue
from hub.catalog_factories.energy_systems.north_america_energy_system_catalog import NorthAmericaEnergySystemCatalog
from hub.helpers.utils import validate_import_export_type
Catalog = TypeVar('Catalog')
@ -35,18 +34,11 @@ class EnergySystemsCatalogFactory:
return MontrealCustomCatalog(self._path)
@property
def _montreal_future(self):
def _north_america(self):
"""
Retrieve North American catalog
"""
return MontrealFutureSystemCatalogue(self._path)
@property
def _palma(self):
"""
Retrieve Palma catalog
"""
return PalmaSystemCatalogue(self._path)
return NorthAmericaEnergySystemCatalog(self._path)
@property
def catalog(self) -> Catalog:

View File

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

View File

@ -188,7 +188,7 @@ class EilatCatalog(Catalog):
schedules_key = {}
for j in range(0, number_usage_types):
usage_parameters = _extracted_data.iloc[j]
usage_type = usage_parameters.iloc[0]
usage_type = usage_parameters[0]
lighting_data[usage_type] = usage_parameters[1:6].values.tolist()
plug_loads_data[usage_type] = usage_parameters[8:13].values.tolist()
occupancy_data[usage_type] = usage_parameters[17:20].values.tolist()

View File

@ -8,8 +8,6 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
import json
import urllib.request
from pathlib import Path
import xmltodict
import hub.helpers.constants as cte
@ -30,11 +28,12 @@ class NrcanCatalog(Catalog):
Nrcan catalog class
"""
def __init__(self, path):
self._schedules_path = Path(path / 'nrcan_schedules.json').resolve()
self._space_types_path = Path(path / 'nrcan_space_types.json').resolve()
self._space_compliance_path = Path(path / 'nrcan_space_compliance_2015.json').resolve()
path = str(path / 'nrcan.xml')
self._content = None
self._schedules = {}
with open(path, 'r', encoding='utf-8') as xml:
self._metadata = xmltodict.parse(xml.read())
self._base_url = self._metadata['nrcan']['@base_url']
self._load_schedules()
self._content = Content(self._load_archetypes())
@ -56,9 +55,11 @@ class NrcanCatalog(Catalog):
return Schedule(hub_type, raw['values'], data_type, time_step, time_range, day_types)
def _load_schedules(self):
usage = self._metadata['nrcan']
url = f'{self._base_url}{usage["schedules"]}'
_schedule_types = []
with open(self._schedules_path, 'r') as f:
schedules_type = json.load(f)
with urllib.request.urlopen(url) as json_file:
schedules_type = json.load(json_file)
for schedule_type in schedules_type['tables']['schedules']['table']:
schedule = NrcanCatalog._extract_schedule(schedule_type)
if schedule_type['name'] not in _schedule_types:
@ -79,11 +80,14 @@ class NrcanCatalog(Catalog):
def _load_archetypes(self):
usages = []
with open(self._space_types_path, 'r') as f:
space_types = json.load(f)['tables']['space_types']['table']
name = self._metadata['nrcan']
url_1 = f'{self._base_url}{name["space_types"]}'
url_2 = f'{self._base_url}{name["space_types_compliance"]}'
with urllib.request.urlopen(url_1) as json_file:
space_types = json.load(json_file)['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']
with urllib.request.urlopen(url_2) as json_file:
space_types_compliance = json.load(json_file)['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:

View File

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

View File

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

View File

@ -70,9 +70,6 @@ class Building(CityObject):
self._min_x = min(self._min_x, surface.lower_corner[0])
self._min_y = min(self._min_y, surface.lower_corner[1])
self._min_z = min(self._min_z, surface.lower_corner[2])
self._max_x = max(self._max_x, surface.upper_corner[0])
self._max_y = max(self._max_y, surface.upper_corner[1])
self._max_z = max(self._max_z, surface.upper_corner[2])
surface.id = surface_id
if surface.type == cte.GROUND:
self._grounds.append(surface)
@ -89,10 +86,7 @@ class Building(CityObject):
elif surface.type == cte.INTERIOR_SLAB:
self._interior_slabs.append(surface)
else:
logging.error('Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type)
self._domestic_hot_water_peak_load = None
self._fuel_consumption_breakdown = {}
self._pv_generation = {}
logging.error(f'Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type)
@property
def shell(self) -> Polyhedron:
@ -292,10 +286,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 +445,8 @@ class Building(CityObject):
monthly_values = PeakLoads(self).heating_peak_loads_from_methodology
if monthly_values is None:
return None
results[cte.MONTH] = [x / cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values) / cte.WATTS_HOUR_TO_JULES]
results[cte.MONTH] = [x * cte.WATTS_HOUR_TO_JULES for x in monthly_values]
results[cte.YEAR] = [max(monthly_values)]
return results
@property
@ -471,24 +462,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
@ -706,17 +681,11 @@ class Building(CityObject):
for i, value in enumerate(item):
_working_hours[key][i] = max(_working_hours[key][i], saved_values[i])
working_hours = {}
values_months = []
for month in cte.WEEK_DAYS_A_MONTH.keys():
_total_hours_month = 0
for key in _working_hours:
hours = sum(_working_hours[key])
_total_hours_month += hours * cte.WEEK_DAYS_A_MONTH[month][key]
values_months.append(_total_hours_month)
working_hours[cte.MONTH] = values_months
working_hours[cte.YEAR] = sum(working_hours[cte.MONTH])
return working_hours
_total_hours = 0
for key in _working_hours:
hours = sum(_working_hours[key])
_total_hours += hours * cte.WEEK_DAYS_A_YEAR[key]
return _total_hours
@property
def distribution_systems_electrical_consumption(self):
@ -724,7 +693,6 @@ class Building(CityObject):
Get total electricity consumption for distribution and emission systems in J
return: dict
"""
_distribution_systems_electrical_consumption = {}
if len(self._distribution_systems_electrical_consumption) != 0:
return self._distribution_systems_electrical_consumption
_peak_load = self.heating_peak_load[cte.YEAR][0]
@ -738,44 +706,36 @@ class Building(CityObject):
if self.energy_systems is None:
return self._distribution_systems_electrical_consumption
for energy_system in self.energy_systems:
distribution_systems = energy_system.distribution_systems
if distribution_systems is not None:
for distribution_system in distribution_systems:
emission_systems = distribution_system.emission_systems
parasitic_energy_consumption = 0
if emission_systems is not None:
for emission_system in emission_systems:
parasitic_energy_consumption += emission_system.parasitic_energy_consumption
consumption_variable_flow = distribution_system.distribution_consumption_variable_flow
for demand_type in energy_system.demand_types:
if demand_type.lower() == cte.HEATING.lower():
if _peak_load_type == cte.HEATING.lower():
_consumption_fix_flow = distribution_system.distribution_consumption_fix_flow
for heating_demand_key in self.heating_demand:
_consumption = [0]*len(self.heating_demand[heating_demand_key])
_demand = self.heating_demand[heating_demand_key]
for i, _ in enumerate(_consumption):
_consumption[i] += (parasitic_energy_consumption + consumption_variable_flow) * _demand[i]
self._distribution_systems_electrical_consumption[heating_demand_key] = _consumption
if demand_type.lower() == cte.COOLING.lower():
if _peak_load_type == cte.COOLING.lower():
_consumption_fix_flow = distribution_system.distribution_consumption_fix_flow
for demand_key in self.cooling_demand:
_consumption = self._distribution_systems_electrical_consumption[demand_key]
_demand = self.cooling_demand[demand_key]
for i, _ in enumerate(_consumption):
_consumption[i] += (parasitic_energy_consumption + consumption_variable_flow) * _demand[i]
self._distribution_systems_electrical_consumption[demand_key] = _consumption
for key, item in self._distribution_systems_electrical_consumption.items():
for i in range(0, len(item)):
_working_hours_value = _working_hours[key]
if len(item) == 12:
_working_hours_value = _working_hours[key][i]
self._distribution_systems_electrical_consumption[key][i] += (
_peak_load * _consumption_fix_flow * _working_hours_value * cte.WATTS_HOUR_TO_JULES
)
emission_system = energy_system.emission_system.generic_emission_system
parasitic_energy_consumption = 0
if emission_system is not None:
parasitic_energy_consumption = emission_system.parasitic_energy_consumption
distribution_system = energy_system.distribution_system.generic_distribution_system
consumption_variable_flow = distribution_system.distribution_consumption_variable_flow
for demand_type in energy_system.demand_types:
if demand_type.lower() == cte.HEATING.lower():
if _peak_load_type == cte.HEATING.lower():
_consumption_fix_flow = distribution_system.distribution_consumption_fix_flow
for heating_demand_key in self.heating_demand:
_consumption = [0]*len(self.heating_demand[heating_demand_key])
_demand = self.heating_demand[heating_demand_key]
for i, _ in enumerate(_consumption):
_consumption[i] += (parasitic_energy_consumption + consumption_variable_flow) * _demand[i]
self._distribution_systems_electrical_consumption[heating_demand_key] = _consumption
if demand_type.lower() == cte.COOLING.lower():
if _peak_load_type == cte.COOLING.lower():
_consumption_fix_flow = distribution_system.distribution_consumption_fix_flow
for demand_key in self.cooling_demand:
_consumption = self._distribution_systems_electrical_consumption[demand_key]
_demand = self.cooling_demand[demand_key]
for i, _ in enumerate(_consumption):
_consumption[i] += (parasitic_energy_consumption + consumption_variable_flow) * _demand[i]
self._distribution_systems_electrical_consumption[demand_key] = _consumption
for key, item in self._distribution_systems_electrical_consumption.items():
for i in range(0, len(item)):
self._distribution_systems_electrical_consumption[key][i] += _peak_load * _consumption_fix_flow \
* _working_hours
return self._distribution_systems_electrical_consumption
def _calculate_consumption(self, consumption_type, demand):
@ -784,21 +744,15 @@ class Building(CityObject):
if self.energy_systems is None:
return None
for energy_system in self.energy_systems:
generation_systems = energy_system.generation_systems
for demand_type in energy_system.demand_types:
if demand_type.lower() == consumption_type.lower():
if consumption_type in (cte.HEATING, cte.DOMESTIC_HOT_WATER):
for generation_system in generation_systems:
if generation_system.heat_efficiency is not None:
coefficient_of_performance = float(generation_system.heat_efficiency)
coefficient_of_performance = energy_system.generation_system.generic_generation_system.heat_efficiency
elif consumption_type == cte.COOLING:
for generation_system in generation_systems:
if generation_system.cooling_efficiency is not None:
coefficient_of_performance = float(generation_system.cooling_efficiency)
coefficient_of_performance = energy_system.generation_system.generic_generation_system.cooling_efficiency
elif consumption_type == cte.ELECTRICITY:
for generation_system in generation_systems:
if generation_system.electricity_efficiency is not None:
coefficient_of_performance = float(generation_system.electricity_efficiency)
coefficient_of_performance = \
energy_system.generation_system.generic_generation_system.electricity_efficiency
if coefficient_of_performance == 0:
values = [0]*len(demand)
final_energy_consumed = values
@ -829,91 +783,16 @@ class Building(CityObject):
if self.energy_systems is None:
return self._onsite_electrical_production
for energy_system in self.energy_systems:
for generation_system in energy_system.generation_systems:
if generation_system.system_type == cte.PHOTOVOLTAIC:
if generation_system.electricity_efficiency is not None:
_efficiency = float(generation_system.electricity_efficiency)
else:
_efficiency = 0
self._onsite_electrical_production = {}
for _key in self.roofs[0].global_irradiance.keys():
_results = [0 for _ in range(0, len(self.roofs[0].global_irradiance[_key]))]
for surface in self.roofs:
if _key in orientation_losses_factor:
_results = [x + y * _efficiency * surface.perimeter_area
* surface.solar_collectors_area_reduction_factor * z
for x, y, z in zip(_results, surface.global_irradiance[_key],
orientation_losses_factor[_key]['south'])]
self._onsite_electrical_production[_key] = _results
if energy_system.generation_system.generic_generation_system.type == cte.PHOTOVOLTAIC:
_efficiency = energy_system.generation_system.generic_generation_system.electricity_efficiency
self._onsite_electrical_production = {}
for _key in self.roofs[0].global_irradiance.keys():
_results = [0 for _ in range(0, len(self.roofs[0].global_irradiance[_key]))]
for surface in self.roofs:
if _key in orientation_losses_factor:
_results = [x + y * _efficiency * surface.perimeter_area
* surface.solar_collectors_area_reduction_factor * z
for x, y, z in zip(_results, surface.global_irradiance[_key],
orientation_losses_factor[_key]['south'])]
self._onsite_electrical_production[_key] = _results
return self._onsite_electrical_production
@property
def lower_corner(self):
"""
Get building lower corner.
"""
return [self._min_x, self._min_y, self._min_z]
@property
def upper_corner(self):
"""
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

View File

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

View File

@ -16,7 +16,7 @@ class Layer:
def __init__(self):
self._thickness = None
self._id = None
self._material_name = None
self._name = None
self._conductivity = None
self._specific_heat = None
self._density = None
@ -54,20 +54,20 @@ class Layer:
self._thickness = float(value)
@property
def material_name(self):
def name(self):
"""
Get material name
:return: str
"""
return self._material_name
return self._name
@material_name.setter
def material_name(self, value):
@name.setter
def name(self, value):
"""
Set material name
:param value: string
"""
self._material_name = str(value)
self._name = str(value)
@property
def conductivity(self) -> Union[None, float]:

View File

@ -18,7 +18,6 @@ from hub.city_model_structure.attributes.point import Point
from hub.city_model_structure.greenery.vegetation import Vegetation
from hub.city_model_structure.building_demand.thermal_boundary import ThermalBoundary
import hub.helpers.constants as cte
from hub.helpers.configuration_helper import ConfigurationHelper
class Surface:
@ -42,12 +41,10 @@ class Surface:
self._short_wave_reflectance = None
self._long_wave_emittance = None
self._inverse = None
self._associated_thermal_boundaries = None
self._associated_thermal_boundaries = []
self._vegetation = None
self._percentage_shared = None
self._solar_collectors_area_reduction_factor = None
self._global_irradiance_tilted = {}
self._installed_solar_collector_area = None
@property
def name(self):
@ -157,6 +154,7 @@ class Surface:
if self._inclination is None:
self._inclination = np.arccos(self.perimeter_polygon.normal[2])
return self._inclination
@property
def type(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

View File

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

View File

@ -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):
"""

View File

@ -14,7 +14,6 @@ import math
import pickle
import sys
import pathlib
import os
from pathlib import Path
from typing import List, Union
@ -62,6 +61,7 @@ class City:
self._level_of_detail = LevelOfDetail()
self._city_objects_dictionary = {}
self._city_objects_alias_dictionary = {}
self._energy_systems_connection_table = None
self._generic_energy_systems = None
def _get_location(self) -> Location:
@ -299,20 +299,6 @@ class City:
with open(city_filename, 'rb') as file:
return pickle.load(file)
@staticmethod
def load_compressed(compressed_city_filename, destination_filename) -> City:
"""
Load a city from compressed_city_filename
:param compressed_city_filename: Compressed pickle as source
:param destination_filename: Pickle file as destination
:return: City
"""
with open(str(compressed_city_filename), 'rb') as source, open(str(destination_filename), 'wb') as destination:
destination.write(bz2.decompress(source.read()))
loaded_city = City.load(destination_filename)
os.unlink(destination_filename)
return loaded_city
def save(self, city_filename):
"""
Save a city into the given filename
@ -504,6 +490,24 @@ class City:
"""
return self._level_of_detail
@property
def energy_systems_connection_table(self) -> Union[None, DataFrame]:
"""
Get energy systems connection table which includes at least two columns: energy_system_type and associated_building
and may also include dimensioned_energy_system and connection_building_to_dimensioned_energy_system
:return: DataFrame
"""
return self._energy_systems_connection_table
@energy_systems_connection_table.setter
def energy_systems_connection_table(self, value):
"""
Set energy systems connection table which includes at least two columns: energy_system_type and associated_building
and may also include dimensioned_energy_system and connection_building_to_dimensioned_energy_system
:param value: DataFrame
"""
self._energy_systems_connection_table = value
@property
def generic_energy_systems(self) -> dict:
"""

View File

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

View File

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

View File

@ -1,104 +0,0 @@
"""
Electrical storage system
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from hub.city_model_structure.energy_systems.energy_storage_system import EnergyStorageSystem
class ElectricalStorageSystem(EnergyStorageSystem):
""""
Electrical Storage System Class
"""
def __init__(self):
super().__init__()
self._rated_output_power = None
self._nominal_efficiency = None
self._battery_voltage = None
self._depth_of_discharge = None
self._self_discharge_rate = None
@property
def rated_output_power(self):
"""
Get the rated output power of storage system in Watts
:return: float
"""
return self._rated_output_power
@rated_output_power.setter
def rated_output_power(self, value):
"""
Set the rated output power of storage system in Watts
:param value: float
"""
self._rated_output_power = value
@property
def nominal_efficiency(self):
"""
Get the nominal efficiency of the storage system
:return: float
"""
return self._nominal_efficiency
@nominal_efficiency.setter
def nominal_efficiency(self, value):
"""
Set the nominal efficiency of the storage system
:param value: float
"""
self._nominal_efficiency = value
@property
def battery_voltage(self):
"""
Get the battery voltage in Volts
:return: float
"""
return self._battery_voltage
@battery_voltage.setter
def battery_voltage(self, value):
"""
Set the battery voltage in Volts
:param value: float
"""
self._battery_voltage = value
@property
def depth_of_discharge(self):
"""
Get the depth of discharge as a percentage
:return: float
"""
return self._depth_of_discharge
@depth_of_discharge.setter
def depth_of_discharge(self, value):
"""
Set the depth of discharge as a percentage
:param value: float
"""
self._depth_of_discharge = value
@property
def self_discharge_rate(self):
"""
Get the self discharge rate of battery as a percentage
:return: float
"""
return self._self_discharge_rate
@self_discharge_rate.setter
def self_discharge_rate(self, value):
"""
Set the self discharge rate of battery as a percentage
:param value: float
"""
self._self_discharge_rate = value

View File

@ -1,64 +1,32 @@
"""
Emission system module
Energy emission system definition
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from hub.city_model_structure.energy_systems.generic_emission_system import GenericEmissionSystem
class EmissionSystem:
"""
EmissionSystem class
"""
def __init__(self):
self._model_name = None
self._type = None
self._parasitic_energy_consumption = 0
self._generic_emission_system = None
@property
def model_name(self):
def generic_emission_system(self) -> GenericEmissionSystem:
"""
Get model name
:return: string
Get associated generic_emission_system
:return: GenericEmissionSystem
"""
return self._model_name
return self._generic_emission_system
@model_name.setter
def model_name(self, value):
@generic_emission_system.setter
def generic_emission_system(self, value):
"""
Set model name
:param value: string
Set associated
:param value: GenericEmissionSystem
"""
self._model_name = value
@property
def type(self):
"""
Get type
:return: string
"""
return self._type
@type.setter
def type(self, value):
"""
Set type
:param value: string
"""
self._type = value
@property
def parasitic_energy_consumption(self):
"""
Get parasitic_energy_consumption in ratio (W/W)
:return: float
"""
return self._parasitic_energy_consumption
@parasitic_energy_consumption.setter
def parasitic_energy_consumption(self, value):
"""
Set parasitic_energy_consumption in ratio (W/W)
:param value: float
"""
self._parasitic_energy_consumption = value
self._generic_emission_system = value

View File

@ -1,118 +0,0 @@
"""
Energy storage system. Abstract class
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from abc import ABC
class EnergyStorageSystem(ABC):
"""
Energy storage System class
"""
def __init__(self):
self._type_energy_stored = None
self._storage_type = None
self._model_name = None
self._manufacturer = None
self._nominal_capacity = None
self._losses_ratio = None
@property
def type_energy_stored(self):
"""
Get type of energy stored from ['electrical', 'thermal']
:return: string
"""
return self._type_energy_stored
@type_energy_stored.setter
def type_energy_stored(self, value):
"""
Set type of energy stored from ['electrical', 'thermal']
:return: string
"""
self._type_energy_stored = value
@property
def storage_type(self):
"""
Get storage type
:return: string
"""
return self._storage_type
@storage_type.setter
def storage_type(self, value):
"""
Get storage type
:param value: string
"""
self._storage_type = value
@property
def model_name(self):
"""
Get system model
:return: string
"""
return self._model_name
@model_name.setter
def model_name(self, value):
"""
Set system model
:param value: string
"""
self._model_name = value
@property
def manufacturer(self):
"""
Get name of manufacturer
:return: string
"""
return self._manufacturer
@manufacturer.setter
def manufacturer(self, value):
"""
Set name of manufacturer
:param value: string
"""
self._manufacturer = value
@property
def nominal_capacity(self):
"""
Get the nominal capacity of storage systems in Jules
:return: float
"""
return self._nominal_capacity
@nominal_capacity.setter
def nominal_capacity(self, value):
"""
Set the nominal capacity of storage systems in Jules
:return: float
"""
self._nominal_capacity = value
@property
def losses_ratio(self):
"""
Get the losses-ratio of storage system in Jules lost / Jules stored
:return: float
"""
return self._losses_ratio
@losses_ratio.setter
def losses_ratio(self, value):
"""
Set the losses-ratio of storage system in Jules lost / Jules stored
:return: float
"""
self._losses_ratio = value

View File

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

View File

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

View File

@ -0,0 +1,100 @@
"""
Generic energy distribution system definition
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
class GenericDistributionSystem:
"""
GenericDistributionSystem class
"""
def __init__(self):
self._type = None
self._supply_temperature = None
self._distribution_consumption_fix_flow = None
self._distribution_consumption_variable_flow = None
self._heat_losses = None
@property
def type(self):
"""
Get type from [air, water, refrigerant]
:return: string
"""
return self._type
@type.setter
def type(self, value):
"""
Set type from [air, water, refrigerant]
:param value: string
"""
self._type = value
@property
def supply_temperature(self):
"""
Get supply_temperature in degree Celsius
:return: float
"""
return self._supply_temperature
@supply_temperature.setter
def supply_temperature(self, value):
"""
Set supply_temperature in degree Celsius
:param value: float
"""
self._supply_temperature = value
@property
def distribution_consumption_fix_flow(self):
"""
Get distribution_consumption if the pump or fan work at fix mass or volume flow in ratio over peak power (W/W)
:return: float
"""
return self._distribution_consumption_fix_flow
@distribution_consumption_fix_flow.setter
def distribution_consumption_fix_flow(self, value):
"""
Set distribution_consumption if the pump or fan work at fix mass or volume flow in ratio over peak power (W/W)
:return: float
"""
self._distribution_consumption_fix_flow = value
@property
def distribution_consumption_variable_flow(self):
"""
Get distribution_consumption if the pump or fan work at variable mass or volume flow in ratio
over energy produced (J/J)
:return: float
"""
return self._distribution_consumption_variable_flow
@distribution_consumption_variable_flow.setter
def distribution_consumption_variable_flow(self, value):
"""
Set distribution_consumption if the pump or fan work at variable mass or volume flow in ratio
over energy produced (J/J)
:return: float
"""
self._distribution_consumption_variable_flow = value
@property
def heat_losses(self):
"""
Get heat_losses in ratio over energy produced
:return: float
"""
return self._heat_losses
@heat_losses.setter
def heat_losses(self, value):
"""
Set heat_losses in ratio over energy produced
:param value: float
"""
self._heat_losses = value

View File

@ -0,0 +1,30 @@
"""
Generic energy emission system module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
class GenericEmissionSystem:
"""
GenericEmissionSystem class
"""
def __init__(self):
self._parasitic_energy_consumption = None
@property
def parasitic_energy_consumption(self):
"""
Get parasitic_energy_consumption in ratio (W/W)
:return: float
"""
return self._parasitic_energy_consumption
@parasitic_energy_consumption.setter
def parasitic_energy_consumption(self, value):
"""
Set parasitic_energy_consumption in ratio (W/W)
:param value: float
"""
self._parasitic_energy_consumption = value

View File

@ -0,0 +1,105 @@
"""
Generic energy system definition
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import Union
from hub.city_model_structure.energy_systems.generic_distribution_system import GenericDistributionSystem
from hub.city_model_structure.energy_systems.generic_emission_system import GenericEmissionSystem
from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem
class GenericEnergySystem:
"""
GenericEnergySystem class
"""
def __init__(self):
self._name = None
self._demand_types = None
self._generation_system = None
self._distribution_system = None
self._emission_system = None
self._connected_city_objects = None
@property
def name(self):
"""
Get energy system name
:return: str
"""
return self._name
@name.setter
def name(self, value):
"""
Set energy system name
:param value:
"""
self._name = value
@property
def demand_types(self):
"""
Get demand able to cover from [Heating, Cooling, Domestic Hot Water, Electricity]
:return: [string]
"""
return self._demand_types
@demand_types.setter
def demand_types(self, value):
"""
Set demand able to cover from [Heating, Cooling, Domestic Hot Water, Electricity]
:param value: [string]
"""
self._demand_types = value
@property
def generation_system(self) -> GenericGenerationSystem:
"""
Get generation system
:return: GenerationSystem
"""
return self._generation_system
@generation_system.setter
def generation_system(self, value):
"""
Set generation system
:return: GenerationSystem
"""
self._generation_system = value
@property
def distribution_system(self) -> Union[None, GenericDistributionSystem]:
"""
Get distribution system
:return: DistributionSystem
"""
return self._distribution_system
@distribution_system.setter
def distribution_system(self, value):
"""
Set distribution system
:param value: DistributionSystem
"""
self._distribution_system = value
@property
def emission_system(self) -> Union[None, GenericEmissionSystem]:
"""
Get emission system
:return: EmissionSystem
"""
return self._emission_system
@emission_system.setter
def emission_system(self, value):
"""
Set emission system
:param value: EmissionSystem
"""
self._emission_system = value

View File

@ -0,0 +1,186 @@
"""
Generic energy generation system definition
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from __future__ import annotations
from typing import Union
class GenericGenerationSystem:
"""
GenericGenerationSystem class
"""
def __init__(self):
self._type = None
self._fuel_type = None
self._source_types = None
self._heat_efficiency = None
self._cooling_efficiency = None
self._electricity_efficiency = None
self._source_temperature = None
self._source_mass_flow = None
self._storage = None
self._auxiliary_equipment = None
@property
def type(self):
"""
Get system type
:return: string
"""
return self._type
@type.setter
def type(self, value):
"""
Set system type
:param value: string
"""
self._type = value
@property
def fuel_type(self):
"""
Get fuel_type from [Renewable, Gas, Diesel, Electricity, Wood, Coal]
:return: string
"""
return self._fuel_type
@fuel_type.setter
def fuel_type(self, value):
"""
Set fuel_type from [Renewable, Gas, Diesel, Electricity, Wood, Coal]
:param value: string
"""
self._fuel_type = value
@property
def source_types(self):
"""
Get source_type from [Air, Water, Geothermal, District Heating, Grid, Onsite Electricity]
:return: [string]
"""
return self._source_types
@source_types.setter
def source_types(self, value):
"""
Set source_type from [Air, Water, Geothermal, District Heating, Grid, Onsite Electricity]
:param value: [string]
"""
self._source_types = value
@property
def heat_efficiency(self):
"""
Get heat_efficiency
:return: float
"""
return self._heat_efficiency
@heat_efficiency.setter
def heat_efficiency(self, value):
"""
Set heat_efficiency
:param value: float
"""
self._heat_efficiency = value
@property
def cooling_efficiency(self):
"""
Get cooling_efficiency
:return: float
"""
return self._cooling_efficiency
@cooling_efficiency.setter
def cooling_efficiency(self, value):
"""
Set cooling_efficiency
:param value: float
"""
self._cooling_efficiency = value
@property
def electricity_efficiency(self):
"""
Get electricity_efficiency
:return: float
"""
return self._electricity_efficiency
@electricity_efficiency.setter
def electricity_efficiency(self, value):
"""
Set electricity_efficiency
:param value: float
"""
self._electricity_efficiency = value
@property
def source_temperature(self):
"""
Get source_temperature in degree Celsius
:return: float
"""
return self._source_temperature
@source_temperature.setter
def source_temperature(self, value):
"""
Set source_temperature in degree Celsius
:param value: float
"""
self._source_temperature = value
@property
def source_mass_flow(self):
"""
Get source_mass_flow in kg/s
:return: float
"""
return self._source_mass_flow
@source_mass_flow.setter
def source_mass_flow(self, value):
"""
Set source_mass_flow in kg/s
:param value: float
"""
self._source_mass_flow = value
@property
def storage(self):
"""
Get boolean storage exists
:return: bool
"""
return self._storage
@storage.setter
def storage(self, value):
"""
Set boolean storage exists
:return: bool
"""
self._storage = value
@property
def auxiliary_equipment(self) -> Union[None, GenericGenerationSystem]:
"""
Get auxiliary_equipment
:return: GenerationSystem
"""
return self._auxiliary_equipment
@auxiliary_equipment.setter
def auxiliary_equipment(self, value):
"""
Set auxiliary_equipment
:return: GenerationSystem
"""
self._auxiliary_equipment = value

View File

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

View File

@ -0,0 +1,32 @@
"""
HvacTerminalUnit module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from typing import Union
class HvacTerminalUnit:
"""
HvacTerminalUnit class
"""
def __init__(self):
self._type = None
@property
def type(self) -> Union[None, str]:
"""
Get type of hvac terminal unit defined for a thermal zone
:return: None or str
"""
return self._type
@type.setter
def type(self, value):
"""
Set type of hvac terminal unit defined for a thermal zone
:param value: str
"""
if value is not None:
self._type = str(value)

View File

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

View File

@ -1,104 +0,0 @@
"""
Energy System catalog heat generation system
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
from __future__ import annotations
class PerformanceCurves:
"""
Parameter function class
"""
def __init__(self):
self._curve_type = None
self._dependant_variable = None
self._parameters = None
self._coefficients = None
@property
def curve_type(self):
"""
Get the type of the fit function from the following
Linear =>>> y = a + b*x
Exponential =>>> y = a*(b**x)
Second degree polynomial =>>> y = a + b*x + c*(x**2)
Power =>>> y = a*(x**b)
Bi-Quadratic =>>> y = a + b*x + c*(x**2) + d*z + e*(z**2) + f*x*z
Get the type of function from ['linear', 'exponential', 'second degree polynomial', 'power', 'bi-quadratic']
:return: string
"""
return self._curve_type
@curve_type.setter
def curve_type(self, value):
"""
Set the type of the fit function from the following
Linear =>>> y = a + b*x
Exponential =>>> y = a*(b**x)
Second degree polynomial =>>> y = a + b*x + c*(x**2)
Power =>>> y = a*(x**b)
Bi-Quadratic =>>> y = a + b*x + c*(x**2) + d*z + e*(z**2) + f*x*z
Get the type of function from ['linear', 'exponential', 'second degree polynomial', 'power', 'bi-quadratic']
:return: string
"""
self._curve_type = value
@property
def dependant_variable(self):
"""
Get y (e.g. COP in COP = a*source temperature**2 + b*source temperature + c*source temperature*supply temperature +
d*supply temperature + e*supply temperature**2 + f)
"""
return self._dependant_variable
@dependant_variable.setter
def dependant_variable(self, value):
"""
Set y (e.g. COP in COP = a*source temperature**2 + b*source temperature + c*source temperature*supply temperature +
d*supply temperature + e*supply temperature**2 + f)
"""
self._dependant_variable = value
@property
def parameters(self):
"""
Get the list of parameters involved in fitting process as ['x', 'z'] (e.g. [source temperature, supply temperature]
in COP= *source temperature**2 + b*source temperature + c*source temperature*supply temperature +
d*supply temperature + e*supply temperature**2 + f)
:return: string
"""
return self._parameters
@parameters.setter
def parameters(self, value):
"""
Set the list of parameters involved in fitting process as ['x', 'z'] (e.g. [source temperature, supply temperature]
in COP= *source temperature**2 + b*source temperature + c*source temperature*supply temperature +
d*supply temperature + e*supply temperature**2 + f)
:return: string
"""
self._parameters = value
@property
def coefficients(self):
"""
Get the coefficients of the functions as list of ['a', 'b', 'c', 'd', 'e', 'f']
:return: [coefficients]
"""
return self._coefficients
@coefficients.setter
def coefficients(self, value):
"""
Set the coefficients of the functions as list of ['a', 'b', 'c', 'd', 'e', 'f']
:return: [coefficients]
"""
self._coefficients = value

View File

@ -1,257 +0,0 @@
"""
PV energy generation system
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
from hub.city_model_structure.energy_systems.generation_system import GenerationSystem
class PvGenerationSystem(GenerationSystem):
"""
PvGenerationSystem class
"""
def __init__(self):
super().__init__()
self._electricity_efficiency = None
self._nominal_electricity_output = None
self._nominal_ambient_temperature = None
self._nominal_cell_temperature = None
self._nominal_radiation = None
self._standard_test_condition_cell_temperature = None
self._standard_test_condition_maximum_power = None
self._standard_test_condition_radiation = None
self._cell_temperature_coefficient = None
self._width = None
self._height = None
self._electricity_power_output = {}
self._tilt_angle = None
self._surface_azimuth = None
self._solar_altitude_angle = None
self._solar_azimuth_angle = None
@property
def nominal_electricity_output(self):
"""
Get nominal_power_output of electricity generation devices or inverters in W
:return: float
"""
return self._nominal_electricity_output
@nominal_electricity_output.setter
def nominal_electricity_output(self, value):
"""
Set nominal_power_output of electricity generation devices or inverters in W
:param value: float
"""
self._nominal_electricity_output = value
@property
def electricity_efficiency(self):
"""
Get electricity_efficiency
:return: float
"""
return self._electricity_efficiency
@electricity_efficiency.setter
def electricity_efficiency(self, value):
"""
Set electricity_efficiency
:param value: float
"""
self._electricity_efficiency = value
@property
def nominal_ambient_temperature(self):
"""
Get nominal ambient temperature of PV panels in degree Celsius
:return: float
"""
return self._nominal_ambient_temperature
@nominal_ambient_temperature.setter
def nominal_ambient_temperature(self, value):
"""
Set nominal ambient temperature of PV panels in degree Celsius
:param value: float
"""
self._nominal_ambient_temperature = value
@property
def nominal_cell_temperature(self):
"""
Get nominal cell temperature of PV panels in degree Celsius
:return: float
"""
return self._nominal_cell_temperature
@nominal_cell_temperature.setter
def nominal_cell_temperature(self, value):
"""
Set nominal cell temperature of PV panels in degree Celsius
:param value: float
"""
self._nominal_cell_temperature = value
@property
def nominal_radiation(self):
"""
Get nominal radiation of PV panels
:return: float
"""
return self._nominal_radiation
@nominal_radiation.setter
def nominal_radiation(self, value):
"""
Set nominal radiation of PV panels
:param value: float
"""
self._nominal_radiation = value
@property
def standard_test_condition_cell_temperature(self):
"""
Get standard test condition cell temperature of PV panels in degree Celsius
:return: float
"""
return self._standard_test_condition_cell_temperature
@standard_test_condition_cell_temperature.setter
def standard_test_condition_cell_temperature(self, value):
"""
Set standard test condition cell temperature of PV panels in degree Celsius
:param value: float
"""
self._standard_test_condition_cell_temperature = value
@property
def standard_test_condition_maximum_power(self):
"""
Get standard test condition maximum power of PV panels in W
:return: float
"""
return self._standard_test_condition_maximum_power
@standard_test_condition_maximum_power.setter
def standard_test_condition_maximum_power(self, value):
"""
Set standard test condition maximum power of PV panels in W
:param value: float
"""
self._standard_test_condition_maximum_power = value
@property
def standard_test_condition_radiation(self):
"""
Get standard test condition radiation in W/m2
:return: float
"""
return self._standard_test_condition_radiation
@standard_test_condition_radiation.setter
def standard_test_condition_radiation(self, value):
"""
Set standard test condition radiation in W/m2
:param value: float
"""
self._standard_test_condition_radiation = value
@property
def cell_temperature_coefficient(self):
"""
Get cell temperature coefficient of PV module
:return: float
"""
return self._cell_temperature_coefficient
@cell_temperature_coefficient.setter
def cell_temperature_coefficient(self, value):
"""
Set cell temperature coefficient of PV module
:param value: float
"""
self._cell_temperature_coefficient = value
@property
def width(self):
"""
Get PV module width in m
:return: float
"""
return self._width
@width.setter
def width(self, value):
"""
Set PV module width in m
:param value: float
"""
self._width = value
@property
def height(self):
"""
Get PV module height in m
:return: float
"""
return self._height
@height.setter
def height(self, value):
"""
Set PV module height in m
:param value: float
"""
self._height = value
@property
def electricity_power_output(self):
"""
Get electricity_power in W
:return: float
"""
return self._electricity_power_output
@electricity_power_output.setter
def electricity_power_output(self, value):
"""
Set electricity_power in W
:param value: float
"""
self._electricity_power_output = value
@property
def tilt_angle(self):
"""
Get tilt angle of PV system in degrees
:return: float
"""
return self._tilt_angle
@tilt_angle.setter
def tilt_angle(self, value):
"""
Set PV system tilt angle in degrees
:param value: float
"""
self._tilt_angle = value
@property
def surface_azimuth(self):
"""
Get surface azimuth angle of PV system in degrees. 0 is North
:return: float
"""
return self._surface_azimuth
@surface_azimuth.setter
def surface_azimuth(self, value):
"""
Set PV system tilt angle in degrees
:param value: float
"""
self._surface_azimuth = value

View File

@ -1,139 +0,0 @@
"""
Thermal storage system
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2023 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
from hub.city_model_structure.energy_systems.energy_storage_system import EnergyStorageSystem
from hub.city_model_structure.building_demand.layer import Layer
class ThermalStorageSystem(EnergyStorageSystem):
""""
Thermal Storage System Class
"""
def __init__(self):
super().__init__()
self._volume = None
self._height = None
self._layers = None
self._maximum_operating_temperature = None
self._heating_coil_capacity = None
self._temperature = None
self._heating_coil_energy_consumption = None
@property
def volume(self):
"""
Get the physical volume of the storage system in cubic meters
:return: float
"""
return self._volume
@volume.setter
def volume(self, value):
"""
Set the physical volume of the storage system in cubic meters
:param value: float
"""
self._volume = value
@property
def height(self):
"""
Get the diameter of the storage system in meters
:return: float
"""
return self._height
@height.setter
def height(self, value):
"""
Set the diameter of the storage system in meters
:param value: float
"""
self._height = value
@property
def layers(self) -> [Layer]:
"""
Get construction layers
:return: [layer]
"""
return self._layers
@layers.setter
def layers(self, value):
"""
Set construction layers
:param value: [layer]
"""
self._layers = value
@property
def maximum_operating_temperature(self):
"""
Get maximum operating temperature of the storage system in degree Celsius
:return: float
"""
return self._maximum_operating_temperature
@maximum_operating_temperature.setter
def maximum_operating_temperature(self, value):
"""
Set maximum operating temperature of the storage system in degree Celsius
:param value: float
"""
self._maximum_operating_temperature = value
@property
def heating_coil_capacity(self):
"""
Get heating coil capacity in Watts
:return: float
"""
return self._heating_coil_capacity
@heating_coil_capacity.setter
def heating_coil_capacity(self, value):
"""
Set heating coil capacity in Watts
:param value: float
"""
self._heating_coil_capacity = value
@property
def temperature(self) -> dict:
"""
Get fuel consumption in W, m3, or kg
:return: dict{[float]}
"""
return self._temperature
@temperature.setter
def temperature(self, value):
"""
Set fuel consumption in W, m3, or kg
:param value: dict{[float]}
"""
self._temperature = value
@property
def heating_coil_energy_consumption(self) -> dict:
"""
Get fuel consumption in W, m3, or kg
:return: dict{[float]}
"""
return self._heating_coil_energy_consumption
@heating_coil_energy_consumption.setter
def heating_coil_energy_consumption(self, value):
"""
Set fuel consumption in W, m3, or kg
:param value: dict{[float]}
"""
self._heating_coil_energy_consumption = value

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,227 @@
<?xml version="1.0" encoding="UTF-8"?>
<EnergySystemCatalog>
<schemas_path>./schemas/</schemas_path>
<medias>
<media media_id="1" media_name="Water" density="981.0" heatCapacity="4180.0" evaporationTemperature="100.0"/>
</medias>
<energy_generation_components>
<boilers generation_id="1" name="Natural-Gas Boiler" modelName="ALP080B" manufacturer="Alpine" installedThermalPower="21.0" minimumHeatOutput="4.7" maximumHeatOutput="23.5" modulationRange="0.88" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="2" name="Natural-Gas Boiler" modelName="ALP105B" manufacturer="Alpine" installedThermalPower="28.0" minimumHeatOutput="6.15" maximumHeatOutput="30.8" modulationRange="0.88" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="3" name="Natural-Gas Boiler" modelName="ALP150B" manufacturer="Alpine" installedThermalPower="40.0" minimumHeatOutput="8.8" maximumHeatOutput="44" modulationRange="0.88" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="4" name="Natural-Gas Boiler" modelName="ALP210B" manufacturer="Alpine" installedThermalPower="57.0" minimumHeatOutput="12.3" maximumHeatOutput="61.5" modulationRange="0.87" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="5" name="Natural-Gas Boiler" modelName="ALTAC-136" manufacturer="Alta" installedThermalPower="33.0" minimumHeatOutput="4.0" maximumHeatOutput="35.2" modulationRange="0.95" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="6" name="Natural-Gas Boiler" modelName="ALTA-120" manufacturer="Alta" installedThermalPower="33.0" minimumHeatOutput="4.0" maximumHeatOutput="35.2" modulationRange="0.95" nominalEfficiency="0.95" combi="false" fuel="natural gas"/>
<boilers generation_id="7" name="Natural-Gas Boiler" modelName="ASPN-085" manufacturer="Aspen" installedThermalPower="23.15" minimumHeatOutput="2.5" maximumHeatOutput="25.0" modulationRange="0.97" nominalEfficiency="0.96" fuel="natural gas"/>
<boilers generation_id="8" name="Natural-Gas Boiler" modelName="ASPN-110" manufacturer="Aspen" installedThermalPower="30.19" minimumHeatOutput="3.2" maximumHeatOutput="32.0" modulationRange="0.96" nominalEfficiency="0.96" fuel="natural gas"/>
<boilers generation_id="9" name="Natural-Gas Boiler" modelName="ASPNC-155" manufacturer="Aspen" installedThermalPower="42.5" minimumHeatOutput="4.5" maximumHeatOutput="45.0" modulationRange="0.96" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="10" name="Natural-Gas Boiler" modelName="K2WTC-135B" manufacturer="K2" installedThermalPower="32.8" minimumHeatOutput="3.5" maximumHeatOutput="35.0" modulationRange="0.96" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<boilers generation_id="11" name="Natural-Gas Boiler" modelName="K2WTC-180B" manufacturer="K2" installedThermalPower="49.5" minimumHeatOutput="5.3" maximumHeatOutput="53.0" modulationRange="0.96" nominalEfficiency="0.95" combi="true" fuel="natural gas"/>
<photovoltaicModules generation_id="12" name="Photovoltaic Module" modelName="445MS" manufacturer="Canadian Solar" nominalPower="334.0" nominalEfficiency="0.201" nominalRadiation="800.0" STCRadiation="1000.0" nominalCellTemperature="41.0" STCCellTemperature="26.0" nominalAmbientTemperature="20.0" STCMaxPower="445.0" CellTemperatureCoefficient="-0.0034" height="1.048" width="2.01"/>
<heatPumps generation_id="13" name="Air-to-Water Heat Pump" modelName="CMAA 012" description="A second degree equation is used in form of A*T_source^2 + B*T_source + C*T_source*T_sup + D*T_sup + E*T_sup^2 + F" manufacturer="TRANE" installedThermalPower="51.7" minimumHeatOutput="0" maximumHeatOutput="51.7" modulationRange="0.0" fuel="Electricity" heatSource="Air" nominalCOP="3.32" maxHeatingSupTemperature="55.0" minHeatingSupTemperature="6.0" maxCoolingSupTemperature="30.0" minCoolingSupTemperature="11.0" supply_medium="water">
<performance_curve curve_type="second degree multivariable function">
<dependant_variable>COP</dependant_variable>
<parameters>source_temperature</parameters>
<parameters>supply_temperature</parameters>
<coefficients a="9.5E-4" b="0.177" c="-0.00242" d="-0.155" e="9.3E-4" f="8.044"/>
</performance_curve>
</heatPumps>
<heatPumps generation_id="14" name="Air-to-Water Heat Pump" modelName="CMAA 70" description="A second degree equation is used in form of A*T_source^2 + B*T_source + C*T_source*T_sup + D*T_sup + E*T_sup^2 + F" manufacturer="TRANE" installedThermalPower="279.3" minimumHeatOutput="0" maximumHeatOutput="279.3" modulationRange="0.0" fuel="Electricity" heatSource="Air" nominalCOP="3.07" maxHeatingSupTemperature="55.0" minHeatingSupTemperature="6.0" maxCoolingSupTemperature="30.0" minCoolingSupTemperature="11.0" supply_medium="water">
<performance_curve curve_type="second degree multivariable function">
<dependant_variable>COP</dependant_variable>
<parameters>source_temperature</parameters>
<parameters>supply_temperature</parameters>
<coefficients a="0.0011" b="0.207" c="-0.00292" d="-0.187" e="0.00121" f="8.95"/>
</performance_curve>
</heatPumps>
<heatPumps generation_id="15" name="Air-to-Water Heat Pump" modelName="CMAA 140" description="A second degree equation is used in form of A*T_source^2 + B*T_source + C*T_source*T_sup + D*T_sup + E*T_sup^2 + F" manufacturer="TRANE" installedThermalPower="557" minimumHeatOutput="0" maximumHeatOutput="557" modulationRange="0.0" fuel="Electricity" heatSource="Air" nominalCOP="3.46" maxHeatingSupTemperature="55.0" minHeatingSupTemperature="6.0" maxCoolingSupTemperature="30.0" minCoolingSupTemperature="11.0" supply_medium="water">
<performance_curve curve_type="second degree multivariable function">
<dependant_variable>COP</dependant_variable>
<parameters>source_temperature</parameters>
<parameters>supply_temperature</parameters>
<coefficients a="0.00109" b="0.209" c="-0.00291" d="-0.172" e="0.00102" f="8.95"/>
</performance_curve>
</heatPumps>
<templateGenerationEquipments generation_id="16" name="template Natural-Gas Boiler" nominalEfficiency="0.90" fuel="natural gas"/>
<templateGenerationEquipments generation_id="17" name="template Electric Boiler" nominalEfficiency="0.95" fuel="electricity"/>
<templateGenerationEquipments generation_id="18" name="template Air-to-Water Heat Pump" fuel="Electricity" heatSource="Air" nominalCOP="3" supply_medium="water"/>
<templateGenerationEquipments generation_id="19" name="template Groundwater-to-Water Heat Pump" fuel="Electricity" heatSource="Ground" nominalCOP="3.5" supply_medium="water"/>
<templateGenerationEquipments generation_id="20" name="template Water-to-Water Heat Pump" fuel="Electricity" heatSource="Water" nominalCOP="3.5" supply_medium="water"/>
<templateGenerationEquipments generation_id="21" name="template Photovoltaic Module" nominalEfficiency="0.2" width="1.0" height="1.0"/>
<manufacturers manufacturer_id="1" name="Alpine" country="USA" product="Natural Gas Boiler"/>
<manufacturers manufacturer_id="2" name="Alta" country="USA" product="Natural Gas Boiler"/>
<manufacturers manufacturer_id="3" name="Aspen" country="USA" product="Natural Gas Boiler"/>
<manufacturers manufacturer_id="4" name="K2" country="USA" product="Natural Gas Boiler"/>
<manufacturers manufacturer_id="5" name="TRANE" product="Air-to-Water Heat Pump"/>
<manufacturers manufacturer_id="6" name="Canadian Solar" country="Canada" product="Photovoltaic Module"/>
</energy_generation_components>
<energy_storage_components>
<thermalStorages storage_id="1" name="Hot Water Storage Tank" modelName="HF 200" manufacturer="reflex" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel" volume="0.5"/>
<medium media_id="1" usesMedium="Water"/>
</thermalStorages>
<thermalStorages storage_id="2" name="Hot Water Storage Tank" modelName="HF 300" manufacturer="reflex" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel" volume="0.6"/>
<medium media_id="1" usesMedium="Water"/>
</thermalStorages>
<thermalStorages storage_id="3" name="Hot Water Storage Tank" modelName="HF 500" manufacturer="reflex" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel" volume="0.5"/>
<medium media_id="1" usesMedium="Water"/>
</thermalStorages>
<thermalStorages storage_id="4" name="Hot Water Storage Tank" modelName="HF 200" manufacturer="reflex" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel" volume="0.5"/>
<medium media_id="1" usesMedium="Water"/>
</thermalStorages>
<thermalStorages storage_id="5" name="Hot Water Storage Tank" modelName="HF 200" manufacturer="reflex" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel" volume="0.5"/>
<medium media_id="1" usesMedium="Water"/>
</thermalStorages>
<templateStorages storage_id="6" name="template Hot Water Storage Tank" maxTemp="95.0">
<insulation material_id="1" insulationMaterial="Polyurethane" insulationThickness="90.0"/>
<physical_characteristics material_id="2" tankThickness="0" height="1.5" tankMaterial="Steel"/>
<medium media_id="1" usesMedium="Water"/>
</templateStorages>
<manufacturers manufacturer_id="1" name="reflex" product="Storage Tank"/>
</energy_storage_components>
<materials>
<material material_id="1" name="Polyurethane" thermalConductivity="0.028"/>
<material material_id="2" name="Steel" thermalConductivity="18.0"/>
</materials>
<systems>
<system id="1">
<name>Air Source Heat Pump with Natural Gas Boiler and thermal storage</name>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>16</generation_id>
<generation_id>18</generation_id>
<storage_id>6</storage_id>
</components>
</system>
<system id="2">
<name>Air Source Heat Pump with Electrical Boiler and thermal storage</name>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>17</generation_id>
<generation_id>18</generation_id>
<storage_id>6</storage_id>
</components>
</system>
<system id="3">
<name>Ground Source Heat Pump with Natural Gas Boiler and thermal storage</name>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>16</generation_id>
<generation_id>19</generation_id>
<storage_id>6</storage_id>
</components>
</system>
<system id="4">
<name>Ground Source Heat Pump with Electrical Boiler and thermal storage</name>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>17</generation_id>
<generation_id>19</generation_id>
<storage_id>6</storage_id>
</components>
</system>
<system id="5">
<name>Water Source Heat Pump with Natural Gas Boiler and thermal storage</name>
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>16</generation_id>
<generation_id>20</generation_id>
<storage_id>6</storage_id>
</components>
</system>
<system id="6">
<name>Water Source Heat Pump with Electrical Boiler and thermal storage</name>\
<demands>
<demand>heating</demand>
<demand>domestic_hot_water</demand>
</demands>
<components>
<generation_id>17</generation_id>
<generation_id>20</generation_id>
<storage_id>6</storage_id>
</components>
</system>
<system id="7">
<name>Photovoltaic System</name>
<demands>
<demand>electricity</demand>
</demands>
<components>
<generation_id>21</generation_id>
</components>
</system>
</systems>
<system_archetypes>
<system_archetype id="1">
<name>PV+ASHP+GasBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>1</system_id>
</systems>
</system_archetype>
<system_archetype id="2">
<name>PV+ASHP+ElectricBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>2</system_id>
</systems>
</system_archetype>
<system_archetype id="3">
<name>PV+GSHP+GasBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>3</system_id>
</systems>
</system_archetype>
<system_archetype id="4">
<name>PV+GSHP+ElectricBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>4</system_id>
</systems>
</system_archetype>
<system_archetype id="5">
<name>PV+WSHP+GasBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>5</system_id>
</systems>
</system_archetype>
<system_archetype id="6">
<name>PV+WSHP+ElectricBoiler+TES</name>
<systems>
<system_id>7</system_id>
<system_id>6</system_id>
</systems>
</system_archetype>
</system_archetypes>
<energy_demands>
<demand demand_id="1" name="heating"/>
<demand demand_id="2" name="domesticHotWater"/>
<demand demand_id="3" name="electricity"/>
<demand demand_id="4" name="cooling"/>
</energy_demands>
</EnergySystemCatalog>

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

6
hub/data/usage/nrcan.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<nrcan base_url="https://raw.githubusercontent.com/NREL/openstudio-standards/master/lib/openstudio-standards/standards/necb/">
<space_types>NECB2015/data/space_types.json</space_types>
<space_types_compliance>NECB2015/qaqc/qaqc_data/space_compliance_2015.json</space_types_compliance>>
<schedules>NECB2015/data/schedules.json</schedules>
</nrcan>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

View File

@ -7,15 +7,11 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
Oriol Gavalda Torrellas oriol.gavalda@concordia.ca
"""
import copy
import datetime
import glob
import os
from pathlib import Path
from geomeppy import IDF
import hub.helpers.constants as cte
from hub.city_model_structure.attributes.schedule import Schedule
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
from hub.helpers.configuration_helper import ConfigurationHelper
class Idf:
@ -59,6 +55,7 @@ class Idf:
_SIMPLE = 'Simple'
idf_surfaces = {
# todo: make an enum for all the surface types
cte.WALL: 'wall',
cte.GROUND: 'floor',
cte.ROOF: 'roof'
@ -151,20 +148,20 @@ class Idf:
def _add_material(self, layer):
for material in self._idf.idfobjects[self._MATERIAL]:
if material.Name == layer.material_name:
if material.Name == layer.name:
return
for material in self._idf.idfobjects[self._MATERIAL_NOMASS]:
if material.Name == layer.material_name:
if material.Name == layer.name:
return
if layer.no_mass:
self._idf.newidfobject(self._MATERIAL_NOMASS,
Name=layer.material_name,
Name=layer.name,
Roughness=self._ROUGHNESS,
Thermal_Resistance=layer.thermal_resistance
)
else:
self._idf.newidfobject(self._MATERIAL,
Name=layer.material_name,
Name=layer.name,
Roughness=self._ROUGHNESS,
Thickness=layer.thickness,
Conductivity=layer.conductivity,
@ -278,13 +275,12 @@ class Idf:
_kwargs[f'Field_{counter + 2}'] = 'Until: 24:00,0.0'
self._idf.newidfobject(self._COMPACT_SCHEDULE, **_kwargs)
def _write_schedules_file(self, schedule, usage):
file_name = str((Path(self._output_path) / f'{schedule.type} schedules {usage.replace("/","_")}.csv').resolve())
if not Path(file_name).exists():
with open(file_name, 'w', encoding='utf8') as file:
for value in schedule.values:
file.write(f'{str(value)},\n')
return Path(file_name).name
def _write_schedules_file(self, usage, schedule):
file_name = str((Path(self._output_path) / f'{schedule.type} schedules {usage}.dat').resolve())
with open(file_name, 'w', encoding='utf8') as file:
for value in schedule.values:
file.write(f'{str(value)},\n')
return file_name
def _add_file_schedule(self, usage, schedule, file_name):
_schedule = self._idf.newidfobject(self._FILE_SCHEDULE, Name=f'{schedule.type} schedules {usage}')
@ -308,7 +304,7 @@ class Idf:
for schedule in self._idf.idfobjects[self._FILE_SCHEDULE]:
if schedule.Name == f'{schedule_type} schedules {usage}':
return
file_name = self._write_schedules_file(new_schedules[0], usage)
file_name = self._write_schedules_file(usage, new_schedules[0])
self._add_file_schedule(usage, new_schedules[0], file_name)
return
@ -325,13 +321,12 @@ class Idf:
if construction.Name == vegetation_name:
return
else:
if construction.Name == f'{thermal_boundary.construction_name} {thermal_boundary.parent_surface.type}':
if construction.Name == thermal_boundary.construction_name:
return
if thermal_boundary.layers is None:
for material in self._idf.idfobjects[self._MATERIAL]:
if material.Name == "DefaultMaterial":
return
self._idf.set_default_constructions()
return
for layer in thermal_boundary.layers:
@ -343,12 +338,11 @@ class Idf:
_kwargs = {'Name': vegetation_name,
'Outside_Layer': thermal_boundary.parent_surface.vegetation.name}
for i in range(0, len(layers) - 1):
_kwargs[f'Layer_{i + 2}'] = layers[i].material_name
_kwargs[f'Layer_{i + 2}'] = layers[i].name
else:
_kwargs = {'Name': f'{thermal_boundary.construction_name} {thermal_boundary.parent_surface.type}',
'Outside_Layer': layers[0].material_name}
_kwargs = {'Name': thermal_boundary.construction_name, 'Outside_Layer': layers[0].name}
for i in range(1, len(layers) - 1):
_kwargs[f'Layer_{i + 1}'] = layers[i].material_name
_kwargs[f'Layer_{i + 1}'] = layers[i].name
self._idf.newidfobject(self._CONSTRUCTION, **_kwargs)
def _add_window_construction_and_material(self, thermal_opening):
@ -393,9 +387,9 @@ class Idf:
thermostat = self._add_thermostat(thermal_zone)
self._idf.newidfobject(self._IDEAL_LOAD_AIR_SYSTEM,
Zone_Name=zone_name,
System_Availability_Schedule_Name=f'Thermostat_availability schedules {thermal_zone.usage_name}',
Heating_Availability_Schedule_Name=f'Thermostat_availability schedules {thermal_zone.usage_name}',
Cooling_Availability_Schedule_Name=f'Thermostat_availability schedules {thermal_zone.usage_name}',
System_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
Heating_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
Cooling_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
Template_Thermostat_Name=thermostat.Name)
def _add_occupancy(self, thermal_zone, zone_name):
@ -409,7 +403,7 @@ class Idf:
self._idf.newidfobject(self._PEOPLE,
Name=f'{zone_name}_occupancy',
Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Zone_or_ZoneList_Name=zone_name,
Number_of_People_Schedule_Name=f'Occupancy schedules {thermal_zone.usage_name}',
Number_of_People_Calculation_Method="People",
Number_of_People=number_of_people,
@ -426,7 +420,7 @@ class Idf:
self._idf.newidfobject(self._LIGHTS,
Name=f'{zone_name}_lights',
Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Zone_or_ZoneList_Name=zone_name,
Schedule_Name=f'Lighting schedules {thermal_zone.usage_name}',
Design_Level_Calculation_Method=method,
Watts_per_Zone_Floor_Area=watts_per_zone_floor_area,
@ -445,7 +439,7 @@ class Idf:
self._idf.newidfobject(self._APPLIANCES,
Fuel_Type=fuel_type,
Name=f'{zone_name}_appliance',
Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Zone_or_ZoneList_Name=zone_name,
Schedule_Name=f'Appliance schedules {thermal_zone.usage_name}',
Design_Level_Calculation_Method=method,
Power_per_Zone_Floor_Area=watts_per_zone_floor_area,
@ -455,39 +449,28 @@ class Idf:
)
def _add_infiltration(self, thermal_zone, zone_name):
schedule = f'INF_CONST schedules {thermal_zone.usage_name}'
schedule = f'Infiltration schedules {thermal_zone.usage_name}'
_infiltration = thermal_zone.infiltration_rate_system_off * cte.HOUR_TO_SECONDS
self._idf.newidfobject(self._INFILTRATION,
Name=f'{zone_name}_infiltration',
Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Zone_or_ZoneList_Name=zone_name,
Schedule_Name=schedule,
Design_Flow_Rate_Calculation_Method='AirChanges/Hour',
Air_Changes_per_Hour=_infiltration
)
def _add_infiltration_surface(self, thermal_zone, zone_name):
schedule = f'INF_CONST schedules {thermal_zone.usage_name}'
_infiltration = thermal_zone.infiltration_rate_area_system_off*1
self._idf.newidfobject(self._INFILTRATION,
Name=f'{zone_name}_infiltration',
Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Schedule_Name=schedule,
Design_Flow_Rate_Calculation_Method='Flow/ExteriorWallArea',
Flow_Rate_per_Exterior_Surface_Area=_infiltration
)
def _add_ventilation(self, thermal_zone, zone_name):
schedule = f'Ventilation schedules {thermal_zone.usage_name}'
_air_change = thermal_zone.mechanical_air_change * cte.HOUR_TO_SECONDS
self._idf.newidfobject(self._VENTILATION,
Name=f'{zone_name}_ventilation',
Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Zone_or_ZoneList_Name=zone_name,
Schedule_Name=schedule,
Design_Flow_Rate_Calculation_Method='AirChanges/Hour',
Air_Changes_per_Hour=_air_change
)
def _add_dhw(self, thermal_zone, zone_name, usage):
def _add_dhw(self, thermal_zone, zone_name):
peak_flow_rate = thermal_zone.domestic_hot_water.peak_flow * thermal_zone.total_floor_area
self._idf.newidfobject(self._DHW,
Name=f'DHW {zone_name}',
@ -495,7 +478,7 @@ class Idf:
Flow_Rate_Fraction_Schedule_Name=f'DHW_prof schedules {thermal_zone.usage_name}',
Target_Temperature_Schedule_Name=f'DHW_temp schedules {thermal_zone.usage_name}',
Hot_Water_Supply_Temperature_Schedule_Name=f'DHW_temp schedules {thermal_zone.usage_name}',
Cold_Water_Supply_Temperature_Schedule_Name=f'cold_temp schedules {usage}',
Cold_Water_Supply_Temperature_Schedule_Name=f'cold_temp schedules {zone_name}',
EndUse_Subcategory=f'DHW {zone_name}',
Zone_Name=zone_name
)
@ -529,25 +512,19 @@ class Idf:
self._rename_building(self._city.name)
self._lod = self._city.level_of_detail.geometry
for building in self._city.buildings:
is_target = building.name in self._target_buildings or building.name in self._adjacent_buildings
for internal_zone in building.internal_zones:
if internal_zone.thermal_zones_from_internal_zones is None:
self._target_buildings.remoidf_surface_typeve(building.name)
is_target = False
continue
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries:
self._add_construction(thermal_boundary)
if thermal_boundary.parent_surface.vegetation is not None:
self._add_vegetation_material(thermal_boundary.parent_surface.vegetation)
for thermal_opening in thermal_boundary.thermal_openings:
self._add_window_construction_and_material(thermal_opening)
if is_target:
start = datetime.datetime.now()
service_temperature = thermal_zone.domestic_hot_water.service_temperature
usage = thermal_zone.usage_name
usage = thermal_zone.usage_name
if building.name in self._target_buildings or building.name in self._adjacent_buildings:
_new_schedules = self._create_infiltration_schedules(thermal_zone)
self._add_schedules(usage, 'Infiltration', _new_schedules)
_new_schedules = self._create_ventilation_schedules(thermal_zone)
@ -559,14 +536,12 @@ class Idf:
self._add_schedules(usage, 'Lighting', thermal_zone.lighting.schedules)
self._add_schedules(usage, 'Appliance', thermal_zone.appliances.schedules)
self._add_schedules(usage, 'DHW_prof', thermal_zone.domestic_hot_water.schedules)
_new_schedules = self._create_yearly_values_schedules('cold_temp', building.cold_water_temperature[cte.HOUR])
self._add_schedules(usage, 'cold_temp', _new_schedules)
_new_schedules = self._create_constant_value_schedules('DHW_temp', service_temperature)
_new_schedules = self._create_yearly_values_schedules('cold_temp',
building.cold_water_temperature[cte.HOUR])
self._add_schedules(building.name, 'cold_temp', _new_schedules)
value = thermal_zone.domestic_hot_water.service_temperature
_new_schedules = self._create_constant_value_schedules('DHW_temp', value)
self._add_schedules(usage, 'DHW_temp', _new_schedules)
_new_schedules = self._create_constant_value_schedules('INF_CONST', 1)
self._add_schedules(usage, 'INF_CONST', _new_schedules)
_new_schedules = self._create_constant_value_schedules('Thermostat_availability', 1)
self._add_schedules(usage, 'Thermostat_availability', _new_schedules)
_occ = thermal_zone.occupancy
if _occ.occupancy_density == 0:
_total_heat = 0
@ -577,18 +552,17 @@ class Idf:
self._add_schedules(usage, 'Activity Level', _new_schedules)
self._add_zone(thermal_zone, building.name)
self._add_heating_system(thermal_zone, building.name)
self._add_infiltration_surface(thermal_zone, building.name)
self._add_infiltration(thermal_zone, building.name)
self._add_ventilation(thermal_zone, building.name)
self._add_occupancy(thermal_zone, building.name)
self._add_lighting(thermal_zone, building.name)
self._add_appliances(thermal_zone, building.name)
self._add_dhw(thermal_zone, building.name, usage)
self._add_dhw(thermal_zone, building.name)
# todo: @Guille: if export_type is not surfaces, we don't differentiate between shadows and buildings?
if self._export_type == "Surfaces":
if is_target:
if building.name in self._target_buildings or building.name in self._adjacent_buildings:
if building.thermal_zones_from_internal_zones is not None:
start = datetime.datetime.now()
self._add_surfaces(building, building.name)
print(f'add surfaces {datetime.datetime.now() - start}')
else:
self._add_pure_geometry(building, building.name)
else:
@ -626,18 +600,6 @@ class Idf:
Reporting_Frequency="Hourly",
)
self._idf.newidfobject(
"OUTPUT:VARIABLE",
Variable_Name="Zone Air Temperature",
Reporting_Frequency="Hourly",
)
self._idf.newidfobject(
"OUTPUT:VARIABLE",
Variable_Name="Zone Air Relative Humidity",
Reporting_Frequency="Hourly",
)
# post-process to erase windows associated to adiabatic walls
windows_list = []
for window in self._idf.idfobjects[self._WINDOW]:
@ -678,26 +640,24 @@ class Idf:
self._idf.intersect_match()
def _add_shading(self, building):
for i, surface in enumerate(building.surfaces):
shading = self._idf.newidfobject(self._SHADING, Name=f'{building.name}_{i}')
for surface in building.surfaces:
shading = self._idf.newidfobject(self._SHADING, Name=f'{surface.name}')
coordinates = self._matrix_to_list(surface.solid_polygon.coordinates,
self._city.lower_corner)
shading.setcoords(coordinates)
solar_reflectance = surface.short_wave_reflectance
if solar_reflectance is None:
solar_reflectance = ConfigurationHelper().short_wave_reflectance
self._idf.newidfobject(self._SHADING_PROPERTY,
Shading_Surface_Name=f'{building.name}_{i}',
Shading_Surface_Name=f'{surface.name}',
Diffuse_Solar_Reflectance_of_Unglazed_Part_of_Shading_Surface=solar_reflectance,
Fraction_of_Shading_Surface_That_Is_Glazed=0)
def _add_pure_geometry(self, building, zone_name):
for index, surface in enumerate(building.surfaces):
for surface in building.surfaces:
outside_boundary_condition = 'Outdoors'
sun_exposure = 'SunExposed'
wind_exposure = 'WindExposed'
idf_surface_type = self.idf_surfaces[surface.type]
_kwargs = {'Name': f'Building_{building.name}_surface_{index}',
_kwargs = {'Name': f'{surface.name}',
'Surface_Type': idf_surface_type,
'Zone_Name': zone_name}
if surface.type == cte.GROUND:
@ -706,7 +666,7 @@ class Idf:
wind_exposure = 'NoWind'
if surface.percentage_shared is not None and surface.percentage_shared > 0.5:
outside_boundary_condition = 'Surface'
outside_boundary_condition_object = f'Building_{building.name}_surface_{index}'
outside_boundary_condition_object = surface.name
sun_exposure = 'NoSun'
wind_exposure = 'NoWind'
_kwargs['Outside_Boundary_Condition_Object'] = outside_boundary_condition_object
@ -731,12 +691,12 @@ class Idf:
def _add_surfaces(self, building, zone_name):
for thermal_zone in building.thermal_zones_from_internal_zones:
for index, boundary in enumerate(thermal_zone.thermal_boundaries):
for boundary in thermal_zone.thermal_boundaries:
idf_surface_type = self.idf_surfaces[boundary.parent_surface.type]
outside_boundary_condition = 'Outdoors'
sun_exposure = 'SunExposed'
wind_exposure = 'WindExposed'
_kwargs = {'Name': f'Building_{building.name}_surface_{index}',
_kwargs = {'Name': f'{boundary.parent_surface.name}',
'Surface_Type': idf_surface_type,
'Zone_Name': zone_name}
if boundary.parent_surface.type == cte.GROUND:
@ -745,7 +705,7 @@ class Idf:
wind_exposure = 'NoWind'
if boundary.parent_surface.percentage_shared is not None and boundary.parent_surface.percentage_shared > 0.5:
outside_boundary_condition = 'Surface'
outside_boundary_condition_object = f'Building_{building.name}_surface_{index}'
outside_boundary_condition_object = boundary.parent_surface.name
sun_exposure = 'NoSun'
wind_exposure = 'NoWind'
_kwargs['Outside_Boundary_Condition_Object'] = outside_boundary_condition_object
@ -756,7 +716,7 @@ class Idf:
if boundary.parent_surface.vegetation is not None:
construction_name = f'{boundary.construction_name}_{boundary.parent_surface.vegetation.name}'
else:
construction_name = f'{boundary.construction_name} {boundary.parent_surface.type}'
construction_name = boundary.construction_name
_kwargs['Construction_Name'] = construction_name
surface = self._idf.newidfobject(self._SURFACE, **_kwargs)

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
! HVAC: None.
!
Version,24.1;
Version,9.5;
Timestep,4;

View File

@ -270,7 +270,7 @@ class InselMonthlyEnergyBalance:
global_irradiance = surface.global_irradiance[cte.MONTH]
for j in range(0, len(global_irradiance)):
parameters.append(f'{j + 1} '
f'{global_irradiance[j] / 24 / _NUMBER_DAYS_PER_MONTH[j]}')
f'{global_irradiance[j] * cte.WATTS_HOUR_TO_JULES / 24 / _NUMBER_DAYS_PER_MONTH[j]}')
else:
for j in range(0, 12):
parameters.append(f'{j + 1} 0.0')

View File

@ -20,10 +20,9 @@ class EnergyBuildingsExportsFactory:
"""
Energy Buildings exports factory class
"""
def __init__(self, handler, city, path, custom_insel_block='d18599', target_buildings=None, weather_file=None):
def __init__(self, handler, city, path, custom_insel_block='d18599', target_buildings=None):
self._city = city
self._export_type = '_' + handler.lower()
self._weather_file = weather_file
validate_import_export_type(EnergyBuildingsExportsFactory, handler)
if isinstance(path, str):
path = Path(path)
@ -54,13 +53,12 @@ class EnergyBuildingsExportsFactory:
"""
idf_data_path = (Path(__file__).parent / './building_energy/idf_files/').resolve()
url = wh().epw_file(self._city.region_code)
if self._weather_file is None:
self._weather_file = (Path(__file__).parent.parent / f'data/weather/epw/{url.rsplit("/", 1)[1]}').resolve()
if not self._weather_file.exists():
with open(self._weather_file, 'wb') as epw_file:
weather_path = (Path(__file__).parent.parent / f'data/weather/epw/{url.rsplit("/", 1)[1]}').resolve()
if not weather_path.exists():
with open(weather_path, 'wb') as epw_file:
epw_file.write(requests.get(url, allow_redirects=True).content)
return Idf(self._city, self._path, (idf_data_path / 'Minimal.idf'), (idf_data_path / 'Energy+.idd'),
self._weather_file, target_buildings=self._target_buildings)
return Idf(self._city, self._path, (idf_data_path / 'Minimal.idf'), (idf_data_path / 'Energy+.idd'), weather_path,
target_buildings=self._target_buildings)
@property
def _insel_monthly_energy_balance(self):

View File

@ -7,12 +7,9 @@ Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
from pathlib import Path
from hub.exports.formats.glb import Glb
from hub.exports.formats.obj import Obj
from hub.exports.formats.geojson import Geojson
from hub.exports.formats.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm
from hub.exports.formats.stl import Stl
from hub.exports.formats.cesiumjs_tileset import CesiumjsTileset
from hub.helpers.utils import validate_import_export_type
@ -20,7 +17,7 @@ class ExportsFactory:
"""
Exports factory class
"""
def __init__(self, handler, city, path, target_buildings=None, adjacent_buildings=None, base_uri=None):
def __init__(self, handler, city, path, target_buildings=None, adjacent_buildings=None):
self._city = city
self._handler = '_' + handler.lower()
validate_import_export_type(ExportsFactory, handler)
@ -29,7 +26,18 @@ class ExportsFactory:
self._path = path
self._target_buildings = target_buildings
self._adjacent_buildings = adjacent_buildings
self._base_uri = base_uri
@property
def _citygml(self):
"""
Export to citygml
:return: None
"""
raise NotImplementedError
@property
def _collada(self):
raise NotImplementedError
@property
def _stl(self):
@ -53,30 +61,9 @@ class ExportsFactory:
Export the city to Simplified Radiosity Algorithm xml format
:return: None
"""
return SimplifiedRadiosityAlgorithm(
self._city, (self._path / f'{self._city.name}_sra.xml'), target_buildings=self._target_buildings
)
@property
def _cesiumjs_tileset(self):
"""
Export the city to a cesiumJs tileset format
:return: None
"""
return CesiumjsTileset(
self._city,
(self._path / f'{self._city.name}.json'),
target_buildings=self._target_buildings,
base_uri=self._base_uri
)
@property
def _glb(self):
return Glb(self._city, self._path, target_buildings=self._target_buildings)
@property
def _geojson(self):
return Geojson(self._city, self._path, target_buildings=self._target_buildings)
return SimplifiedRadiosityAlgorithm(self._city,
(self._path / f'{self._city.name}_sra.xml'),
target_buildings=self._target_buildings)
def export(self):
"""

View File

@ -1,159 +0,0 @@
"""
export a city into Cesium tileset format
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
import json
import math
import pyproj
from pyproj import Transformer
from hub.helpers.geometry_helper import GeometryHelper
class CesiumjsTileset:
def __init__(self, city, file_name, target_buildings=None, base_uri=None):
self._city = city
self._file_name = file_name
self._target_buildings = target_buildings
if base_uri is None:
base_uri = '.'
self._base_uri = base_uri
try:
srs_name = self._city.srs_name
if self._city.srs_name in GeometryHelper.srs_transformations:
srs_name = GeometryHelper.srs_transformations[self._city.srs_name]
input_reference = pyproj.CRS(srs_name) # Projected coordinate system from input data
except pyproj.exceptions.CRSError as err:
raise pyproj.exceptions.CRSError from err
self._to_gps = Transformer.from_crs(input_reference, pyproj.CRS('EPSG:4326'))
city_upper_corner = [
self._city.upper_corner[0] - self._city.lower_corner[0],
self._city.upper_corner[1] - self._city.lower_corner[1],
self._city.upper_corner[2] - self._city.lower_corner[2]
]
city_lower_corner = [0, 0, 0]
self._tile_set = {
'asset': {
'version': '1.1',
"tilesetVersion": "1.2.3"
},
'position': self._to_gps.transform(self._city.lower_corner[0], self._city.lower_corner[1]),
'schema': {
'id': "building",
'classes': {
'building': {
"properties": {
'name': {
'type': 'STRING'
},
'position': {
'type': 'SCALAR',
'array': True,
'componentType': 'FLOAT32'
},
'aliases': {
'type': 'STRING',
'array': True,
},
'volume': {
'type': 'SCALAR',
'componentType': 'FLOAT32'
},
'floor_area': {
'type': 'SCALAR',
'componentType': 'FLOAT32'
},
'max_height': {
'type': 'SCALAR',
'componentType': 'INT32'
},
'year_of_construction': {
'type': 'SCALAR',
'componentType': 'INT32'
},
'function': {
'type': 'STRING'
},
'usages_percentage': {
'type': 'STRING'
}
}
}
}
},
'geometricError': 500,
'root': {
'boundingVolume': {
'box': CesiumjsTileset._box_values(city_upper_corner, city_lower_corner)
},
'geometricError': 70,
'refine': 'ADD',
'children': []
}
}
self._export()
@staticmethod
def _box_values(upper_corner, lower_corner):
x = (upper_corner[0] - lower_corner[0]) / 2
x_center = ((upper_corner[0] - lower_corner[0]) / 2) + lower_corner[0]
y = (upper_corner[1] - lower_corner[1]) / 2
y_center = ((upper_corner[1] - lower_corner[1]) / 2) + lower_corner[1]
z = (upper_corner[2] - lower_corner[2]) / 2
return [x_center, y_center, z, x, 0, 0, 0, y, 0, 0, 0, z]
def _ground_coordinates(self, coordinates):
ground_coordinates = []
for coordinate in coordinates:
ground_coordinates.append(
(coordinate[0] - self._city.lower_corner[0], coordinate[1] - self._city.lower_corner[1])
)
return ground_coordinates
def _export(self):
for building in self._city.buildings:
upper_corner = [-math.inf, -math.inf, 0]
lower_corner = [math.inf, math.inf, 0]
lower_corner_coordinates = lower_corner
for surface in building.grounds: # todo: maybe we should add the terrain?
coordinates = self._ground_coordinates(surface.solid_polygon.coordinates)
lower_corner = [min([c[0] for c in coordinates]), min([c[1] for c in coordinates]), 0]
lower_corner_coordinates = [
min([c[0] for c in surface.solid_polygon.coordinates]),
min([c[1] for c in surface.solid_polygon.coordinates]),
0
]
upper_corner = [max([c[0] for c in coordinates]), max([c[1] for c in coordinates]), building.max_height]
tile = {
'boundingVolume': {
'box': CesiumjsTileset._box_values(upper_corner, lower_corner)
},
'geometricError': 250,
'metadata': {
'class': 'building',
'properties': {
'name': building.name,
'position': self._to_gps.transform(lower_corner_coordinates[0], lower_corner_coordinates[1]),
'aliases': building.aliases,
'volume': building.volume,
'floor_area': building.floor_area,
'max_height': building.max_height,
'year_of_construction': building.year_of_construction,
'function': building.function,
'usages_percentage': building.usages_percentage
}
},
'content': {
'uri': f'{self._base_uri}/{building.name}.glb'
}
}
self._tile_set['root']['children'].append(tile)
with open(self._file_name, 'w') as f:
json.dump(self._tile_set, f, indent=2)

View File

@ -1,112 +0,0 @@
"""
export a city into Geojson format
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
import json
from pathlib import Path
import numpy as np
import pyproj
from pyproj import Transformer
from hub.helpers.geometry_helper import GeometryHelper
class Geojson:
"""
Export to geojson format
"""
def __init__(self, city, path, target_buildings):
self._city = city
self._file_path = Path(path / f'{self._city.name}.geojson').resolve()
try:
srs_name = self._city.srs_name
if self._city.srs_name in GeometryHelper.srs_transformations:
srs_name = GeometryHelper.srs_transformations[self._city.srs_name]
input_reference = pyproj.CRS(srs_name) # Projected coordinate system from input data
except pyproj.exceptions.CRSError as err:
raise pyproj.exceptions.CRSError from err
self._to_gps = Transformer.from_crs(input_reference, pyproj.CRS('EPSG:4326'))
if target_buildings is None:
target_buildings = [b.name for b in self._city.buildings]
self._geojson_skeleton = {
'type': 'FeatureCollection',
'features': []
}
self._feature_skeleton = {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': []
},
'properties': {}
}
self._export()
def _export(self):
for building in self._city.buildings:
if len(building.grounds) == 1:
ground = building.grounds[0]
feature = self._polygon(ground)
else:
feature = self._multipolygon(building.grounds)
feature['id'] = building.name
feature['properties']['height'] = f'{building.max_height - building.lower_corner[2]}'
feature['properties']['function'] = f'{building.function}'
feature['properties']['year_of_construction'] = f'{building.year_of_construction}'
feature['properties']['aliases'] = building.aliases
feature['properties']['elevation'] = f'{building.lower_corner[2]}'
self._geojson_skeleton['features'].append(feature)
with open(self._file_path, 'w', encoding='utf-8') as f:
json.dump(self._geojson_skeleton, f, indent=2)
def _polygon(self, ground):
feature = {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': []
},
'properties': {}
}
ground_coordinates = []
for coordinate in ground.solid_polygon.coordinates:
gps_coordinate = self._to_gps.transform(coordinate[0], coordinate[1])
ground_coordinates.insert(0, [gps_coordinate[1], gps_coordinate[0]])
first_gps_coordinate = self._to_gps.transform(
ground.solid_polygon.coordinates[0][0],
ground.solid_polygon.coordinates[0][1]
)
ground_coordinates.insert(0, [first_gps_coordinate[1], first_gps_coordinate[0]])
feature['geometry']['coordinates'].append(ground_coordinates)
return feature
def _multipolygon(self, grounds):
feature = {
'type': 'Feature',
'geometry': {
'type': 'MultiPolygon',
'coordinates': []
},
'properties': {}
}
polygons = []
for ground in grounds:
ground_coordinates = []
for coordinate in ground.solid_polygon.coordinates:
gps_coordinate = self._to_gps.transform(coordinate[0], coordinate[1])
ground_coordinates.insert(0, [gps_coordinate[1], gps_coordinate[0]])
first_gps_coordinate = self._to_gps.transform(
ground.solid_polygon.coordinates[0][0],
ground.solid_polygon.coordinates[0][1]
)
ground_coordinates.insert(0, [first_gps_coordinate[1], first_gps_coordinate[0]])
polygons.append(ground_coordinates)
feature['geometry']['coordinates'].append(polygons)
return feature

View File

@ -1,54 +0,0 @@
"""
export a city into Glb format
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
import os
import shutil
import subprocess
from hub.city_model_structure.city import City
from hub.exports.formats.obj import Obj
class GltExceptionError(Exception):
"""
Glt execution error
"""
class Glb:
"""
Glb class
"""
def __init__(self, city, path, target_buildings=None):
self._city = city
self._path = path
if target_buildings is None:
target_buildings = [b.name for b in self._city.buildings]
self._target_buildings = target_buildings
self._export()
@property
def _obj2gltf(self):
return shutil.which('obj2gltf')
def _export(self):
try:
for building in self._city.buildings:
city = City(self._city.lower_corner, self._city.upper_corner, self._city.srs_name)
city.add_city_object(building)
city.name = building.name
Obj(city, self._path)
glb = f'{self._path}/{building.name}.glb'
subprocess.run([
self._obj2gltf,
'-i', f'{self._path}/{building.name}.obj',
'-b',
'-o', f'{glb}'
])
os.unlink(f'{self._path}/{building.name}.obj')
os.unlink(f'{self._path}/{building.name}.mtl')
except (subprocess.SubprocessError, subprocess.TimeoutExpired, subprocess.CalledProcessError) as err:
raise GltExceptionError from err

View File

@ -4,9 +4,8 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
"""
from pathlib import Path
import numpy as np
from pathlib import Path
class Obj:
@ -18,64 +17,29 @@ class Obj:
self._path = path
self._export()
def _ground(self, coordinate):
def _to_vertex(self, coordinate):
x = coordinate[0] - self._city.lower_corner[0]
y = coordinate[1] - self._city.lower_corner[1]
z = coordinate[2] - self._city.lower_corner[2]
return x, y, z
def _to_vertex(self, coordinate):
x, y, z = self._ground(coordinate)
return f'v {x} {z} -{y}\n' # to match opengl expectations
def _to_texture_vertex(self, coordinate):
u, v, _ = self._ground(coordinate)
return f'vt {u} {v}\n'
def _to_normal_vertex(self, coordinates):
ground_vertex = []
for coordinate in coordinates:
x, y, z = self._ground(coordinate)
ground_vertex.append(np.array([x, y, z]))
# recalculate the normal to get grounded values
edge_1 = ground_vertex[1] - ground_vertex[0]
edge_2 = ground_vertex[2] - ground_vertex[0]
normal = np.cross(edge_1, edge_2)
normal = normal / np.linalg.norm(normal)
return f'vn {normal[0]} {normal[1]} {normal[2]}\n'
return f'v {x} {y} {z}\n'
def _export(self):
if self._city.name is None:
self._city.name = 'unknown_city'
obj_name = f'{self._city.name}.obj'
mtl_name = f'{self._city.name}.mtl'
obj_file_path = (Path(self._path).resolve() / obj_name).resolve()
mtl_file_path = (Path(self._path).resolve() / mtl_name).resolve()
with open(mtl_file_path, 'w', encoding='utf-8') as mtl:
mtl.write("newmtl cerc_base_material\n")
mtl.write("Ka 1.0 1.0 1.0 # Ambient color (white)\n")
mtl.write("Kd 0.1 0.3 0.1 # Diffuse color (greenish)\n")
mtl.write("Ks 1.0 1.0 1.0 # Specular color (white)\n")
mtl.write("Ns 400.0 # Specular exponent (defines shininess)\n")
file_name = self._city.name + '.obj'
file_path = (Path(self._path).resolve() / file_name).resolve()
vertices = {}
faces = []
vertex_index = 0
normal_index = 0
with open(obj_file_path, 'w', encoding='utf-8') as obj:
with open(file_path, 'w', encoding='utf-8') as obj:
obj.write("# cerc-hub export\n")
obj.write(f'mtllib {mtl_name}\n')
vertex_index = 0
faces = []
for building in self._city.buildings:
obj.write(f'# building {building.name}\n')
obj.write(f'g {building.name}\n')
obj.write('s off\n')
for surface in building.surfaces:
obj.write(f'# surface {surface.name}\n')
face = []
normal = self._to_normal_vertex(surface.perimeter_polygon.coordinates)
normal_index += 1
textures = []
face = 'f '
for coordinate in surface.perimeter_polygon.coordinates:
vertex = self._to_vertex(coordinate)
if vertex not in vertices:
@ -83,13 +47,11 @@ class Obj:
vertices[vertex] = vertex_index
current = vertex_index
obj.write(vertex)
textures.append(self._to_texture_vertex(coordinate)) # only append if non-existing
else:
current = vertices[vertex]
face.append(f'{current}/{current}/{normal_index}') # insert clockwise
obj.writelines(normal) # add the normal
obj.writelines(textures) # add the texture vertex
faces.append(f"f {' '.join(face)}\n")
face = f'{face} {current}'
faces.append(f'{face} {face.split(" ")[1]}\n')
obj.writelines(faces)
faces = []

View File

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

View File

@ -10,11 +10,11 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
KELVIN = 273.15
WATER_DENSITY = 1000 # kg/m3
WATER_HEAT_CAPACITY = 4182 # J/kgK
WATER_THERMAL_CONDUCTIVITY = 0.65 # W/mK
NATURAL_GAS_LHV = 36.6e6 # J/m3
AIR_DENSITY = 1.293 # kg/m3
AIR_HEAT_CAPACITY = 1005.2 # J/kgK
# converters
HOUR_TO_MINUTES = 60
MINUTES_TO_SECONDS = 60
@ -24,8 +24,6 @@ BTU_H_TO_WATTS = 0.29307107
KILO_WATTS_HOUR_TO_JULES = 3600000
WATTS_HOUR_TO_JULES = 3600
GALLONS_TO_QUBIC_METERS = 0.0037854117954011185
INFILTRATION_75PA_TO_4PA = (4/75)**0.65
# time
SECOND = 'second'
@ -51,140 +49,36 @@ WEEK_DAYS = 'Weekdays'
WEEK_ENDS = 'Weekends'
ALL_DAYS = 'Alldays'
JANUARY = 'January'
FEBRUARY = 'February'
MARCH = 'March'
APRIL = 'April'
MAY = 'May'
JUNE = 'June'
JULY = 'July'
AUGUST = 'August'
SEPTEMBER = 'September'
OCTOBER = 'October'
NOVEMBER = 'November'
DECEMBER = 'December'
WEEK_DAYS_A_MONTH = {'monday': [5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 5],
'tuesday': [5, 4, 4, 4, 5, 4, 5, 4, 4, 5, 4, 4],
'wednesday': [5, 4, 4, 4, 5, 4, 4, 5, 4, 5, 4, 4],
'thursday': [4, 4, 5, 4, 5, 4, 4, 5, 4, 4, 5, 4],
'friday': [4, 4, 5, 4, 4, 5, 4, 5, 4, 4, 5, 4],
'saturday': [4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5],
'sunday': [4, 4, 4, 5, 4, 4, 5, 4, 5, 4, 4, 5],
'holiday': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}
MONTHS = [JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER]
WEEK_DAYS_A_YEAR = {'monday': 51,
'tuesday': 50,
'wednesday': 50,
'thursday': 50,
'friday': 50,
'saturday': 52,
'sunday': 52,
'holiday': 10}
WEEK_DAYS_A_MONTH = {JANUARY: {MONDAY: 5,
TUESDAY: 5,
WEDNESDAY: 5,
THURSDAY: 4,
FRIDAY: 4,
SATURDAY: 4,
SUNDAY: 4,
HOLIDAY: 0},
FEBRUARY: {MONDAY: 4,
TUESDAY: 4,
WEDNESDAY: 4,
THURSDAY: 4,
FRIDAY: 4,
SATURDAY: 4,
SUNDAY: 4,
HOLIDAY: 0},
MARCH: {MONDAY: 4,
TUESDAY: 4,
WEDNESDAY: 4,
THURSDAY: 5,
FRIDAY: 5,
SATURDAY: 5,
SUNDAY: 4,
HOLIDAY: 0},
APRIL: {MONDAY: 5,
TUESDAY: 4,
WEDNESDAY: 4,
THURSDAY: 4,
FRIDAY: 4,
SATURDAY: 4,
SUNDAY: 5,
HOLIDAY: 0},
MAY: {MONDAY: 4,
TUESDAY: 5,
WEDNESDAY: 5,
THURSDAY: 5,
FRIDAY: 4,
SATURDAY: 4,
SUNDAY: 4,
HOLIDAY: 0},
JUNE: {MONDAY: 4,
TUESDAY: 4,
WEDNESDAY: 4,
THURSDAY: 4,
FRIDAY: 5,
SATURDAY: 5,
SUNDAY: 4,
HOLIDAY: 0},
JULY: {MONDAY: 5,
TUESDAY: 5,
WEDNESDAY: 4,
THURSDAY: 4,
FRIDAY: 4,
SATURDAY: 4,
SUNDAY: 5,
HOLIDAY: 0},
AUGUST: {MONDAY: 4,
TUESDAY: 4,
WEDNESDAY: 5,
THURSDAY: 5,
FRIDAY: 5,
SATURDAY: 4,
SUNDAY: 4,
HOLIDAY: 0},
SEPTEMBER: {MONDAY: 4,
TUESDAY: 4,
WEDNESDAY: 4,
THURSDAY: 4,
FRIDAY: 4,
SATURDAY: 5,
SUNDAY: 5,
HOLIDAY: 0},
OCTOBER: {MONDAY: 5,
TUESDAY: 5,
WEDNESDAY: 5,
THURSDAY: 4,
FRIDAY: 4,
SATURDAY: 4,
SUNDAY: 4,
HOLIDAY: 0},
NOVEMBER: {MONDAY: 4,
TUESDAY: 4,
WEDNESDAY: 4,
THURSDAY: 5,
FRIDAY: 5,
SATURDAY: 4,
SUNDAY: 4,
HOLIDAY: 0},
DECEMBER: {MONDAY: 5,
TUESDAY: 4,
WEDNESDAY: 4,
THURSDAY: 4,
FRIDAY: 4,
SATURDAY: 5,
SUNDAY: 5,
HOLIDAY: 0},
}
WEEK_DAYS_A_YEAR = {MONDAY: 51,
TUESDAY: 50,
WEDNESDAY: 50,
THURSDAY: 50,
FRIDAY: 50,
SATURDAY: 52,
SUNDAY: 52,
HOLIDAY: 10}
DAYS_A_MONTH = {JANUARY: 31,
FEBRUARY: 28,
MARCH: 31,
APRIL: 30,
MAY: 31,
JUNE: 30,
JULY: 31,
AUGUST: 31,
SEPTEMBER: 30,
OCTOBER: 31,
NOVEMBER: 30,
DECEMBER: 31}
DAYS_A_MONTH = {'January': 31,
'February': 28,
'March': 31,
'April': 30,
'May': 31,
'June': 30,
'July': 31,
'August': 31,
'September': 30,
'October': 31,
'November': 30,
'December': 31}
# data types
ANY_NUMBER = 'any_number'
@ -294,8 +188,6 @@ WOOD = 'Wood'
GAS = 'Gas'
DIESEL = 'Diesel'
COAL = 'Coal'
BIOMASS = 'Biomass'
BUTANE = 'Butane'
AIR = 'Air'
WATER = 'Water'
GEOTHERMAL = 'Geothermal'
@ -306,16 +198,7 @@ PHOTOVOLTAIC = 'Photovoltaic'
BOILER = 'Boiler'
HEAT_PUMP = 'Heat Pump'
BASEBOARD = 'Baseboard'
ELECTRICITY_GENERATOR = 'Electricity generator'
CHILLER = 'Chiller'
SPLIT = 'Split'
JOULE = 'Joule'
BUTANE_HEATER = 'Butane Heater'
SENSIBLE = 'sensible'
LATENT = 'Latent'
LITHIUMION = 'Lithium Ion'
NICD = 'NiCd'
LEADACID = 'Lead Acid'
# Geometry
EPSILON = 0.0000001

View File

@ -16,9 +16,7 @@ class HubFunctionToEilatConstructionFunction:
self._dictionary = {
cte.RESIDENTIAL: 'Residential_building',
cte.HOTEL: 'Residential_building',
cte.DORMITORY: 'Residential_building',
cte.DATACENTER: 'n/a',
cte.FARM: 'n/a'
cte.DORMITORY: 'Residential_building'
}
@property

View File

@ -73,9 +73,7 @@ class HubFunctionToMontrealCustomCostsFunction:
cte.AUTOMOTIVE_FACILITY: 'non-residential',
cte.PARKING_GARAGE: 'non-residential',
cte.RELIGIOUS: 'non-residential',
cte.NON_HEATED: 'non-residential',
cte.DATACENTER: 'n/a',
cte.FARM: 'n/a'
cte.NON_HEATED: 'non-residential'
}
@property

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