Compare commits
402 Commits
Author | SHA1 | Date | |
---|---|---|---|
3db3acd3c6 | |||
15aaf2a337 | |||
7ad16ba640 | |||
f42bb64b85 | |||
3dd64143ab | |||
164ffbf9c8 | |||
bf4018a649 | |||
6c7f652390 | |||
4e46b6bc0d | |||
4ac9ccda81 | |||
df2d7a3054 | |||
47810737fa | |||
99535a979c | |||
9986552ec1 | |||
d1719b50ed | |||
5e01f4eb7f | |||
d38150ac2d | |||
5e5129ecd7 | |||
3905f228dc | |||
33049441f0 | |||
70dd9f7c6a | |||
0ce392ea06 | |||
|
4b6a942324 | ||
2495046c44 | |||
4738de0d8c | |||
e220bf2c0d | |||
a45cf02b28 | |||
ef62e2531f | |||
|
cd34435a9f | ||
|
15b96fe154 | ||
|
54a6e6b2db | ||
|
a7375f0b53 | ||
|
725746fbcb | ||
ec320a2e1c | |||
8a68118503 | |||
a3ec3c7e19 | |||
|
ace666553a | ||
c4636c2c3c | |||
4a01ac51d8 | |||
ee846a6225 | |||
a4f3b48617 | |||
abc3fc48dd | |||
db371aecf3 | |||
998df80b63 | |||
446c7fa4ce | |||
3c5f1b7357 | |||
6d2bb98470 | |||
26b2af1e2b | |||
dc3372ff5e | |||
a81c0cfee3 | |||
1279dffff8 | |||
1cc7b2cb8c | |||
2d11bf6640 | |||
9adacadc2a | |||
15e43a0f35 | |||
6dbff12ff9 | |||
982bcab045 | |||
83d308e03b | |||
915170e60f | |||
6afc076402 | |||
6e79541816 | |||
c36ce1b83a | |||
3de2e00a54 | |||
5fb31fc5ca | |||
7851968bdc | |||
6684e7ef1b | |||
64449aee1d | |||
a0f7ca0e17 | |||
58d84021cf | |||
84d80d5d2a | |||
6b3110d1c0 | |||
f095483b36 | |||
841098b615 | |||
73e6dcdaf7 | |||
8fe002a22c | |||
ffd0367d50 | |||
f15401c148 | |||
9a99f69bdf | |||
fe99059e5a | |||
d9d9a628b4 | |||
d9a941a97a | |||
b52e66c263 | |||
039a0f30ba | |||
ebeafddc74 | |||
355cc6ecdf | |||
cbe720f0de | |||
52382566d3 | |||
4056a2ab8a | |||
1f7b4924fe | |||
20200f0efe | |||
919ab60bd5 | |||
aa85473a81 | |||
aac006f63a | |||
199d7dc4f9 | |||
3a6a712cad | |||
27291ad1b8 | |||
5fdfee9265 | |||
0f0a923329 | |||
bf23730281 | |||
11d493ba0e | |||
1266f50e29 | |||
674393970c | |||
8d75fe1f3a | |||
57a9d24f4c | |||
087fead489 | |||
ebaec9bb7c | |||
3e193f04a6 | |||
ac4742d2c4 | |||
f976040f45 | |||
54b62ec2d0 | |||
9357cef641 | |||
002d5a659d | |||
f9815dfa49 | |||
eeda66f410 | |||
aa0f790d8e | |||
e0e7daf64b | |||
5181ddcabb | |||
68457b9d26 | |||
673cbac77a | |||
11f78ccb89 | |||
3891c866cf | |||
5230da861c | |||
87b2319fda | |||
1916d21c4e | |||
57388a9dc4 | |||
89d0d0eae8 | |||
e025510c93 | |||
d592de6759 | |||
eeac9a24a8 | |||
7328118861 | |||
9444de6bae | |||
27ceed01fe | |||
57c7a76529 | |||
020190829f | |||
c3f2cfb02a | |||
e3f1d52a21 | |||
716465f1eb | |||
81702e0008 | |||
953b6796e9 | |||
898f364e28 | |||
03da727d29 | |||
b51d49d598 | |||
802641b4a3 | |||
914375171a | |||
72b6cddea4 | |||
7f16449edb | |||
c8545835d9 | |||
4bc8df8e9d | |||
fca74eeb08 | |||
227685695a | |||
ac6b023080 | |||
383a480f65 | |||
67525e50fa | |||
601058fc5e | |||
cfd2586f80 | |||
a3c5219ccd | |||
5fa55ea79f | |||
68bb9223e3 | |||
a1ca764057 | |||
8c27e69a79 | |||
557d77661e | |||
38d8013356 | |||
43fa1e0d92 | |||
812c9541f4 | |||
c1e392d828 | |||
fe315bc6bb | |||
087379b010 | |||
452bfdf780 | |||
63803efccb | |||
0f0368c074 | |||
08e701a972 | |||
914d521e81 | |||
7f8e0d48ee | |||
26c0ef7864 | |||
5ce3a24e55 | |||
0894c5dac6 | |||
ee06d45ba9 | |||
3dd928574a | |||
9591db3bf8 | |||
69f3b7f814 | |||
6e6c78b6f4 | |||
75bb316848 | |||
ed7d6d13f6 | |||
42de9cea97 | |||
255f9f861a | |||
4449d0b92d | |||
89452dcf31 | |||
6aafda7f42 | |||
6da8fde949 | |||
6332519e12 | |||
9ce97edc13 | |||
98676e81e0 | |||
5cba38cf65 | |||
3512d4b1e4 | |||
b0fabf3b7f | |||
6d987f43f7 | |||
f62ab95cf0 | |||
b711bceb7b | |||
6ee1466b8e | |||
a31281cae7 | |||
8d5010218b | |||
a102a201e6 | |||
2afce4acce | |||
9c1e05939a | |||
978cc9d1ea | |||
0240e89170 | |||
c6d4feec89 | |||
3f649fd020 | |||
d94bce4174 | |||
f865490ff9 | |||
31a4893ed8 | |||
1a7ad20135 | |||
fe76d2fe3d | |||
57ee3e734b | |||
7cb4600c15 | |||
3578d2faae | |||
d6bfe730eb | |||
84f5ebe4a0 | |||
6b24a59178 | |||
11dc02d0e8 | |||
d29161b05e | |||
a331dce966 | |||
3f91da9f45 | |||
f13d7fd860 | |||
ef89da8552 | |||
9654bee978 | |||
dae117fb44 | |||
91fa9d5ca1 | |||
8e145eefa1 | |||
6f40a15609 | |||
4a14deece1 | |||
ca48d6448b | |||
f2bfc297b3 | |||
d5c443a57b | |||
568317ebf1 | |||
af32decf96 | |||
bb05b01312 | |||
cbda6ce13d | |||
2b696f9251 | |||
a97c068513 | |||
f0ad1462d0 | |||
23a8fbe86d | |||
087384475f | |||
fac6844da1 | |||
b914c9e7bf | |||
cf783d8998 | |||
8bd75c790f | |||
eaa3064a3f | |||
207058a16f | |||
8dbbfb9460 | |||
3809cf2885 | |||
8b66e20e9a | |||
6d34e41e90 | |||
f495c1d27a | |||
a43c971bbb | |||
4ce9f99e4d | |||
e3c9c64e9f | |||
8099037225 | |||
|
12d20f2d7a | ||
|
bf004f9e18 | ||
|
482c06e4c2 | ||
cb3e100fd4 | |||
41cf280aab | |||
ee875859e8 | |||
989d89df80 | |||
73dffdc367 | |||
b24a616d00 | |||
aa6b3c9e74 | |||
707b42f2a9 | |||
cd7104206a | |||
29ba43f1d9 | |||
70cc659c14 | |||
f0ffc26348 | |||
cde3bfb4ae | |||
8f8a6dbf71 | |||
1392c05489 | |||
a0d2f7e5bc | |||
2a5c552f17 | |||
86b7378a54 | |||
cf6542cb0c | |||
4004ff3c84 | |||
4ae09915b1 | |||
9624be2cf9 | |||
c072527dc6 | |||
56c84ad399 | |||
a5f70f4720 | |||
b7c2bbae96 | |||
8763523d3b | |||
7810f8f91d | |||
d4b424357d | |||
8dbeeaafa1 | |||
c77b2254f1 | |||
b1d42ee00b | |||
6ac63adaaf | |||
644b1c9346 | |||
8f1f344769 | |||
6551eb6402 | |||
24a670755a | |||
cfb76a9ebd | |||
5d4813f2f6 | |||
2f62ce3fdb | |||
58e7ce7574 | |||
43e5bb7310 | |||
fe0a2d3003 | |||
3deb63b14a | |||
9b0bdf2b7e | |||
ade5ef94bb | |||
40bc0154dd | |||
ff1bb80a6c | |||
76d3ba8495 | |||
491b976fd9 | |||
072d2a6d9d | |||
72b5ff1040 | |||
e20a700deb | |||
0528aa0718 | |||
923b1fe267 | |||
32a40f17a6 | |||
e91e61741e | |||
16618fb54a | |||
21ca1e1e28 | |||
ccdc7a454d | |||
3feecac15d | |||
acd7ad2266 | |||
6ce82c52de | |||
d6ee3d6e6b | |||
231e4a17f2 | |||
012076492f | |||
61d4c012dc | |||
fa518126a5 | |||
e0037e788f | |||
e08080c601 | |||
1b3a128f33 | |||
a3028221e3 | |||
19d05940fa | |||
fde6f0f751 | |||
fdead81f26 | |||
db0e400343 | |||
ec288f8db1 | |||
b746387133 | |||
480acc6552 | |||
7c29405f21 | |||
|
e1ca39950f | ||
|
02a03b8239 | ||
d564218531 | |||
ebb712ebaf | |||
|
9094c286c4 | ||
9034c3375e | |||
e2c8ef0c56 | |||
30908eda6d | |||
deb04cbe2d | |||
2b95173dfc | |||
7f5cde8175 | |||
bb76d05f17 | |||
ca81ce3020 | |||
3f4038286e | |||
c4930b940f | |||
527bf4448b | |||
1b3053b37f | |||
cf3f85c7f4 | |||
db7caad218 | |||
7fb39171f4 | |||
b7d7c9aadb | |||
4012408e2f | |||
8502efc710 | |||
19011d3fc1 | |||
bdf0deb3b3 | |||
ab81edc33d | |||
a3bf594071 | |||
04ef636423 | |||
d7e041b686 | |||
90a196465a | |||
7cf926bc5b | |||
83fc351fc7 | |||
8a41c4f656 | |||
589f3e7f11 | |||
67cd435fd5 | |||
1e9afa28a8 | |||
212b4b0621 | |||
fe8c79d7c2 | |||
e138a24555 | |||
86845dd05f | |||
1691ada01c | |||
4bbd65bb41 | |||
9365b47dc2 | |||
7143913144 | |||
75848ef250 | |||
9f24ed8fae | |||
4b5c037ffa | |||
6b89008698 | |||
0f982df32e | |||
c38b025c2e | |||
4d0f247a83 | |||
a147afe76f | |||
2292bff1b8 | |||
1abf76125f | |||
ce995c375d | |||
eb246a18e6 | |||
f95c45660e | |||
4add8b2cff | |||
f3208f1735 | |||
b60be9c39e | |||
ac96b0467b |
2
hub/.gitignore → .gitignore
vendored
2
hub/.gitignore → .gitignore
vendored
|
@ -9,4 +9,4 @@
|
|||
**/hub/logs/
|
||||
**/__pycache__/
|
||||
**/.idea/
|
||||
|
||||
cerc_hub.egg-info
|
3
cerc_hub.egg-info/.gitignore
vendored
3
cerc_hub.egg-info/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
# Except this file
|
||||
*
|
||||
!.gitignore
|
50
hub/LINUX_INSTALL.md
Normal file
50
hub/LINUX_INSTALL.md
Normal file
|
@ -0,0 +1,50 @@
|
|||
# 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.
|
|
@ -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 Gitlab and created your first python file.
|
||||
set up your own project on CERC's Gitea 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 Gitlab and have the necessary permissions for
|
||||
You also need to register a user account with the CERC's code repository on Gitea 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,6 +47,29 @@ _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.
|
||||
|
@ -55,7 +78,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)
|
||||
|
||||
|
@ -70,14 +93,12 @@ 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**. For the URL use the link to the Hub repository, as seen below.
|
||||
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.
|
||||
|
||||
![pycharm get from version control screen](docs/img_windows_install/img_1.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)
|
||||
![gitea get https](docs/img_windows_install/img_39.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.
|
||||
|
||||
|
@ -152,7 +173,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 Gitlab repository know about this new branch. You do this by right-clicking on
|
||||
4. Now we need to let the CERC Gitea 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.
|
||||
|
@ -180,33 +201,35 @@ See the picture below.
|
|||
|
||||
![pycharm configuration screen](docs/img_windows_install/img_5.png)
|
||||
|
||||
## Set up a new project on Gitlab
|
||||
## 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.
|
||||
|
||||
1. Open a browser and to the [CERC Git](https://rs-loy-gitlab.concordia.ca/). Click on the blue **New project** button.
|
||||
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.
|
||||
|
||||
![git new project screen](docs/img_windows_install/img_14.png)
|
||||
![git new project screen](docs/img_windows_install/img_37.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)).
|
||||
Check the option **Initialize repository with a README**, and ideally, check the **Visibility Level** to be **Public**.
|
||||
Ideally, uncheck the option **Make Repository Private**, and check the **Initialize Repository**
|
||||
Then click on the **Create project** button.
|
||||
|
||||
![git give a name](docs/img_windows_install/img_15.png)
|
||||
![git give a name](docs/img_windows_install/img_38.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, 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.
|
||||
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.
|
||||
|
||||
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 gitlab project.
|
||||
section above, but using the URL link that you just copied for your Gitea project.
|
||||
|
||||
4. Select **File->Settings** to open the **Settings** window. From the panel on the left click on
|
||||
**Project:<project name> -> Project Structure**.
|
||||
|
@ -242,5 +265,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 (gitlab).
|
||||
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).
|
||||
Once the conflicts are solved and the merge in local is done, push the changes by clicking on the green arrow.
|
||||
|
|
|
@ -15,12 +15,14 @@ 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 EilatCatalog(Catalog):
|
||||
"""
|
||||
Eilat catalog class
|
||||
"""
|
||||
|
||||
def __init__(self, path):
|
||||
_path_archetypes = Path(path / 'eilat_archetypes.json').resolve()
|
||||
_path_constructions = (path / 'eilat_constructions.json').resolve()
|
||||
|
@ -120,8 +122,10 @@ 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']
|
||||
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on']
|
||||
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']:
|
||||
|
@ -159,7 +163,9 @@ class EilatCatalog(Catalog):
|
|||
extra_loses_due_to_thermal_bridges,
|
||||
None,
|
||||
infiltration_rate_for_ventilation_system_off,
|
||||
infiltration_rate_for_ventilation_system_on))
|
||||
infiltration_rate_for_ventilation_system_on,
|
||||
0,
|
||||
0))
|
||||
return _catalog_archetypes
|
||||
|
||||
def names(self, category=None):
|
||||
|
|
|
@ -15,6 +15,7 @@ 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 NrcanCatalog(Catalog):
|
||||
|
@ -121,8 +122,18 @@ class NrcanCatalog(Catalog):
|
|||
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']
|
||||
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on']
|
||||
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']:
|
||||
|
@ -148,7 +159,6 @@ class NrcanCatalog(Catalog):
|
|||
_window)
|
||||
archetype_constructions.append(_construction)
|
||||
break
|
||||
|
||||
_catalog_archetypes.append(Archetype(archetype_id,
|
||||
name,
|
||||
function,
|
||||
|
@ -160,7 +170,10 @@ class NrcanCatalog(Catalog):
|
|||
extra_loses_due_to_thermal_bridges,
|
||||
None,
|
||||
infiltration_rate_for_ventilation_system_off,
|
||||
infiltration_rate_for_ventilation_system_on))
|
||||
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):
|
||||
|
|
|
@ -15,6 +15,7 @@ from hub.catalog_factories.data_models.construction.construction import Construc
|
|||
from hub.catalog_factories.data_models.construction.content import Content
|
||||
from hub.catalog_factories.data_models.construction.archetype import Archetype
|
||||
from hub.catalog_factories.construction.construction_helper import ConstructionHelper
|
||||
import hub.helpers.constants as cte
|
||||
|
||||
|
||||
class NrelCatalog(Catalog):
|
||||
|
@ -124,10 +125,10 @@ class NrelCatalog(Catalog):
|
|||
indirect_heated_ratio = float(archetype['indirect_heated_ratio']['#text'])
|
||||
infiltration_rate_for_ventilation_system_off = float(
|
||||
archetype['infiltration_rate_for_ventilation_system_off']['#text']
|
||||
)
|
||||
) / cte.HOUR_TO_SECONDS
|
||||
infiltration_rate_for_ventilation_system_on = float(
|
||||
archetype['infiltration_rate_for_ventilation_system_on']['#text']
|
||||
)
|
||||
) / cte.HOUR_TO_SECONDS
|
||||
|
||||
archetype_constructions = []
|
||||
for archetype_construction in archetype['constructions']['construction']:
|
||||
|
@ -161,7 +162,9 @@ class NrelCatalog(Catalog):
|
|||
extra_loses_due_to_thermal_bridges,
|
||||
indirect_heated_ratio,
|
||||
infiltration_rate_for_ventilation_system_off,
|
||||
infiltration_rate_for_ventilation_system_on))
|
||||
infiltration_rate_for_ventilation_system_on,
|
||||
0,
|
||||
0))
|
||||
return _catalog_archetypes
|
||||
|
||||
def names(self, category=None):
|
||||
|
|
242
hub/catalog_factories/construction/palma_catalog.py
Normal file
242
hub/catalog_factories/construction/palma_catalog.py
Normal file
|
@ -0,0 +1,242 @@
|
|||
"""
|
||||
Palma construction catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2023 Concordia CERC group
|
||||
Project Coder Cecilia Pérez Pérez cperez@irec.cat
|
||||
"""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from hub.catalog_factories.catalog import Catalog
|
||||
from hub.catalog_factories.data_models.construction.content import Content
|
||||
from hub.catalog_factories.construction.construction_helper import ConstructionHelper
|
||||
from hub.catalog_factories.data_models.construction.construction import Construction
|
||||
from hub.catalog_factories.data_models.construction.archetype import Archetype
|
||||
from hub.catalog_factories.data_models.construction.window import Window
|
||||
from hub.catalog_factories.data_models.construction.material import Material
|
||||
from hub.catalog_factories.data_models.construction.layer import Layer
|
||||
import hub.helpers.constants as cte
|
||||
|
||||
|
||||
class PalmaCatalog(Catalog):
|
||||
"""
|
||||
Palma catalog class
|
||||
"""
|
||||
def __init__(self, path):
|
||||
_path_archetypes = Path(path / 'palma_archetypes.json').resolve()
|
||||
_path_constructions = (path / 'palma_constructions.json').resolve()
|
||||
with open(_path_archetypes, 'r', encoding='utf-8') as file:
|
||||
self._archetypes = json.load(file)
|
||||
with open(_path_constructions, 'r', encoding='utf-8') as file:
|
||||
self._constructions = json.load(file)
|
||||
|
||||
self._catalog_windows = self._load_windows()
|
||||
self._catalog_materials = self._load_materials()
|
||||
self._catalog_constructions = self._load_constructions()
|
||||
self._catalog_archetypes = self._load_archetypes()
|
||||
|
||||
# store the full catalog data model in self._content
|
||||
self._content = Content(self._catalog_archetypes,
|
||||
self._catalog_constructions,
|
||||
self._catalog_materials,
|
||||
self._catalog_windows)
|
||||
|
||||
def _load_windows(self):
|
||||
_catalog_windows = []
|
||||
windows = self._constructions['transparent_surfaces']
|
||||
for window in windows:
|
||||
name = list(window.keys())[0]
|
||||
window_id = name
|
||||
g_value = window[name]['shgc']
|
||||
window_type = window[name]['type']
|
||||
frame_ratio = window[name]['frame_ratio']
|
||||
overall_u_value = window[name]['u_value']
|
||||
_catalog_windows.append(Window(window_id, frame_ratio, g_value, overall_u_value, name, window_type))
|
||||
return _catalog_windows
|
||||
|
||||
def _load_materials(self):
|
||||
_catalog_materials = []
|
||||
materials = self._constructions['materials']
|
||||
for material in materials:
|
||||
name = list(material.keys())[0]
|
||||
material_id = name
|
||||
no_mass = material[name]['no_mass']
|
||||
thermal_resistance = None
|
||||
conductivity = None
|
||||
density = None
|
||||
specific_heat = None
|
||||
solar_absorptance = None
|
||||
thermal_absorptance = None
|
||||
visible_absorptance = None
|
||||
if no_mass:
|
||||
thermal_resistance = material[name]['thermal_resistance']
|
||||
else:
|
||||
solar_absorptance = material[name]['solar_absorptance']
|
||||
thermal_absorptance = str(1 - float(material[name]['thermal_emittance']))
|
||||
visible_absorptance = material[name]['visible_absorptance']
|
||||
conductivity = material[name]['conductivity']
|
||||
density = material[name]['density']
|
||||
specific_heat = material[name]['specific_heat']
|
||||
_material = Material(material_id,
|
||||
name,
|
||||
solar_absorptance,
|
||||
thermal_absorptance,
|
||||
visible_absorptance,
|
||||
no_mass,
|
||||
thermal_resistance,
|
||||
conductivity,
|
||||
density,
|
||||
specific_heat)
|
||||
_catalog_materials.append(_material)
|
||||
return _catalog_materials
|
||||
|
||||
def _load_constructions(self):
|
||||
_catalog_constructions = []
|
||||
constructions = self._constructions['opaque_surfaces']
|
||||
for construction in constructions:
|
||||
name = list(construction.keys())[0]
|
||||
construction_id = name
|
||||
construction_type = ConstructionHelper().nrcan_surfaces_types_to_hub_types[construction[name]['type']]
|
||||
layers = []
|
||||
for layer in construction[name]['layers']:
|
||||
layer_id = layer
|
||||
layer_name = layer
|
||||
material_id = layer
|
||||
thickness = construction[name]['layers'][layer]
|
||||
for material in self._catalog_materials:
|
||||
if str(material_id) == str(material.id):
|
||||
layers.append(Layer(layer_id, layer_name, material, thickness))
|
||||
break
|
||||
_catalog_constructions.append(Construction(construction_id, construction_type, name, layers))
|
||||
return _catalog_constructions
|
||||
|
||||
def _load_archetypes(self):
|
||||
_catalog_archetypes = []
|
||||
archetypes = self._archetypes['archetypes']
|
||||
for archetype in archetypes:
|
||||
archetype_id = f'{archetype["function"]}_{archetype["period_of_construction"]}_{archetype["climate_zone"]}'
|
||||
function = archetype['function']
|
||||
name = archetype_id
|
||||
climate_zone = archetype['climate_zone']
|
||||
construction_period = archetype['period_of_construction']
|
||||
average_storey_height = archetype['average_storey_height']
|
||||
thermal_capacity = float(archetype['thermal_capacity']) * 1000
|
||||
extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges']
|
||||
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
|
||||
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
|
||||
infiltration_rate_area_for_ventilation_system_off = (
|
||||
archetype['infiltration_rate_area_for_ventilation_system_off'] * 1
|
||||
)
|
||||
infiltration_rate_area_for_ventilation_system_on = (
|
||||
archetype['infiltration_rate_area_for_ventilation_system_on'] * 1
|
||||
)
|
||||
|
||||
archetype_constructions = []
|
||||
for archetype_construction in archetype['constructions']:
|
||||
archetype_construction_type = ConstructionHelper().nrcan_surfaces_types_to_hub_types[archetype_construction]
|
||||
archetype_construction_name = archetype['constructions'][archetype_construction]['opaque_surface_name']
|
||||
for construction in self._catalog_constructions:
|
||||
if archetype_construction_type == construction.type and construction.name == archetype_construction_name:
|
||||
_construction = None
|
||||
_window = None
|
||||
_window_ratio = None
|
||||
if 'transparent_surface_name' in archetype['constructions'][archetype_construction].keys():
|
||||
_window_ratio = archetype['constructions'][archetype_construction]['transparent_ratio']
|
||||
_window_id = archetype['constructions'][archetype_construction]['transparent_surface_name']
|
||||
for window in self._catalog_windows:
|
||||
if _window_id == window.id:
|
||||
_window = window
|
||||
break
|
||||
_construction = Construction(construction.id,
|
||||
construction.type,
|
||||
construction.name,
|
||||
construction.layers,
|
||||
_window_ratio,
|
||||
_window)
|
||||
archetype_constructions.append(_construction)
|
||||
break
|
||||
|
||||
_catalog_archetypes.append(Archetype(archetype_id,
|
||||
name,
|
||||
function,
|
||||
climate_zone,
|
||||
construction_period,
|
||||
archetype_constructions,
|
||||
average_storey_height,
|
||||
thermal_capacity,
|
||||
extra_loses_due_to_thermal_bridges,
|
||||
None,
|
||||
infiltration_rate_for_ventilation_system_off,
|
||||
infiltration_rate_for_ventilation_system_on,
|
||||
infiltration_rate_area_for_ventilation_system_off,
|
||||
infiltration_rate_area_for_ventilation_system_on))
|
||||
return _catalog_archetypes
|
||||
|
||||
def names(self, category=None):
|
||||
"""
|
||||
Get the catalog elements names
|
||||
:parm: optional category filter
|
||||
"""
|
||||
if category is None:
|
||||
_names = {'archetypes': [], 'constructions': [], 'materials': [], 'windows': []}
|
||||
for archetype in self._content.archetypes:
|
||||
_names['archetypes'].append(archetype.name)
|
||||
for construction in self._content.constructions:
|
||||
_names['constructions'].append(construction.name)
|
||||
for material in self._content.materials:
|
||||
_names['materials'].append(material.name)
|
||||
for window in self._content.windows:
|
||||
_names['windows'].append(window.name)
|
||||
else:
|
||||
_names = {category: []}
|
||||
if category.lower() == 'archetypes':
|
||||
for archetype in self._content.archetypes:
|
||||
_names[category].append(archetype.name)
|
||||
elif category.lower() == 'constructions':
|
||||
for construction in self._content.constructions:
|
||||
_names[category].append(construction.name)
|
||||
elif category.lower() == 'materials':
|
||||
for material in self._content.materials:
|
||||
_names[category].append(material.name)
|
||||
elif category.lower() == 'windows':
|
||||
for window in self._content.windows:
|
||||
_names[category].append(window.name)
|
||||
else:
|
||||
raise ValueError(f'Unknown category [{category}]')
|
||||
return _names
|
||||
|
||||
def entries(self, category=None):
|
||||
"""
|
||||
Get the catalog elements
|
||||
:parm: optional category filter
|
||||
"""
|
||||
if category is None:
|
||||
return self._content
|
||||
if category.lower() == 'archetypes':
|
||||
return self._content.archetypes
|
||||
if category.lower() == 'constructions':
|
||||
return self._content.constructions
|
||||
if category.lower() == 'materials':
|
||||
return self._content.materials
|
||||
if category.lower() == 'windows':
|
||||
return self._content.windows
|
||||
raise ValueError(f'Unknown category [{category}]')
|
||||
|
||||
def get_entry(self, name):
|
||||
"""
|
||||
Get one catalog element by names
|
||||
:parm: entry name
|
||||
"""
|
||||
for entry in self._content.archetypes:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.constructions:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.materials:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.windows:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
raise IndexError(f"{name} doesn't exists in the catalog")
|
|
@ -11,6 +11,7 @@ from typing import TypeVar
|
|||
from hub.catalog_factories.construction.nrcan_catalog import NrcanCatalog
|
||||
from hub.catalog_factories.construction.nrel_catalog import NrelCatalog
|
||||
from hub.catalog_factories.construction.eilat_catalog import EilatCatalog
|
||||
from hub.catalog_factories.construction.palma_catalog import PalmaCatalog
|
||||
from hub.helpers.utils import validate_import_export_type
|
||||
|
||||
Catalog = TypeVar('Catalog')
|
||||
|
@ -48,6 +49,13 @@ class ConstructionCatalogFactory:
|
|||
"""
|
||||
return EilatCatalog(self._path)
|
||||
|
||||
@property
|
||||
def _palma(self):
|
||||
"""
|
||||
Retrieve Palma catalog
|
||||
"""
|
||||
return PalmaCatalog(self._path)
|
||||
|
||||
@property
|
||||
def catalog(self) -> Catalog:
|
||||
"""
|
||||
|
|
|
@ -23,7 +23,10 @@ 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_for_ventilation_system_on,
|
||||
infiltration_rate_area_for_ventilation_system_off,
|
||||
infiltration_rate_area_for_ventilation_system_on
|
||||
):
|
||||
self._id = archetype_id
|
||||
self._name = name
|
||||
self._function = function
|
||||
|
@ -36,6 +39,8 @@ 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):
|
||||
|
@ -120,7 +125,7 @@ class Archetype:
|
|||
@property
|
||||
def infiltration_rate_for_ventilation_system_off(self):
|
||||
"""
|
||||
Get archetype infiltration rate for ventilation system off in ACH
|
||||
Get archetype infiltration rate for ventilation system off in 1/s
|
||||
:return: float
|
||||
"""
|
||||
return self._infiltration_rate_for_ventilation_system_off
|
||||
|
@ -128,7 +133,23 @@ class Archetype:
|
|||
@property
|
||||
def infiltration_rate_for_ventilation_system_on(self):
|
||||
"""
|
||||
Get archetype infiltration rate for ventilation system on in ACH
|
||||
Get archetype infiltration rate for ventilation system on in 1/s
|
||||
:return: float
|
||||
"""
|
||||
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
|
||||
|
@ -147,8 +168,10 @@ class Archetype:
|
|||
'thermal capacity [J/m3K]': self.thermal_capacity,
|
||||
'extra loses due to thermal bridges [W/m2K]': self.extra_loses_due_to_thermal_bridges,
|
||||
'indirect heated ratio': self.indirect_heated_ratio,
|
||||
'infiltration rate for ventilation off [ACH]': self.infiltration_rate_for_ventilation_system_off,
|
||||
'infiltration rate for ventilation on [ACH]': self.infiltration_rate_for_ventilation_system_on,
|
||||
'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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ class Fuel:
|
|||
"""
|
||||
if self._fixed_power is not None:
|
||||
return self._fixed_power/1000
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
|
|
|
@ -27,7 +27,7 @@ class Income:
|
|||
@property
|
||||
def construction_subsidy(self) -> Union[None, float]:
|
||||
"""
|
||||
Get subsidy for construction in percentage
|
||||
Get subsidy for construction in percentage %
|
||||
:return: None or float
|
||||
"""
|
||||
return self._construction_subsidy
|
||||
|
@ -35,7 +35,7 @@ class Income:
|
|||
@property
|
||||
def hvac_subsidy(self) -> Union[None, float]:
|
||||
"""
|
||||
Get subsidy for HVAC system in percentage
|
||||
Get subsidy for HVAC system in percentage %
|
||||
:return: None or float
|
||||
"""
|
||||
return self._hvac_subsidy
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
"""
|
||||
Energy System catalog archetype
|
||||
Energy System catalog archetype, understood as a cluster of energy systems
|
||||
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 List
|
||||
|
@ -14,27 +15,18 @@ class Archetype:
|
|||
"""
|
||||
Archetype class
|
||||
"""
|
||||
def __init__(self, lod, name, systems):
|
||||
def __init__(self, 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):
|
||||
"""
|
||||
Get name
|
||||
:return: string
|
||||
"""
|
||||
return f'{self._name}_lod{self._lod}'
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def systems(self) -> List[System]:
|
||||
|
@ -49,8 +41,9 @@ class Archetype:
|
|||
_systems = []
|
||||
for _system in self.systems:
|
||||
_systems.append(_system.to_dictionary())
|
||||
content = {'Archetype': {'name': self.name,
|
||||
'level of detail': self.lod,
|
||||
content = {
|
||||
'Archetype': {
|
||||
'name': self.name,
|
||||
'systems': _systems
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,12 +10,11 @@ class Content:
|
|||
"""
|
||||
Content class
|
||||
"""
|
||||
def __init__(self, archetypes, systems, generations, distributions, emissions):
|
||||
def __init__(self, archetypes, systems, generations=None, distributions=None):
|
||||
self._archetypes = archetypes
|
||||
self._systems = systems
|
||||
self._generations = generations
|
||||
self._distributions = distributions
|
||||
self._emissions = emissions
|
||||
|
||||
@property
|
||||
def archetypes(self):
|
||||
|
@ -45,13 +44,6 @@ class Content:
|
|||
"""
|
||||
return self._distributions
|
||||
|
||||
@property
|
||||
def emission_equipments(self):
|
||||
"""
|
||||
All emission equipments in the catalog
|
||||
"""
|
||||
return self._emissions
|
||||
|
||||
def to_dictionary(self):
|
||||
"""Class content to dictionary"""
|
||||
_archetypes = []
|
||||
|
|
|
@ -3,23 +3,35 @@ Energy System catalog distribution 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, 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, name, system_type, supply_temperature, distribution_consumption_fix_flow,
|
||||
distribution_consumption_variable_flow, heat_losses):
|
||||
|
||||
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):
|
||||
self._system_id = system_id
|
||||
self._name = name
|
||||
self._model_name = model_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):
|
||||
|
@ -30,12 +42,12 @@ class DistributionSystem:
|
|||
return self._system_id
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
def model_name(self):
|
||||
"""
|
||||
Get name
|
||||
Get model name
|
||||
:return: string
|
||||
"""
|
||||
return self._name
|
||||
return self._model_name
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
|
@ -78,15 +90,51 @@ 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"""
|
||||
content = {'Layer': {'id': self.id,
|
||||
'name': self.name,
|
||||
_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,
|
||||
'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
|
||||
'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
|
||||
}
|
||||
}
|
||||
return content
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
"""
|
||||
Energy System catalog electrical 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.catalog_factories.data_models.energy_systems.energy_storage_system import EnergyStorageSystem
|
||||
|
||||
|
||||
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):
|
||||
|
||||
super().__init__(storage_id, model_name, manufacturer, nominal_capacity, losses_ratio)
|
||||
self._type_energy_stored = type_energy_stored
|
||||
self._storage_type = storage_type
|
||||
self._rated_output_power = rated_output_power
|
||||
self._nominal_efficiency = nominal_efficiency
|
||||
self._battery_voltage = battery_voltage
|
||||
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']
|
||||
:return: string
|
||||
"""
|
||||
return self._storage_type
|
||||
|
||||
@property
|
||||
def rated_output_power(self):
|
||||
"""
|
||||
Get the rated output power of storage system in Watts
|
||||
:return: float
|
||||
"""
|
||||
return self._rated_output_power
|
||||
|
||||
@property
|
||||
def nominal_efficiency(self):
|
||||
"""
|
||||
Get the nominal efficiency of the storage system
|
||||
:return: float
|
||||
"""
|
||||
return self._nominal_efficiency
|
||||
|
||||
@property
|
||||
def battery_voltage(self):
|
||||
"""
|
||||
Get the battery voltage in Volts
|
||||
:return: float
|
||||
"""
|
||||
return self._battery_voltage
|
||||
|
||||
@property
|
||||
def depth_of_discharge(self):
|
||||
"""
|
||||
Get the depth of discharge as a percentage
|
||||
:return: float
|
||||
"""
|
||||
return self._depth_of_discharge
|
||||
|
||||
@property
|
||||
def self_discharge_rate(self):
|
||||
"""
|
||||
Get the self discharge rate of battery as a percentage
|
||||
:return: float
|
||||
"""
|
||||
return self._self_discharge_rate
|
||||
|
||||
def to_dictionary(self):
|
||||
"""Class content 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,
|
||||
'rated power [W]': self.rated_output_power,
|
||||
'nominal efficiency': self.nominal_efficiency,
|
||||
'battery voltage [V]': self.battery_voltage,
|
||||
'depth of discharge [%]': self.depth_of_discharge,
|
||||
'self discharge rate': self.self_discharge_rate
|
||||
}
|
||||
}
|
||||
return content
|
|
@ -10,10 +10,10 @@ class EmissionSystem:
|
|||
"""
|
||||
Emission system class
|
||||
"""
|
||||
def __init__(self, system_id, name, system_type, parasitic_energy_consumption):
|
||||
def __init__(self, system_id, model_name=None, system_type=None, parasitic_energy_consumption=0):
|
||||
|
||||
self._system_id = system_id
|
||||
self._name = name
|
||||
self._model_name = model_name
|
||||
self._type = system_type
|
||||
self._parasitic_energy_consumption = parasitic_energy_consumption
|
||||
|
||||
|
@ -26,12 +26,12 @@ class EmissionSystem:
|
|||
return self._system_id
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
def model_name(self):
|
||||
"""
|
||||
Get name
|
||||
Get model name
|
||||
:return: string
|
||||
"""
|
||||
return self._name
|
||||
return self._model_name
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
|
@ -52,7 +52,7 @@ class EmissionSystem:
|
|||
def to_dictionary(self):
|
||||
"""Class content to dictionary"""
|
||||
content = {'Layer': {'id': self.id,
|
||||
'name': self.name,
|
||||
'model name': self.model_name,
|
||||
'type': self.type,
|
||||
'parasitic energy consumption per energy produced [J/J]': self.parasitic_energy_consumption
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
"""
|
||||
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 abc import ABC
|
||||
|
||||
|
||||
class EnergyStorageSystem(ABC):
|
||||
""""
|
||||
Energy Storage System Abstract Class
|
||||
"""
|
||||
|
||||
def __init__(self, storage_id, model_name=None, manufacturer=None,
|
||||
nominal_capacity=None, losses_ratio=None):
|
||||
self._storage_id = storage_id
|
||||
self._model_name = model_name
|
||||
self._manufacturer = manufacturer
|
||||
self._nominal_capacity = nominal_capacity
|
||||
self._losses_ratio = losses_ratio
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
Get storage id
|
||||
:return: string
|
||||
"""
|
||||
return self._storage_id
|
||||
|
||||
@property
|
||||
def type_energy_stored(self):
|
||||
"""
|
||||
Get type of energy stored from ['electrical', 'thermal']
|
||||
:return: string
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def model_name(self):
|
||||
"""
|
||||
Get system model
|
||||
:return: string
|
||||
"""
|
||||
return self._model_name
|
||||
|
||||
@property
|
||||
def manufacturer(self):
|
||||
"""
|
||||
Get name of manufacturer
|
||||
:return: string
|
||||
"""
|
||||
return self._manufacturer
|
||||
|
||||
@property
|
||||
def nominal_capacity(self):
|
||||
"""
|
||||
Get the nominal capacity of the storage system in Jules
|
||||
:return: float
|
||||
"""
|
||||
return self._nominal_capacity
|
||||
|
||||
@property
|
||||
def losses_ratio(self):
|
||||
"""
|
||||
Get the losses-ratio of storage system in Jules lost / Jules stored
|
||||
:return: float
|
||||
"""
|
||||
return self._losses_ratio
|
||||
|
||||
def to_dictionary(self):
|
||||
"""Class content to dictionary"""
|
||||
raise NotImplementedError
|
|
@ -1,33 +1,33 @@
|
|||
"""
|
||||
Energy System catalog generation 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
|
||||
Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import Union
|
||||
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
|
||||
|
||||
|
||||
class GenerationSystem:
|
||||
class GenerationSystem(ABC):
|
||||
"""
|
||||
Generation system class
|
||||
Heat Generation system class
|
||||
"""
|
||||
def __init__(self, system_id, name, system_type, fuel_type, source_types, heat_efficiency, cooling_efficiency,
|
||||
electricity_efficiency, source_temperature, source_mass_flow, storage, auxiliary_equipment):
|
||||
|
||||
def __init__(self, system_id, name, model_name=None, manufacturer=None, fuel_type=None,
|
||||
distribution_systems=None, energy_storage_systems=None):
|
||||
self._system_id = system_id
|
||||
self._name = name
|
||||
self._type = system_type
|
||||
self._model_name = model_name
|
||||
self._manufacturer = manufacturer
|
||||
self._fuel_type = fuel_type
|
||||
self._source_types = source_types
|
||||
self._heat_efficiency = heat_efficiency
|
||||
self._cooling_efficiency = cooling_efficiency
|
||||
self._electricity_efficiency = electricity_efficiency
|
||||
self._source_temperature = source_temperature
|
||||
self._source_mass_flow = source_mass_flow
|
||||
self._storage = storage
|
||||
self._auxiliary_equipment = auxiliary_equipment
|
||||
self._distribution_systems = distribution_systems
|
||||
self._energy_storage_systems = energy_storage_systems
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -40,108 +40,59 @@ class GenerationSystem:
|
|||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Get name
|
||||
Get system name
|
||||
:return: string
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
def system_type(self):
|
||||
"""
|
||||
Get type
|
||||
:return: string
|
||||
"""
|
||||
return self._type
|
||||
raise NotImplementedError
|
||||
|
||||
@property
|
||||
def model_name(self):
|
||||
"""
|
||||
Get system id
|
||||
:return: float
|
||||
"""
|
||||
return self._model_name
|
||||
|
||||
@property
|
||||
def manufacturer(self):
|
||||
"""
|
||||
Get name
|
||||
:return: string
|
||||
"""
|
||||
return self._manufacturer
|
||||
|
||||
@property
|
||||
def fuel_type(self):
|
||||
"""
|
||||
Get fuel_type from [renewable, gas, diesel, electricity, wood, coal]
|
||||
Get fuel_type from [renewable, gas, diesel, electricity, wood, coal, biogas]
|
||||
:return: string
|
||||
"""
|
||||
return self._fuel_type
|
||||
|
||||
@property
|
||||
def source_types(self):
|
||||
def distribution_systems(self) -> Union[None, List[DistributionSystem]]:
|
||||
"""
|
||||
Get source_type from [air, water, geothermal, district_heating, grid, on_site_electricity]
|
||||
:return: [string]
|
||||
Get distributions systems connected to this generation system
|
||||
:return: [DistributionSystem]
|
||||
"""
|
||||
return self._source_types
|
||||
return self._distribution_systems
|
||||
|
||||
@property
|
||||
def heat_efficiency(self):
|
||||
def energy_storage_systems(self) -> Union[None, List[EnergyStorageSystem]]:
|
||||
"""
|
||||
Get heat_efficiency
|
||||
:return: float
|
||||
Get energy storage systems connected to this generation system
|
||||
:return: [EnergyStorageSystem]
|
||||
"""
|
||||
return self._heat_efficiency
|
||||
|
||||
@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 storage(self):
|
||||
"""
|
||||
Get boolean storage exists
|
||||
:return: bool
|
||||
"""
|
||||
return self._storage
|
||||
|
||||
@property
|
||||
def auxiliary_equipment(self) -> Union[None, GenerationSystem]:
|
||||
"""
|
||||
Get auxiliary_equipment
|
||||
:return: GenerationSystem
|
||||
"""
|
||||
return self._auxiliary_equipment
|
||||
return self._energy_storage_systems
|
||||
|
||||
def to_dictionary(self):
|
||||
"""Class content to dictionary"""
|
||||
_auxiliary_equipment = []
|
||||
if self.auxiliary_equipment is not None:
|
||||
_auxiliary_equipment = self.auxiliary_equipment.to_dictionary()
|
||||
content = {'Layer': {'id': self.id,
|
||||
'name': self.name,
|
||||
'type': self.type,
|
||||
'fuel type': self.fuel_type,
|
||||
'source types': self.source_types,
|
||||
'source temperature [Celsius]': self.source_temperature,
|
||||
'source mass flow [kg/s]': self.source_mass_flow,
|
||||
'heat efficiency': self.heat_efficiency,
|
||||
'cooling efficiency': self.cooling_efficiency,
|
||||
'electricity efficiency': self.electricity_efficiency,
|
||||
'it has storage': self.storage,
|
||||
'auxiliary equipment': _auxiliary_equipment
|
||||
}
|
||||
}
|
||||
return content
|
||||
raise NotImplementedError
|
||||
|
|
|
@ -0,0 +1,344 @@
|
|||
"""
|
||||
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
|
|
@ -0,0 +1,72 @@
|
|||
"""
|
||||
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, curve_type, dependant_variable, parameters, coefficients):
|
||||
self._curve_type = curve_type
|
||||
self._dependant_variable = dependant_variable
|
||||
self._parameters = parameters
|
||||
self._coefficients = coefficients
|
||||
|
||||
@property
|
||||
def curve_type(self):
|
||||
"""
|
||||
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
|
||||
|
||||
@property
|
||||
def dependant_variable(self):
|
||||
"""
|
||||
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
|
||||
|
||||
@property
|
||||
def parameters(self):
|
||||
"""
|
||||
Get the list of parameters involved in fitting process as ['x', 'z'] (e.g. [source temperature, supply temperature]
|
||||
in COP=)
|
||||
:return: string
|
||||
"""
|
||||
return self._parameters
|
||||
|
||||
@property
|
||||
def coefficients(self):
|
||||
"""
|
||||
Get the coefficients of the functions as list of ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
:return: [coefficients]
|
||||
"""
|
||||
return self._coefficients
|
||||
|
||||
def to_dictionary(self):
|
||||
"""Class content to dictionary"""
|
||||
content = {'Parameter Function': {
|
||||
'curve type': self.curve_type,
|
||||
'dependant variable': self.dependant_variable,
|
||||
'parameter(s)': self.parameters,
|
||||
'coefficients': self.coefficients,
|
||||
}
|
||||
}
|
||||
return content
|
|
@ -0,0 +1,165 @@
|
|||
"""
|
||||
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 hub.catalog_factories.data_models.energy_systems.generation_system import GenerationSystem
|
||||
|
||||
|
||||
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):
|
||||
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
|
||||
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):
|
||||
"""
|
||||
Get nominal ambient temperature of PV panels in degree Celsius
|
||||
:return: float
|
||||
"""
|
||||
return self._nominal_ambient_temperature
|
||||
|
||||
@property
|
||||
def nominal_cell_temperature(self):
|
||||
"""
|
||||
Get nominal cell temperature of PV panels in degree Celsius
|
||||
:return: float
|
||||
"""
|
||||
return self._nominal_cell_temperature
|
||||
|
||||
@property
|
||||
def nominal_radiation(self):
|
||||
"""
|
||||
Get nominal radiation of PV panels
|
||||
:return: float
|
||||
"""
|
||||
return self._nominal_radiation
|
||||
|
||||
@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
|
||||
|
||||
@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
|
||||
|
||||
@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):
|
||||
"""
|
||||
Get cell temperature coefficient of PV module
|
||||
:return: float
|
||||
"""
|
||||
return self._cell_temperature_coefficient
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
"""
|
||||
Get PV module width in m
|
||||
:return: float
|
||||
"""
|
||||
return self._width
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
"""
|
||||
Get PV module height in m
|
||||
:return: float
|
||||
"""
|
||||
return self._height
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
return content
|
|
@ -1,45 +1,36 @@
|
|||
"""
|
||||
Energy System catalog equipment
|
||||
Energy Systems catalog 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 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.distribution_system import DistributionSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem
|
||||
|
||||
|
||||
class System:
|
||||
"""
|
||||
System class
|
||||
"""
|
||||
def __init__(self,
|
||||
lod,
|
||||
system_id,
|
||||
name,
|
||||
demand_types,
|
||||
generation_system,
|
||||
distribution_system,
|
||||
emission_system):
|
||||
|
||||
self._lod = lod
|
||||
def __init__(self,
|
||||
system_id,
|
||||
demand_types,
|
||||
name=None,
|
||||
generation_systems=None,
|
||||
distribution_systems=None,
|
||||
configuration_schema=None):
|
||||
self._system_id = system_id
|
||||
self._name = name
|
||||
self._demand_types = demand_types
|
||||
self._generation_system = generation_system
|
||||
self._distribution_system = distribution_system
|
||||
self._emission_system = emission_system
|
||||
|
||||
@property
|
||||
def lod(self):
|
||||
"""
|
||||
Get level of detail of the catalog
|
||||
:return: string
|
||||
"""
|
||||
return self._lod
|
||||
self._generation_systems = generation_systems
|
||||
self._distribution_systems = distribution_systems
|
||||
self._configuration_schema = configuration_schema
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -52,58 +43,57 @@ class System:
|
|||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Get name
|
||||
Get the system name
|
||||
:return: string
|
||||
"""
|
||||
return f'{self._name}_lod{self._lod}'
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def demand_types(self):
|
||||
"""
|
||||
Get demand able to cover from [heating, cooling, domestic_hot_water, electricity]
|
||||
Get demand able to cover from ['heating', 'cooling', 'domestic_hot_water', 'electricity']
|
||||
:return: [string]
|
||||
"""
|
||||
return self._demand_types
|
||||
|
||||
@property
|
||||
def generation_system(self) -> GenerationSystem:
|
||||
def generation_systems(self) -> Union[None, List[GenerationSystem]]:
|
||||
"""
|
||||
Get generation system
|
||||
:return: GenerationSystem
|
||||
Get generation systems
|
||||
:return: [GenerationSystem]
|
||||
"""
|
||||
return self._generation_system
|
||||
return self._generation_systems
|
||||
|
||||
@property
|
||||
def distribution_system(self) -> Union[None, DistributionSystem]:
|
||||
def distribution_systems(self) -> Union[None, List[DistributionSystem]]:
|
||||
"""
|
||||
Get distribution system
|
||||
:return: DistributionSystem
|
||||
Get distribution systems
|
||||
:return: [DistributionSystem]
|
||||
"""
|
||||
return self._distribution_system
|
||||
return self._distribution_systems
|
||||
|
||||
@property
|
||||
def emission_system(self) -> Union[None, EmissionSystem]:
|
||||
def configuration_schema(self) -> Path:
|
||||
"""
|
||||
Get emission system
|
||||
:return: EmissionSystem
|
||||
Get system configuration schema
|
||||
:return: Path
|
||||
"""
|
||||
return self._emission_system
|
||||
return self._configuration_schema
|
||||
|
||||
def to_dictionary(self):
|
||||
"""Class content to dictionary"""
|
||||
_distribution_system = None
|
||||
if self.distribution_system is not None:
|
||||
_distribution_system = self.distribution_system.to_dictionary()
|
||||
_emission_system = None
|
||||
if self.emission_system is not None:
|
||||
_emission_system = self.emission_system.to_dictionary()
|
||||
content = {'Layer': {'id': self.id,
|
||||
_generation_systems = []
|
||||
for _generation in self.generation_systems:
|
||||
_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
|
||||
|
||||
content = {'system': {'id': self.id,
|
||||
'name': self.name,
|
||||
'level of detail': self.lod,
|
||||
'demand types': self.demand_types,
|
||||
'generation system': self.generation_system.to_dictionary(),
|
||||
'distribution system': _distribution_system,
|
||||
'emission system': _emission_system
|
||||
'generation system(s)': _generation_systems,
|
||||
'distribution system(s)': _distribution_systems,
|
||||
'configuration schema path': self.configuration_schema
|
||||
}
|
||||
}
|
||||
return content
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
"""
|
||||
Energy System catalog 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.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):
|
||||
|
||||
super().__init__(storage_id, model_name, manufacturer, nominal_capacity, losses_ratio)
|
||||
self._type_energy_stored = type_energy_stored
|
||||
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):
|
||||
"""
|
||||
Get storage type from ['thermal', 'sensible', 'latent']
|
||||
:return: string
|
||||
"""
|
||||
return self._storage_type
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
"""
|
||||
Get the physical volume of the storage system in cubic meters
|
||||
:return: float
|
||||
"""
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
"""
|
||||
Get the diameter of the storage system in meters
|
||||
:return: float
|
||||
"""
|
||||
return self._height
|
||||
|
||||
@property
|
||||
def layers(self) -> [Layer]:
|
||||
"""
|
||||
Get construction layers
|
||||
:return: [layer]
|
||||
"""
|
||||
return self._layers
|
||||
|
||||
@property
|
||||
def maximum_operating_temperature(self):
|
||||
"""
|
||||
Get maximum operating temperature of the storage system in degree Celsius
|
||||
:return: float
|
||||
"""
|
||||
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
|
||||
}
|
||||
}
|
||||
return content
|
|
@ -24,7 +24,7 @@ class Appliances:
|
|||
@property
|
||||
def density(self) -> Union[None, float]:
|
||||
"""
|
||||
Get appliances density in Watts per m2
|
||||
Get appliances density in W/m2
|
||||
:return: None or float
|
||||
"""
|
||||
return self._density
|
||||
|
|
|
@ -65,7 +65,7 @@ class Usage:
|
|||
@property
|
||||
def mechanical_air_change(self) -> Union[None, float]:
|
||||
"""
|
||||
Get usage zone mechanical air change in air change per hour (ACH)
|
||||
Get usage zone mechanical air change in air change per second (1/s)
|
||||
:return: None or float
|
||||
"""
|
||||
return self._mechanical_air_change
|
||||
|
|
|
@ -10,45 +10,46 @@ 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.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.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
|
||||
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
|
||||
|
||||
|
||||
class MontrealCustomCatalog(Catalog):
|
||||
"""
|
||||
Montreal custom energy systems catalog class
|
||||
"""
|
||||
|
||||
def __init__(self, path):
|
||||
path = str(path / 'montreal_custom_systems.xml')
|
||||
with open(path, 'r', encoding='utf-8') as xml:
|
||||
self._archetypes = xmltodict.parse(xml.read(), force_list=('system', 'system_cluster', 'equipment',
|
||||
'demand', 'system_id'))
|
||||
|
||||
self._lod = float(self._archetypes['catalog']['@lod'])
|
||||
|
||||
self._catalog_generation_equipments = self._load_generation_equipments()
|
||||
self._catalog_distribution_equipments = self._load_distribution_equipments()
|
||||
self._catalog_emission_equipments = self._load_emission_equipments()
|
||||
self._catalog_distribution_equipments = self._load_distribution_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_emission_equipments)
|
||||
self._catalog_distribution_equipments)
|
||||
|
||||
def _load_generation_equipments(self):
|
||||
_equipments = []
|
||||
_storages = []
|
||||
equipments = self._archetypes['catalog']['generation_equipments']['equipment']
|
||||
for equipment in equipments:
|
||||
equipment_id = float(equipment['@id'])
|
||||
equipment_type = equipment['@type']
|
||||
fuel_type = equipment['@fuel_type']
|
||||
name = equipment['name']
|
||||
model_name = equipment['name']
|
||||
heating_efficiency = None
|
||||
if 'heating_efficiency' in equipment:
|
||||
heating_efficiency = float(equipment['heating_efficiency'])
|
||||
|
@ -58,21 +59,38 @@ class MontrealCustomCatalog(Catalog):
|
|||
electricity_efficiency = None
|
||||
if 'electrical_efficiency' in equipment:
|
||||
electricity_efficiency = float(equipment['electrical_efficiency'])
|
||||
storage = literal_eval(equipment['storage'].capitalize())
|
||||
generation_system = GenerationSystem(equipment_id,
|
||||
name,
|
||||
equipment_type,
|
||||
fuel_type,
|
||||
None,
|
||||
heating_efficiency,
|
||||
cooling_efficiency,
|
||||
electricity_efficiency,
|
||||
None,
|
||||
None,
|
||||
storage,
|
||||
None)
|
||||
|
||||
storage_systems = None
|
||||
storage = literal_eval(equipment['storage'].capitalize())
|
||||
if storage:
|
||||
if equipment_type == 'electricity generator':
|
||||
storage_system = ElectricalStorageSystem(equipment_id)
|
||||
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)
|
||||
|
||||
return _equipments
|
||||
|
||||
def _load_distribution_equipments(self):
|
||||
|
@ -81,7 +99,7 @@ class MontrealCustomCatalog(Catalog):
|
|||
for equipment in equipments:
|
||||
equipment_id = float(equipment['@id'])
|
||||
equipment_type = equipment['@type']
|
||||
name = equipment['name']
|
||||
model_name = equipment['name']
|
||||
distribution_heat_losses = None
|
||||
if 'distribution_heat_losses' in equipment:
|
||||
distribution_heat_losses = float(equipment['distribution_heat_losses']['#text']) / 100
|
||||
|
@ -90,15 +108,22 @@ class MontrealCustomCatalog(Catalog):
|
|||
distribution_consumption_fix_flow = float(equipment['distribution_consumption_fix_flow']['#text']) / 100
|
||||
distribution_consumption_variable_flow = None
|
||||
if 'distribution_consumption_variable_flow' in equipment:
|
||||
distribution_consumption_variable_flow = float(equipment['distribution_consumption_variable_flow']['#text']) / 100
|
||||
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,
|
||||
name,
|
||||
equipment_type,
|
||||
None,
|
||||
distribution_consumption_fix_flow,
|
||||
distribution_consumption_variable_flow,
|
||||
distribution_heat_losses)
|
||||
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)
|
||||
|
||||
_equipments.append(distribution_system)
|
||||
return _equipments
|
||||
|
@ -109,15 +134,15 @@ class MontrealCustomCatalog(Catalog):
|
|||
for equipment in equipments:
|
||||
equipment_id = float(equipment['@id'])
|
||||
equipment_type = equipment['@type']
|
||||
name = equipment['name']
|
||||
parasitic_consumption = None
|
||||
model_name = equipment['name']
|
||||
parasitic_consumption = 0
|
||||
if 'parasitic_consumption' in equipment:
|
||||
parasitic_consumption = float(equipment['parasitic_consumption']['#text']) / 100
|
||||
|
||||
emission_system = EmissionSystem(equipment_id,
|
||||
name,
|
||||
equipment_type,
|
||||
parasitic_consumption)
|
||||
model_name=model_name,
|
||||
system_type=equipment_type,
|
||||
parasitic_energy_consumption=parasitic_consumption)
|
||||
|
||||
_equipments.append(emission_system)
|
||||
return _equipments
|
||||
|
@ -130,28 +155,21 @@ class MontrealCustomCatalog(Catalog):
|
|||
name = system['name']
|
||||
demands = system['demands']['demand']
|
||||
generation_equipment = system['equipments']['generation_id']
|
||||
_generation_equipment = None
|
||||
_generation_equipments = None
|
||||
for equipment_archetype in self._catalog_generation_equipments:
|
||||
if int(equipment_archetype.id) == int(generation_equipment):
|
||||
_generation_equipment = equipment_archetype
|
||||
_generation_equipments = [equipment_archetype]
|
||||
distribution_equipment = system['equipments']['distribution_id']
|
||||
_distribution_equipment = None
|
||||
_distribution_equipments = None
|
||||
for equipment_archetype in self._catalog_distribution_equipments:
|
||||
if int(equipment_archetype.id) == int(distribution_equipment):
|
||||
_distribution_equipment = equipment_archetype
|
||||
emission_equipment = system['equipments']['dissipation_id']
|
||||
_emission_equipment = None
|
||||
for equipment_archetype in self._catalog_emission_equipments:
|
||||
if int(equipment_archetype.id) == int(emission_equipment):
|
||||
_emission_equipment = equipment_archetype
|
||||
_distribution_equipments = [equipment_archetype]
|
||||
|
||||
_catalog_systems.append(System(self._lod,
|
||||
system_id,
|
||||
name,
|
||||
_catalog_systems.append(System(system_id,
|
||||
demands,
|
||||
_generation_equipment,
|
||||
_distribution_equipment,
|
||||
_emission_equipment))
|
||||
name=name,
|
||||
generation_systems=_generation_equipments,
|
||||
distribution_systems=_distribution_equipments))
|
||||
return _catalog_systems
|
||||
|
||||
def _load_archetypes(self):
|
||||
|
@ -165,7 +183,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(self._lod, name, _systems))
|
||||
_catalog_archetypes.append(Archetype(name, _systems))
|
||||
return _catalog_archetypes
|
||||
|
||||
def names(self, category=None):
|
||||
|
@ -175,17 +193,15 @@ class MontrealCustomCatalog(Catalog):
|
|||
"""
|
||||
if category is None:
|
||||
_names = {'archetypes': [], 'systems': [], 'generation_equipments': [], 'distribution_equipments': [],
|
||||
'emission_equipments':[]}
|
||||
'emission_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)
|
||||
_names['generation_equipments'].append(equipment.model_name)
|
||||
for equipment in self._content.distribution_equipments:
|
||||
_names['distribution_equipments'].append(equipment.name)
|
||||
for equipment in self._content.emission_equipments:
|
||||
_names['emission_equipments'].append(equipment.name)
|
||||
_names['distribution_equipments'].append(equipment.model_name)
|
||||
else:
|
||||
_names = {category: []}
|
||||
if category.lower() == 'archetypes':
|
||||
|
@ -196,13 +212,10 @@ class MontrealCustomCatalog(Catalog):
|
|||
_names[category].append(system.name)
|
||||
elif category.lower() == 'generation_equipments':
|
||||
for system in self._content.generation_equipments:
|
||||
_names[category].append(system.name)
|
||||
_names[category].append(system.model_name)
|
||||
elif category.lower() == 'distribution_equipments':
|
||||
for system in self._content.distribution_equipments:
|
||||
_names[category].append(system.name)
|
||||
elif category.lower() == 'emission_equipments':
|
||||
for system in self._content.emission_equipments:
|
||||
_names[category].append(system.name)
|
||||
_names[category].append(system.model_name)
|
||||
else:
|
||||
raise ValueError(f'Unknown category [{category}]')
|
||||
return _names
|
||||
|
@ -222,9 +235,6 @@ 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):
|
||||
"""
|
||||
|
@ -238,12 +248,9 @@ class MontrealCustomCatalog(Catalog):
|
|||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.generation_equipments:
|
||||
if entry.name.lower() == name.lower():
|
||||
if entry.model_name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.distribution_equipments:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.emission_equipments:
|
||||
if entry.name.lower() == name.lower():
|
||||
if entry.model_name.lower() == name.lower():
|
||||
return entry
|
||||
raise IndexError(f"{name} doesn't exists in the catalog")
|
||||
|
|
|
@ -0,0 +1,559 @@
|
|||
"""
|
||||
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")
|
520
hub/catalog_factories/energy_systems/palma_system_catalgue.py
Normal file
520
hub/catalog_factories/energy_systems/palma_system_catalgue.py
Normal file
|
@ -0,0 +1,520 @@
|
|||
"""
|
||||
Palma energy system catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
|
||||
"""
|
||||
|
||||
import xmltodict
|
||||
from pathlib import Path
|
||||
from hub.catalog_factories.catalog import Catalog
|
||||
from hub.catalog_factories.data_models.energy_systems.distribution_system import DistributionSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.emission_system import EmissionSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.system import System
|
||||
from hub.catalog_factories.data_models.energy_systems.content import Content
|
||||
from hub.catalog_factories.data_models.energy_systems.non_pv_generation_system import NonPvGenerationSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.pv_generation_system import PvGenerationSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.thermal_storage_system import ThermalStorageSystem
|
||||
from hub.catalog_factories.data_models.energy_systems.performance_curves import PerformanceCurves
|
||||
from hub.catalog_factories.data_models.energy_systems.archetype import Archetype
|
||||
from hub.catalog_factories.data_models.construction.material import Material
|
||||
from hub.catalog_factories.data_models.construction.layer import Layer
|
||||
|
||||
|
||||
class PalmaSystemCatalogue(Catalog):
|
||||
"""
|
||||
North america energy system catalog class
|
||||
"""
|
||||
|
||||
def __init__(self, path):
|
||||
path = str(path / 'palma_systems.xml')
|
||||
with open(path, 'r', encoding='utf-8') as xml:
|
||||
self._archetypes = xmltodict.parse(xml.read(),
|
||||
force_list=['pv_generation_component', 'demand'])
|
||||
|
||||
self._storage_components = self._load_storage_components()
|
||||
self._generation_components = self._load_generation_components()
|
||||
self._energy_emission_components = self._load_emission_equipments()
|
||||
self._distribution_components = self._load_distribution_equipments()
|
||||
self._systems = self._load_systems()
|
||||
self._system_archetypes = self._load_archetypes()
|
||||
self._content = Content(self._system_archetypes,
|
||||
self._systems,
|
||||
generations=self._generation_components,
|
||||
distributions=self._distribution_components)
|
||||
|
||||
def _load_generation_components(self):
|
||||
generation_components = []
|
||||
non_pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][
|
||||
'non_pv_generation_component']
|
||||
if non_pv_generation_components is not None:
|
||||
for non_pv in non_pv_generation_components:
|
||||
system_id = non_pv['system_id']
|
||||
name = non_pv['name']
|
||||
system_type = non_pv['system_type']
|
||||
model_name = non_pv['model_name']
|
||||
manufacturer = non_pv['manufacturer']
|
||||
fuel_type = non_pv['fuel_type']
|
||||
distribution_systems = non_pv['distribution_systems']
|
||||
energy_storage_systems = None
|
||||
if non_pv['energy_storage_systems'] is not None:
|
||||
storage_component = non_pv['energy_storage_systems']['storage_id']
|
||||
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component)
|
||||
energy_storage_systems = storage_systems
|
||||
nominal_heat_output = non_pv['nominal_heat_output']
|
||||
maximum_heat_output = non_pv['maximum_heat_output']
|
||||
minimum_heat_output = non_pv['minimum_heat_output']
|
||||
source_medium = non_pv['source_medium']
|
||||
supply_medium = non_pv['supply_medium']
|
||||
heat_efficiency = non_pv['heat_efficiency']
|
||||
nominal_cooling_output = non_pv['nominal_cooling_output']
|
||||
maximum_cooling_output = non_pv['maximum_cooling_output']
|
||||
minimum_cooling_output = non_pv['minimum_cooling_output']
|
||||
cooling_efficiency = non_pv['cooling_efficiency']
|
||||
electricity_efficiency = non_pv['electricity_efficiency']
|
||||
source_temperature = non_pv['source_temperature']
|
||||
source_mass_flow = non_pv['source_mass_flow']
|
||||
nominal_electricity_output = non_pv['nominal_electricity_output']
|
||||
maximum_heat_supply_temperature = non_pv['maximum_heat_supply_temperature']
|
||||
minimum_heat_supply_temperature = non_pv['minimum_heat_supply_temperature']
|
||||
maximum_cooling_supply_temperature = non_pv['maximum_cooling_supply_temperature']
|
||||
minimum_cooling_supply_temperature = non_pv['minimum_cooling_supply_temperature']
|
||||
heat_output_curve = None
|
||||
heat_fuel_consumption_curve = None
|
||||
heat_efficiency_curve = None
|
||||
cooling_output_curve = None
|
||||
cooling_fuel_consumption_curve = None
|
||||
cooling_efficiency_curve = None
|
||||
if non_pv['heat_output_curve'] is not None:
|
||||
curve_type = non_pv['heat_output_curve']['curve_type']
|
||||
dependant_variable = non_pv['heat_output_curve']['dependant_variable']
|
||||
parameters = non_pv['heat_output_curve']['parameters']
|
||||
coefficients = list(non_pv['heat_output_curve']['coefficients'].values())
|
||||
heat_output_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
if non_pv['heat_fuel_consumption_curve'] is not None:
|
||||
curve_type = non_pv['heat_fuel_consumption_curve']['curve_type']
|
||||
dependant_variable = non_pv['heat_fuel_consumption_curve']['dependant_variable']
|
||||
parameters = non_pv['heat_fuel_consumption_curve']['parameters']
|
||||
coefficients = list(non_pv['heat_fuel_consumption_curve']['coefficients'].values())
|
||||
heat_fuel_consumption_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
if non_pv['heat_efficiency_curve'] is not None:
|
||||
curve_type = non_pv['heat_efficiency_curve']['curve_type']
|
||||
dependant_variable = non_pv['heat_efficiency_curve']['dependant_variable']
|
||||
parameters = non_pv['heat_efficiency_curve']['parameters']
|
||||
coefficients = list(non_pv['heat_efficiency_curve']['coefficients'].values())
|
||||
heat_efficiency_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
if non_pv['cooling_output_curve'] is not None:
|
||||
curve_type = non_pv['cooling_output_curve']['curve_type']
|
||||
dependant_variable = non_pv['cooling_output_curve']['dependant_variable']
|
||||
parameters = non_pv['cooling_output_curve']['parameters']
|
||||
coefficients = list(non_pv['cooling_output_curve']['coefficients'].values())
|
||||
cooling_output_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
if non_pv['cooling_fuel_consumption_curve'] is not None:
|
||||
curve_type = non_pv['cooling_fuel_consumption_curve']['curve_type']
|
||||
dependant_variable = non_pv['cooling_fuel_consumption_curve']['dependant_variable']
|
||||
parameters = non_pv['cooling_fuel_consumption_curve']['parameters']
|
||||
coefficients = list(non_pv['cooling_fuel_consumption_curve']['coefficients'].values())
|
||||
cooling_fuel_consumption_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
if non_pv['cooling_efficiency_curve'] is not None:
|
||||
curve_type = non_pv['cooling_efficiency_curve']['curve_type']
|
||||
dependant_variable = non_pv['cooling_efficiency_curve']['dependant_variable']
|
||||
parameters = non_pv['cooling_efficiency_curve']['parameters']
|
||||
coefficients = list(non_pv['cooling_efficiency_curve']['coefficients'].values())
|
||||
cooling_efficiency_curve = PerformanceCurves(curve_type, dependant_variable, parameters, coefficients)
|
||||
dhw = None
|
||||
if non_pv['domestic_hot_water'] is not None:
|
||||
if non_pv['domestic_hot_water'] == 'True':
|
||||
dhw = True
|
||||
else:
|
||||
dhw = False
|
||||
|
||||
reversible = None
|
||||
if non_pv['reversible'] is not None:
|
||||
if non_pv['reversible'] == 'True':
|
||||
reversible = True
|
||||
else:
|
||||
reversible = False
|
||||
|
||||
dual_supply = None
|
||||
if non_pv['simultaneous_heat_cold'] is not None:
|
||||
if non_pv['simultaneous_heat_cold'] == 'True':
|
||||
dual_supply = True
|
||||
else:
|
||||
dual_supply = False
|
||||
non_pv_component = NonPvGenerationSystem(system_id=system_id,
|
||||
name=name,
|
||||
system_type=system_type,
|
||||
model_name=model_name,
|
||||
manufacturer=manufacturer,
|
||||
fuel_type=fuel_type,
|
||||
nominal_heat_output=nominal_heat_output,
|
||||
maximum_heat_output=maximum_heat_output,
|
||||
minimum_heat_output=minimum_heat_output,
|
||||
source_medium=source_medium,
|
||||
supply_medium=supply_medium,
|
||||
heat_efficiency=heat_efficiency,
|
||||
nominal_cooling_output=nominal_cooling_output,
|
||||
maximum_cooling_output=maximum_cooling_output,
|
||||
minimum_cooling_output=minimum_cooling_output,
|
||||
cooling_efficiency=cooling_efficiency,
|
||||
electricity_efficiency=electricity_efficiency,
|
||||
source_temperature=source_temperature,
|
||||
source_mass_flow=source_mass_flow,
|
||||
nominal_electricity_output=nominal_electricity_output,
|
||||
maximum_heat_supply_temperature=maximum_heat_supply_temperature,
|
||||
minimum_heat_supply_temperature=minimum_heat_supply_temperature,
|
||||
maximum_cooling_supply_temperature=maximum_cooling_supply_temperature,
|
||||
minimum_cooling_supply_temperature=minimum_cooling_supply_temperature,
|
||||
heat_output_curve=heat_output_curve,
|
||||
heat_fuel_consumption_curve=heat_fuel_consumption_curve,
|
||||
heat_efficiency_curve=heat_efficiency_curve,
|
||||
cooling_output_curve=cooling_output_curve,
|
||||
cooling_fuel_consumption_curve=cooling_fuel_consumption_curve,
|
||||
cooling_efficiency_curve=cooling_efficiency_curve,
|
||||
distribution_systems=distribution_systems,
|
||||
energy_storage_systems=energy_storage_systems,
|
||||
domestic_hot_water=dhw,
|
||||
reversible=reversible,
|
||||
simultaneous_heat_cold=dual_supply)
|
||||
generation_components.append(non_pv_component)
|
||||
pv_generation_components = self._archetypes['EnergySystemCatalog']['energy_generation_components'][
|
||||
'pv_generation_component']
|
||||
if pv_generation_components is not None:
|
||||
for pv in pv_generation_components:
|
||||
system_id = pv['system_id']
|
||||
name = pv['name']
|
||||
system_type = pv['system_type']
|
||||
model_name = pv['model_name']
|
||||
manufacturer = pv['manufacturer']
|
||||
electricity_efficiency = pv['electricity_efficiency']
|
||||
nominal_electricity_output = pv['nominal_electricity_output']
|
||||
nominal_ambient_temperature = pv['nominal_ambient_temperature']
|
||||
nominal_cell_temperature = pv['nominal_cell_temperature']
|
||||
nominal_radiation = pv['nominal_radiation']
|
||||
standard_test_condition_cell_temperature = pv['standard_test_condition_cell_temperature']
|
||||
standard_test_condition_maximum_power = pv['standard_test_condition_maximum_power']
|
||||
standard_test_condition_radiation = pv['standard_test_condition_radiation']
|
||||
cell_temperature_coefficient = pv['cell_temperature_coefficient']
|
||||
width = pv['width']
|
||||
height = pv['height']
|
||||
distribution_systems = pv['distribution_systems']
|
||||
energy_storage_systems = None
|
||||
if pv['energy_storage_systems'] is not None:
|
||||
storage_component = pv['energy_storage_systems']['storage_id']
|
||||
storage_systems = self._search_storage_equipment(self._load_storage_components(), storage_component)
|
||||
energy_storage_systems = storage_systems
|
||||
pv_component = PvGenerationSystem(system_id=system_id,
|
||||
name=name,
|
||||
system_type=system_type,
|
||||
model_name=model_name,
|
||||
manufacturer=manufacturer,
|
||||
electricity_efficiency=electricity_efficiency,
|
||||
nominal_electricity_output=nominal_electricity_output,
|
||||
nominal_ambient_temperature=nominal_ambient_temperature,
|
||||
nominal_cell_temperature=nominal_cell_temperature,
|
||||
nominal_radiation=nominal_radiation,
|
||||
standard_test_condition_cell_temperature=
|
||||
standard_test_condition_cell_temperature,
|
||||
standard_test_condition_maximum_power=standard_test_condition_maximum_power,
|
||||
standard_test_condition_radiation=standard_test_condition_radiation,
|
||||
cell_temperature_coefficient=cell_temperature_coefficient,
|
||||
width=width,
|
||||
height=height,
|
||||
distribution_systems=distribution_systems,
|
||||
energy_storage_systems=energy_storage_systems)
|
||||
generation_components.append(pv_component)
|
||||
|
||||
return generation_components
|
||||
|
||||
def _load_distribution_equipments(self):
|
||||
_equipments = []
|
||||
distribution_systems = self._archetypes['EnergySystemCatalog']['distribution_systems']['distribution_system']
|
||||
if distribution_systems is not None:
|
||||
for distribution_system in distribution_systems:
|
||||
system_id = None
|
||||
model_name = None
|
||||
system_type = None
|
||||
supply_temperature = None
|
||||
distribution_consumption_fix_flow = None
|
||||
distribution_consumption_variable_flow = None
|
||||
heat_losses = None
|
||||
generation_systems = None
|
||||
energy_storage_systems = None
|
||||
emission_systems = None
|
||||
distribution_equipment = DistributionSystem(system_id=system_id,
|
||||
model_name=model_name,
|
||||
system_type=system_type,
|
||||
supply_temperature=supply_temperature,
|
||||
distribution_consumption_fix_flow=distribution_consumption_fix_flow,
|
||||
distribution_consumption_variable_flow=
|
||||
distribution_consumption_variable_flow,
|
||||
heat_losses=heat_losses,
|
||||
generation_systems=generation_systems,
|
||||
energy_storage_systems=energy_storage_systems,
|
||||
emission_systems=emission_systems
|
||||
)
|
||||
_equipments.append(distribution_equipment)
|
||||
return _equipments
|
||||
|
||||
def _load_emission_equipments(self):
|
||||
_equipments = []
|
||||
dissipation_systems = self._archetypes['EnergySystemCatalog']['dissipation_systems']['dissipation_system']
|
||||
if dissipation_systems is not None:
|
||||
for dissipation_system in dissipation_systems:
|
||||
system_id = None
|
||||
model_name = None
|
||||
system_type = None
|
||||
parasitic_energy_consumption = 0
|
||||
emission_system = EmissionSystem(system_id=system_id,
|
||||
model_name=model_name,
|
||||
system_type=system_type,
|
||||
parasitic_energy_consumption=parasitic_energy_consumption)
|
||||
_equipments.append(emission_system)
|
||||
return _equipments
|
||||
|
||||
def _load_storage_components(self):
|
||||
storage_components = []
|
||||
thermal_storages = self._archetypes['EnergySystemCatalog']['energy_storage_components']['thermalStorages']
|
||||
for tes in thermal_storages:
|
||||
storage_id = tes['storage_id']
|
||||
type_energy_stored = tes['type_energy_stored']
|
||||
model_name = tes['model_name']
|
||||
manufacturer = tes['manufacturer']
|
||||
storage_type = tes['storage_type']
|
||||
volume = tes['physical_characteristics']['volume']
|
||||
height = tes['physical_characteristics']['height']
|
||||
maximum_operating_temperature = tes['maximum_operating_temperature']
|
||||
materials = self._load_materials()
|
||||
insulation_material_id = tes['insulation']['material_id']
|
||||
insulation_material = self._search_material(materials, insulation_material_id)
|
||||
material_id = tes['physical_characteristics']['material_id']
|
||||
tank_material = self._search_material(materials, material_id)
|
||||
thickness = float(tes['insulation']['insulationThickness']) / 100 # from cm to m
|
||||
insulation_layer = Layer(None, 'insulation', insulation_material, thickness)
|
||||
thickness = float(tes['physical_characteristics']['tankThickness']) / 100 # from cm to m
|
||||
tank_layer = Layer(None, 'tank', tank_material, thickness)
|
||||
media = self._load_media()
|
||||
media_id = tes['storage_medium']['medium_id']
|
||||
medium = self._search_media(media, media_id)
|
||||
layers = [insulation_layer, tank_layer]
|
||||
nominal_capacity = tes['nominal_capacity']
|
||||
losses_ratio = tes['losses_ratio']
|
||||
heating_coil_capacity = tes['heating_coil_capacity']
|
||||
storage_component = ThermalStorageSystem(storage_id=storage_id,
|
||||
model_name=model_name,
|
||||
type_energy_stored=type_energy_stored,
|
||||
manufacturer=manufacturer,
|
||||
storage_type=storage_type,
|
||||
nominal_capacity=nominal_capacity,
|
||||
losses_ratio=losses_ratio,
|
||||
volume=volume,
|
||||
height=height,
|
||||
layers=layers,
|
||||
maximum_operating_temperature=maximum_operating_temperature,
|
||||
storage_medium=medium,
|
||||
heating_coil_capacity=heating_coil_capacity)
|
||||
storage_components.append(storage_component)
|
||||
return storage_components
|
||||
|
||||
def _load_systems(self):
|
||||
base_path = Path(Path(__file__).parent.parent.parent / 'data/energy_systems')
|
||||
_catalog_systems = []
|
||||
systems = self._archetypes['EnergySystemCatalog']['systems']['system']
|
||||
for system in systems:
|
||||
system_id = system['id']
|
||||
name = system['name']
|
||||
demands = system['demands']['demand']
|
||||
generation_components = system['components']['generation_id']
|
||||
generation_systems = self._search_generation_equipment(self._load_generation_components(), generation_components)
|
||||
configuration_schema = None
|
||||
if system['schema'] is not None:
|
||||
configuration_schema = Path(base_path / system['schema'])
|
||||
energy_system = System(system_id=system_id,
|
||||
name=name,
|
||||
demand_types=demands,
|
||||
generation_systems=generation_systems,
|
||||
distribution_systems=None,
|
||||
configuration_schema=configuration_schema)
|
||||
_catalog_systems.append(energy_system)
|
||||
return _catalog_systems
|
||||
|
||||
def _load_archetypes(self):
|
||||
_system_archetypes = []
|
||||
system_clusters = self._archetypes['EnergySystemCatalog']['system_archetypes']['system_archetype']
|
||||
for system_cluster in system_clusters:
|
||||
name = system_cluster['name']
|
||||
systems = system_cluster['systems']['system_id']
|
||||
integer_system_ids = [int(item) for item in systems]
|
||||
_systems = []
|
||||
for system_archetype in self._systems:
|
||||
if int(system_archetype.id) in integer_system_ids:
|
||||
_systems.append(system_archetype)
|
||||
_system_archetypes.append(Archetype(name=name, systems=_systems))
|
||||
return _system_archetypes
|
||||
|
||||
def _load_materials(self):
|
||||
materials = []
|
||||
_materials = self._archetypes['EnergySystemCatalog']['materials']['material']
|
||||
for _material in _materials:
|
||||
material_id = _material['material_id']
|
||||
name = _material['name']
|
||||
conductivity = _material['conductivity']
|
||||
solar_absorptance = _material['solar_absorptance']
|
||||
thermal_absorptance = _material['thermal_absorptance']
|
||||
density = _material['density']
|
||||
specific_heat = _material['specific_heat']
|
||||
no_mass = _material['no_mass']
|
||||
visible_absorptance = _material['visible_absorptance']
|
||||
thermal_resistance = _material['thermal_resistance']
|
||||
|
||||
material = Material(material_id,
|
||||
name,
|
||||
solar_absorptance=solar_absorptance,
|
||||
thermal_absorptance=thermal_absorptance,
|
||||
density=density,
|
||||
conductivity=conductivity,
|
||||
thermal_resistance=thermal_resistance,
|
||||
visible_absorptance=visible_absorptance,
|
||||
no_mass=no_mass,
|
||||
specific_heat=specific_heat)
|
||||
materials.append(material)
|
||||
return materials
|
||||
|
||||
@staticmethod
|
||||
def _search_material(materials, material_id):
|
||||
_material = None
|
||||
for material in materials:
|
||||
if int(material.id) == int(material_id):
|
||||
_material = material
|
||||
break
|
||||
if _material is None:
|
||||
raise ValueError(f'Material with the id = [{material_id}] not found in catalog ')
|
||||
return _material
|
||||
|
||||
def _load_media(self):
|
||||
media = []
|
||||
_media = [self._archetypes['EnergySystemCatalog']['media']['medium']]
|
||||
for _medium in _media:
|
||||
medium_id = _medium['medium_id']
|
||||
density = _medium['density']
|
||||
name = _medium['name']
|
||||
conductivity = _medium['conductivity']
|
||||
solar_absorptance = _medium['solar_absorptance']
|
||||
thermal_absorptance = _medium['thermal_absorptance']
|
||||
specific_heat = _medium['specific_heat']
|
||||
no_mass = _medium['no_mass']
|
||||
visible_absorptance = _medium['visible_absorptance']
|
||||
thermal_resistance = _medium['thermal_resistance']
|
||||
medium = Material(material_id=medium_id,
|
||||
name=name,
|
||||
solar_absorptance=solar_absorptance,
|
||||
thermal_absorptance=thermal_absorptance,
|
||||
visible_absorptance=visible_absorptance,
|
||||
no_mass=no_mass,
|
||||
thermal_resistance=thermal_resistance,
|
||||
conductivity=conductivity,
|
||||
density=density,
|
||||
specific_heat=specific_heat)
|
||||
media.append(medium)
|
||||
return media
|
||||
|
||||
@staticmethod
|
||||
def _search_media(media, medium_id):
|
||||
_medium = None
|
||||
for medium in media:
|
||||
if int(medium.id) == int(medium_id):
|
||||
_medium = medium
|
||||
break
|
||||
if _medium is None:
|
||||
raise ValueError(f'media with the id = [{medium_id}] not found in catalog ')
|
||||
return _medium
|
||||
|
||||
@staticmethod
|
||||
def _search_generation_equipment(generation_systems, generation_id):
|
||||
_generation_systems = []
|
||||
|
||||
if isinstance(generation_id, list):
|
||||
integer_ids = [int(item) for item in generation_id]
|
||||
for generation in generation_systems:
|
||||
if int(generation.id) in integer_ids:
|
||||
_generation_systems.append(generation)
|
||||
else:
|
||||
integer_id = int(generation_id)
|
||||
for generation in generation_systems:
|
||||
if int(generation.id) == integer_id:
|
||||
_generation_systems.append(generation)
|
||||
|
||||
if len(_generation_systems) == 0:
|
||||
_generation_systems = None
|
||||
raise ValueError(f'The system with the following id is not found in catalog [{generation_id}]')
|
||||
return _generation_systems
|
||||
|
||||
@staticmethod
|
||||
def _search_storage_equipment(storage_systems, storage_id):
|
||||
_storage_systems = []
|
||||
for storage in storage_systems:
|
||||
if storage.id in storage_id:
|
||||
_storage_systems.append(storage)
|
||||
if len(_storage_systems) == 0:
|
||||
_storage_systems = None
|
||||
raise ValueError(f'The system with the following id is not found in catalog [{storage_id}]')
|
||||
return _storage_systems
|
||||
|
||||
def names(self, category=None):
|
||||
"""
|
||||
Get the catalog elements names
|
||||
:parm: optional category filter
|
||||
"""
|
||||
if category is None:
|
||||
_names = {'archetypes': [], 'systems': [], 'generation_equipments': [], 'storage_equipments': []}
|
||||
for archetype in self._content.archetypes:
|
||||
_names['archetypes'].append(archetype.name)
|
||||
for system in self._content.systems:
|
||||
_names['systems'].append(system.name)
|
||||
for equipment in self._content.generation_equipments:
|
||||
_names['generation_equipments'].append(equipment.name)
|
||||
else:
|
||||
_names = {category: []}
|
||||
if category.lower() == 'archetypes':
|
||||
for archetype in self._content.archetypes:
|
||||
_names[category].append(archetype.name)
|
||||
elif category.lower() == 'systems':
|
||||
for system in self._content.systems:
|
||||
_names[category].append(system.name)
|
||||
elif category.lower() == 'generation_equipments':
|
||||
for system in self._content.generation_equipments:
|
||||
_names[category].append(system.name)
|
||||
else:
|
||||
raise ValueError(f'Unknown category [{category}]')
|
||||
return _names
|
||||
|
||||
def entries(self, category=None):
|
||||
"""
|
||||
Get the catalog elements
|
||||
:parm: optional category filter
|
||||
"""
|
||||
if category is None:
|
||||
return self._content
|
||||
if category.lower() == 'archetypes':
|
||||
return self._content.archetypes
|
||||
if category.lower() == 'systems':
|
||||
return self._content.systems
|
||||
if category.lower() == 'generation_equipments':
|
||||
return self._content.generation_equipments
|
||||
raise ValueError(f'Unknown category [{category}]')
|
||||
|
||||
def get_entry(self, name):
|
||||
"""
|
||||
Get one catalog element by names
|
||||
:parm: entry name
|
||||
"""
|
||||
for entry in self._content.archetypes:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.systems:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
for entry in self._content.generation_equipments:
|
||||
if entry.name.lower() == name.lower():
|
||||
return entry
|
||||
raise IndexError(f"{name} doesn't exists in the catalog")
|
|
@ -9,6 +9,8 @@ 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.helpers.utils import validate_import_export_type
|
||||
|
||||
Catalog = TypeVar('Catalog')
|
||||
|
@ -32,6 +34,20 @@ class EnergySystemsCatalogFactory:
|
|||
"""
|
||||
return MontrealCustomCatalog(self._path)
|
||||
|
||||
@property
|
||||
def _montreal_future(self):
|
||||
"""
|
||||
Retrieve North American catalog
|
||||
"""
|
||||
return MontrealFutureSystemCatalogue(self._path)
|
||||
|
||||
@property
|
||||
def _palma(self):
|
||||
"""
|
||||
Retrieve Palma catalog
|
||||
"""
|
||||
return PalmaSystemCatalogue(self._path)
|
||||
|
||||
@property
|
||||
def catalog(self) -> Catalog:
|
||||
"""
|
||||
|
|
|
@ -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[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()
|
||||
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()
|
||||
|
||||
return {'lighting': lighting_data,
|
||||
'plug loads': plug_loads_data,
|
||||
|
|
|
@ -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[0]
|
||||
usage_type = usage_parameters.iloc[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()
|
||||
|
|
|
@ -8,6 +8,8 @@ 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
|
||||
|
@ -28,12 +30,11 @@ class NrcanCatalog(Catalog):
|
|||
Nrcan catalog class
|
||||
"""
|
||||
def __init__(self, path):
|
||||
path = str(path / 'nrcan.xml')
|
||||
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()
|
||||
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())
|
||||
|
||||
|
@ -55,11 +56,9 @@ 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 urllib.request.urlopen(url) as json_file:
|
||||
schedules_type = json.load(json_file)
|
||||
with open(self._schedules_path, 'r') as f:
|
||||
schedules_type = json.load(f)
|
||||
for schedule_type in schedules_type['tables']['schedules']['table']:
|
||||
schedule = NrcanCatalog._extract_schedule(schedule_type)
|
||||
if schedule_type['name'] not in _schedule_types:
|
||||
|
@ -80,14 +79,11 @@ class NrcanCatalog(Catalog):
|
|||
|
||||
def _load_archetypes(self):
|
||||
usages = []
|
||||
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']
|
||||
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 urllib.request.urlopen(url_2) as json_file:
|
||||
space_types_compliance = json.load(json_file)['tables']['space_compliance']['table']
|
||||
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:
|
||||
|
@ -134,8 +130,8 @@ class NrcanCatalog(Catalog):
|
|||
hvac_availability = self._get_schedules(hvac_schedule_name)
|
||||
domestic_hot_water_load_schedule = self._get_schedules(domestic_hot_water_schedule_name)
|
||||
|
||||
# ACH
|
||||
mechanical_air_change = space_type['ventilation_air_changes']
|
||||
# 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
|
||||
|
|
227
hub/catalog_factories/usage/palma_catalog.py
Normal file
227
hub/catalog_factories/usage/palma_catalog.py
Normal file
|
@ -0,0 +1,227 @@
|
|||
"""
|
||||
Palma usage catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Cecilia Pérez cperez@irec.cat
|
||||
"""
|
||||
|
||||
import json
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
import xmltodict
|
||||
|
||||
import hub.helpers.constants as cte
|
||||
from hub.catalog_factories.catalog import Catalog
|
||||
from hub.catalog_factories.data_models.usages.appliances import Appliances
|
||||
from hub.catalog_factories.data_models.usages.content import Content
|
||||
from hub.catalog_factories.data_models.usages.lighting import Lighting
|
||||
from hub.catalog_factories.data_models.usages.occupancy import Occupancy
|
||||
from hub.catalog_factories.data_models.usages.domestic_hot_water import DomesticHotWater
|
||||
from hub.catalog_factories.data_models.usages.schedule import Schedule
|
||||
from hub.catalog_factories.data_models.usages.thermal_control import ThermalControl
|
||||
from hub.catalog_factories.data_models.usages.usage import Usage
|
||||
from hub.catalog_factories.usage.usage_helper import UsageHelper
|
||||
|
||||
|
||||
class PalmaCatalog(Catalog):
|
||||
"""
|
||||
Palma catalog class
|
||||
"""
|
||||
def __init__(self, path):
|
||||
self._schedules_path = Path(path / 'palma_schedules.json').resolve()
|
||||
self._space_types_path = Path(path / 'palma_space_types.json').resolve()
|
||||
self._space_compliance_path = Path(path / 'palma_space_compliance.json').resolve()
|
||||
self._content = None
|
||||
self._schedules = {}
|
||||
self._load_schedules()
|
||||
self._content = Content(self._load_archetypes())
|
||||
|
||||
@staticmethod
|
||||
def _extract_schedule(raw):
|
||||
nrcan_schedule_type = raw['category']
|
||||
if 'Heating' in raw['name'] and 'Water' not in raw['name']:
|
||||
nrcan_schedule_type = f'{nrcan_schedule_type} Heating'
|
||||
elif 'Cooling' in raw['name']:
|
||||
nrcan_schedule_type = f'{nrcan_schedule_type} Cooling'
|
||||
if nrcan_schedule_type not in UsageHelper().nrcan_schedule_type_to_hub_schedule_type:
|
||||
return None
|
||||
hub_type = UsageHelper().nrcan_schedule_type_to_hub_schedule_type[nrcan_schedule_type]
|
||||
data_type = UsageHelper().nrcan_data_type_to_hub_data_type[raw['units']]
|
||||
time_step = UsageHelper().nrcan_time_to_hub_time[raw['type']]
|
||||
# nrcan only uses daily range for the schedules
|
||||
time_range = cte.DAY
|
||||
day_types = UsageHelper().nrcan_day_type_to_hub_days[raw['day_types']]
|
||||
return Schedule(hub_type, raw['values'], data_type, time_step, time_range, day_types)
|
||||
|
||||
def _load_schedules(self):
|
||||
_schedule_types = []
|
||||
with open(self._schedules_path, 'r') as f:
|
||||
schedules_type = json.load(f)
|
||||
for schedule_type in schedules_type['tables']['schedules']['table']:
|
||||
schedule = PalmaCatalog._extract_schedule(schedule_type)
|
||||
if schedule_type['name'] not in _schedule_types:
|
||||
_schedule_types.append(schedule_type['name'])
|
||||
if schedule is not None:
|
||||
self._schedules[schedule_type['name']] = [schedule]
|
||||
else:
|
||||
if schedule is not None:
|
||||
_schedules = self._schedules[schedule_type['name']]
|
||||
_schedules.append(schedule)
|
||||
self._schedules[schedule_type['name']] = _schedules
|
||||
|
||||
def _get_schedules(self, name):
|
||||
schedule = None
|
||||
if name in self._schedules:
|
||||
schedule = self._schedules[name]
|
||||
return schedule
|
||||
|
||||
def _load_archetypes(self):
|
||||
usages = []
|
||||
with open(self._space_types_path, 'r') as f:
|
||||
space_types = json.load(f)['tables']['space_types']['table']
|
||||
space_types = [st for st in space_types if st['space_type'] == 'WholeBuilding']
|
||||
with open(self._space_compliance_path, 'r') as f:
|
||||
space_types_compliance = json.load(f)['tables']['space_compliance']['table']
|
||||
space_types_compliance = [st for st in space_types_compliance if st['space_type'] == 'WholeBuilding']
|
||||
space_types_dictionary = {}
|
||||
for space_type in space_types_compliance:
|
||||
usage_type = space_type['building_type']
|
||||
# people/m2
|
||||
occupancy_density = space_type['occupancy_per_area_people_per_m2']
|
||||
# W/m2
|
||||
lighting_density = space_type['lighting_per_area_w_per_m2']
|
||||
# W/m2
|
||||
appliances_density = space_type['electric_equipment_per_area_w_per_m2']
|
||||
# peak flow in gallons/h/m2
|
||||
domestic_hot_water_peak_flow = (
|
||||
space_type['service_water_heating_peak_flow_per_area'] *
|
||||
cte.GALLONS_TO_QUBIC_METERS / cte.HOUR_TO_SECONDS
|
||||
)
|
||||
space_types_dictionary[usage_type] = {'occupancy_per_area': occupancy_density,
|
||||
'lighting_per_area': lighting_density,
|
||||
'electric_equipment_per_area': appliances_density,
|
||||
'service_water_heating_peak_flow_per_area': domestic_hot_water_peak_flow
|
||||
}
|
||||
|
||||
for space_type in space_types:
|
||||
usage_type = space_type['building_type']
|
||||
space_type_compliance = space_types_dictionary[usage_type]
|
||||
occupancy_density = space_type_compliance['occupancy_per_area']
|
||||
sensible_convective_internal_gain = space_type['sensible_convective_internal_gain']
|
||||
sensible_radiative_internal_gain = space_type['sensible_radiative_internal_gain']
|
||||
latent_internal_gain = space_type['latent_internal_gain']
|
||||
lighting_density = space_type_compliance['lighting_per_area']
|
||||
appliances_density = space_type_compliance['electric_equipment_per_area']
|
||||
domestic_hot_water_peak_flow = space_type_compliance['service_water_heating_peak_flow_per_area']
|
||||
|
||||
occupancy_schedule_name = space_type['occupancy_schedule']
|
||||
lighting_schedule_name = space_type['lighting_schedule']
|
||||
appliance_schedule_name = space_type['electric_equipment_schedule']
|
||||
hvac_schedule_name = space_type['exhaust_schedule']
|
||||
if hvac_schedule_name and 'FAN' in hvac_schedule_name:
|
||||
hvac_schedule_name = hvac_schedule_name.replace('FAN', 'Fan')
|
||||
if not hvac_schedule_name:
|
||||
hvac_schedule_name = 'default_HVAC_schedule'
|
||||
heating_setpoint_schedule_name = space_type['heating_setpoint_schedule']
|
||||
cooling_setpoint_schedule_name = space_type['cooling_setpoint_schedule']
|
||||
domestic_hot_water_schedule_name = space_type['service_water_heating_schedule']
|
||||
occupancy_schedule = self._get_schedules(occupancy_schedule_name)
|
||||
lighting_schedule = self._get_schedules(lighting_schedule_name)
|
||||
appliance_schedule = self._get_schedules(appliance_schedule_name)
|
||||
heating_schedule = self._get_schedules(heating_setpoint_schedule_name)
|
||||
cooling_schedule = self._get_schedules(cooling_setpoint_schedule_name)
|
||||
hvac_availability = self._get_schedules(hvac_schedule_name)
|
||||
domestic_hot_water_load_schedule = self._get_schedules(domestic_hot_water_schedule_name)
|
||||
|
||||
# ACH -> 1/s
|
||||
mechanical_air_change = space_type['ventilation_air_changes'] / cte.HOUR_TO_SECONDS
|
||||
# cfm/ft2 to m3/m2.s
|
||||
ventilation_rate = space_type['ventilation_per_area'] / (cte.METERS_TO_FEET * cte.MINUTES_TO_SECONDS)
|
||||
# cfm/person to m3/m2.s
|
||||
ventilation_rate += space_type['ventilation_per_person'] / (
|
||||
pow(cte.METERS_TO_FEET, 3) * cte.MINUTES_TO_SECONDS
|
||||
) * occupancy_density
|
||||
|
||||
lighting_radiative_fraction = space_type['lighting_fraction_radiant']
|
||||
lighting_convective_fraction = 0
|
||||
if lighting_radiative_fraction is not None:
|
||||
lighting_convective_fraction = 1 - lighting_radiative_fraction
|
||||
lighting_latent_fraction = 0
|
||||
appliances_radiative_fraction = space_type['electric_equipment_fraction_radiant']
|
||||
appliances_latent_fraction = space_type['electric_equipment_fraction_latent']
|
||||
appliances_convective_fraction = 0
|
||||
if appliances_radiative_fraction is not None and appliances_latent_fraction is not None:
|
||||
appliances_convective_fraction = 1 - appliances_radiative_fraction - appliances_latent_fraction
|
||||
|
||||
domestic_hot_water_service_temperature = space_type['service_water_heating_target_temperature']
|
||||
|
||||
occupancy = Occupancy(occupancy_density,
|
||||
sensible_convective_internal_gain,
|
||||
sensible_radiative_internal_gain,
|
||||
latent_internal_gain,
|
||||
occupancy_schedule)
|
||||
lighting = Lighting(lighting_density,
|
||||
lighting_convective_fraction,
|
||||
lighting_radiative_fraction,
|
||||
lighting_latent_fraction,
|
||||
lighting_schedule)
|
||||
appliances = Appliances(appliances_density,
|
||||
appliances_convective_fraction,
|
||||
appliances_radiative_fraction,
|
||||
appliances_latent_fraction,
|
||||
appliance_schedule)
|
||||
thermal_control = ThermalControl(None,
|
||||
None,
|
||||
None,
|
||||
hvac_availability,
|
||||
heating_schedule,
|
||||
cooling_schedule)
|
||||
domestic_hot_water = DomesticHotWater(None,
|
||||
domestic_hot_water_peak_flow,
|
||||
domestic_hot_water_service_temperature,
|
||||
domestic_hot_water_load_schedule)
|
||||
|
||||
hours_day = None
|
||||
days_year = None
|
||||
|
||||
usages.append(Usage(usage_type,
|
||||
hours_day,
|
||||
days_year,
|
||||
mechanical_air_change,
|
||||
ventilation_rate,
|
||||
occupancy,
|
||||
lighting,
|
||||
appliances,
|
||||
thermal_control,
|
||||
domestic_hot_water))
|
||||
|
||||
|
||||
return usages
|
||||
|
||||
def names(self, category=None):
|
||||
"""
|
||||
Get the catalog elements names
|
||||
:parm: for usage catalog category filter does nothing as there is only one category (usages)
|
||||
"""
|
||||
_names = {'usages': []}
|
||||
for usage in self._content.usages:
|
||||
_names['usages'].append(usage.name)
|
||||
return _names
|
||||
|
||||
def entries(self, category=None):
|
||||
"""
|
||||
Get the catalog elements
|
||||
:parm: for usage catalog category filter does nothing as there is only one category (usages)
|
||||
"""
|
||||
return self._content
|
||||
|
||||
def get_entry(self, name):
|
||||
"""
|
||||
Get one catalog element by names
|
||||
:parm: entry name
|
||||
"""
|
||||
for usage in self._content.usages:
|
||||
if usage.name.lower() == name.lower():
|
||||
return usage
|
||||
raise IndexError(f"{name} doesn't exists in the catalog")
|
|
@ -11,6 +11,7 @@ from typing import TypeVar
|
|||
from hub.catalog_factories.usage.comnet_catalog import ComnetCatalog
|
||||
from hub.catalog_factories.usage.nrcan_catalog import NrcanCatalog
|
||||
from hub.catalog_factories.usage.eilat_catalog import EilatCatalog
|
||||
from hub.catalog_factories.usage.palma_catalog import PalmaCatalog
|
||||
from hub.helpers.utils import validate_import_export_type
|
||||
|
||||
Catalog = TypeVar('Catalog')
|
||||
|
@ -42,6 +43,13 @@ class UsageCatalogFactory:
|
|||
# nrcan retrieves the data directly from github
|
||||
return NrcanCatalog(self._path)
|
||||
|
||||
@property
|
||||
def _palma(self):
|
||||
"""
|
||||
Retrieve Palma catalog
|
||||
"""
|
||||
return PalmaCatalog(self._path)
|
||||
|
||||
@property
|
||||
def _eilat(self):
|
||||
"""
|
||||
|
|
|
@ -41,7 +41,7 @@ class Building(CityObject):
|
|||
self._floor_area = None
|
||||
self._roof_type = None
|
||||
self._internal_zones = None
|
||||
self._thermal_zones = None
|
||||
self._thermal_zones_from_internal_zones = None
|
||||
self._shell = None
|
||||
self._aliases = []
|
||||
self._type = 'building'
|
||||
|
@ -70,6 +70,9 @@ 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)
|
||||
|
@ -86,7 +89,10 @@ class Building(CityObject):
|
|||
elif surface.type == cte.INTERIOR_SLAB:
|
||||
self._interior_slabs.append(surface)
|
||||
else:
|
||||
logging.error(f'Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type)
|
||||
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 = {}
|
||||
|
||||
@property
|
||||
def shell(self) -> Polyhedron:
|
||||
|
@ -114,26 +120,23 @@ class Building(CityObject):
|
|||
:return: [InternalZone]
|
||||
"""
|
||||
if self._internal_zones is None:
|
||||
self._internal_zones = [InternalZone(self.surfaces, self.floor_area)]
|
||||
self._internal_zones = [InternalZone(self.surfaces, self.floor_area, self.volume)]
|
||||
return self._internal_zones
|
||||
|
||||
@property
|
||||
def thermal_zones(self) -> Union[None, List[ThermalZone]]:
|
||||
def thermal_zones_from_internal_zones(self) -> Union[None, List[ThermalZone]]:
|
||||
"""
|
||||
Get building thermal zones
|
||||
For Lod up to 3, there can be more than one thermal zone per internal zone.
|
||||
In LoD 4, there can be more than one internal zone, and therefore, only one thermal zone per internal zone
|
||||
:return: [ThermalZone]
|
||||
"""
|
||||
if self._thermal_zones is None:
|
||||
self._thermal_zones = []
|
||||
if self._thermal_zones_from_internal_zones is None:
|
||||
self._thermal_zones_from_internal_zones = []
|
||||
for internal_zone in self.internal_zones:
|
||||
if internal_zone.thermal_zones is None:
|
||||
self._thermal_zones = None
|
||||
return self._thermal_zones
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
self._thermal_zones.append(thermal_zone)
|
||||
return self._thermal_zones
|
||||
if internal_zone.thermal_zones_from_internal_zones is None:
|
||||
self._thermal_zones_from_internal_zones = None
|
||||
return self._thermal_zones_from_internal_zones
|
||||
self._thermal_zones_from_internal_zones.append(internal_zone.thermal_zones_from_internal_zones[0])
|
||||
return self._thermal_zones_from_internal_zones
|
||||
|
||||
@property
|
||||
def grounds(self) -> List[Surface]:
|
||||
|
@ -261,6 +264,15 @@ class Building(CityObject):
|
|||
Get building average storey height in meters
|
||||
:return: None or float
|
||||
"""
|
||||
if len(self.internal_zones) > 1:
|
||||
self._average_storey_height = 0
|
||||
for internal_zone in self.internal_zones:
|
||||
self._average_storey_height += internal_zone.mean_height / len(self.internal_zones)
|
||||
else:
|
||||
if self.internal_zones[0].thermal_archetype is None:
|
||||
self._average_storey_height = None
|
||||
else:
|
||||
self._average_storey_height = self.internal_zones[0].thermal_archetype.average_storey_height
|
||||
return self._average_storey_height
|
||||
|
||||
@average_storey_height.setter
|
||||
|
@ -280,7 +292,10 @@ class Building(CityObject):
|
|||
"""
|
||||
if self._storeys_above_ground is None:
|
||||
if self.eave_height is not None and self.average_storey_height is not None:
|
||||
self._storeys_above_ground = int(self.eave_height / self.average_storey_height)
|
||||
storeys_above_ground = int(self.eave_height / self.average_storey_height)
|
||||
if storeys_above_ground == 0:
|
||||
storeys_above_ground += 1
|
||||
self._storeys_above_ground = storeys_above_ground
|
||||
return self._storeys_above_ground
|
||||
|
||||
@storeys_above_ground.setter
|
||||
|
@ -296,7 +311,7 @@ class Building(CityObject):
|
|||
def cold_water_temperature(self) -> {float}:
|
||||
"""
|
||||
Get cold water temperature in degrees Celsius
|
||||
:return: dict{DataFrame(float)}
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
return self._cold_water_temperature
|
||||
|
||||
|
@ -304,123 +319,176 @@ class Building(CityObject):
|
|||
def cold_water_temperature(self, value):
|
||||
"""
|
||||
Set cold water temperature in degrees Celsius
|
||||
:param value: dict{DataFrame(float)}
|
||||
:param value: dict{[float]}
|
||||
"""
|
||||
self._cold_water_temperature = value
|
||||
|
||||
@property
|
||||
def heating_demand(self) -> dict:
|
||||
"""
|
||||
Get heating demand in Wh
|
||||
:return: dict{DataFrame(float)}
|
||||
Get heating demand in J
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
return self._heating_demand
|
||||
|
||||
@heating_demand.setter
|
||||
def heating_demand(self, value):
|
||||
"""
|
||||
Set heating demand in Wh
|
||||
:param value: dict{DataFrame(float)}
|
||||
Set heating demand in J
|
||||
:param value: dict{[float]}
|
||||
"""
|
||||
self._heating_demand = value
|
||||
|
||||
@property
|
||||
def cooling_demand(self) -> dict:
|
||||
"""
|
||||
Get cooling demand in Wh
|
||||
:return: dict{DataFrame(float)}
|
||||
Get cooling demand in J
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
return self._cooling_demand
|
||||
|
||||
@cooling_demand.setter
|
||||
def cooling_demand(self, value):
|
||||
"""
|
||||
Set cooling demand in Wh
|
||||
:param value: dict{DataFrame(float)}
|
||||
Set cooling demand in J
|
||||
:param value: dict{[float]}
|
||||
"""
|
||||
self._cooling_demand = value
|
||||
|
||||
@property
|
||||
def lighting_electrical_demand(self) -> dict:
|
||||
"""
|
||||
Get lighting electrical demand in Wh
|
||||
:return: dict{DataFrame(float)}
|
||||
Get lighting electrical demand in J
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
return self._lighting_electrical_demand
|
||||
|
||||
@lighting_electrical_demand.setter
|
||||
def lighting_electrical_demand(self, value):
|
||||
"""
|
||||
Set lighting electrical demand in Wh
|
||||
:param value: dict{DataFrame(float)}
|
||||
Set lighting electrical demand in J
|
||||
:param value: dict{[float]}
|
||||
"""
|
||||
self._lighting_electrical_demand = value
|
||||
|
||||
@property
|
||||
def appliances_electrical_demand(self) -> dict:
|
||||
"""
|
||||
Get appliances electrical demand in Wh
|
||||
:return: dict{DataFrame(float)}
|
||||
Get appliances electrical demand in J
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
return self._appliances_electrical_demand
|
||||
|
||||
@appliances_electrical_demand.setter
|
||||
def appliances_electrical_demand(self, value):
|
||||
"""
|
||||
Set appliances electrical demand in Wh
|
||||
:param value: dict{DataFrame(float)}
|
||||
Set appliances electrical demand in J
|
||||
:param value: dict{[float]}
|
||||
"""
|
||||
self._appliances_electrical_demand = value
|
||||
|
||||
@property
|
||||
def domestic_hot_water_heat_demand(self) -> dict:
|
||||
"""
|
||||
Get domestic hot water heat demand in Wh
|
||||
:return: dict{DataFrame(float)}
|
||||
Get domestic hot water heat demand in J
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
return self._domestic_hot_water_heat_demand
|
||||
|
||||
@domestic_hot_water_heat_demand.setter
|
||||
def domestic_hot_water_heat_demand(self, value):
|
||||
"""
|
||||
Set domestic hot water heat demand in Wh
|
||||
:param value: dict{DataFrame(float)}
|
||||
Set domestic hot water heat demand in J
|
||||
:param value: dict{[float]}
|
||||
"""
|
||||
self._domestic_hot_water_heat_demand = value
|
||||
|
||||
@property
|
||||
def lighting_peak_load(self) -> Union[None, dict]:
|
||||
"""
|
||||
Get lighting peak load in W
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
results = {}
|
||||
peak_lighting = 0
|
||||
peak = 0
|
||||
for thermal_zone in self.thermal_zones_from_internal_zones:
|
||||
lighting = thermal_zone.lighting
|
||||
for schedule in lighting.schedules:
|
||||
peak = max(schedule.values) * lighting.density * thermal_zone.total_floor_area
|
||||
if peak > peak_lighting:
|
||||
peak_lighting = peak
|
||||
results[cte.MONTH] = [peak for _ in range(0, 12)]
|
||||
results[cte.YEAR] = [peak]
|
||||
return results
|
||||
|
||||
@property
|
||||
def appliances_peak_load(self) -> Union[None, dict]:
|
||||
"""
|
||||
Get appliances peak load in W
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
results = {}
|
||||
peak_appliances = 0
|
||||
peak = 0
|
||||
for thermal_zone in self.thermal_zones_from_internal_zones:
|
||||
appliances = thermal_zone.appliances
|
||||
for schedule in appliances.schedules:
|
||||
peak = max(schedule.values) * appliances.density * thermal_zone.total_floor_area
|
||||
if peak > peak_appliances:
|
||||
peak_appliances = peak
|
||||
results[cte.MONTH] = [peak for _ in range(0, 12)]
|
||||
results[cte.YEAR] = [peak]
|
||||
return results
|
||||
|
||||
@property
|
||||
def heating_peak_load(self) -> Union[None, dict]:
|
||||
"""
|
||||
Get heating peak load in W
|
||||
:return: dict{DataFrame(float)}
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
results = {}
|
||||
if cte.HOUR in self.heating_demand:
|
||||
monthly_values = PeakLoads().\
|
||||
peak_loads_from_hourly(self.heating_demand[cte.HOUR][next(iter(self.heating_demand[cte.HOUR]))])
|
||||
monthly_values = PeakLoads().peak_loads_from_hourly(self.heating_demand[cte.HOUR])
|
||||
else:
|
||||
monthly_values = PeakLoads(self).heating_peak_loads_from_methodology
|
||||
if monthly_values is None:
|
||||
return None
|
||||
results[cte.MONTH] = monthly_values
|
||||
results[cte.YEAR] = [max(monthly_values)]
|
||||
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 cooling_peak_load(self) -> Union[None, dict]:
|
||||
"""
|
||||
Get cooling peak load in W
|
||||
:return: dict{DataFrame(float)}
|
||||
:return: dict{[float]}
|
||||
"""
|
||||
results = {}
|
||||
if cte.HOUR in self.cooling_demand:
|
||||
monthly_values = PeakLoads().peak_loads_from_hourly(self.cooling_demand[cte.HOUR][next(iter(self.cooling_demand[cte.HOUR]))])
|
||||
monthly_values = PeakLoads().peak_loads_from_hourly(self.cooling_demand[cte.HOUR])
|
||||
else:
|
||||
monthly_values = PeakLoads(self).cooling_peak_loads_from_methodology
|
||||
if monthly_values is None:
|
||||
return None
|
||||
results[cte.MONTH] = monthly_values
|
||||
results[cte.YEAR] = [max(monthly_values)]
|
||||
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]
|
||||
return results
|
||||
|
||||
@property
|
||||
|
@ -573,12 +641,12 @@ class Building(CityObject):
|
|||
@property
|
||||
def heating_consumption(self):
|
||||
"""
|
||||
Get energy consumption for heating according to the heating system installed in Wh
|
||||
Get energy consumption for heating according to the heating system installed in J
|
||||
return: dict
|
||||
"""
|
||||
if len(self._heating_consumption) == 0:
|
||||
for heating_demand_key in self.heating_demand:
|
||||
demand = self.heating_demand[heating_demand_key][cte.INSEL_MEB]
|
||||
demand = self.heating_demand[heating_demand_key]
|
||||
consumption_type = cte.HEATING
|
||||
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
||||
if final_energy_consumed is None:
|
||||
|
@ -589,12 +657,12 @@ class Building(CityObject):
|
|||
@property
|
||||
def cooling_consumption(self):
|
||||
"""
|
||||
Get energy consumption for cooling according to the cooling system installed in Wh
|
||||
Get energy consumption for cooling according to the cooling system installed in J
|
||||
return: dict
|
||||
"""
|
||||
if len(self._cooling_consumption) == 0:
|
||||
for cooling_demand_key in self.cooling_demand:
|
||||
demand = self.cooling_demand[cooling_demand_key][cte.INSEL_MEB]
|
||||
demand = self.cooling_demand[cooling_demand_key]
|
||||
consumption_type = cte.COOLING
|
||||
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
||||
if final_energy_consumed is None:
|
||||
|
@ -605,12 +673,12 @@ class Building(CityObject):
|
|||
@property
|
||||
def domestic_hot_water_consumption(self):
|
||||
"""
|
||||
Get energy consumption for domestic according to the domestic hot water system installed in Wh
|
||||
Get energy consumption for domestic according to the domestic hot water system installed in J
|
||||
return: dict
|
||||
"""
|
||||
if len(self._domestic_hot_water_consumption) == 0:
|
||||
for domestic_hot_water_demand_key in self.domestic_hot_water_heat_demand:
|
||||
demand = self.domestic_hot_water_heat_demand[domestic_hot_water_demand_key][cte.INSEL_MEB]
|
||||
demand = self.domestic_hot_water_heat_demand[domestic_hot_water_demand_key]
|
||||
consumption_type = cte.DOMESTIC_HOT_WATER
|
||||
final_energy_consumed = self._calculate_consumption(consumption_type, demand)
|
||||
if final_energy_consumed is None:
|
||||
|
@ -621,7 +689,7 @@ class Building(CityObject):
|
|||
def _calculate_working_hours(self):
|
||||
_working_hours = {}
|
||||
for internal_zone in self.internal_zones:
|
||||
for thermal_zone in internal_zone.thermal_zones:
|
||||
for thermal_zone in internal_zone.thermal_zones_from_internal_zones:
|
||||
_working_hours_per_thermal_zone = {}
|
||||
for schedule in thermal_zone.thermal_control.hvac_availability_schedules:
|
||||
_working_hours_per_schedule = [0] * len(schedule.values)
|
||||
|
@ -638,18 +706,25 @@ class Building(CityObject):
|
|||
for i, value in enumerate(item):
|
||||
_working_hours[key][i] = max(_working_hours[key][i], saved_values[i])
|
||||
|
||||
_total_hours = 0
|
||||
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 += hours * cte.DAYS_A_YEAR[key]
|
||||
return _total_hours
|
||||
_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
|
||||
|
||||
@property
|
||||
def distribution_systems_electrical_consumption(self):
|
||||
"""
|
||||
Get total electricity consumption for distribution and emission systems in Wh
|
||||
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]
|
||||
|
@ -663,19 +738,22 @@ class Building(CityObject):
|
|||
if self.energy_systems is None:
|
||||
return self._distribution_systems_electrical_consumption
|
||||
for energy_system in self.energy_systems:
|
||||
emission_system = energy_system.emission_system.generic_emission_system
|
||||
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_system is not None:
|
||||
parasitic_energy_consumption = emission_system.parasitic_energy_consumption
|
||||
distribution_system = energy_system.distribution_system.generic_distribution_system
|
||||
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][cte.INSEL_MEB])
|
||||
_demand = self.heating_demand[heating_demand_key][cte.INSEL_MEB]
|
||||
_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
|
||||
|
@ -684,15 +762,20 @@ class Building(CityObject):
|
|||
_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][cte.INSEL_MEB]
|
||||
_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
|
||||
_working_hours_value = _working_hours[key]
|
||||
if len(item) == 12:
|
||||
_working_hours_value = _working_hours[key][i]
|
||||
self._distribution_systems_electrical_consumption[key][i] += (
|
||||
_peak_load * _consumption_fix_flow * _working_hours_value * cte.WATTS_HOUR_TO_JULES
|
||||
)
|
||||
|
||||
return self._distribution_systems_electrical_consumption
|
||||
|
||||
def _calculate_consumption(self, consumption_type, demand):
|
||||
|
@ -701,15 +784,21 @@ 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):
|
||||
coefficient_of_performance = energy_system.generation_system.generic_generation_system.heat_efficiency
|
||||
for generation_system in generation_systems:
|
||||
if generation_system.heat_efficiency is not None:
|
||||
coefficient_of_performance = float(generation_system.heat_efficiency)
|
||||
elif consumption_type == cte.COOLING:
|
||||
coefficient_of_performance = energy_system.generation_system.generic_generation_system.cooling_efficiency
|
||||
for generation_system in generation_systems:
|
||||
if generation_system.cooling_efficiency is not None:
|
||||
coefficient_of_performance = float(generation_system.cooling_efficiency)
|
||||
elif consumption_type == cte.ELECTRICITY:
|
||||
coefficient_of_performance = \
|
||||
energy_system.generation_system.generic_generation_system.electricity_efficiency
|
||||
for generation_system in generation_systems:
|
||||
if generation_system.electricity_efficiency is not None:
|
||||
coefficient_of_performance = float(generation_system.electricity_efficiency)
|
||||
if coefficient_of_performance == 0:
|
||||
values = [0]*len(demand)
|
||||
final_energy_consumed = values
|
||||
|
@ -722,11 +811,9 @@ class Building(CityObject):
|
|||
@property
|
||||
def onsite_electrical_production(self):
|
||||
"""
|
||||
Get total electricity produced onsite in Wh
|
||||
Get total electricity produced onsite in J
|
||||
return: dict
|
||||
"""
|
||||
|
||||
# Add other systems whenever new ones appear
|
||||
orientation_losses_factor = {cte.MONTH: {'north': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
'east': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
'south': [2.137931, 1.645503, 1.320946, 1.107817, 0.993213, 0.945175,
|
||||
|
@ -737,19 +824,96 @@ class Building(CityObject):
|
|||
'south': [1.212544],
|
||||
'west': [0]}
|
||||
}
|
||||
|
||||
# Add other systems whenever new ones appear
|
||||
if self.energy_systems is None:
|
||||
return self._onsite_electrical_production
|
||||
for energy_system in self.energy_systems:
|
||||
if energy_system.generation_system.generic_generation_system.type == cte.PHOTOVOLTAIC:
|
||||
_efficiency = energy_system.generation_system.generic_generation_system.electricity_efficiency
|
||||
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][cte.SRA]))]
|
||||
_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][cte.SRA],
|
||||
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
|
||||
|
||||
|
|
151
hub/city_model_structure/building_demand/construction.py
Normal file
151
hub/city_model_structure/building_demand/construction.py
Normal file
|
@ -0,0 +1,151 @@
|
|||
"""
|
||||
Construction thermal parameters
|
||||
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.building_demand.layer import Layer
|
||||
|
||||
|
||||
class Construction:
|
||||
"""
|
||||
Construction class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._type = None
|
||||
self._name = None
|
||||
self._layers = None
|
||||
self._window_ratio = None
|
||||
self._window_frame_ratio = None
|
||||
self._window_g_value = None
|
||||
self._window_overall_u_value = None
|
||||
self._window_type = None
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
Get construction type
|
||||
:return: str
|
||||
"""
|
||||
return self._type
|
||||
|
||||
@type.setter
|
||||
def type(self, value):
|
||||
"""
|
||||
Set construction type
|
||||
:param value: str
|
||||
"""
|
||||
self._type = value
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Get construction name
|
||||
:return: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
"""
|
||||
Set construction name
|
||||
:param value: str
|
||||
"""
|
||||
self._name = value
|
||||
|
||||
@property
|
||||
def layers(self) -> [Layer]:
|
||||
"""
|
||||
Get layers
|
||||
:return: [layer]
|
||||
"""
|
||||
return self._layers
|
||||
|
||||
@layers.setter
|
||||
def layers(self, value):
|
||||
"""
|
||||
Set layers
|
||||
:param value: [layer]
|
||||
"""
|
||||
self._layers = value
|
||||
|
||||
@property
|
||||
def window_ratio(self):
|
||||
"""
|
||||
Get window ratio
|
||||
:return: dict
|
||||
"""
|
||||
return self._window_ratio
|
||||
|
||||
@window_ratio.setter
|
||||
def window_ratio(self, value):
|
||||
"""
|
||||
Set window ratio
|
||||
:param value: dict
|
||||
"""
|
||||
self._window_ratio = value
|
||||
|
||||
@property
|
||||
def window_frame_ratio(self):
|
||||
"""
|
||||
Get window frame ratio
|
||||
:return: float
|
||||
"""
|
||||
return self._window_frame_ratio
|
||||
|
||||
@window_frame_ratio.setter
|
||||
def window_frame_ratio(self, value):
|
||||
"""
|
||||
Set window frame ratio
|
||||
:param value: float
|
||||
"""
|
||||
self._window_frame_ratio = value
|
||||
|
||||
@property
|
||||
def window_g_value(self):
|
||||
"""
|
||||
Get transparent surface g-value
|
||||
:return: float
|
||||
"""
|
||||
return self._window_g_value
|
||||
|
||||
@window_g_value.setter
|
||||
def window_g_value(self, value):
|
||||
"""
|
||||
Set transparent surface g-value
|
||||
:param value: float
|
||||
"""
|
||||
self._window_g_value = value
|
||||
|
||||
@property
|
||||
def window_overall_u_value(self):
|
||||
"""
|
||||
Get transparent surface overall U-value in W/m2K
|
||||
:return: float
|
||||
"""
|
||||
return self._window_overall_u_value
|
||||
|
||||
@window_overall_u_value.setter
|
||||
def window_overall_u_value(self, value):
|
||||
"""
|
||||
Set transparent surface overall U-value in W/m2K
|
||||
:param value: float
|
||||
"""
|
||||
self._window_overall_u_value = value
|
||||
|
||||
@property
|
||||
def window_type(self):
|
||||
"""
|
||||
Get transparent surface type, 'window' or 'skylight'
|
||||
:return: str
|
||||
"""
|
||||
return self._window_type
|
||||
|
||||
@window_type.setter
|
||||
def window_type(self, value):
|
||||
"""
|
||||
Set transparent surface type, 'window' or 'skylight'
|
||||
:return: str
|
||||
"""
|
||||
self._window_type = value
|
|
@ -8,24 +8,25 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
|||
import uuid
|
||||
from typing import Union, List
|
||||
from hub.city_model_structure.building_demand.usage import Usage
|
||||
from hub.city_model_structure.building_demand.thermal_archetype import ThermalArchetype
|
||||
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
|
||||
from hub.city_model_structure.building_demand.thermal_boundary import ThermalBoundary
|
||||
from hub.city_model_structure.attributes.polyhedron import Polyhedron
|
||||
from hub.city_model_structure.energy_systems.hvac_system import HvacSystem
|
||||
|
||||
|
||||
class InternalZone:
|
||||
"""
|
||||
InternalZone class
|
||||
"""
|
||||
def __init__(self, surfaces, area):
|
||||
def __init__(self, surfaces, area, volume):
|
||||
self._surfaces = surfaces
|
||||
self._id = None
|
||||
self._geometry = None
|
||||
self._volume = None
|
||||
self._volume = volume
|
||||
self._area = area
|
||||
self._thermal_zones = None
|
||||
self._thermal_zones_from_internal_zones = None
|
||||
self._usages = None
|
||||
self._hvac_system = None
|
||||
self._thermal_archetype = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -64,7 +65,7 @@ class InternalZone:
|
|||
Get internal zone volume in cubic meters
|
||||
:return: float
|
||||
"""
|
||||
return self.geometry.volume
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
def area(self):
|
||||
|
@ -74,10 +75,18 @@ class InternalZone:
|
|||
"""
|
||||
return self._area
|
||||
|
||||
@property
|
||||
def mean_height(self):
|
||||
"""
|
||||
Get internal zone mean height in meters
|
||||
:return: float
|
||||
"""
|
||||
return self.volume / self.area
|
||||
|
||||
@property
|
||||
def usages(self) -> [Usage]:
|
||||
"""
|
||||
Get internal zone usage zones
|
||||
Get usage archetypes
|
||||
:return: [Usage]
|
||||
"""
|
||||
return self._usages
|
||||
|
@ -85,39 +94,59 @@ class InternalZone:
|
|||
@usages.setter
|
||||
def usages(self, value):
|
||||
"""
|
||||
Set internal zone usage zones
|
||||
Set usage archetypes
|
||||
:param value: [Usage]
|
||||
"""
|
||||
self._usages = value
|
||||
|
||||
@property
|
||||
def hvac_system(self) -> Union[None, HvacSystem]:
|
||||
def thermal_archetype(self) -> ThermalArchetype:
|
||||
"""
|
||||
Get HVAC system installed for this thermal zone
|
||||
:return: None or HvacSystem
|
||||
Get thermal archetype parameters
|
||||
:return: ThermalArchetype
|
||||
"""
|
||||
return self._hvac_system
|
||||
return self._thermal_archetype
|
||||
|
||||
@hvac_system.setter
|
||||
def hvac_system(self, value):
|
||||
@thermal_archetype.setter
|
||||
def thermal_archetype(self, value):
|
||||
"""
|
||||
Set HVAC system installed for this thermal zone
|
||||
:param value: HvacSystem
|
||||
Set thermal archetype parameters
|
||||
:param value: ThermalArchetype
|
||||
"""
|
||||
self._hvac_system = value
|
||||
self._thermal_archetype = value
|
||||
|
||||
@property
|
||||
def thermal_zones(self) -> Union[None, List[ThermalZone]]:
|
||||
def thermal_zones_from_internal_zones(self) -> Union[None, List[ThermalZone]]:
|
||||
"""
|
||||
Get building thermal zones
|
||||
Get building thermal zones as one per internal zone
|
||||
:return: [ThermalZone]
|
||||
"""
|
||||
return self._thermal_zones
|
||||
_thermal_boundaries = []
|
||||
for surface in self.surfaces:
|
||||
if surface.holes_polygons is None:
|
||||
windows_areas = None
|
||||
else:
|
||||
windows_areas = []
|
||||
for hole in surface.holes_polygons:
|
||||
windows_areas.append(hole.area)
|
||||
_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]
|
||||
self._thermal_zones_from_internal_zones = [_thermal_zone]
|
||||
return self._thermal_zones_from_internal_zones
|
||||
|
||||
@thermal_zones.setter
|
||||
def thermal_zones(self, value):
|
||||
@thermal_zones_from_internal_zones.setter
|
||||
def thermal_zones_from_internal_zones(self, value):
|
||||
"""
|
||||
Set city object thermal zones
|
||||
Set city object thermal zones as one per internal zone
|
||||
:param value: [ThermalZone]
|
||||
"""
|
||||
self._thermal_zones = value
|
||||
self._thermal_zones_from_internal_zones = value
|
||||
|
|
|
@ -4,9 +4,9 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
import uuid
|
||||
from typing import Union
|
||||
from hub.city_model_structure.building_demand.material import Material
|
||||
|
||||
|
||||
class Layer:
|
||||
|
@ -14,9 +14,17 @@ class Layer:
|
|||
Layer class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._material = None
|
||||
self._thickness = None
|
||||
self._id = None
|
||||
self._material_name = None
|
||||
self._conductivity = None
|
||||
self._specific_heat = None
|
||||
self._density = None
|
||||
self._solar_absorptance = None
|
||||
self._thermal_absorptance = None
|
||||
self._visible_absorptance = None
|
||||
self._no_mass = False
|
||||
self._thermal_resistance = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -28,22 +36,6 @@ class Layer:
|
|||
self._id = uuid.uuid4()
|
||||
return self._id
|
||||
|
||||
@property
|
||||
def material(self) -> Material:
|
||||
"""
|
||||
Get layer material
|
||||
:return: Material
|
||||
"""
|
||||
return self._material
|
||||
|
||||
@material.setter
|
||||
def material(self, value):
|
||||
"""
|
||||
Set layer material
|
||||
:param value: Material
|
||||
"""
|
||||
self._material = value
|
||||
|
||||
@property
|
||||
def thickness(self) -> Union[None, float]:
|
||||
"""
|
||||
|
@ -60,3 +52,155 @@ class Layer:
|
|||
"""
|
||||
if value is not None:
|
||||
self._thickness = float(value)
|
||||
|
||||
@property
|
||||
def material_name(self):
|
||||
"""
|
||||
Get material name
|
||||
:return: str
|
||||
"""
|
||||
return self._material_name
|
||||
|
||||
@material_name.setter
|
||||
def material_name(self, value):
|
||||
"""
|
||||
Set material name
|
||||
:param value: string
|
||||
"""
|
||||
self._material_name = str(value)
|
||||
|
||||
@property
|
||||
def conductivity(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material conductivity in W/mK
|
||||
:return: None or float
|
||||
"""
|
||||
return self._conductivity
|
||||
|
||||
@conductivity.setter
|
||||
def conductivity(self, value):
|
||||
"""
|
||||
Set material conductivity in W/mK
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._conductivity = float(value)
|
||||
|
||||
@property
|
||||
def specific_heat(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material conductivity in J/kgK
|
||||
:return: None or float
|
||||
"""
|
||||
return self._specific_heat
|
||||
|
||||
@specific_heat.setter
|
||||
def specific_heat(self, value):
|
||||
"""
|
||||
Get material conductivity in J/kgK
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._specific_heat = float(value)
|
||||
|
||||
@property
|
||||
def density(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material density in kg/m3
|
||||
:return: None or float
|
||||
"""
|
||||
return self._density
|
||||
|
||||
@density.setter
|
||||
def density(self, value):
|
||||
"""
|
||||
Set material density
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._density = float(value)
|
||||
|
||||
@property
|
||||
def solar_absorptance(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material solar absorptance
|
||||
:return: None or float
|
||||
"""
|
||||
return self._solar_absorptance
|
||||
|
||||
@solar_absorptance.setter
|
||||
def solar_absorptance(self, value):
|
||||
"""
|
||||
Set material solar absorptance
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._solar_absorptance = float(value)
|
||||
|
||||
@property
|
||||
def thermal_absorptance(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material thermal absorptance
|
||||
:return: None or float
|
||||
"""
|
||||
return self._thermal_absorptance
|
||||
|
||||
@thermal_absorptance.setter
|
||||
def thermal_absorptance(self, value):
|
||||
"""
|
||||
Set material thermal absorptance
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._thermal_absorptance = float(value)
|
||||
|
||||
@property
|
||||
def visible_absorptance(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material visible absorptance
|
||||
:return: None or float
|
||||
"""
|
||||
return self._visible_absorptance
|
||||
|
||||
@visible_absorptance.setter
|
||||
def visible_absorptance(self, value):
|
||||
"""
|
||||
Set material visible absorptance
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._visible_absorptance = float(value)
|
||||
|
||||
@property
|
||||
def no_mass(self) -> Union[None, bool]:
|
||||
"""
|
||||
Get material no mass flag
|
||||
:return: None or Boolean
|
||||
"""
|
||||
return self._no_mass
|
||||
|
||||
@no_mass.setter
|
||||
def no_mass(self, value):
|
||||
"""
|
||||
Set material no mass flag
|
||||
:param value: Boolean
|
||||
"""
|
||||
if value is not None:
|
||||
self._no_mass = value
|
||||
|
||||
@property
|
||||
def thermal_resistance(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material thermal resistance in m2K/W
|
||||
:return: None or float
|
||||
"""
|
||||
return self._thermal_resistance
|
||||
|
||||
@thermal_resistance.setter
|
||||
def thermal_resistance(self, value):
|
||||
"""
|
||||
Set material thermal resistance in m2K/W
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._thermal_resistance = float(value)
|
||||
|
|
|
@ -1,193 +0,0 @@
|
|||
"""
|
||||
Material module
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import Union
|
||||
|
||||
|
||||
class Material:
|
||||
"""
|
||||
Material class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._id = None
|
||||
self._name = None
|
||||
self._conductivity = None
|
||||
self._specific_heat = None
|
||||
self._density = None
|
||||
self._solar_absorptance = None
|
||||
self._thermal_absorptance = None
|
||||
self._visible_absorptance = None
|
||||
self._no_mass = False
|
||||
self._thermal_resistance = None
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
"""
|
||||
Get material id
|
||||
:return: str
|
||||
"""
|
||||
return self._id
|
||||
|
||||
@id.setter
|
||||
def id(self, value):
|
||||
"""
|
||||
Set material id
|
||||
:param value: str
|
||||
"""
|
||||
self._id = value
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""
|
||||
Get material name
|
||||
:return: str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
"""
|
||||
Set material name
|
||||
:param value: string
|
||||
"""
|
||||
self._name = str(value)
|
||||
|
||||
@property
|
||||
def conductivity(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material conductivity in W/mK
|
||||
:return: None or float
|
||||
"""
|
||||
return self._conductivity
|
||||
|
||||
@conductivity.setter
|
||||
def conductivity(self, value):
|
||||
"""
|
||||
Set material conductivity in W/mK
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._conductivity = float(value)
|
||||
|
||||
@property
|
||||
def specific_heat(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material conductivity in J/kgK
|
||||
:return: None or float
|
||||
"""
|
||||
return self._specific_heat
|
||||
|
||||
@specific_heat.setter
|
||||
def specific_heat(self, value):
|
||||
"""
|
||||
Get material conductivity in J/kgK
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._specific_heat = float(value)
|
||||
|
||||
@property
|
||||
def density(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material density in kg/m3
|
||||
:return: None or float
|
||||
"""
|
||||
return self._density
|
||||
|
||||
@density.setter
|
||||
def density(self, value):
|
||||
"""
|
||||
Set material density
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._density = float(value)
|
||||
|
||||
@property
|
||||
def solar_absorptance(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material solar absorptance
|
||||
:return: None or float
|
||||
"""
|
||||
return self._solar_absorptance
|
||||
|
||||
@solar_absorptance.setter
|
||||
def solar_absorptance(self, value):
|
||||
"""
|
||||
Set material solar absorptance
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._solar_absorptance = float(value)
|
||||
|
||||
@property
|
||||
def thermal_absorptance(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material thermal absorptance
|
||||
:return: None or float
|
||||
"""
|
||||
return self._thermal_absorptance
|
||||
|
||||
@thermal_absorptance.setter
|
||||
def thermal_absorptance(self, value):
|
||||
"""
|
||||
Set material thermal absorptance
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._thermal_absorptance = float(value)
|
||||
|
||||
@property
|
||||
def visible_absorptance(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material visible absorptance
|
||||
:return: None or float
|
||||
"""
|
||||
return self._visible_absorptance
|
||||
|
||||
@visible_absorptance.setter
|
||||
def visible_absorptance(self, value):
|
||||
"""
|
||||
Set material visible absorptance
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._visible_absorptance = float(value)
|
||||
|
||||
@property
|
||||
def no_mass(self) -> Union[None, bool]:
|
||||
"""
|
||||
Get material no mass flag
|
||||
:return: None or Boolean
|
||||
"""
|
||||
return self._no_mass
|
||||
|
||||
@no_mass.setter
|
||||
def no_mass(self, value):
|
||||
"""
|
||||
Set material no mass flag
|
||||
:param value: Boolean
|
||||
"""
|
||||
if value is not None:
|
||||
self._no_mass = value
|
||||
|
||||
@property
|
||||
def thermal_resistance(self) -> Union[None, float]:
|
||||
"""
|
||||
Get material thermal resistance in m2K/W
|
||||
:return: None or float
|
||||
"""
|
||||
return self._thermal_resistance
|
||||
|
||||
@thermal_resistance.setter
|
||||
def thermal_resistance(self, value):
|
||||
"""
|
||||
Set material thermal resistance in m2K/W
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._thermal_resistance = float(value)
|
|
@ -90,7 +90,9 @@ class Storey:
|
|||
:return: ThermalZone
|
||||
"""
|
||||
if self._thermal_zone is None:
|
||||
self._thermal_zone = ThermalZone(self.thermal_boundaries, self._internal_zone, self.volume, self.floor_area)
|
||||
_number_of_storeys = 1
|
||||
self._thermal_zone = ThermalZone(self.thermal_boundaries, self._internal_zone,
|
||||
self.volume, self.floor_area, _number_of_storeys)
|
||||
return self._thermal_zone
|
||||
|
||||
@property
|
||||
|
|
|
@ -18,6 +18,7 @@ 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:
|
||||
|
@ -41,10 +42,12 @@ class Surface:
|
|||
self._short_wave_reflectance = None
|
||||
self._long_wave_emittance = None
|
||||
self._inverse = None
|
||||
self._associated_thermal_boundaries = []
|
||||
self._associated_thermal_boundaries = None
|
||||
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):
|
||||
|
@ -154,7 +157,6 @@ class Surface:
|
|||
if self._inclination is None:
|
||||
self._inclination = np.arccos(self.perimeter_polygon.normal[2])
|
||||
return self._inclination
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
|
@ -178,16 +180,16 @@ class Surface:
|
|||
@property
|
||||
def global_irradiance(self) -> dict:
|
||||
"""
|
||||
Get global irradiance on surface in Wh/m2
|
||||
:return: dict{DataFrame(float)}
|
||||
Get global irradiance on surface in W/m2
|
||||
:return: dict
|
||||
"""
|
||||
return self._global_irradiance
|
||||
|
||||
@global_irradiance.setter
|
||||
def global_irradiance(self, value):
|
||||
"""
|
||||
Set global irradiance on surface in Wh/m2
|
||||
:param value: dict{DataFrame(float)}
|
||||
Set global irradiance on surface in W/m2
|
||||
:param value: dict
|
||||
"""
|
||||
self._global_irradiance = value
|
||||
|
||||
|
@ -384,3 +386,35 @@ 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
|
168
hub/city_model_structure/building_demand/thermal_archetype.py
Normal file
168
hub/city_model_structure/building_demand/thermal_archetype.py
Normal file
|
@ -0,0 +1,168 @@
|
|||
"""
|
||||
Thermal archetype 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 hub.city_model_structure.building_demand.construction import Construction
|
||||
|
||||
|
||||
class ThermalArchetype:
|
||||
"""
|
||||
ThermalArchetype class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._constructions = None
|
||||
self._average_storey_height = None
|
||||
self._thermal_capacity = None
|
||||
self._extra_loses_due_to_thermal_bridges = None
|
||||
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]:
|
||||
"""
|
||||
Get archetype constructions
|
||||
:return: [Construction]
|
||||
"""
|
||||
return self._constructions
|
||||
|
||||
@constructions.setter
|
||||
def constructions(self, value):
|
||||
"""
|
||||
Set archetype constructions
|
||||
:param value: [Construction]
|
||||
"""
|
||||
self._constructions = value
|
||||
|
||||
@property
|
||||
def average_storey_height(self):
|
||||
"""
|
||||
Get average storey height in m
|
||||
:return: float
|
||||
"""
|
||||
return self._average_storey_height
|
||||
|
||||
@average_storey_height.setter
|
||||
def average_storey_height(self, value):
|
||||
"""
|
||||
Set average storey height in m
|
||||
:param value: float
|
||||
"""
|
||||
self._average_storey_height = value
|
||||
|
||||
@property
|
||||
def thermal_capacity(self):
|
||||
"""
|
||||
Get thermal capacity in J/m3K
|
||||
:return: float
|
||||
"""
|
||||
return self._thermal_capacity
|
||||
|
||||
@thermal_capacity.setter
|
||||
def thermal_capacity(self, value):
|
||||
"""
|
||||
Set thermal capacity in J/m3K
|
||||
:param value: float
|
||||
"""
|
||||
self._thermal_capacity = value
|
||||
|
||||
@property
|
||||
def extra_loses_due_to_thermal_bridges(self):
|
||||
"""
|
||||
Get extra loses due to thermal bridges in W/m2K
|
||||
:return: float
|
||||
"""
|
||||
return self._extra_loses_due_to_thermal_bridges
|
||||
|
||||
@extra_loses_due_to_thermal_bridges.setter
|
||||
def extra_loses_due_to_thermal_bridges(self, value):
|
||||
"""
|
||||
Set extra loses due to thermal bridges in W/m2K
|
||||
:param value: float
|
||||
"""
|
||||
self._extra_loses_due_to_thermal_bridges = value
|
||||
|
||||
@property
|
||||
def indirect_heated_ratio(self):
|
||||
"""
|
||||
Get indirect heated area ratio
|
||||
:return: float
|
||||
"""
|
||||
return self._indirect_heated_ratio
|
||||
|
||||
@indirect_heated_ratio.setter
|
||||
def indirect_heated_ratio(self, value):
|
||||
"""
|
||||
Set indirect heated area ratio
|
||||
:param value: float
|
||||
"""
|
||||
self._indirect_heated_ratio = value
|
||||
|
||||
@property
|
||||
def infiltration_rate_for_ventilation_system_off(self):
|
||||
"""
|
||||
Get infiltration rate for ventilation system off in ACH
|
||||
:return: float
|
||||
"""
|
||||
return self._infiltration_rate_for_ventilation_system_off
|
||||
|
||||
@infiltration_rate_for_ventilation_system_off.setter
|
||||
def infiltration_rate_for_ventilation_system_off(self, value):
|
||||
"""
|
||||
Set infiltration rate for ventilation system off in ACH
|
||||
:param value: float
|
||||
"""
|
||||
self._infiltration_rate_for_ventilation_system_off = value
|
||||
|
||||
@property
|
||||
def infiltration_rate_for_ventilation_system_on(self):
|
||||
"""
|
||||
Get infiltration rate for ventilation system on in ACH
|
||||
:return: float
|
||||
"""
|
||||
return self._infiltration_rate_for_ventilation_system_on
|
||||
|
||||
@infiltration_rate_for_ventilation_system_on.setter
|
||||
def infiltration_rate_for_ventilation_system_on(self, value):
|
||||
"""
|
||||
Set infiltration rate for ventilation system on in ACH
|
||||
: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
|
|
@ -7,7 +7,9 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
|
|||
"""
|
||||
|
||||
import uuid
|
||||
import math
|
||||
from typing import List, Union, TypeVar
|
||||
import logging
|
||||
from hub.helpers.configuration_helper import ConfigurationHelper as ch
|
||||
import hub.helpers.constants as cte
|
||||
from hub.city_model_structure.building_demand.layer import Layer
|
||||
|
@ -35,7 +37,8 @@ class ThermalBoundary:
|
|||
self._construction_name = None
|
||||
self._thickness = None
|
||||
self._internal_surface = None
|
||||
self._window_ratio = None
|
||||
self._external_surface = None
|
||||
self._window_ratio = 0
|
||||
self._window_ratio_to_be_calculated = False
|
||||
if self._windows_areas is not None:
|
||||
self._window_ratio_to_be_calculated = True
|
||||
|
@ -53,7 +56,7 @@ class ThermalBoundary:
|
|||
@property
|
||||
def parent_surface(self) -> Surface:
|
||||
"""
|
||||
Get the surface that belongs to the thermal boundary
|
||||
Get the surface that belongs to the thermal boundary, considered the external surface of that boundary
|
||||
:return: Surface
|
||||
"""
|
||||
return self._parent_surface
|
||||
|
@ -92,7 +95,7 @@ class ThermalBoundary:
|
|||
self._thickness = 0.0
|
||||
if self.layers is not None:
|
||||
for layer in self.layers:
|
||||
if not layer.material.no_mass:
|
||||
if not layer.no_mass:
|
||||
self._thickness += layer.thickness
|
||||
return self._thickness
|
||||
|
||||
|
@ -148,24 +151,21 @@ class ThermalBoundary:
|
|||
else:
|
||||
_area = self.opaque_area * self.window_ratio / (1-self.window_ratio)
|
||||
_thermal_opening.area = _area
|
||||
self._thermal_openings = [_thermal_opening]
|
||||
for thermal_opening in self._thermal_openings:
|
||||
thermal_opening.g_value = self._construction_archetype.window_g_value
|
||||
thermal_opening.overall_u_value = self._construction_archetype.window_overall_u_value
|
||||
thermal_opening.frame_ratio = self._construction_archetype.window_frame_ratio
|
||||
thermal_opening.construction_name = self._construction_archetype.window_type
|
||||
return self._thermal_openings
|
||||
|
||||
@property
|
||||
def construction_name(self) -> Union[None, str]:
|
||||
"""
|
||||
Get construction name
|
||||
:return: None or str
|
||||
"""
|
||||
return self._construction_name
|
||||
|
||||
@construction_name.setter
|
||||
def construction_name(self, value):
|
||||
"""
|
||||
Set construction name
|
||||
:param value: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._construction_name = str(value)
|
||||
def _construction_archetype(self):
|
||||
construction_archetypes = self.thermal_zones[0].parent_internal_zone.thermal_archetype.constructions
|
||||
for construction_archetype in construction_archetypes:
|
||||
if str(self.type) == str(construction_archetype.type):
|
||||
return construction_archetype
|
||||
return None
|
||||
|
||||
@property
|
||||
def layers(self) -> List[Layer]:
|
||||
|
@ -173,16 +173,13 @@ class ThermalBoundary:
|
|||
Get thermal boundary layers
|
||||
:return: [Layers]
|
||||
"""
|
||||
if self._construction_archetype is not None:
|
||||
self._layers = self._construction_archetype.layers
|
||||
else:
|
||||
logging.error('Layers not defined\n')
|
||||
raise ValueError('Layers not defined')
|
||||
return self._layers
|
||||
|
||||
@layers.setter
|
||||
def layers(self, value):
|
||||
"""
|
||||
Set thermal boundary layers
|
||||
:param value: [Layer]
|
||||
"""
|
||||
self._layers = value
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
|
@ -209,18 +206,23 @@ class ThermalBoundary:
|
|||
for window_area in self.windows_areas:
|
||||
total_window_area += window_area
|
||||
self._window_ratio = total_window_area / (self.opaque_area + total_window_area)
|
||||
else:
|
||||
if self.type in (cte.WALL, cte.ROOF):
|
||||
if -math.sqrt(2) / 2 < math.sin(self.parent_surface.azimuth) < math.sqrt(2) / 2:
|
||||
if 0 < math.cos(self.parent_surface.azimuth):
|
||||
self._window_ratio = \
|
||||
float(self._construction_archetype.window_ratio['north']) / 100
|
||||
else:
|
||||
self._window_ratio = \
|
||||
float(self._construction_archetype.window_ratio['south']) / 100
|
||||
elif math.sqrt(2) / 2 <= math.sin(self._parent_surface.azimuth):
|
||||
self._window_ratio = \
|
||||
float(self._construction_archetype.window_ratio['east']) / 100
|
||||
else:
|
||||
self._window_ratio = \
|
||||
float(self._construction_archetype.window_ratio['west']) / 100
|
||||
return self._window_ratio
|
||||
|
||||
@window_ratio.setter
|
||||
def window_ratio(self, value):
|
||||
"""
|
||||
Set thermal boundary window ratio
|
||||
:param value: str
|
||||
"""
|
||||
if self._window_ratio_to_be_calculated:
|
||||
raise ValueError('Window ratio cannot be assigned when the windows are defined in the geometry.')
|
||||
self._window_ratio = float(value)
|
||||
|
||||
@property
|
||||
def windows_areas(self) -> [float]:
|
||||
"""
|
||||
|
@ -245,15 +247,28 @@ class ThermalBoundary:
|
|||
r_value = 1.0/h_i + 1.0/h_e
|
||||
try:
|
||||
for layer in self.layers:
|
||||
if layer.material.no_mass:
|
||||
r_value += float(layer.material.thermal_resistance)
|
||||
if layer.no_mass:
|
||||
r_value += float(layer.thermal_resistance)
|
||||
else:
|
||||
r_value += float(layer.thickness) / float(layer.material.conductivity)
|
||||
r_value += float(layer.thickness) / float(layer.conductivity)
|
||||
self._u_value = 1.0/r_value
|
||||
except TypeError:
|
||||
raise TypeError('Constructions layers are not initialized') from TypeError
|
||||
return self._u_value
|
||||
|
||||
@property
|
||||
def construction_name(self):
|
||||
"""
|
||||
Get construction name
|
||||
:return: str
|
||||
"""
|
||||
if self._construction_archetype is not None:
|
||||
self._construction_name = self._construction_archetype.name
|
||||
else:
|
||||
logging.error('Construction name not defined\n')
|
||||
raise ValueError('Construction name not defined')
|
||||
return self._construction_name
|
||||
|
||||
@u_value.setter
|
||||
def u_value(self, value):
|
||||
"""
|
||||
|
@ -305,4 +320,18 @@ class ThermalBoundary:
|
|||
"""
|
||||
if self._internal_surface is None:
|
||||
self._internal_surface = self.parent_surface.inverse
|
||||
# The agreement is that the layers are defined from outside to inside
|
||||
internal_layer = self.layers[len(self.layers) - 1]
|
||||
self._internal_surface.short_wave_reflectance = 1 - internal_layer.solar_absorptance
|
||||
self._internal_surface.long_wave_emittance = 1 - internal_layer.solar_absorptance
|
||||
|
||||
return self._internal_surface
|
||||
|
||||
@property
|
||||
def external_surface(self) -> Surface:
|
||||
if self._external_surface is None:
|
||||
# The agreement is that the layers are defined from outside to inside
|
||||
self._external_surface = self.parent_surface
|
||||
self._external_surface.short_wave_reflectance = 1 - self.layers[0].solar_absorptance
|
||||
self._external_surface.long_wave_emittance = 1 - self.layers[0].solar_absorptance
|
||||
return self._external_surface
|
||||
|
|
|
@ -4,6 +4,7 @@ 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 math import inf
|
||||
from typing import Union, List
|
||||
from hub.city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
@ -22,20 +23,16 @@ class ThermalControl:
|
|||
|
||||
@staticmethod
|
||||
def _maximum_value(schedules):
|
||||
maximum = -1000
|
||||
maximum = -inf
|
||||
for schedule in schedules:
|
||||
for value in schedule.values:
|
||||
if value > maximum:
|
||||
maximum = value
|
||||
maximum = max(maximum, max(schedule.values))
|
||||
return maximum
|
||||
|
||||
@staticmethod
|
||||
def _minimum_value(schedules):
|
||||
minimum = 1000
|
||||
minimum = inf
|
||||
for schedule in schedules:
|
||||
for value in schedule.values:
|
||||
if value < minimum:
|
||||
minimum = value
|
||||
minimum = min(minimum, min(schedule.values))
|
||||
return minimum
|
||||
|
||||
@property
|
||||
|
|
|
@ -29,7 +29,12 @@ class ThermalZone:
|
|||
ThermalZone class
|
||||
"""
|
||||
|
||||
def __init__(self, thermal_boundaries, parent_internal_zone, volume, footprint_area, usage_name=None):
|
||||
def __init__(self, thermal_boundaries,
|
||||
parent_internal_zone,
|
||||
volume,
|
||||
footprint_area,
|
||||
number_of_storeys,
|
||||
usage_name=None):
|
||||
self._id = None
|
||||
self._parent_internal_zone = parent_internal_zone
|
||||
self._footprint_area = footprint_area
|
||||
|
@ -39,10 +44,13 @@ class ThermalZone:
|
|||
self._indirectly_heated_area_ratio = None
|
||||
self._infiltration_rate_system_on = None
|
||||
self._infiltration_rate_system_off = None
|
||||
self._infiltration_rate_area_system_on = None
|
||||
self._infiltration_rate_area_system_off = None
|
||||
self._volume = volume
|
||||
self._ordinate_number = None
|
||||
self._view_factors_matrix = None
|
||||
self._total_floor_area = None
|
||||
self._number_of_storeys = number_of_storeys
|
||||
self._usage_name = usage_name
|
||||
self._usage_from_parent = False
|
||||
if usage_name is None:
|
||||
|
@ -58,6 +66,14 @@ class ThermalZone:
|
|||
self._domestic_hot_water = None
|
||||
self._usages = None
|
||||
|
||||
@property
|
||||
def parent_internal_zone(self) -> InternalZone:
|
||||
"""
|
||||
Get the internal zone to which this thermal zone belongs
|
||||
:return: InternalZone
|
||||
"""
|
||||
return self._parent_internal_zone
|
||||
|
||||
@property
|
||||
def usages(self):
|
||||
"""
|
||||
|
@ -113,82 +129,62 @@ class ThermalZone:
|
|||
Get thermal zone additional thermal bridge u value per footprint area W/m2K
|
||||
:return: None or float
|
||||
"""
|
||||
self._additional_thermal_bridge_u_value = self.parent_internal_zone.thermal_archetype.extra_loses_due_to_thermal_bridges
|
||||
return self._additional_thermal_bridge_u_value
|
||||
|
||||
@additional_thermal_bridge_u_value.setter
|
||||
def additional_thermal_bridge_u_value(self, value):
|
||||
"""
|
||||
Set thermal zone additional thermal bridge u value per footprint area W/m2K
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._additional_thermal_bridge_u_value = float(value)
|
||||
|
||||
@property
|
||||
def effective_thermal_capacity(self) -> Union[None, float]:
|
||||
"""
|
||||
Get thermal zone effective thermal capacity in J/m3K
|
||||
:return: None or float
|
||||
"""
|
||||
self._effective_thermal_capacity = self._parent_internal_zone.thermal_archetype.thermal_capacity
|
||||
return self._effective_thermal_capacity
|
||||
|
||||
@effective_thermal_capacity.setter
|
||||
def effective_thermal_capacity(self, value):
|
||||
"""
|
||||
Set thermal zone effective thermal capacity in J/m3K
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._effective_thermal_capacity = float(value)
|
||||
|
||||
@property
|
||||
def indirectly_heated_area_ratio(self) -> Union[None, float]:
|
||||
"""
|
||||
Get thermal zone indirectly heated area ratio
|
||||
:return: None or float
|
||||
"""
|
||||
self._indirectly_heated_area_ratio = self._parent_internal_zone.thermal_archetype.indirect_heated_ratio
|
||||
return self._indirectly_heated_area_ratio
|
||||
|
||||
@indirectly_heated_area_ratio.setter
|
||||
def indirectly_heated_area_ratio(self, value):
|
||||
"""
|
||||
Set thermal zone indirectly heated area ratio
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._indirectly_heated_area_ratio = float(value)
|
||||
|
||||
@property
|
||||
def infiltration_rate_system_on(self):
|
||||
"""
|
||||
Get thermal zone infiltration rate system on in air changes per hour (ACH)
|
||||
Get thermal zone infiltration rate system on in air changes per second (1/s)
|
||||
:return: None or float
|
||||
"""
|
||||
self._infiltration_rate_system_on = self._parent_internal_zone.thermal_archetype.infiltration_rate_for_ventilation_system_on
|
||||
return self._infiltration_rate_system_on
|
||||
|
||||
@infiltration_rate_system_on.setter
|
||||
def infiltration_rate_system_on(self, value):
|
||||
"""
|
||||
Set thermal zone infiltration rate system on in air changes per hour (ACH)
|
||||
:param value: float
|
||||
"""
|
||||
self._infiltration_rate_system_on = value
|
||||
|
||||
@property
|
||||
def infiltration_rate_system_off(self):
|
||||
"""
|
||||
Get thermal zone infiltration rate system off in air changes per hour (ACH)
|
||||
Get thermal zone infiltration rate system off in air changes per second (1/s)
|
||||
:return: None or float
|
||||
"""
|
||||
self._infiltration_rate_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_for_ventilation_system_off
|
||||
return self._infiltration_rate_system_off
|
||||
|
||||
@infiltration_rate_system_off.setter
|
||||
def infiltration_rate_system_off(self, value):
|
||||
@property
|
||||
def infiltration_rate_area_system_on(self):
|
||||
"""
|
||||
Set thermal zone infiltration rate system on in air changes per hour (ACH)
|
||||
:param value: float
|
||||
Get thermal zone infiltration rate system on in air changes per second (1/s)
|
||||
:return: None or float
|
||||
"""
|
||||
self._infiltration_rate_system_off = value
|
||||
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):
|
||||
|
@ -221,15 +217,43 @@ class ThermalZone:
|
|||
Get thermal zone view factors matrix
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._view_factors_matrix
|
||||
# todo: review method if windows not in window_ratio but in geometry
|
||||
if self._view_factors_matrix is None:
|
||||
total_area = 0
|
||||
for thermal_boundary in self.thermal_boundaries:
|
||||
total_area += thermal_boundary.opaque_area
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
total_area += thermal_opening.area
|
||||
|
||||
@view_factors_matrix.setter
|
||||
def view_factors_matrix(self, value):
|
||||
"""
|
||||
Set thermal zone view factors matrix
|
||||
:param value: [[float]]
|
||||
"""
|
||||
self._view_factors_matrix = value
|
||||
view_factors_matrix = []
|
||||
for thermal_boundary_1 in self.thermal_boundaries:
|
||||
values = []
|
||||
for thermal_boundary_2 in self.thermal_boundaries:
|
||||
value = 0
|
||||
if thermal_boundary_1.id != thermal_boundary_2.id:
|
||||
value = thermal_boundary_2.opaque_area / (total_area - thermal_boundary_1.opaque_area)
|
||||
values.append(value)
|
||||
for thermal_boundary in self.thermal_boundaries:
|
||||
for thermal_opening in thermal_boundary.thermal_openings:
|
||||
value = thermal_opening.area / (total_area - thermal_boundary_1.opaque_area)
|
||||
values.append(value)
|
||||
view_factors_matrix.append(values)
|
||||
|
||||
for thermal_boundary_1 in self.thermal_boundaries:
|
||||
values = []
|
||||
for thermal_opening_1 in thermal_boundary_1.thermal_openings:
|
||||
for thermal_boundary_2 in self.thermal_boundaries:
|
||||
value = thermal_boundary_2.opaque_area / (total_area - thermal_opening_1.area)
|
||||
values.append(value)
|
||||
for thermal_boundary in self.thermal_boundaries:
|
||||
for thermal_opening_2 in thermal_boundary.thermal_openings:
|
||||
value = 0
|
||||
if thermal_opening_1.id != thermal_opening_2.id:
|
||||
value = thermal_opening_2.area / (total_area - thermal_opening_1.area)
|
||||
values.append(value)
|
||||
view_factors_matrix.append(values)
|
||||
self._view_factors_matrix = view_factors_matrix
|
||||
return self._view_factors_matrix
|
||||
|
||||
@property
|
||||
def usage_name(self) -> Union[None, str]:
|
||||
|
@ -285,7 +309,7 @@ class ThermalZone:
|
|||
@property
|
||||
def mechanical_air_change(self) -> Union[None, float]:
|
||||
"""
|
||||
Get thermal zone mechanical air change in air change per hour (ACH)
|
||||
Get thermal zone mechanical air change in air change per second (1/s)
|
||||
:return: None or float
|
||||
"""
|
||||
if self.usages is None:
|
||||
|
@ -653,15 +677,8 @@ class ThermalZone:
|
|||
@property
|
||||
def total_floor_area(self):
|
||||
"""
|
||||
Get the total floor area of this thermal zone
|
||||
Get the total floor area of this thermal zone in m2
|
||||
:return: float
|
||||
"""
|
||||
self._total_floor_area = self.footprint_area * self._number_of_storeys
|
||||
return self._total_floor_area
|
||||
|
||||
@total_floor_area.setter
|
||||
def total_floor_area(self, value):
|
||||
"""
|
||||
Set the total floor area of this thermal zone
|
||||
:param value: float
|
||||
"""
|
||||
self._total_floor_area = value
|
||||
|
|
|
@ -173,7 +173,7 @@ class Usage:
|
|||
@property
|
||||
def mechanical_air_change(self) -> Union[None, float]:
|
||||
"""
|
||||
Get usage zone mechanical air change in air change per hour (ACH)
|
||||
Get usage zone mechanical air change in air change per second (1/s)
|
||||
:return: None or float
|
||||
"""
|
||||
return self._mechanical_air_change
|
||||
|
@ -181,7 +181,7 @@ class Usage:
|
|||
@mechanical_air_change.setter
|
||||
def mechanical_air_change(self, value):
|
||||
"""
|
||||
Set usage zone mechanical air change in air change per hour (ACH)
|
||||
Set usage zone mechanical air change in air change per second (1/s)
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
"""
|
||||
Bus system 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 List
|
||||
from hub.city_model_structure.city_object import CityObject
|
||||
from hub.city_model_structure.attributes.polygon import Polygon
|
||||
from hub.city_model_structure.transport.bus_network import BusNetwork
|
||||
from hub.city_model_structure.transport.bus_node import BusNode
|
||||
from hub.city_model_structure.transport.bus import Bus
|
||||
|
||||
|
||||
class BusSystem(CityObject):
|
||||
"""
|
||||
BusSystem(CityObject) class
|
||||
"""
|
||||
def __init__(self, name, surfaces):
|
||||
super().__init__(name, surfaces)
|
||||
self._bus_routes = None
|
||||
self._bus_network = None
|
||||
self._buses = None
|
||||
self._restricted_polygons = None
|
||||
|
||||
@property
|
||||
def bus_routes(self) -> List[BusNode]:
|
||||
"""
|
||||
Add explanation here
|
||||
:return: [BusNode]
|
||||
"""
|
||||
return self._bus_routes
|
||||
|
||||
@property
|
||||
def bus_network(self) -> BusNetwork:
|
||||
"""
|
||||
Add explanation here
|
||||
:return: BusNetwork
|
||||
"""
|
||||
return self._bus_network
|
||||
|
||||
@property
|
||||
def buses(self) -> List[Bus]:
|
||||
"""
|
||||
Add explanation here
|
||||
:return: [Bus]
|
||||
"""
|
||||
return self._buses
|
||||
|
||||
@property
|
||||
def restricted_polygons(self) -> List[Polygon]:
|
||||
"""
|
||||
Add explanation here
|
||||
:return: [Polygon]
|
||||
"""
|
||||
return self._restricted_polygons
|
|
@ -14,6 +14,7 @@ import math
|
|||
import pickle
|
||||
import sys
|
||||
import pathlib
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import List, Union
|
||||
|
||||
|
@ -25,7 +26,6 @@ from hub.city_model_structure.building import Building
|
|||
from hub.city_model_structure.buildings_cluster import BuildingsCluster
|
||||
from hub.city_model_structure.city_object import CityObject
|
||||
from hub.city_model_structure.city_objects_cluster import CityObjectsCluster
|
||||
from hub.city_model_structure.energy_system import EnergySystem
|
||||
from hub.city_model_structure.iot.station import Station
|
||||
from hub.city_model_structure.level_of_detail import LevelOfDetail
|
||||
from hub.city_model_structure.parts_consisting_building import PartsConsistingBuilding
|
||||
|
@ -62,7 +62,6 @@ 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:
|
||||
|
@ -102,7 +101,7 @@ class City:
|
|||
Get city location
|
||||
:return: Location
|
||||
"""
|
||||
return self._get_location().city
|
||||
return self._get_location()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -114,6 +113,15 @@ class City:
|
|||
return self._get_location().city
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
"""
|
||||
Set city name
|
||||
:param value:str
|
||||
"""
|
||||
if value is not None:
|
||||
self._name = str(value)
|
||||
|
||||
@property
|
||||
def climate_reference_city(self) -> Union[None, str]:
|
||||
"""
|
||||
|
@ -163,9 +171,6 @@ class City:
|
|||
if self.buildings is not None:
|
||||
for building in self.buildings:
|
||||
self._city_objects.append(building)
|
||||
if self.energy_systems is not None:
|
||||
for energy_system in self.energy_systems:
|
||||
self._city_objects.append(energy_system)
|
||||
return self._city_objects
|
||||
|
||||
@property
|
||||
|
@ -279,15 +284,6 @@ class City:
|
|||
"""
|
||||
return self._srs_name
|
||||
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
"""
|
||||
Set city name
|
||||
:param value:str
|
||||
"""
|
||||
if value is not None:
|
||||
self._name = str(value)
|
||||
|
||||
@staticmethod
|
||||
def load(city_filename) -> City:
|
||||
"""
|
||||
|
@ -303,6 +299,20 @@ 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
|
||||
|
@ -409,14 +419,6 @@ class City:
|
|||
"""
|
||||
return self._parts_consisting_buildings
|
||||
|
||||
@property
|
||||
def energy_systems(self) -> Union[List[EnergySystem], None]:
|
||||
"""
|
||||
Get energy systems belonging to the city
|
||||
:return: None or [EnergySystem]
|
||||
"""
|
||||
return self._energy_systems
|
||||
|
||||
@property
|
||||
def stations(self) -> [Station]:
|
||||
"""
|
||||
|
@ -478,12 +480,12 @@ class City:
|
|||
parameter_city_building_total_radiation = 0
|
||||
for surface in building.surfaces:
|
||||
if surface.global_irradiance:
|
||||
parameter_city_building_total_radiation += surface.global_irradiance[cte.YEAR].iloc[0, 0]
|
||||
parameter_city_building_total_radiation += surface.global_irradiance[cte.YEAR][0]
|
||||
|
||||
merged_city_building_total_radiation = 0
|
||||
for surface in merged_city.city_object(building.name).surfaces:
|
||||
if surface.global_irradiance:
|
||||
merged_city_building_total_radiation += surface.global_irradiance[cte.YEAR].iloc[0, 0]
|
||||
merged_city_building_total_radiation += surface.global_irradiance[cte.YEAR][0]
|
||||
|
||||
if merged_city_building_total_radiation == 0:
|
||||
merged_city.remove_city_object(merged_city.city_object(building.name))
|
||||
|
@ -502,24 +504,6 @@ 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:
|
||||
"""
|
||||
|
|
|
@ -41,9 +41,10 @@ class CityObject:
|
|||
self._ground_temperature = {}
|
||||
self._global_horizontal = {}
|
||||
self._diffuse = {}
|
||||
self._beam = {}
|
||||
self._direct_normal = {}
|
||||
self._sensors = []
|
||||
self._neighbours = None
|
||||
self._beam = {}
|
||||
|
||||
@property
|
||||
def level_of_detail(self) -> LevelOfDetail:
|
||||
|
@ -81,6 +82,10 @@ class CityObject:
|
|||
|
||||
@volume.setter
|
||||
def volume(self, value):
|
||||
"""
|
||||
Set city object volume in cubic meters
|
||||
:param value: float
|
||||
"""
|
||||
self._volume = value
|
||||
|
||||
@property
|
||||
|
@ -172,7 +177,7 @@ class CityObject:
|
|||
def external_temperature(self) -> {float}:
|
||||
"""
|
||||
Get external temperature surrounding the city object in Celsius
|
||||
:return: dict{DataFrame(float)}
|
||||
:return: dict{dict{[float]}}
|
||||
"""
|
||||
return self._external_temperature
|
||||
|
||||
|
@ -180,11 +185,10 @@ class CityObject:
|
|||
def external_temperature(self, value):
|
||||
"""
|
||||
Set external temperature surrounding the city object in Celsius
|
||||
:param value: dict{DataFrame(float)}
|
||||
:param value: dict{dict{[float]}}
|
||||
"""
|
||||
self._external_temperature = value
|
||||
|
||||
# todo: this is the new format we will use to get rid of the data frames
|
||||
@property
|
||||
def ground_temperature(self) -> dict:
|
||||
"""
|
||||
|
@ -205,50 +209,50 @@ class CityObject:
|
|||
@property
|
||||
def global_horizontal(self) -> dict:
|
||||
"""
|
||||
Get global horizontal radiation surrounding the city object in W/m2
|
||||
:return: dict{DataFrame(float)}
|
||||
Get global horizontal radiation surrounding the city object in J/m2
|
||||
:return: dict{dict{[float]}}
|
||||
"""
|
||||
return self._global_horizontal
|
||||
|
||||
@global_horizontal.setter
|
||||
def global_horizontal(self, value):
|
||||
"""
|
||||
Set global horizontal radiation surrounding the city object in W/m2
|
||||
:param value: dict{DataFrame(float)}
|
||||
Set global horizontal radiation surrounding the city object in J/m2
|
||||
:param value: dict{dict{[float]}}
|
||||
"""
|
||||
self._global_horizontal = value
|
||||
|
||||
@property
|
||||
def diffuse(self) -> dict:
|
||||
"""
|
||||
Get diffuse radiation surrounding the city object in W/m2
|
||||
:return: dict{DataFrame(float)}
|
||||
Get diffuse radiation surrounding the city object in J/m2
|
||||
:return: dict{dict{[float]}}
|
||||
"""
|
||||
return self._diffuse
|
||||
|
||||
@diffuse.setter
|
||||
def diffuse(self, value):
|
||||
"""
|
||||
Set diffuse radiation surrounding the city object in W/m2
|
||||
:param value: dict{DataFrame(float)}
|
||||
Set diffuse radiation surrounding the city object in J/m2
|
||||
:param value: dict{dict{[float]}}
|
||||
"""
|
||||
self._diffuse = value
|
||||
|
||||
@property
|
||||
def beam(self) -> dict:
|
||||
def direct_normal(self) -> dict:
|
||||
"""
|
||||
Get beam radiation surrounding the city object in W/m2
|
||||
:return: dict{DataFrame(float)}
|
||||
Get beam radiation surrounding the city object in J/m2
|
||||
:return: dict{dict{[float]}}
|
||||
"""
|
||||
return self._beam
|
||||
return self._direct_normal
|
||||
|
||||
@beam.setter
|
||||
def beam(self, value):
|
||||
@direct_normal.setter
|
||||
def direct_normal(self, value):
|
||||
"""
|
||||
Set beam radiation surrounding the city object in W/m2
|
||||
:param value: dict{DataFrame(float)}
|
||||
Set beam radiation surrounding the city object in J/m2
|
||||
:param value: dict{dict{[float]}}
|
||||
"""
|
||||
self._beam = value
|
||||
self._direct_normal = value
|
||||
|
||||
@property
|
||||
def lower_corner(self):
|
||||
|
@ -299,3 +303,19 @@ 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
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
"""
|
||||
EnergySystem 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
|
||||
Code contributors: Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from hub.city_model_structure.city_object import CityObject
|
||||
from hub.city_model_structure.energy_systems.air_source_hp import AirSourceHP
|
||||
from hub.city_model_structure.energy_systems.water_to_water_hp import WaterToWaterHP
|
||||
|
||||
|
||||
class EnergySystem(CityObject):
|
||||
"""
|
||||
EnergySystem(CityObject) class
|
||||
"""
|
||||
|
||||
def __init__(self, name, surfaces):
|
||||
super().__init__(name, surfaces)
|
||||
self._air_source_hp = None
|
||||
self._water_to_water_hp = None
|
||||
self._type = 'energy_system'
|
||||
|
||||
@property
|
||||
def air_source_hp(self) -> AirSourceHP:
|
||||
"""
|
||||
Heat pump energy system
|
||||
:return:
|
||||
"""
|
||||
return self._air_source_hp
|
||||
|
||||
@air_source_hp.setter
|
||||
def air_source_hp(self, value):
|
||||
"""
|
||||
Set heat pump for energy system
|
||||
:param value: AirSourceHP
|
||||
"""
|
||||
if self._air_source_hp is None:
|
||||
self._air_source_hp = value
|
||||
|
||||
@property
|
||||
def water_to_water_hp(self) -> WaterToWaterHP:
|
||||
"""
|
||||
Water to water heat pump energy system
|
||||
:return:
|
||||
"""
|
||||
return self._water_to_water_hp
|
||||
|
||||
@water_to_water_hp.setter
|
||||
def water_to_water_hp(self, value):
|
||||
"""
|
||||
Set water to water heat pump for energy system
|
||||
:param value: WaterToWaterHP
|
||||
"""
|
||||
if self._water_to_water_hp is None:
|
||||
self._water_to_water_hp = value
|
||||
|
||||
@property
|
||||
def type(self) -> str:
|
||||
"""
|
||||
Type of city object
|
||||
:return: str
|
||||
"""
|
||||
return self._type
|
|
@ -1,132 +0,0 @@
|
|||
"""
|
||||
air_source_hp module defines an air source heat pump
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
Code contributors: Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from hub.city_model_structure.energy_systems.heat_pump import HeatPump
|
||||
|
||||
|
||||
class AirSourceHP(HeatPump):
|
||||
"""
|
||||
AirSourceHP class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._cooling_capacity = None
|
||||
self._cooling_comp_power = None
|
||||
self._cooling_capacity_coff = None # a coefficients for insel
|
||||
self._heating_capacity = None
|
||||
self._heating_comp_power = None
|
||||
self._heating_capacity_coff = None
|
||||
|
||||
@property
|
||||
def cooling_capacity(self) -> List[float]:
|
||||
"""
|
||||
Get cooling capacity in kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._cooling_capacity
|
||||
|
||||
@cooling_capacity.setter
|
||||
def cooling_capacity(self, value):
|
||||
"""
|
||||
Set cooling capacity in kW
|
||||
:param value: [[float]]
|
||||
"""
|
||||
if self._cooling_capacity is None:
|
||||
self._cooling_capacity = value
|
||||
|
||||
@property
|
||||
def cooling_comp_power(self) -> List[float]:
|
||||
"""
|
||||
Get cooling compressor power input in kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._cooling_comp_power
|
||||
|
||||
@cooling_comp_power.setter
|
||||
def cooling_comp_power(self, value):
|
||||
"""
|
||||
Set the cooling compressor in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._cooling_comp_power is None:
|
||||
self._cooling_comp_power = value
|
||||
|
||||
@property
|
||||
def cooling_capacity_coff(self) -> List[float]:
|
||||
"""
|
||||
Get cooling capacity coefficients
|
||||
:return: [float]
|
||||
"""
|
||||
return self._cooling_capacity_coff
|
||||
|
||||
@cooling_capacity_coff.setter
|
||||
def cooling_capacity_coff(self, value):
|
||||
"""
|
||||
Set the value for cooling capacity coefficients
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._cooling_capacity_coff is None:
|
||||
self._cooling_capacity_coff = value
|
||||
|
||||
@property
|
||||
def heating_capacity(self) -> List[float]:
|
||||
"""
|
||||
Get heating capacity kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._heating_capacity
|
||||
|
||||
@heating_capacity.setter
|
||||
def heating_capacity(self, value):
|
||||
"""
|
||||
Set the heating capacity in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._heating_capacity is None:
|
||||
self._heating_capacity = value
|
||||
|
||||
@property
|
||||
def heating_comp_power(self) -> List[float]:
|
||||
"""
|
||||
Get heating compressor power kW
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._heating_comp_power
|
||||
|
||||
@heating_comp_power.setter
|
||||
def heating_comp_power(self, value):
|
||||
"""
|
||||
Set the heating compressor power in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._heating_comp_power is None:
|
||||
self._heating_comp_power = value
|
||||
|
||||
@property
|
||||
def heating_capacity_coff(self) -> List[float]:
|
||||
"""
|
||||
Get heating capacity coefficients
|
||||
:return: [float]
|
||||
"""
|
||||
return self._heating_capacity_coff
|
||||
|
||||
@heating_capacity_coff.setter
|
||||
def heating_capacity_coff(self, value):
|
||||
"""
|
||||
Set the value for heating capacity coefficients
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._heating_capacity_coff is None:
|
||||
self._heating_capacity_coff = value
|
|
@ -5,7 +5,12 @@ Copyright © 2023 Concordia CERC group
|
|||
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
from hub.city_model_structure.energy_systems.generic_distribution_system import GenericDistributionSystem
|
||||
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')
|
||||
|
||||
|
||||
class DistributionSystem:
|
||||
|
@ -13,20 +18,158 @@ class DistributionSystem:
|
|||
DistributionSystem class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._generic_distribution_system = None
|
||||
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
|
||||
|
||||
@property
|
||||
def generic_distribution_system(self) -> GenericDistributionSystem:
|
||||
def model_name(self):
|
||||
"""
|
||||
Get generic_distribution_system
|
||||
:return: GenericDistributionSystem
|
||||
Get model name
|
||||
:return: string
|
||||
"""
|
||||
return self._generic_distribution_system
|
||||
return self._model_name
|
||||
|
||||
@generic_distribution_system.setter
|
||||
def generic_distribution_system(self, value):
|
||||
@model_name.setter
|
||||
def model_name(self, value):
|
||||
"""
|
||||
Set associated generic_distribution_system
|
||||
:param value: GenericDistributionSystem
|
||||
Set model name
|
||||
:param value: string
|
||||
"""
|
||||
self._generic_distribution_system = value
|
||||
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
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
"""
|
||||
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
|
|
@ -1,32 +1,64 @@
|
|||
"""
|
||||
Energy emission system definition
|
||||
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
|
||||
"""
|
||||
|
||||
from hub.city_model_structure.energy_systems.generic_emission_system import GenericEmissionSystem
|
||||
|
||||
|
||||
class EmissionSystem:
|
||||
"""
|
||||
EmissionSystem class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._generic_emission_system = None
|
||||
self._model_name = None
|
||||
self._type = None
|
||||
self._parasitic_energy_consumption = 0
|
||||
|
||||
@property
|
||||
def generic_emission_system(self) -> GenericEmissionSystem:
|
||||
def model_name(self):
|
||||
"""
|
||||
Get associated generic_emission_system
|
||||
:return: GenericEmissionSystem
|
||||
Get model name
|
||||
:return: string
|
||||
"""
|
||||
return self._generic_emission_system
|
||||
return self._model_name
|
||||
|
||||
@generic_emission_system.setter
|
||||
def generic_emission_system(self, value):
|
||||
@model_name.setter
|
||||
def model_name(self, value):
|
||||
"""
|
||||
Set associated
|
||||
:param value: GenericEmissionSystem
|
||||
Set model name
|
||||
:param value: string
|
||||
"""
|
||||
self._generic_emission_system = value
|
||||
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
|
||||
|
|
118
hub/city_model_structure/energy_systems/energy_storage_system.py
Normal file
118
hub/city_model_structure/energy_systems/energy_storage_system.py
Normal file
|
@ -0,0 +1,118 @@
|
|||
"""
|
||||
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
|
|
@ -6,10 +6,11 @@ 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.emission_system import EmissionSystem
|
||||
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.control_system import ControlSystem
|
||||
from hub.city_model_structure.city_object import CityObject
|
||||
|
||||
|
@ -19,30 +20,14 @@ class EnergySystem:
|
|||
EnergySystem class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._name = None
|
||||
self._demand_types = None
|
||||
self._generation_system = None
|
||||
self._distribution_system = None
|
||||
self._emission_system = None
|
||||
self._name = None
|
||||
self._generation_systems = None
|
||||
self._distribution_systems = None
|
||||
self._configuration_schema = None
|
||||
self._connected_city_objects = None
|
||||
self._control_system = 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):
|
||||
"""
|
||||
|
@ -60,58 +45,74 @@ class EnergySystem:
|
|||
self._demand_types = value
|
||||
|
||||
@property
|
||||
def generation_system(self) -> GenerationSystem:
|
||||
def name(self):
|
||||
"""
|
||||
Get generation system
|
||||
:return: GenerationSystem
|
||||
Get energy system name
|
||||
:return: str
|
||||
"""
|
||||
return self._generation_system
|
||||
return self._name
|
||||
|
||||
@generation_system.setter
|
||||
def generation_system(self, value):
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
"""
|
||||
Set generation system
|
||||
:param value: GenerationSystem
|
||||
Set energy system name
|
||||
:param value:
|
||||
"""
|
||||
self._generation_system = value
|
||||
self._name = value
|
||||
|
||||
@property
|
||||
def distribution_system(self) -> Union[None, DistributionSystem]:
|
||||
def generation_systems(self) -> Union[List[NonPvGenerationSystem], List[PvGenerationSystem]]:
|
||||
"""
|
||||
Get distribution system
|
||||
:return: DistributionSystem
|
||||
Get generation systems
|
||||
:return: [GenerationSystem]
|
||||
"""
|
||||
return self._distribution_system
|
||||
return self._generation_systems
|
||||
|
||||
@distribution_system.setter
|
||||
def distribution_system(self, value):
|
||||
@generation_systems.setter
|
||||
def generation_systems(self, value):
|
||||
"""
|
||||
Set distribution system
|
||||
:param value: DistributionSystem
|
||||
Set generation systems
|
||||
:return: [GenerationSystem]
|
||||
"""
|
||||
self._distribution_system = value
|
||||
self._generation_systems = value
|
||||
|
||||
@property
|
||||
def emission_system(self) -> Union[None, EmissionSystem]:
|
||||
def distribution_systems(self) -> Union[None, List[DistributionSystem]]:
|
||||
"""
|
||||
Get emission system
|
||||
:return: EmissionSystem
|
||||
Get distribution systems
|
||||
:return: [DistributionSystem]
|
||||
"""
|
||||
return self._emission_system
|
||||
return self._distribution_systems
|
||||
|
||||
@emission_system.setter
|
||||
def emission_system(self, value):
|
||||
@distribution_systems.setter
|
||||
def distribution_systems(self, value):
|
||||
"""
|
||||
Set emission system
|
||||
:param value: EmissionSystem
|
||||
Set distribution systems
|
||||
:param value: [DistributionSystem]
|
||||
"""
|
||||
self._emission_system = value
|
||||
self._distribution_systems = value
|
||||
|
||||
@property
|
||||
def configuration_schema(self) -> Path:
|
||||
"""
|
||||
Get the schema of the system configuration
|
||||
:return: Path
|
||||
"""
|
||||
return self._configuration_schema
|
||||
|
||||
@configuration_schema.setter
|
||||
def configuration_schema(self, value):
|
||||
"""
|
||||
Set the schema of the system configuration
|
||||
:param value: Path
|
||||
"""
|
||||
self._configuration_schema = value
|
||||
|
||||
@property
|
||||
def connected_city_objects(self) -> Union[None, List[CityObject]]:
|
||||
"""
|
||||
Get list of city objects that are connected to this energy system
|
||||
:return: List[CityObject]
|
||||
:return: [CityObject]
|
||||
"""
|
||||
return self._connected_city_objects
|
||||
|
||||
|
@ -119,7 +120,7 @@ class EnergySystem:
|
|||
def connected_city_objects(self, value):
|
||||
"""
|
||||
Set list of city objects that are connected to this energy system
|
||||
:param value: List[CityObject]
|
||||
:param value: [CityObject]
|
||||
"""
|
||||
self._connected_city_objects = value
|
||||
|
||||
|
|
|
@ -1,120 +1,158 @@
|
|||
"""
|
||||
Energy generation system definition
|
||||
Energy generation system (abstract class)
|
||||
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 typing import Union
|
||||
from abc import ABC
|
||||
from typing import Union, List
|
||||
|
||||
from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem
|
||||
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
|
||||
|
||||
|
||||
class GenerationSystem:
|
||||
class GenerationSystem(ABC):
|
||||
"""
|
||||
GenerationSystem class
|
||||
"""
|
||||
def __init__(self):
|
||||
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
|
||||
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
|
||||
|
||||
@property
|
||||
def generic_generation_system(self) -> GenericGenerationSystem:
|
||||
def system_type(self):
|
||||
"""
|
||||
Get associated generic_generation_system
|
||||
:return: GenericGenerationSystem
|
||||
Get type
|
||||
:return: string
|
||||
"""
|
||||
return self._generic_generation_system
|
||||
return self._system_type
|
||||
|
||||
@generic_generation_system.setter
|
||||
def generic_generation_system(self, value):
|
||||
@system_type.setter
|
||||
def system_type(self, value):
|
||||
"""
|
||||
Set associated generic_generation_system
|
||||
:param value: GenericGenerationSystem
|
||||
Set type
|
||||
:param value: string
|
||||
"""
|
||||
self._generic_generation_system = value
|
||||
self._system_type = value
|
||||
|
||||
@property
|
||||
def heat_power(self):
|
||||
def name(self):
|
||||
"""
|
||||
Get heat_power in W
|
||||
:return: float
|
||||
Get name
|
||||
:return: string
|
||||
"""
|
||||
return self._heat_power
|
||||
return self._name
|
||||
|
||||
@heat_power.setter
|
||||
def heat_power(self, value):
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
"""
|
||||
Set heat_power in W
|
||||
:param value: float
|
||||
Set name
|
||||
:param value: string
|
||||
"""
|
||||
self._heat_power = value
|
||||
self._name = value
|
||||
|
||||
@property
|
||||
def cooling_power(self):
|
||||
def model_name(self):
|
||||
"""
|
||||
Get cooling_power in W
|
||||
:return: float
|
||||
Get model name
|
||||
:return: string
|
||||
"""
|
||||
return self._cooling_power
|
||||
return self._model_name
|
||||
|
||||
@cooling_power.setter
|
||||
def cooling_power(self, value):
|
||||
@model_name.setter
|
||||
def model_name(self, value):
|
||||
"""
|
||||
Set cooling_power in W
|
||||
:param value: float
|
||||
Set model name
|
||||
:param value: string
|
||||
"""
|
||||
self._cooling_power = value
|
||||
self._model_name = value
|
||||
|
||||
@property
|
||||
def electricity_power(self):
|
||||
def manufacturer(self):
|
||||
"""
|
||||
Get electricity_power in W
|
||||
:return: float
|
||||
Get manufacturer's name
|
||||
:return: string
|
||||
"""
|
||||
return self._electricity_power
|
||||
return self._manufacturer
|
||||
|
||||
@electricity_power.setter
|
||||
def electricity_power(self, value):
|
||||
@manufacturer.setter
|
||||
def manufacturer(self, value):
|
||||
"""
|
||||
Set electricity_power in W
|
||||
:param value: float
|
||||
Set manufacturer's name
|
||||
:param value: string
|
||||
"""
|
||||
self._electricity_power = value
|
||||
self._manufacturer = value
|
||||
|
||||
@property
|
||||
def storage_capacity(self):
|
||||
def fuel_type(self):
|
||||
"""
|
||||
Get storage_capacity in J
|
||||
:return: float
|
||||
Get fuel_type from [Renewable, Gas, Diesel, Electricity, Wood, Coal]
|
||||
:return: string
|
||||
"""
|
||||
return self._storage_capacity
|
||||
return self._fuel_type
|
||||
|
||||
@storage_capacity.setter
|
||||
def storage_capacity(self, value):
|
||||
@fuel_type.setter
|
||||
def fuel_type(self, value):
|
||||
"""
|
||||
Set storage_capacity in J
|
||||
:param value: float
|
||||
Set fuel_type from [Renewable, Gas, Diesel, Electricity, Wood, Coal]
|
||||
:param value: string
|
||||
"""
|
||||
self._storage_capacity = value
|
||||
self._fuel_type = value
|
||||
|
||||
@property
|
||||
def auxiliary_equipment(self) -> Union[None, GenerationSystem]:
|
||||
def distribution_systems(self) -> Union[None, List[DistributionSystem]]:
|
||||
"""
|
||||
Get auxiliary_equipment
|
||||
:return: GenerationSystem
|
||||
Get distributions systems connected to this generation system
|
||||
:return: [DistributionSystem]
|
||||
"""
|
||||
return self._auxiliary_equipment
|
||||
return self._distribution_systems
|
||||
|
||||
@auxiliary_equipment.setter
|
||||
def auxiliary_equipment(self, value):
|
||||
@distribution_systems.setter
|
||||
def distribution_systems(self, value):
|
||||
"""
|
||||
Set auxiliary_equipment
|
||||
:param value: GenerationSystem
|
||||
Set distributions systems connected to this generation system
|
||||
:param value: [DistributionSystem]
|
||||
"""
|
||||
self._auxiliary_equipment = value
|
||||
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
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
"""
|
||||
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 (Wh/Wh)
|
||||
: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 (Wh/Wh)
|
||||
: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
|
|
@ -1,30 +0,0 @@
|
|||
"""
|
||||
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
|
|
@ -1,105 +0,0 @@
|
|||
"""
|
||||
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
|
|
@ -1,186 +0,0 @@
|
|||
"""
|
||||
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
|
|
@ -1,64 +0,0 @@
|
|||
"""
|
||||
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
|
|
@ -1,50 +0,0 @@
|
|||
"""
|
||||
HvacSystem 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, List
|
||||
from hub.city_model_structure.building_demand.thermal_zone import ThermalZone
|
||||
|
||||
|
||||
class HvacSystem:
|
||||
"""
|
||||
HvacSystem class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._type = None
|
||||
self._thermal_zones = None
|
||||
|
||||
@property
|
||||
def type(self) -> Union[None, str]:
|
||||
"""
|
||||
Get hvac system type
|
||||
:return: None or str
|
||||
"""
|
||||
return self._type
|
||||
|
||||
@type.setter
|
||||
def type(self, value):
|
||||
"""
|
||||
Set hvac system type
|
||||
:param value: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._type = str(value)
|
||||
|
||||
@property
|
||||
def thermal_zones(self) -> Union[None, List[ThermalZone]]:
|
||||
"""
|
||||
Get list of zones that this unit serves
|
||||
:return: None or [ThermalZone]
|
||||
"""
|
||||
return self._thermal_zones
|
||||
|
||||
@thermal_zones.setter
|
||||
def thermal_zones(self, value):
|
||||
"""
|
||||
Set list of zones that this unit serves
|
||||
:param value: [ThermalZone]
|
||||
"""
|
||||
self._thermal_zones = value
|
|
@ -1,32 +0,0 @@
|
|||
"""
|
||||
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)
|
|
@ -0,0 +1,539 @@
|
|||
"""
|
||||
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
|
||||
|
104
hub/city_model_structure/energy_systems/performance_curve.py
Normal file
104
hub/city_model_structure/energy_systems/performance_curve.py
Normal file
|
@ -0,0 +1,104 @@
|
|||
"""
|
||||
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
|
257
hub/city_model_structure/energy_systems/pv_generation_system.py
Normal file
257
hub/city_model_structure/energy_systems/pv_generation_system.py
Normal file
|
@ -0,0 +1,257 @@
|
|||
"""
|
||||
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
|
|
@ -0,0 +1,139 @@
|
|||
"""
|
||||
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
|
|
@ -1,131 +0,0 @@
|
|||
"""
|
||||
water_to_water_hp module defines a water to water heat pump 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 hub.city_model_structure.energy_systems.heat_pump import HeatPump
|
||||
|
||||
|
||||
class WaterToWaterHP(HeatPump):
|
||||
"""
|
||||
WaterToWaterHP class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._entering_water_temp = None
|
||||
self._leaving_water_temp = None
|
||||
self._total_cooling_capacity = None
|
||||
self._power_demand = None
|
||||
self._flow_rate = None
|
||||
self._power_demand_coff = None # a coefficients
|
||||
|
||||
@property
|
||||
def entering_water_temp(self) -> List[float]:
|
||||
"""
|
||||
Get entering water temperature in degree celsius
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._entering_water_temp
|
||||
|
||||
@entering_water_temp.setter
|
||||
def entering_water_temp(self, value):
|
||||
"""
|
||||
Set entering water temperature in degree celsius
|
||||
:param value: [[float]]
|
||||
"""
|
||||
if self._entering_water_temp is None:
|
||||
self._entering_water_temp = value
|
||||
|
||||
@property
|
||||
def leaving_water_temp(self) -> List[float]:
|
||||
"""
|
||||
Get leaving water temperature in degree celsius
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._leaving_water_temp
|
||||
|
||||
@leaving_water_temp.setter
|
||||
def leaving_water_temp(self, value):
|
||||
"""
|
||||
Set the leaving water temperature in degree celsius
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._leaving_water_temp is None:
|
||||
self._leaving_water_temp = value
|
||||
|
||||
@property
|
||||
def total_cooling_capacity(self) -> List[float]:
|
||||
"""
|
||||
Get total cooling capacity
|
||||
:return: [float]
|
||||
"""
|
||||
return self._total_cooling_capacity
|
||||
|
||||
@total_cooling_capacity.setter
|
||||
def total_cooling_capacity(self, value):
|
||||
"""
|
||||
Set the value for total cooling capacity
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._total_cooling_capacity is None:
|
||||
self._total_cooling_capacity = value
|
||||
|
||||
@property
|
||||
def power_demand(self) -> List[float]:
|
||||
"""
|
||||
Get power demand in kW
|
||||
:return: [float]
|
||||
"""
|
||||
return self._power_demand
|
||||
|
||||
@power_demand.setter
|
||||
def power_demand(self, value):
|
||||
"""
|
||||
Set the value for power demand in kW
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._power_demand is None:
|
||||
self._power_demand = value
|
||||
|
||||
@property
|
||||
def flow_rate(self) -> List[float]:
|
||||
"""
|
||||
Get flow rate in kg/s
|
||||
:return: [[float]]
|
||||
"""
|
||||
return self._flow_rate
|
||||
|
||||
@flow_rate.setter
|
||||
def flow_rate(self, value):
|
||||
"""
|
||||
Set flow rate in kW
|
||||
:param value: [[float]]
|
||||
:return:
|
||||
"""
|
||||
if self._flow_rate is None:
|
||||
self._flow_rate = value
|
||||
|
||||
@property
|
||||
def power_demand_coff(self) -> List[float]:
|
||||
"""
|
||||
Get power demand coefficients
|
||||
:return: [float]
|
||||
"""
|
||||
return self._power_demand_coff
|
||||
|
||||
@power_demand_coff.setter
|
||||
def power_demand_coff(self, value):
|
||||
"""
|
||||
Set the value for power demand coefficients
|
||||
:param value: [float]
|
||||
:return:
|
||||
"""
|
||||
if self._power_demand_coff is None:
|
||||
self._power_demand_coff = value
|
|
@ -1,115 +0,0 @@
|
|||
"""
|
||||
Bus 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 hub.city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
class Bus:
|
||||
"""
|
||||
Bus class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._maintenance_time = None
|
||||
self._charging_time = None
|
||||
self._recovery_time = None
|
||||
self._vehicle_type = None
|
||||
self._energy_consumption = None
|
||||
self._trips_schedule = None
|
||||
self._capacity = None
|
||||
self._maintenance_cost = None
|
||||
self._investment_cost = None
|
||||
self._charging_range = None
|
||||
self._maximum_travel_range = None
|
||||
|
||||
@property
|
||||
def maintenance_time(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._maintenance_time
|
||||
|
||||
@property
|
||||
def charging_time(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._charging_time
|
||||
|
||||
@property
|
||||
def recovery_time(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self.maintenance_time + self.charging_time
|
||||
|
||||
@property
|
||||
def vehicle_type(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._vehicle_type
|
||||
|
||||
@property
|
||||
def energy_consumption(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._energy_consumption
|
||||
|
||||
@property
|
||||
def trips_schedule(self) -> Schedule:
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._trips_schedule
|
||||
|
||||
@property
|
||||
def capacity(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._capacity
|
||||
|
||||
@property
|
||||
def maintenance_cost(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._maintenance_cost
|
||||
|
||||
@property
|
||||
def investment_cost(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._investment_cost
|
||||
|
||||
@property
|
||||
def charging_range(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._charging_range
|
||||
|
||||
@property
|
||||
def maximum_travel_range(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._maximum_travel_range
|
|
@ -1,35 +0,0 @@
|
|||
"""
|
||||
Bus depot 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 hub.city_model_structure.transport.bus_node import BusNode
|
||||
|
||||
|
||||
class BusDepot(BusNode):
|
||||
"""
|
||||
BusDepot class
|
||||
"""
|
||||
|
||||
def __init__(self, name, coordinates, edges=None):
|
||||
super().__init__(name, coordinates, edges=edges, node_type='BusDepot')
|
||||
self._number_of_charging_poles = None
|
||||
self._number_of_available_buses = None
|
||||
|
||||
@property
|
||||
def number_of_charging_poles(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._number_of_charging_poles
|
||||
|
||||
@property
|
||||
def number_of_available_buses(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._number_of_available_buses
|
|
@ -1,47 +0,0 @@
|
|||
"""
|
||||
Bus edge 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 List, TypeVar
|
||||
from hub.city_model_structure.attributes.edge import Edge
|
||||
|
||||
BusNode = TypeVar('BusNode')
|
||||
|
||||
|
||||
class BusEdge(Edge):
|
||||
"""
|
||||
BusEdge class
|
||||
Each edge is unidirectional and starts at the "from" node and ends at the "to" node
|
||||
"""
|
||||
|
||||
def __init__(self, name, nodes, edge_type='BusEdge'):
|
||||
super().__init__(name, nodes)
|
||||
self._edge_type = edge_type
|
||||
self._average_travel_time = None
|
||||
|
||||
@property
|
||||
def edge_type(self):
|
||||
"""
|
||||
Get the edge type
|
||||
:return: str
|
||||
"""
|
||||
return self._edge_type
|
||||
|
||||
@property
|
||||
def nodes(self) -> List[BusNode]:
|
||||
"""
|
||||
Get delimiting nodes for the edge
|
||||
:return: [BusNode]
|
||||
"""
|
||||
return self._nodes
|
||||
|
||||
@property
|
||||
def average_travel_time(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._average_travel_time
|
|
@ -1,44 +0,0 @@
|
|||
"""
|
||||
Bus network 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 List
|
||||
from hub.city_model_structure.network import Network
|
||||
from hub.city_model_structure.transport.bus_edge import BusEdge
|
||||
from hub.city_model_structure.transport.bus_node import BusNode
|
||||
|
||||
|
||||
class BusNetwork(Network):
|
||||
"""
|
||||
BusNetwork(Network) class
|
||||
"""
|
||||
def __init__(self, name, edges=None, nodes=None):
|
||||
super().__init__(name, edges, nodes)
|
||||
self._type = "BusNetwork"
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
Get network type
|
||||
:return: str
|
||||
"""
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def edges(self) -> List[BusEdge]:
|
||||
"""
|
||||
Get network edges
|
||||
:return: [BusEdge]
|
||||
"""
|
||||
return self._edges
|
||||
|
||||
@property
|
||||
def nodes(self) -> List[BusNode]:
|
||||
"""
|
||||
Get network nodes
|
||||
:return: [BusNode]
|
||||
"""
|
||||
return self._nodes
|
|
@ -1,56 +0,0 @@
|
|||
"""
|
||||
Bus node 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 List, TypeVar
|
||||
|
||||
from hub.city_model_structure.attributes.node import Node
|
||||
from hub.city_model_structure.attributes.point import Point
|
||||
|
||||
BusEdge = TypeVar('BusEdge')
|
||||
|
||||
|
||||
class BusNode(Node):
|
||||
"""
|
||||
BusNode class
|
||||
"""
|
||||
|
||||
def __init__(self, name, coordinates, node_type='BusNode', edges=None):
|
||||
super().__init__(name, edges)
|
||||
self._coordinates = coordinates
|
||||
self._node_type = node_type
|
||||
|
||||
@property
|
||||
def node_type(self):
|
||||
"""
|
||||
Get node type
|
||||
:return: str
|
||||
"""
|
||||
return self._node_type
|
||||
|
||||
@property
|
||||
def coordinates(self) -> Point:
|
||||
"""
|
||||
Get node coordinates
|
||||
:return: Point
|
||||
"""
|
||||
return self._coordinates
|
||||
|
||||
@coordinates.setter
|
||||
def coordinates(self, value):
|
||||
"""
|
||||
Set node coordinates
|
||||
:param value: Point
|
||||
"""
|
||||
self._coordinates = value
|
||||
|
||||
@property
|
||||
def edges(self) -> List[BusEdge]:
|
||||
"""
|
||||
get edges delimited by the node
|
||||
:return: [BusEdge]
|
||||
"""
|
||||
return self._edges
|
|
@ -1,56 +0,0 @@
|
|||
"""
|
||||
Bus stop 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
|
||||
from hub.city_model_structure.transport.bus_node import BusNode
|
||||
from hub.city_model_structure.transport.fast_charging_infrastructure import FastChargingInfrastructure
|
||||
from hub.city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
|
||||
class BusStop(BusNode):
|
||||
"""
|
||||
BusStop class
|
||||
"""
|
||||
|
||||
def __init__(self, name, coordinates, edges=None):
|
||||
super().__init__(name, coordinates, edges=edges, node_type='BusStop')
|
||||
self._time_table = None
|
||||
self._average_hourly_passengers_demand = None
|
||||
self._fast_charging_infrastructure = None
|
||||
self._waiting_time = None
|
||||
|
||||
@property
|
||||
def time_table(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._time_table
|
||||
|
||||
@property
|
||||
def average_hourly_passengers_demand(self) -> Schedule:
|
||||
"""
|
||||
Add explanation here
|
||||
:return: Schedule
|
||||
"""
|
||||
return self._average_hourly_passengers_demand
|
||||
|
||||
@property
|
||||
def fast_charging_infrastructure(self) -> Union[None, FastChargingInfrastructure]:
|
||||
"""
|
||||
Add explanation here
|
||||
:return: FastChargingInfrastructure
|
||||
"""
|
||||
return self._fast_charging_infrastructure
|
||||
|
||||
@property
|
||||
def waiting_time(self):
|
||||
"""
|
||||
Add explanation here
|
||||
:return: add type of variable here
|
||||
"""
|
||||
return self._waiting_time
|
|
@ -1,125 +0,0 @@
|
|||
"""
|
||||
Connection 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
|
||||
Code contributors: Guille guille.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
import ast
|
||||
from typing import Union
|
||||
|
||||
from hub.city_model_structure.attributes.edge import Edge
|
||||
from hub.city_model_structure.transport.lane import Lane
|
||||
|
||||
|
||||
class Connection:
|
||||
"""
|
||||
Connection class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._from_edge = None
|
||||
self._to_edge = None
|
||||
self._from_lane = None
|
||||
self._to_lane = None
|
||||
self._pass = None
|
||||
self._keep_clear = None
|
||||
|
||||
@property
|
||||
def from_edge(self) -> Edge:
|
||||
"""
|
||||
Get "from" edge
|
||||
:return: Edge
|
||||
"""
|
||||
return self._from_edge
|
||||
|
||||
@from_edge.setter
|
||||
def from_edge(self, value):
|
||||
"""
|
||||
Set "from" edge
|
||||
:param value: Edge
|
||||
"""
|
||||
self._from_edge = value
|
||||
|
||||
@property
|
||||
def to_edge(self) -> Edge:
|
||||
"""
|
||||
Get "to" edge
|
||||
:return: Edge
|
||||
"""
|
||||
return self._to_edge
|
||||
|
||||
@to_edge.setter
|
||||
def to_edge(self, value):
|
||||
"""
|
||||
Set "to" edge
|
||||
:param value: Edge
|
||||
"""
|
||||
self._to_edge = value
|
||||
|
||||
@property
|
||||
def from_lane(self) -> Lane:
|
||||
"""
|
||||
Get "from" lane
|
||||
:return: Lane
|
||||
"""
|
||||
return self._to_lane
|
||||
|
||||
@from_lane.setter
|
||||
def from_lane(self, value):
|
||||
"""
|
||||
Set "from" lane
|
||||
:param value: Lane
|
||||
"""
|
||||
self._from_lane = value
|
||||
|
||||
@property
|
||||
def to_lane(self) -> Lane:
|
||||
"""
|
||||
Get "to" lane
|
||||
:return: Lane
|
||||
"""
|
||||
return self._to_lane
|
||||
|
||||
@to_lane.setter
|
||||
def to_lane(self, value):
|
||||
"""
|
||||
Set "to" lane
|
||||
:param value: Lane
|
||||
"""
|
||||
self._to_lane = value
|
||||
|
||||
@property
|
||||
def pass_not_wait(self) -> Union[None, bool]:
|
||||
"""
|
||||
Get if the vehicles which pass this (lane to lane) connection will not wait
|
||||
:return: None or Boolean
|
||||
"""
|
||||
return self._pass
|
||||
|
||||
@pass_not_wait.setter
|
||||
def pass_not_wait(self, value):
|
||||
"""
|
||||
Set if the vehicles which pass this (lane to lane) connection will not wait
|
||||
:param value: Boolean
|
||||
"""
|
||||
if value is not None:
|
||||
self._pass = ast.literal_eval(value)
|
||||
|
||||
@property
|
||||
def keep_clear(self) -> Union[None, bool]:
|
||||
"""
|
||||
Get if vehicles which pass this (lane to lane) connection should keep the intersection clear
|
||||
:return: None or Boolean
|
||||
"""
|
||||
return self._keep_clear
|
||||
|
||||
@keep_clear.setter
|
||||
def keep_clear(self, value):
|
||||
"""
|
||||
Set if vehicles which pass this (lane to lane) connection should keep the intersection clear
|
||||
:param value: Boolean
|
||||
"""
|
||||
if value is not None:
|
||||
self._keep_clear = ast.literal_eval(value)
|
|
@ -1,74 +0,0 @@
|
|||
"""
|
||||
Crossing 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
|
||||
Code contributors: Guille guille.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
import ast
|
||||
from typing import List, Union
|
||||
from hub.city_model_structure.transport.traffic_node import TrafficNode
|
||||
|
||||
|
||||
class Crossing(TrafficNode):
|
||||
"""
|
||||
Crossing class
|
||||
"""
|
||||
|
||||
def __init__(self, name, coordinates, priority, width, shape=None, edges=None):
|
||||
super().__init__(name, coordinates, edges=edges, node_type='Crossing')
|
||||
self._priority = priority
|
||||
self._width = width
|
||||
self._shape = shape
|
||||
|
||||
@property
|
||||
def priority(self) -> Union[None, bool]:
|
||||
"""
|
||||
Get whether the pedestrians have priority over the vehicles
|
||||
:return: None or bool
|
||||
"""
|
||||
return self._priority
|
||||
|
||||
@priority.setter
|
||||
def priority(self, value):
|
||||
"""
|
||||
Set whether the pedestrians have priority over the vehicles
|
||||
:param value: bool
|
||||
"""
|
||||
if value is not None:
|
||||
self._priority = ast.literal_eval(value)
|
||||
|
||||
@property
|
||||
def width(self) -> Union[None, float]:
|
||||
"""
|
||||
Get crossing width in meters
|
||||
:return: None or float
|
||||
"""
|
||||
return self._width
|
||||
|
||||
@width.setter
|
||||
def width(self, value):
|
||||
"""
|
||||
Set crossing width in meters
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._width = float(value)
|
||||
|
||||
@property
|
||||
def shape(self) -> Union[None, List[List[float]]]:
|
||||
"""
|
||||
Get the list of positions
|
||||
:return: None or [[x, y, (z)]]
|
||||
"""
|
||||
return self._shape
|
||||
|
||||
@shape.setter
|
||||
def shape(self, value):
|
||||
"""
|
||||
Set the list of positions
|
||||
:param value: [[x, y, (z)]]
|
||||
"""
|
||||
if value is not None:
|
||||
self._shape = [[float(i) for i in value]]
|
|
@ -1,27 +0,0 @@
|
|||
"""
|
||||
Join 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
|
||||
Code contributors: Guille guille.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from hub.city_model_structure.transport.traffic_node import TrafficNode
|
||||
|
||||
|
||||
class Join(TrafficNode):
|
||||
"""
|
||||
Join class
|
||||
"""
|
||||
|
||||
def __init__(self, name, coordinates, nodes):
|
||||
self._nodes = nodes
|
||||
edges = []
|
||||
prohibitions = []
|
||||
connections = []
|
||||
for node in self._nodes:
|
||||
edges = edges + node.edges
|
||||
prohibitions = prohibitions + node.prohibitions
|
||||
connections = connections + node.connections
|
||||
super().__init__(name, coordinates, edges=edges, prohibitions=prohibitions, connections=connections,
|
||||
node_type='Join')
|
|
@ -1,144 +0,0 @@
|
|||
"""
|
||||
Lane 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 List, Union
|
||||
|
||||
|
||||
class Lane:
|
||||
"""
|
||||
Lane class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._index = None
|
||||
self._allow = None
|
||||
self._disallow = None
|
||||
self._change_left = None
|
||||
self._change_right = None
|
||||
self._speed = None
|
||||
self._width = None
|
||||
|
||||
@property
|
||||
def index(self) -> Union[None, int]:
|
||||
"""
|
||||
Get lane index
|
||||
The enumeration index of the lane (0 is the rightmost lane, <NUMBER_LANES>-1 is the leftmost one)
|
||||
:return: None or int
|
||||
"""
|
||||
return self._index
|
||||
|
||||
@index.setter
|
||||
def index(self, value):
|
||||
"""
|
||||
Set lane index
|
||||
The enumeration index of the lane (0 is the rightmost lane, <NUMBER_LANES>-1 is the leftmost one)
|
||||
:param value: int
|
||||
"""
|
||||
if value is not None:
|
||||
self._index = int(value)
|
||||
|
||||
@property
|
||||
def allow(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
Get the list of allowed vehicle classes
|
||||
:return: None or [str]
|
||||
"""
|
||||
return self._allow
|
||||
|
||||
@allow.setter
|
||||
def allow(self, value):
|
||||
"""
|
||||
Set the list of allowed vehicle classes setter
|
||||
:param value: [str]
|
||||
"""
|
||||
if value is not None:
|
||||
self._allow = [str(i) for i in value]
|
||||
|
||||
@property
|
||||
def disallow(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
Get the list of not allowed vehicle classes
|
||||
:return: None or [str]
|
||||
"""
|
||||
return self._disallow
|
||||
|
||||
@disallow.setter
|
||||
def disallow(self, value):
|
||||
"""
|
||||
Get the list of not allowed vehicle classes setter
|
||||
:param value: [str]
|
||||
"""
|
||||
if value is not None:
|
||||
self._disallow = [str(i) for i in value]
|
||||
|
||||
@property
|
||||
def change_left(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
Get the list of vehicle classes that may change left from this lane
|
||||
:return: None or [str]
|
||||
"""
|
||||
return self._change_left
|
||||
|
||||
@change_left.setter
|
||||
def change_left(self, value):
|
||||
"""
|
||||
Set the list of vehicle classes that may change left from this lane
|
||||
:param value: [str]
|
||||
"""
|
||||
if value is not None:
|
||||
self._change_left = [str(i) for i in value]
|
||||
|
||||
@property
|
||||
def change_right(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
Get the list of vehicle classes that may change right from this lane
|
||||
:return: None or [str]
|
||||
"""
|
||||
return self._change_right
|
||||
|
||||
@change_right.setter
|
||||
def change_right(self, value):
|
||||
"""
|
||||
Set the list of vehicle classes that may change right from this lane
|
||||
:param value: [str]
|
||||
"""
|
||||
if value is not None:
|
||||
self._change_right = [str(i) for i in value]
|
||||
|
||||
@property
|
||||
def speed(self) -> Union[None, float]:
|
||||
"""
|
||||
Get the lane speed in m/s
|
||||
:return: None or float
|
||||
"""
|
||||
return self._speed
|
||||
|
||||
@speed.setter
|
||||
def speed(self, value):
|
||||
"""
|
||||
Set the lane speed in m/s
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._speed = float(value)
|
||||
|
||||
@property
|
||||
def width(self) -> Union[None, float]:
|
||||
"""
|
||||
Get the lane width in meters
|
||||
:return: None or float
|
||||
"""
|
||||
return self._width
|
||||
|
||||
@width.setter
|
||||
def width(self, value):
|
||||
"""
|
||||
Set the lane width in meters
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._width = float(value)
|
|
@ -1,48 +0,0 @@
|
|||
"""
|
||||
Origin-Destination edge 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 List, TypeVar
|
||||
from hub.city_model_structure.attributes.edge import Edge
|
||||
from hub.city_model_structure.attributes.schedule import Schedule
|
||||
|
||||
OriginDestinationNode = TypeVar('OriginDestinationNode')
|
||||
|
||||
|
||||
class OriginDestinationEdge(Edge):
|
||||
"""
|
||||
OriginDestinationEdge class
|
||||
Each edge is unidirectional and starts at the "from" node and ends at the "to" node
|
||||
"""
|
||||
|
||||
def __init__(self, name, nodes, edge_type='OriginDestinationEdge'):
|
||||
super().__init__(name, nodes)
|
||||
self._edge_type = edge_type
|
||||
self._movement_schedule = None
|
||||
|
||||
@property
|
||||
def edge_type(self):
|
||||
"""
|
||||
Get the edge type
|
||||
:return: str
|
||||
"""
|
||||
return self._edge_type
|
||||
|
||||
@property
|
||||
def nodes(self) -> List[OriginDestinationNode]:
|
||||
"""
|
||||
Get delimiting nodes for the edge
|
||||
:return: [OriginDestinationNode]
|
||||
"""
|
||||
return self._nodes
|
||||
|
||||
@property
|
||||
def movement_schedule(self) -> Schedule:
|
||||
"""
|
||||
Get the schedule of the movement of people along this edge
|
||||
:return: Schedule
|
||||
"""
|
||||
return self._movement_schedule
|
|
@ -1,44 +0,0 @@
|
|||
"""
|
||||
Origin-Destination network 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 List
|
||||
from hub.city_model_structure.network import Network
|
||||
from hub.city_model_structure.transport.origin_destination_edge import OriginDestinationEdge
|
||||
from hub.city_model_structure.transport.origin_destination_node import OriginDestinationNode
|
||||
|
||||
|
||||
class OriginDestinationNetwork(Network):
|
||||
"""
|
||||
OriginDestinationNetwork(Network) class
|
||||
"""
|
||||
def __init__(self, name, edges=None, nodes=None):
|
||||
super().__init__(name, edges, nodes)
|
||||
self._type = "OriginDestinationNetwork"
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
Get network type
|
||||
:return: str
|
||||
"""
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def edges(self) -> List[OriginDestinationEdge]:
|
||||
"""
|
||||
Get network edges
|
||||
:return: [OriginDestinationEdge]
|
||||
"""
|
||||
return self._edges
|
||||
|
||||
@property
|
||||
def nodes(self) -> List[OriginDestinationNode]:
|
||||
"""
|
||||
Get network nodes
|
||||
:return: [OriginDestinationNode]
|
||||
"""
|
||||
return self._nodes
|
|
@ -1,85 +0,0 @@
|
|||
"""
|
||||
Origin-Destination node 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 List, TypeVar
|
||||
|
||||
from hub.city_model_structure.attributes.node import Node
|
||||
from hub.city_model_structure.attributes.point import Point
|
||||
from hub.city_model_structure.attributes.polygon import Polygon
|
||||
from hub.city_model_structure.city_object import CityObject
|
||||
|
||||
OriginDestinationEdge = TypeVar('OriginDestinationEdge')
|
||||
|
||||
|
||||
class OriginDestinationNode(Node):
|
||||
"""
|
||||
OriginDestinationNode class
|
||||
"""
|
||||
|
||||
def __init__(self, name, coordinates, node_type='OriginDestinationNode', edges=None, polygon=None):
|
||||
super().__init__(name, edges)
|
||||
self._coordinates = coordinates
|
||||
self._node_type = node_type
|
||||
self._polygon = polygon
|
||||
self._land_use_types = None
|
||||
self._city_objects = None
|
||||
|
||||
@property
|
||||
def node_type(self):
|
||||
"""
|
||||
Get node type
|
||||
:return: str
|
||||
"""
|
||||
return self._node_type
|
||||
|
||||
@property
|
||||
def coordinates(self) -> Point:
|
||||
"""
|
||||
Get node coordinates
|
||||
:return: Point
|
||||
"""
|
||||
return self._coordinates
|
||||
|
||||
@coordinates.setter
|
||||
def coordinates(self, value):
|
||||
"""
|
||||
Set node coordinates
|
||||
:param value: Point
|
||||
"""
|
||||
self._coordinates = value
|
||||
|
||||
@property
|
||||
def edges(self) -> List[OriginDestinationEdge]:
|
||||
"""
|
||||
get edges delimited by the node
|
||||
:return: [OriginDestinationEdge]
|
||||
"""
|
||||
return self._edges
|
||||
|
||||
@property
|
||||
def polygon(self) -> Polygon:
|
||||
"""
|
||||
Get node polygon that defines the zone represented by the node
|
||||
:return: Polygon
|
||||
"""
|
||||
return self._polygon
|
||||
|
||||
@property
|
||||
def land_use_types(self) -> dict:
|
||||
"""
|
||||
Get land use types inside the node polygon. It returns a dictionary with the types of land use together with the
|
||||
percentage of the land that corresponds to each type
|
||||
:return: {string : float}
|
||||
"""
|
||||
return self._land_use_types
|
||||
|
||||
@property
|
||||
def city_objects(self) -> List[CityObject]:
|
||||
"""
|
||||
Get the list of city objects place inside the zone
|
||||
:return: List[CityObject]
|
||||
"""
|
||||
return self._city_objects
|
|
@ -1,134 +0,0 @@
|
|||
"""
|
||||
Phase 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 List, Union
|
||||
|
||||
|
||||
class Phase:
|
||||
"""
|
||||
Phase class
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self._duration = None
|
||||
self._state = None
|
||||
self._min_duration = None
|
||||
self._max_duration = None
|
||||
self._name = None
|
||||
self._next = None
|
||||
|
||||
@property
|
||||
def duration(self) -> Union[None, int]:
|
||||
"""
|
||||
Get phase duration in seconds
|
||||
:return: None or int
|
||||
"""
|
||||
return self._duration
|
||||
|
||||
@duration.setter
|
||||
def duration(self, value):
|
||||
"""
|
||||
Set phase duration in seconds
|
||||
:param value: int
|
||||
"""
|
||||
if value is not None:
|
||||
self._duration = int(value)
|
||||
|
||||
@property
|
||||
def state(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
Get the list of signal states
|
||||
:return: None or [str]
|
||||
"""
|
||||
return self._state
|
||||
|
||||
@state.setter
|
||||
def state(self, value):
|
||||
"""
|
||||
Set the list of signal states
|
||||
:param value: [str]
|
||||
"""
|
||||
if value is not None:
|
||||
self._state = [str(i) for i in value]
|
||||
|
||||
@property
|
||||
def min_duration(self) -> Union[None, int]:
|
||||
"""
|
||||
Get phase minimum duration in seconds
|
||||
:return: None or int
|
||||
"""
|
||||
if self._min_duration is None:
|
||||
self._min_duration = self._duration
|
||||
return self._min_duration
|
||||
|
||||
@min_duration.setter
|
||||
def min_duration(self, value):
|
||||
"""
|
||||
Set phase minimum duration in seconds
|
||||
:param value: int
|
||||
"""
|
||||
if value is not None:
|
||||
self._min_duration = int(value)
|
||||
|
||||
@property
|
||||
def max_duration(self) -> Union[None, int]:
|
||||
"""
|
||||
Get phase maximum duration in seconds
|
||||
:return: None or int
|
||||
"""
|
||||
if self._max_duration is None:
|
||||
self._max_duration = self._duration
|
||||
return self._max_duration
|
||||
|
||||
@max_duration.setter
|
||||
def max_duration(self, value):
|
||||
"""
|
||||
Set phase maximum duration in seconds
|
||||
:param value: int
|
||||
"""
|
||||
if value is not None:
|
||||
self._max_duration = int(value)
|
||||
|
||||
@property
|
||||
def name(self) -> Union[None, str]:
|
||||
"""
|
||||
Get phase name
|
||||
:return: None or str
|
||||
"""
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
"""
|
||||
Set phase name
|
||||
:param value: str
|
||||
"""
|
||||
if value is not None:
|
||||
self._name = str(value)
|
||||
|
||||
@property
|
||||
def next(self) -> Union[None, List[int]]:
|
||||
"""
|
||||
Get the next phase in the cycle after the current.
|
||||
This is useful when adding extra transition phases to a traffic light plan which are not part of every cycle.
|
||||
Traffic lights of type 'actuated' can make use of a list of indices for selecting among alternative
|
||||
successor phases.
|
||||
:return: None or [int]
|
||||
"""
|
||||
return self._next
|
||||
|
||||
@next.setter
|
||||
def next(self, value):
|
||||
"""
|
||||
Get the next phase in the cycle after the current.
|
||||
This is useful when adding extra transition phases to a traffic light plan which are not part of every cycle.
|
||||
Traffic lights of type 'actuated' can make use of a list of indices for selecting among alternative
|
||||
successor phases.
|
||||
:param value: [int]
|
||||
"""
|
||||
if value is not None:
|
||||
self._next = [int(i) for i in value]
|
|
@ -1,150 +0,0 @@
|
|||
"""
|
||||
Traffic edge 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
|
||||
Code contributors: Guille guille.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import List, Union
|
||||
from hub.city_model_structure.attributes.edge import Edge
|
||||
from hub.city_model_structure.transport.traffic_node import TrafficNode
|
||||
from hub.city_model_structure.transport.lane import Lane
|
||||
|
||||
|
||||
class TrafficEdge(Edge):
|
||||
"""
|
||||
TrafficEdge class
|
||||
Each edge is unidirectional and starts at the "from" node and ends at the "to" node
|
||||
"""
|
||||
|
||||
def __init__(self, name, nodes, priority, speed, lanes, length, allows=None, disallows=None, sidewalk_width=None,
|
||||
edge_type='TrafficEdge'):
|
||||
super().__init__(name, nodes)
|
||||
self._edge_type = edge_type
|
||||
self._lanes = lanes
|
||||
self._priority = priority
|
||||
self._speed = speed
|
||||
self._length = length
|
||||
self._allows = allows
|
||||
self._disallows = disallows
|
||||
self._sidewalk_width = sidewalk_width
|
||||
|
||||
@property
|
||||
def edge_type(self):
|
||||
"""
|
||||
Get the edge type
|
||||
:return: str
|
||||
"""
|
||||
return self._edge_type
|
||||
|
||||
@property
|
||||
def nodes(self) -> List[TrafficNode]:
|
||||
"""
|
||||
Get delimiting nodes for the edge
|
||||
:return: [TrafficNode]
|
||||
"""
|
||||
return self._nodes
|
||||
|
||||
@property
|
||||
def lanes(self) -> List[Lane]:
|
||||
"""
|
||||
Get the lanes on an edge
|
||||
:return: List[Lane]
|
||||
"""
|
||||
return self._lanes
|
||||
|
||||
@lanes.setter
|
||||
def lanes(self, value):
|
||||
"""
|
||||
Set the lanes on an edge
|
||||
:param value: List[Lane]
|
||||
"""
|
||||
self._lanes = value
|
||||
|
||||
@property
|
||||
def priority(self) -> Union[None, int]:
|
||||
"""
|
||||
Get the priority between different road types.
|
||||
It starts with one; higher numbers represent more important roads.
|
||||
:return: None or int
|
||||
"""
|
||||
return self._priority
|
||||
|
||||
@priority.setter
|
||||
def priority(self, value):
|
||||
"""
|
||||
Set the priority between different road types.
|
||||
It starts with one; higher numbers represent more important roads.
|
||||
:param value: int
|
||||
"""
|
||||
if value is not None:
|
||||
self._priority = int(value)
|
||||
|
||||
@property
|
||||
def speed(self) -> Union[None, float]:
|
||||
"""
|
||||
Get he speed limit in m/s
|
||||
:return: None or float
|
||||
"""
|
||||
return self._speed
|
||||
|
||||
@speed.setter
|
||||
def speed(self, value):
|
||||
"""
|
||||
Set the speed limit in m/s
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._speed = float(value)
|
||||
|
||||
@property
|
||||
def length(self) -> Union[None, float]:
|
||||
"""
|
||||
Get the lane length in meters
|
||||
:return: None or float
|
||||
"""
|
||||
return self._length
|
||||
|
||||
@length.setter
|
||||
def length(self, value):
|
||||
"""
|
||||
Set the lane length in meters
|
||||
:param value: float
|
||||
"""
|
||||
if value is not None:
|
||||
self._length = float(value)
|
||||
|
||||
@property
|
||||
def allows(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
Get the list of allowed vehicle classes
|
||||
:return: None or [str]
|
||||
"""
|
||||
return self._allows
|
||||
|
||||
@allows.setter
|
||||
def allows(self, value):
|
||||
"""
|
||||
Set the list of allowed vehicle classes
|
||||
:param value: [str]
|
||||
"""
|
||||
if value is not None:
|
||||
self._allows = [str(i) for i in value]
|
||||
|
||||
@property
|
||||
def disallows(self) -> Union[None, List[str]]:
|
||||
"""
|
||||
Get the list of not allowed vehicle classes
|
||||
:return: None or [str]
|
||||
"""
|
||||
return self._disallows
|
||||
|
||||
@disallows.setter
|
||||
def disallows(self, value):
|
||||
"""
|
||||
Set the list of not allowed vehicle classes
|
||||
:param value: [str]
|
||||
"""
|
||||
if value is not None:
|
||||
self._disallows = [str(i) for i in value]
|
|
@ -1,75 +0,0 @@
|
|||
"""
|
||||
Traffic light 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
|
||||
Code contributors: Guille guille.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
import ast
|
||||
from typing import List, Union
|
||||
from hub.city_model_structure.transport.phase import Phase
|
||||
from hub.city_model_structure.transport.traffic_node import TrafficNode
|
||||
|
||||
|
||||
class TrafficLight(TrafficNode):
|
||||
"""
|
||||
Traffic light class
|
||||
"""
|
||||
def __init__(self, name, coordinates, offset, phases=None, edges=None, right_on_red=False):
|
||||
super().__init__(name, coordinates, edges=edges, node_type='TrafficLight')
|
||||
if phases is None:
|
||||
phases = []
|
||||
self._right_on_red = right_on_red
|
||||
self._offset = offset
|
||||
self._phases = phases
|
||||
|
||||
@property
|
||||
def right_on_red(self) -> Union[None, bool]:
|
||||
"""
|
||||
Get if is possible to turn right when the traffic light is red
|
||||
:return: None or Boolean
|
||||
"""
|
||||
return self._right_on_red
|
||||
|
||||
@right_on_red.setter
|
||||
def right_on_red(self, value):
|
||||
"""
|
||||
Get if is possible to turn right when the traffic light is red
|
||||
:param value: Boolean
|
||||
"""
|
||||
if value is not None:
|
||||
self._right_on_red = ast.literal_eval(value)
|
||||
|
||||
@property
|
||||
def offset(self) -> Union[None, int]:
|
||||
"""
|
||||
Get program initial time offset
|
||||
:return: None or int
|
||||
"""
|
||||
return self._offset
|
||||
|
||||
@offset.setter
|
||||
def offset(self, value):
|
||||
"""
|
||||
Set program initial time offset
|
||||
:param value: int
|
||||
"""
|
||||
if value is not None:
|
||||
self._offset = int(value)
|
||||
|
||||
@property
|
||||
def phases(self) -> List[Phase]:
|
||||
"""
|
||||
Get traffic light logic phases
|
||||
:return: [Phase]
|
||||
"""
|
||||
return self._phases
|
||||
|
||||
@phases.setter
|
||||
def phases(self, value):
|
||||
"""
|
||||
Set traffic light logic phases
|
||||
:param value: [Phase]
|
||||
"""
|
||||
self._phases = value
|
|
@ -1,45 +0,0 @@
|
|||
"""
|
||||
Traffic network 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
|
||||
Code contributors: Guille guille.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from hub.city_model_structure.network import Network
|
||||
from hub.city_model_structure.transport.traffic_edge import TrafficEdge
|
||||
from hub.city_model_structure.transport.traffic_node import TrafficNode
|
||||
|
||||
|
||||
class TrafficNetwork(Network):
|
||||
"""
|
||||
TrafficNetwork(Network) class
|
||||
"""
|
||||
def __init__(self, name, edges=None, nodes=None):
|
||||
super().__init__(name, edges, nodes)
|
||||
self._type = "TrafficNetwork"
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
Get network type
|
||||
:return: str
|
||||
"""
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def edges(self) -> List[TrafficEdge]:
|
||||
"""
|
||||
Get network edges
|
||||
:return: [TrafficEdge]
|
||||
"""
|
||||
return self._edges
|
||||
|
||||
@property
|
||||
def nodes(self) -> List[TrafficNode]:
|
||||
"""
|
||||
Get network nodes
|
||||
:return: [TrafficNode]
|
||||
"""
|
||||
return self._nodes
|
|
@ -1,97 +0,0 @@
|
|||
"""
|
||||
TrafficNode 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
|
||||
Code contributors: Guille guille.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import List, TypeVar
|
||||
|
||||
from hub.city_model_structure.attributes.edge import Edge
|
||||
from hub.city_model_structure.attributes.node import Node
|
||||
from hub.city_model_structure.attributes.point import Point
|
||||
|
||||
Connection = TypeVar('Connection')
|
||||
TrafficEdge = TypeVar('TrafficEdge')
|
||||
|
||||
|
||||
class TrafficNode(Node):
|
||||
"""
|
||||
TrafficNode class
|
||||
"""
|
||||
|
||||
def __init__(self, name, coordinates, node_type='TrafficNode', edges=None, prohibitions=None, connections=None):
|
||||
super().__init__(name, edges)
|
||||
if connections is None:
|
||||
connections = []
|
||||
if prohibitions is None:
|
||||
prohibitions = []
|
||||
self._coordinates = coordinates
|
||||
self._prohibitions = prohibitions
|
||||
self._connections = connections
|
||||
self._node_type = node_type
|
||||
|
||||
@property
|
||||
def node_type(self):
|
||||
"""
|
||||
Get node type
|
||||
:return: str
|
||||
"""
|
||||
return self._node_type
|
||||
|
||||
@property
|
||||
def coordinates(self) -> Point:
|
||||
"""
|
||||
Get node coordinates
|
||||
:return: Point
|
||||
"""
|
||||
return self._coordinates
|
||||
|
||||
@coordinates.setter
|
||||
def coordinates(self, value):
|
||||
"""
|
||||
Set node coordinates
|
||||
:param value: Point
|
||||
"""
|
||||
self._coordinates = value
|
||||
|
||||
@property
|
||||
def edges(self) -> List[TrafficEdge]:
|
||||
"""
|
||||
get edges delimited by the node
|
||||
:return: [TrafficEdge]
|
||||
"""
|
||||
return self._edges
|
||||
|
||||
@property
|
||||
def prohibitions(self) -> [(Edge, Edge)]:
|
||||
"""
|
||||
Get node prohibitions
|
||||
:return: [(Edge, Edge)]
|
||||
"""
|
||||
return self._prohibitions
|
||||
|
||||
@prohibitions.setter
|
||||
def prohibitions(self, value):
|
||||
"""
|
||||
Set node prohibitions
|
||||
:param value: [(Edge, Edge)]
|
||||
"""
|
||||
self._prohibitions = value
|
||||
|
||||
@property
|
||||
def connections(self) -> List[Connection]:
|
||||
"""
|
||||
Get node connections
|
||||
:return: [Connection]
|
||||
"""
|
||||
return self._connections
|
||||
|
||||
@connections.setter
|
||||
def connections(self, value):
|
||||
"""
|
||||
Set node connections
|
||||
:param value: [Connection]
|
||||
"""
|
||||
self._connections = value
|
|
@ -1,37 +0,0 @@
|
|||
"""
|
||||
Walkway node 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
|
||||
Code contributors: Guille guille.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from typing import List, Union
|
||||
from hub.city_model_structure.transport.traffic_node import TrafficNode
|
||||
|
||||
|
||||
class WalkwayNode(TrafficNode):
|
||||
"""
|
||||
WalkwayNode class
|
||||
"""
|
||||
|
||||
def __init__(self, name, coordinates, edges=None, shape=None):
|
||||
super().__init__(name, coordinates, edges=edges, node_type='WalkwayNode')
|
||||
self._shape = shape
|
||||
|
||||
@property
|
||||
def shape(self) -> Union[None, List[List[float]]]:
|
||||
"""
|
||||
Get the list of positions
|
||||
:return: None or [[x, y, (z)]]
|
||||
"""
|
||||
return self._shape
|
||||
|
||||
@shape.setter
|
||||
def shape(self, value):
|
||||
"""
|
||||
Set the list of positions
|
||||
:param value: [[x, y, (z)]]
|
||||
"""
|
||||
if value is not None:
|
||||
self._shape = [[float(i) for i in value]]
|
File diff suppressed because it is too large
Load Diff
774
hub/data/construction/palma_archetypes.json
Normal file
774
hub/data/construction/palma_archetypes.json
Normal file
|
@ -0,0 +1,774 @@
|
|||
{
|
||||
"archetypes": [
|
||||
{
|
||||
"function": "Large multifamily building",
|
||||
"period_of_construction": "2021_2050",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.57,
|
||||
"thermal_capacity": 83.018,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
|
||||
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "5",
|
||||
"south": "60",
|
||||
"west": "5"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
|
||||
},
|
||||
"GroundWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
|
||||
},
|
||||
"GroundRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "2021_2050",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.57,
|
||||
"thermal_capacity": 83.018,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
|
||||
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "5",
|
||||
"south": "60",
|
||||
"west": "5"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
|
||||
},
|
||||
"GroundWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
|
||||
},
|
||||
"GroundRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Small multifamily building",
|
||||
"period_of_construction": "2021_2050",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.57,
|
||||
"thermal_capacity": 83.018,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
|
||||
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "5",
|
||||
"south": "60",
|
||||
"west": "5"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
|
||||
},
|
||||
"GroundWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
|
||||
},
|
||||
"GroundRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Single-family building",
|
||||
"period_of_construction": "2021_2050",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.57,
|
||||
"thermal_capacity": 83.018,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
|
||||
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "5",
|
||||
"south": "60",
|
||||
"west": "5"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
|
||||
},
|
||||
"GroundWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
|
||||
},
|
||||
"GroundRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Large multifamily building",
|
||||
"period_of_construction": "1961_1980",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.57,
|
||||
"thermal_capacity": 3000,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0045,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1",
|
||||
"transparent_surface_name": "PA1_PA2_1961_1980_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "60",
|
||||
"south": "60",
|
||||
"west": "60"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR1"
|
||||
},
|
||||
"GroundWall": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1"
|
||||
},
|
||||
"GroundRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR4"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Large multifamily building",
|
||||
"period_of_construction": "1981_2007",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.2,
|
||||
"thermal_capacity": 3179,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.003,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "E_1981_2007_FACEXT1",
|
||||
"transparent_surface_name": "E_1981_2007_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "45",
|
||||
"east": "45",
|
||||
"south": "45",
|
||||
"west": "45"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "E_1981_2007_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "E_1981_2007_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "1800_1900",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 4.39,
|
||||
"thermal_capacity": 3330,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.006,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "A_B1900_FACEXT1",
|
||||
"transparent_surface_name": "A_B1900_WIN2",
|
||||
"transparent_ratio": {
|
||||
"north": "20",
|
||||
"east": "20",
|
||||
"south": "20",
|
||||
"west": "20"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "A_B1900_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "A_B1900_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "1901_1940",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.65,
|
||||
"thermal_capacity": 3420,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.006,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "B_1901_1940_FACEXT1",
|
||||
"transparent_surface_name": "B_1901_1940_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "B_1901_1940_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "B_1901_1940_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "1941_1960",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.6,
|
||||
"thermal_capacity": 3000,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0055,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": " C_1941_1960_FACEXT1",
|
||||
"transparent_surface_name": "C_1941_1960_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "30",
|
||||
"east": "30",
|
||||
"south": "30",
|
||||
"west": "30"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "C_1941_1960_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "C_1941_1960_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "1961_1980",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 4.5,
|
||||
"thermal_capacity": 3540,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0045,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1",
|
||||
"transparent_surface_name": "PA1_PA2_1961_1980_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "55",
|
||||
"east": "55",
|
||||
"south": "55",
|
||||
"west": "55"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "1981_2007",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.2,
|
||||
"thermal_capacity": 3179,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.003,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "E_1981_2007_FACEXT1",
|
||||
"transparent_surface_name": "E_1981_2007_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "45",
|
||||
"east": "45",
|
||||
"south": "45",
|
||||
"west": "45"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "E_1981_2007_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "E_1981_2007_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "2008_2014",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 2.75,
|
||||
"thermal_capacity": 3290,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0015,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "F_2008_2014_FACEXT1",
|
||||
"transparent_surface_name": "F_2008_2014_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "F_2008_2014_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "F_2008_2014_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Small multifamily building",
|
||||
"period_of_construction": "1800_1980",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.8,
|
||||
"thermal_capacity": 3527.9,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.006,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_FACEXT1",
|
||||
"transparent_surface_name": "PA3_PA4_1901_1940_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Small multifamily building",
|
||||
"period_of_construction": "1981_2007",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.2,
|
||||
"thermal_capacity": 3179,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.003,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "E_1981_2007_FACEXT1",
|
||||
"transparent_surface_name": "E_1981_2007_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "45",
|
||||
"east": "45",
|
||||
"south": "45",
|
||||
"west": "45"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "E_1981_2007_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "E_1981_2007_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Small multifamily building",
|
||||
"period_of_construction": "2008_2014",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 2.75,
|
||||
"thermal_capacity": 3290,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0015,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "F_2008_2014_FACEXT1",
|
||||
"transparent_surface_name": "F_2008_2014_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "F_2008_2014_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "F_2008_2014_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Small multifamily building",
|
||||
"period_of_construction": "2015_2019",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 2.75,
|
||||
"thermal_capacity": 3290,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "G_2015_2019_FACEXT1",
|
||||
"transparent_surface_name": "G_2015_2019_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "G_2015_2019_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "G_2015_2019_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Single-family building",
|
||||
"period_of_construction": "1800_1980",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.68,
|
||||
"thermal_capacity": 4400,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.006,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_FACEXT1",
|
||||
"transparent_surface_name": "PA3_PA4_1901_1940_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Single-family building",
|
||||
"period_of_construction": "1981_2007",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.2,
|
||||
"thermal_capacity": 3179,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.003,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "E_1981_2007_FACEXT1",
|
||||
"transparent_surface_name": "E_1981_2007_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "45",
|
||||
"east": "45",
|
||||
"south": "45",
|
||||
"west": "45"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "E_1981_2007_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "E_1981_2007_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Single-family building",
|
||||
"period_of_construction": "2008_2014",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.75,
|
||||
"thermal_capacity": 3200,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0015,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "F_2008_2014_FACEXT1",
|
||||
"transparent_surface_name": "F_2008_2014_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "60",
|
||||
"south": "60",
|
||||
"west": "60"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "F_2008_2014_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "F_2008_2014_FLOORGR1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"function": "Single-family building",
|
||||
"period_of_construction": "2015_2019",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.75,
|
||||
"thermal_capacity": 3200,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0.0005,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "G_2015_2019_FACEXT1",
|
||||
"transparent_surface_name": "G_2015_2019_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "60",
|
||||
"south": "60",
|
||||
"west": "60"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "G_2015_2019_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "G_2015_2019_FLOORGR1"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
774
hub/data/construction/palma_archetypes_modified.json
Normal file
774
hub/data/construction/palma_archetypes_modified.json
Normal file
|
@ -0,0 +1,774 @@
|
|||
{
|
||||
"archetypes": [
|
||||
{
|
||||
"function": "Large multifamily building",
|
||||
"period_of_construction": "2021_2050",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.57,
|
||||
"thermal_capacity": 83.018,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
|
||||
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "5",
|
||||
"south": "60",
|
||||
"west": "5"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
|
||||
},
|
||||
"GroundWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
|
||||
},
|
||||
"GroundRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "2021_2050",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.57,
|
||||
"thermal_capacity": 83.018,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
|
||||
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "5",
|
||||
"south": "60",
|
||||
"west": "5"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
|
||||
},
|
||||
"GroundWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
|
||||
},
|
||||
"GroundRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Small multifamily building",
|
||||
"period_of_construction": "2021_2050",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.57,
|
||||
"thermal_capacity": 83.018,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
|
||||
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "5",
|
||||
"south": "60",
|
||||
"west": "5"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
|
||||
},
|
||||
"GroundWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
|
||||
},
|
||||
"GroundRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Single-family building",
|
||||
"period_of_construction": "2021_2050",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.57,
|
||||
"thermal_capacity": 83.018,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT",
|
||||
"transparent_surface_name": "PA1_PA2_2021_2050_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "5",
|
||||
"south": "60",
|
||||
"west": "5"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_ROOF",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOOR"
|
||||
},
|
||||
"GroundWall": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FACEXT"
|
||||
},
|
||||
"GroundRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_2021_2050_FLOORINT"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Large multifamily building",
|
||||
"period_of_construction": "1961_1980",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.57,
|
||||
"thermal_capacity": 3000,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1",
|
||||
"transparent_surface_name": "PA1_PA2_1961_1980_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "60",
|
||||
"south": "60",
|
||||
"west": "60"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR1"
|
||||
},
|
||||
"GroundWall": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1"
|
||||
},
|
||||
"GroundRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR4"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Large multifamily building",
|
||||
"period_of_construction": "1981_2007",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.2,
|
||||
"thermal_capacity": 3179,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "E_1981_2007_FACEXT1",
|
||||
"transparent_surface_name": "E_1981_2007_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "45",
|
||||
"east": "45",
|
||||
"south": "45",
|
||||
"west": "45"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "E_1981_2007_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "E_1981_2007_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "1800_1900",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 4.39,
|
||||
"thermal_capacity": 3330,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "A_B1900_FACEXT1",
|
||||
"transparent_surface_name": "A_B1900_WIN2",
|
||||
"transparent_ratio": {
|
||||
"north": "20",
|
||||
"east": "20",
|
||||
"south": "20",
|
||||
"west": "20"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "A_B1900_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "A_B1900_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "1901_1940",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.65,
|
||||
"thermal_capacity": 3420,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "B_1901_1940_FACEXT1",
|
||||
"transparent_surface_name": "B_1901_1940_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "B_1901_1940_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "B_1901_1940_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "1941_1960",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.6,
|
||||
"thermal_capacity": 3000,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": " C_1941_1960_FACEXT1",
|
||||
"transparent_surface_name": "C_1941_1960_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "30",
|
||||
"east": "30",
|
||||
"south": "30",
|
||||
"west": "30"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "C_1941_1960_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "C_1941_1960_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "1961_1980",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 4.5,
|
||||
"thermal_capacity": 3540,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FACEXT1",
|
||||
"transparent_surface_name": "PA1_PA2_1961_1980_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "55",
|
||||
"east": "55",
|
||||
"south": "55",
|
||||
"west": "55"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA1_PA2_1961_1980_FLOOR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "1981_2007",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.2,
|
||||
"thermal_capacity": 3179,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "E_1981_2007_FACEXT1",
|
||||
"transparent_surface_name": "E_1981_2007_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "45",
|
||||
"east": "45",
|
||||
"south": "45",
|
||||
"west": "45"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "E_1981_2007_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "E_1981_2007_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Medium multifamily building",
|
||||
"period_of_construction": "2008_2014",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 2.75,
|
||||
"thermal_capacity": 3290,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "F_2008_2014_FACEXT1",
|
||||
"transparent_surface_name": "F_2008_2014_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "F_2008_2014_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "F_2008_2014_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Small multifamily building",
|
||||
"period_of_construction": "1800_1980",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.8,
|
||||
"thermal_capacity": 3527.9,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_FACEXT1",
|
||||
"transparent_surface_name": "PA3_PA4_1901_1940_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Small multifamily building",
|
||||
"period_of_construction": "1981_2007",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.2,
|
||||
"thermal_capacity": 3179,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "E_1981_2007_FACEXT1",
|
||||
"transparent_surface_name": "E_1981_2007_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "45",
|
||||
"east": "45",
|
||||
"south": "45",
|
||||
"west": "45"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "E_1981_2007_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "E_1981_2007_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Small multifamily building",
|
||||
"period_of_construction": "2008_2014",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 2.75,
|
||||
"thermal_capacity": 3290,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "F_2008_2014_FACEXT1",
|
||||
"transparent_surface_name": "F_2008_2014_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "F_2008_2014_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "F_2008_2014_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Small multifamily building",
|
||||
"period_of_construction": "2015_2019",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 2.75,
|
||||
"thermal_capacity": 3290,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "G_2015_2019_FACEXT1",
|
||||
"transparent_surface_name": "G_2015_2019_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "G_2015_2019_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "G_2015_2019_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Single-family building",
|
||||
"period_of_construction": "1800_1980",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.68,
|
||||
"thermal_capacity": 4400,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_FACEXT1",
|
||||
"transparent_surface_name": "PA3_PA4_1901_1940_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "40",
|
||||
"east": "40",
|
||||
"south": "40",
|
||||
"west": "40"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "PA3_PA4_1901_1940_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Single-family building",
|
||||
"period_of_construction": "1981_2007",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.2,
|
||||
"thermal_capacity": 3179,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "E_1981_2007_FACEXT1",
|
||||
"transparent_surface_name": "E_1981_2007_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "45",
|
||||
"east": "45",
|
||||
"south": "45",
|
||||
"west": "45"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "E_1981_2007_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "E_1981_2007_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Single-family building",
|
||||
"period_of_construction": "2008_2014",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.75,
|
||||
"thermal_capacity": 3200,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "F_2008_2014_FACEXT1",
|
||||
"transparent_surface_name": "F_2008_2014_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "60",
|
||||
"south": "60",
|
||||
"west": "60"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "F_2008_2014_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "F_2008_2014_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
},
|
||||
{
|
||||
"function": "Single-family building",
|
||||
"period_of_construction": "2015_2019",
|
||||
"climate_zone": "B3",
|
||||
"average_storey_height": 3.75,
|
||||
"thermal_capacity": 3200,
|
||||
"extra_loses_due_thermal_bridges": 0.1,
|
||||
"infiltration_rate_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_for_ventilation_system_off": 0.9,
|
||||
"constructions": {
|
||||
"OutdoorsWall": {
|
||||
"opaque_surface_name": "G_2015_2019_FACEXT1",
|
||||
"transparent_surface_name": "G_2015_2019_WIN1",
|
||||
"transparent_ratio": {
|
||||
"north": "60",
|
||||
"east": "60",
|
||||
"south": "60",
|
||||
"west": "60"
|
||||
}
|
||||
},
|
||||
"OutdoorsRoofCeiling": {
|
||||
"opaque_surface_name": "G_2015_2019_ROOF1",
|
||||
"transparent_surface_name": null,
|
||||
"transparent_ratio": {
|
||||
"north": null,
|
||||
"east": null,
|
||||
"south": null,
|
||||
"west": null
|
||||
}
|
||||
},
|
||||
"GroundFloor": {
|
||||
"opaque_surface_name": "G_2015_2019_FLOORGR1"
|
||||
}
|
||||
},
|
||||
"infiltration_rate_area_for_ventilation_system_on": 0,
|
||||
"infiltration_rate_area_for_ventilation_system_off": 0
|
||||
}
|
||||
]
|
||||
}
|
1895
hub/data/construction/palma_constructions.json
Normal file
1895
hub/data/construction/palma_constructions.json
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -38,53 +38,96 @@
|
|||
</equipment>
|
||||
</generation_equipments>
|
||||
<distribution_equipments>
|
||||
<equipment id="1" type="Water distribution heating">
|
||||
<equipment id="1" type="Water distribution heating with baseboards">
|
||||
<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 cooling">
|
||||
<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">
|
||||
<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="3" type="Central air distribution heating">
|
||||
<equipment id="5" type="Central air distribution heating with fan-coils">
|
||||
<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="4" type="Central air distribution cooling">
|
||||
<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">
|
||||
<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="5" type="Local air distribution heating">
|
||||
<equipment id="8" type="Local air distribution heating with baseboards">
|
||||
<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="6" type="Local air distribution cooling">
|
||||
<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">
|
||||
<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="7" type="Refrigerant distribution">
|
||||
<equipment id="11" type="Refrigerant distribution with fan-coils">
|
||||
<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="8" type="No distribution">
|
||||
<equipment id="12" type="No distribution with baseboards">
|
||||
<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>
|
||||
|
@ -111,7 +154,6 @@
|
|||
<equipments>
|
||||
<generation_id>1</generation_id>
|
||||
<distribution_id>1</distribution_id>
|
||||
<dissipation_id>1</dissipation_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id = "16">
|
||||
|
@ -122,8 +164,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>2</generation_id>
|
||||
<distribution_id>8</distribution_id>
|
||||
<dissipation_id>1</dissipation_id>
|
||||
<distribution_id>12</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id = "2">
|
||||
|
@ -134,8 +175,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>1</generation_id>
|
||||
<distribution_id>1</distribution_id>
|
||||
<dissipation_id>2</dissipation_id>
|
||||
<distribution_id>2</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="3">
|
||||
|
@ -146,8 +186,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>2</generation_id>
|
||||
<distribution_id>1</distribution_id>
|
||||
<dissipation_id>2</dissipation_id>
|
||||
<distribution_id>2</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="4">
|
||||
|
@ -158,9 +197,8 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>3</generation_id>
|
||||
<distribution_id>5</distribution_id>
|
||||
<dissipation_id>1</dissipation_id>
|
||||
</equipments>
|
||||
<distribution_id>8</distribution_id>
|
||||
g </equipments>
|
||||
</system>
|
||||
<system id="5">
|
||||
<name>Single zone packaged rooftop unit with electrical resistance furnace and baseboards and fuel boiler for acs</name>
|
||||
|
@ -170,8 +208,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>4</generation_id>
|
||||
<distribution_id>5</distribution_id>
|
||||
<dissipation_id>1</dissipation_id>
|
||||
<distribution_id>8</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="6">
|
||||
|
@ -183,7 +220,6 @@
|
|||
<equipments>
|
||||
<generation_id>1</generation_id>
|
||||
<distribution_id>1</distribution_id>
|
||||
<dissipation_id>1</dissipation_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="7">
|
||||
|
@ -194,8 +230,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>2</generation_id>
|
||||
<distribution_id>8</distribution_id>
|
||||
<dissipation_id>3</dissipation_id>
|
||||
<distribution_id>13</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="8">
|
||||
|
@ -206,8 +241,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>2</generation_id>
|
||||
<distribution_id>1</distribution_id>
|
||||
<dissipation_id>3</dissipation_id>
|
||||
<distribution_id>3</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="9">
|
||||
|
@ -218,8 +252,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>2</generation_id>
|
||||
<distribution_id>8</distribution_id>
|
||||
<dissipation_id>3</dissipation_id>
|
||||
<distribution_id>13</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="10">
|
||||
|
@ -229,8 +262,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>5</generation_id>
|
||||
<distribution_id>6</distribution_id>
|
||||
<dissipation_id>3</dissipation_id>
|
||||
<distribution_id>10</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="11">
|
||||
|
@ -240,8 +272,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>5</generation_id>
|
||||
<distribution_id>2</distribution_id>
|
||||
<dissipation_id>2</dissipation_id>
|
||||
<distribution_id>4</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="12">
|
||||
|
@ -251,8 +282,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>5</generation_id>
|
||||
<distribution_id>6</distribution_id>
|
||||
<dissipation_id>3</dissipation_id>
|
||||
<distribution_id>10</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="13">
|
||||
|
@ -262,8 +292,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>5</generation_id>
|
||||
<distribution_id>6</distribution_id>
|
||||
<dissipation_id>3</dissipation_id>
|
||||
<distribution_id>10</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="14">
|
||||
|
@ -273,8 +302,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>5</generation_id>
|
||||
<distribution_id>3</distribution_id>
|
||||
<dissipation_id>3</dissipation_id>
|
||||
<distribution_id>6</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="15">
|
||||
|
@ -284,8 +312,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>6</generation_id>
|
||||
<distribution_id>5</distribution_id>
|
||||
<dissipation_id>3</dissipation_id>
|
||||
<distribution_id>9</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="17">
|
||||
|
@ -296,8 +323,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>7</generation_id>
|
||||
<distribution_id>3</distribution_id>
|
||||
<dissipation_id>2</dissipation_id>
|
||||
<distribution_id>5</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
<system id="18">
|
||||
|
@ -307,8 +333,7 @@
|
|||
</demands>
|
||||
<equipments>
|
||||
<generation_id>7</generation_id>
|
||||
<distribution_id>4</distribution_id>
|
||||
<dissipation_id>2</dissipation_id>
|
||||
<distribution_id>7</distribution_id>
|
||||
</equipments>
|
||||
</system>
|
||||
</systems>
|
||||
|
|
1575
hub/data/energy_systems/montreal_future_systems.xml
Normal file
1575
hub/data/energy_systems/montreal_future_systems.xml
Normal file
File diff suppressed because it is too large
Load Diff
809
hub/data/energy_systems/palma_systems.xml
Normal file
809
hub/data/energy_systems/palma_systems.xml
Normal file
|
@ -0,0 +1,809 @@
|
|||
<?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>
|
||||
|
BIN
hub/data/energy_systems/schemas/ASHP+TES+ElectricBoiler.jpg
Normal file
BIN
hub/data/energy_systems/schemas/ASHP+TES+ElectricBoiler.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
BIN
hub/data/energy_systems/schemas/ASHP+TES+GasBoiler.jpg
Normal file
BIN
hub/data/energy_systems/schemas/ASHP+TES+GasBoiler.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
BIN
hub/data/energy_systems/schemas/GSHP+TES+ElectricBoiler.jpg
Normal file
BIN
hub/data/energy_systems/schemas/GSHP+TES+ElectricBoiler.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
BIN
hub/data/energy_systems/schemas/GSHP+TES+GasBoiler.jpg
Normal file
BIN
hub/data/energy_systems/schemas/GSHP+TES+GasBoiler.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user