Merge remote-tracking branch 'origin/energy_system_central_data_model' into energy_system_central_data_model
# Conflicts: # hub/imports/energy_systems/montreal_custom_energy_system_parameters.py
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.
|
||||
|
|
|
@ -50,11 +50,11 @@ class Archetype:
|
|||
_systems = []
|
||||
for _system in self.systems:
|
||||
_systems.append(_system.to_dictionary())
|
||||
content = {'Archetype': {'name': self.name,
|
||||
'level of detail': self.lod,
|
||||
'systems': _systems
|
||||
}
|
||||
}
|
||||
content = {
|
||||
'Archetype': {
|
||||
'name': self.name,
|
||||
'level of detail': self.lod,
|
||||
'systems': _systems
|
||||
}
|
||||
}
|
||||
return content
|
||||
|
||||
|
||||
|
|
|
@ -30,9 +30,7 @@ class MontrealCustomCatalog(Catalog):
|
|||
'demand', 'system_id'))
|
||||
|
||||
self._lod = float(self._archetypes['catalog']['@lod'])
|
||||
|
||||
self._catalog_generation_equipments, self._catalog_storage_equipments = \
|
||||
self._load_generation_and_storage_equipments()
|
||||
self._catalog_generation_equipments, self._catalog_storage_equipments = self._load_generation_and_storage_equipments()
|
||||
self._catalog_distribution_equipments = self._load_distribution_equipments()
|
||||
self._catalog_emission_equipments = self._load_emission_equipments()
|
||||
self._catalog_systems = self._load_systems()
|
||||
|
@ -63,6 +61,7 @@ class MontrealCustomCatalog(Catalog):
|
|||
electricity_efficiency = None
|
||||
if 'electrical_efficiency' in equipment:
|
||||
electricity_efficiency = float(equipment['electrical_efficiency'])
|
||||
# todo: this may be optionals instead?
|
||||
generation_system = GenerationSystem(equipment_id,
|
||||
name,
|
||||
None,
|
||||
|
|
|
@ -56,7 +56,7 @@ class NorthAmericaEnergySystemCatalog(Catalog):
|
|||
boiler_maximum_heat_output = float(boiler['@maximumHeatOutput'])
|
||||
boiler_minimum_heat_output = float(boiler['@minimumHeatOutput'])
|
||||
boiler_heat_efficiency = float(boiler['@nominalEfficiency'])
|
||||
|
||||
# todo: this may be optionals instead?
|
||||
boiler_component = GenerationSystem(boiler_id,
|
||||
boiler_name,
|
||||
boiler_model_name,
|
||||
|
@ -405,15 +405,16 @@ class NorthAmericaEnergySystemCatalog(Catalog):
|
|||
for material in materials:
|
||||
if int(material.id) == int(material_id):
|
||||
_material = material
|
||||
return _material
|
||||
|
||||
break
|
||||
if _material is None:
|
||||
raise ValueError(f'Material with the id = [{material_id}] not found in catalog ')
|
||||
return _material
|
||||
|
||||
@staticmethod
|
||||
def _search_generation_equipment(generation_systems, generation_id):
|
||||
_generation_systems = []
|
||||
if type(generation_id) == list:
|
||||
|
||||
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:
|
||||
|
|
|
@ -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,7 @@ 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)
|
||||
|
||||
@property
|
||||
def shell(self) -> Polyhedron:
|
||||
|
@ -681,11 +684,17 @@ class Building(CityObject):
|
|||
for i, value in enumerate(item):
|
||||
_working_hours[key][i] = max(_working_hours[key][i], saved_values[i])
|
||||
|
||||
_total_hours = 0
|
||||
for key in _working_hours:
|
||||
hours = sum(_working_hours[key])
|
||||
_total_hours += hours * cte.WEEK_DAYS_A_YEAR[key]
|
||||
return _total_hours
|
||||
working_hours = {}
|
||||
values_months = []
|
||||
for month in cte.WEEK_DAYS_A_MONTH.keys():
|
||||
_total_hours_month = 0
|
||||
for key in _working_hours:
|
||||
hours = sum(_working_hours[key])
|
||||
_total_hours_month += hours * cte.WEEK_DAYS_A_MONTH[month][key]
|
||||
values_months.append(_total_hours_month)
|
||||
working_hours[cte.MONTH] = values_months
|
||||
working_hours[cte.YEAR] = sum(working_hours[cte.MONTH])
|
||||
return working_hours
|
||||
|
||||
@property
|
||||
def distribution_systems_electrical_consumption(self):
|
||||
|
@ -706,11 +715,11 @@ 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
|
||||
emission_system = energy_system.emission_systems.generic_emission_system
|
||||
parasitic_energy_consumption = 0
|
||||
if emission_system is not None:
|
||||
parasitic_energy_consumption = emission_system.parasitic_energy_consumption
|
||||
distribution_system = energy_system.distribution_system.generic_distribution_system
|
||||
distribution_system = energy_system.distribution_systems.generic_distribution_system
|
||||
consumption_variable_flow = distribution_system.distribution_consumption_variable_flow
|
||||
for demand_type in energy_system.demand_types:
|
||||
if demand_type.lower() == cte.HEATING.lower():
|
||||
|
@ -735,7 +744,7 @@ class Building(CityObject):
|
|||
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[key] * cte.WATTS_HOUR_TO_JULES
|
||||
return self._distribution_systems_electrical_consumption
|
||||
|
||||
def _calculate_consumption(self, consumption_type, demand):
|
||||
|
@ -744,7 +753,9 @@ class Building(CityObject):
|
|||
if self.energy_systems is None:
|
||||
return None
|
||||
for energy_system in self.energy_systems:
|
||||
generation_systems = energy_system.generation_system
|
||||
generation_systems = energy_system.generation_systems
|
||||
print(generation_systems)
|
||||
print(type(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):
|
||||
|
@ -786,8 +797,8 @@ class Building(CityObject):
|
|||
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
|
||||
if energy_system.generation_systems.generic_generation_system.type == cte.PHOTOVOLTAIC:
|
||||
_efficiency = energy_system.generation_systems.generic_generation_system.electricity_efficiency
|
||||
self._onsite_electrical_production = {}
|
||||
for _key in self.roofs[0].global_irradiance.keys():
|
||||
_results = [0 for _ in range(0, len(self.roofs[0].global_irradiance[_key]))]
|
||||
|
|
|
@ -59,6 +59,7 @@ class Layer:
|
|||
Get material name
|
||||
:return: str
|
||||
"""
|
||||
# todo: this should be named material_name instead
|
||||
return self._name
|
||||
|
||||
@name.setter
|
||||
|
@ -67,6 +68,7 @@ class Layer:
|
|||
Set material name
|
||||
:param value: string
|
||||
"""
|
||||
# todo: this should be named material_name instead
|
||||
self._name = str(value)
|
||||
|
||||
@property
|
||||
|
|
|
@ -154,7 +154,6 @@ class Surface:
|
|||
if self._inclination is None:
|
||||
self._inclination = np.arccos(self.perimeter_polygon.normal[2])
|
||||
return self._inclination
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
"""
|
||||
|
|
|
@ -578,7 +578,7 @@ class ThermalZone:
|
|||
for i_type, _ in enumerate(_types_reference):
|
||||
_schedules = []
|
||||
_schedule_type = _types_reference[i_type][1]
|
||||
for i_schedule, schedule_value in enumerate(_schedule_type):
|
||||
for _, schedule_value in enumerate(_schedule_type):
|
||||
schedule = Schedule()
|
||||
schedule.type = schedule_value.type
|
||||
schedule.day_types = schedule_value.day_types
|
||||
|
|
|
@ -14,6 +14,7 @@ import math
|
|||
import pickle
|
||||
import sys
|
||||
import pathlib
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import List, Union
|
||||
|
||||
|
@ -299,6 +300,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
|
||||
|
|
|
@ -13,6 +13,9 @@ from hub.city_model_structure.energy_systems.generic_storage_system import Gener
|
|||
|
||||
|
||||
class ElectricalStorageSystem:
|
||||
"""
|
||||
Electrical Storage system class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._model_name = None
|
||||
self._manufacturer = None
|
||||
|
@ -150,6 +153,3 @@ class ElectricalStorageSystem:
|
|||
:return: float
|
||||
"""
|
||||
self._self_discharge_rate = value
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -23,12 +23,12 @@ class EnergySystem:
|
|||
def __init__(self):
|
||||
self._name = None
|
||||
self._demand_types = None
|
||||
self._generation_system = None
|
||||
self._distribution_system = None
|
||||
self._emission_system = None
|
||||
self._generation_systems = None
|
||||
self._distribution_systems = None
|
||||
self._emission_systems = None
|
||||
self._connected_city_objects = None
|
||||
self._control_system = None
|
||||
self._energy_storage_system = None
|
||||
self._energy_storage_systems = None
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
|
@ -63,52 +63,52 @@ class EnergySystem:
|
|||
self._demand_types = value
|
||||
|
||||
@property
|
||||
def generation_system(self) -> List[GenerationSystem]:
|
||||
def generation_systems(self) -> List[GenerationSystem]:
|
||||
"""
|
||||
Get generation systems
|
||||
:return: GenerationSystem
|
||||
"""
|
||||
return self._generation_system
|
||||
return self._generation_systems
|
||||
|
||||
@generation_system.setter
|
||||
def generation_system(self, value):
|
||||
@generation_systems.setter
|
||||
def generation_systems(self, value):
|
||||
"""
|
||||
Set generation system
|
||||
:param value: GenerationSystem
|
||||
"""
|
||||
self._generation_system = value
|
||||
self._generation_systems = value
|
||||
|
||||
@property
|
||||
def distribution_system(self) -> Union[None, DistributionSystem]:
|
||||
def distribution_systems(self) -> Union[None, List[DistributionSystem]]:
|
||||
"""
|
||||
Get distribution system
|
||||
:return: DistributionSystem
|
||||
"""
|
||||
return self._distribution_system
|
||||
return self._distribution_systems
|
||||
|
||||
@distribution_system.setter
|
||||
def distribution_system(self, value):
|
||||
@distribution_systems.setter
|
||||
def distribution_systems(self, value):
|
||||
"""
|
||||
Set distribution system
|
||||
:param value: DistributionSystem
|
||||
"""
|
||||
self._distribution_system = value
|
||||
self._distribution_systems = value
|
||||
|
||||
@property
|
||||
def emission_system(self) -> Union[None, EmissionSystem]:
|
||||
def emission_systems(self) -> Union[None, List[EmissionSystem]]:
|
||||
"""
|
||||
Get emission system
|
||||
:return: EmissionSystem
|
||||
"""
|
||||
return self._emission_system
|
||||
return self._emission_systems
|
||||
|
||||
@emission_system.setter
|
||||
def emission_system(self, value):
|
||||
@emission_systems.setter
|
||||
def emission_systems(self, value):
|
||||
"""
|
||||
Set emission system
|
||||
:param value: EmissionSystem
|
||||
"""
|
||||
self._emission_system = value
|
||||
self._emission_systems = value
|
||||
|
||||
@property
|
||||
def connected_city_objects(self) -> Union[None, List[CityObject]]:
|
||||
|
@ -143,17 +143,17 @@ class EnergySystem:
|
|||
self._control_system = value
|
||||
|
||||
@property
|
||||
def energy_storage_system(self) -> Union[None, List[ThermalStorageSystem], List[ElectricalStorageSystem]]:
|
||||
def energy_storage_systems(self) -> Union[None, List[ThermalStorageSystem], List[ElectricalStorageSystem]]:
|
||||
"""
|
||||
Get energy storage systems
|
||||
:return: [EnergyStorageSystem]
|
||||
"""
|
||||
return self._energy_storage_system
|
||||
return self._energy_storage_systems
|
||||
|
||||
@energy_storage_system.setter
|
||||
def energy_storage_system(self, value):
|
||||
@energy_storage_systems.setter
|
||||
def energy_storage_systems(self, value):
|
||||
"""
|
||||
Set storage system
|
||||
:param value: [EnergyStorageSystem]
|
||||
"""
|
||||
self._energy_storage_system = value
|
||||
self._energy_storage_systems = value
|
||||
|
|
|
@ -59,15 +59,15 @@ class GenericEnergySystem:
|
|||
self._demand_types = value
|
||||
|
||||
@property
|
||||
def generation_system(self) -> List[GenericGenerationSystem]:
|
||||
def generation_systems(self) -> List[GenericGenerationSystem]:
|
||||
"""
|
||||
Get generation system
|
||||
:return: GenerationSystem
|
||||
"""
|
||||
return self._generation_system
|
||||
|
||||
@generation_system.setter
|
||||
def generation_system(self, value):
|
||||
@generation_systems.setter
|
||||
def generation_systems(self, value):
|
||||
"""
|
||||
Set generation system
|
||||
:return: GenerationSystem
|
||||
|
@ -75,15 +75,15 @@ class GenericEnergySystem:
|
|||
self._generation_system = value
|
||||
|
||||
@property
|
||||
def distribution_system(self) -> Union[None, GenericDistributionSystem]:
|
||||
def distribution_systems(self) -> Union[None, List[GenericDistributionSystem]]:
|
||||
"""
|
||||
Get distribution system
|
||||
:return: DistributionSystem
|
||||
"""
|
||||
return self._distribution_system
|
||||
|
||||
@distribution_system.setter
|
||||
def distribution_system(self, value):
|
||||
@distribution_systems.setter
|
||||
def distribution_systems(self, value):
|
||||
"""
|
||||
Set distribution system
|
||||
:param value: DistributionSystem
|
||||
|
@ -91,15 +91,15 @@ class GenericEnergySystem:
|
|||
self._distribution_system = value
|
||||
|
||||
@property
|
||||
def emission_system(self) -> Union[None, GenericEmissionSystem]:
|
||||
def emission_systems(self) -> Union[None, List[GenericEmissionSystem]]:
|
||||
"""
|
||||
Get emission system
|
||||
:return: EmissionSystem
|
||||
"""
|
||||
return self._emission_system
|
||||
|
||||
@emission_system.setter
|
||||
def emission_system(self, value):
|
||||
@emission_systems.setter
|
||||
def emission_systems(self, value):
|
||||
"""
|
||||
Set emission system
|
||||
:param value: EmissionSystem
|
||||
|
@ -107,15 +107,15 @@ class GenericEnergySystem:
|
|||
self._emission_system = value
|
||||
|
||||
@property
|
||||
def energy_storage_system(self) -> Union[None, GenericStorageSystem]:
|
||||
def energy_storage_systems(self) -> Union[None, List[GenericStorageSystem]]:
|
||||
"""
|
||||
Get storage system
|
||||
:return: EnergyStorageSystem
|
||||
"""
|
||||
return self._energy_storage_system
|
||||
|
||||
@energy_storage_system.setter
|
||||
def energy_storage_system(self, value):
|
||||
@energy_storage_systems.setter
|
||||
def energy_storage_systems(self, value):
|
||||
"""
|
||||
Set storage system
|
||||
:return: EnergyStorageSystem
|
||||
|
|
|
@ -10,6 +10,9 @@ from __future__ import annotations
|
|||
|
||||
|
||||
class GenericStorageSystem:
|
||||
"""
|
||||
Generic storage System class
|
||||
"""
|
||||
def __init__(self):
|
||||
self._storage_type = None
|
||||
self._nominal_capacity = None
|
||||
|
@ -62,4 +65,3 @@ class GenericStorageSystem:
|
|||
:return: float
|
||||
"""
|
||||
self._losses_ratio = value
|
||||
|
||||
|
|
|
@ -101,5 +101,3 @@ class PerformanceCurves:
|
|||
:return: [coefficients]
|
||||
"""
|
||||
self._coefficients = value
|
||||
|
||||
|
||||
|
|
BIN
hub/docs/img_windows_install/img_34.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
hub/docs/img_windows_install/img_35.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
hub/docs/img_windows_install/img_36.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
hub/docs/img_windows_install/img_37.png
Normal file
After Width: | Height: | Size: 43 KiB |
BIN
hub/docs/img_windows_install/img_38.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
hub/docs/img_windows_install/img_39.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
hub/docs/img_windows_install/img_40.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
hub/docs/img_windows_install/img_41.png
Normal file
After Width: | Height: | Size: 23 KiB |
|
@ -4,9 +4,10 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
|||
Copyright © 2022 Concordia CERC group
|
||||
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
class Obj:
|
||||
"""
|
||||
|
@ -17,41 +18,79 @@ class Obj:
|
|||
self._path = path
|
||||
self._export()
|
||||
|
||||
def _to_vertex(self, coordinate):
|
||||
def _ground(self, coordinate):
|
||||
x = coordinate[0] - self._city.lower_corner[0]
|
||||
y = coordinate[1] - self._city.lower_corner[1]
|
||||
z = coordinate[2] - self._city.lower_corner[2]
|
||||
return f'v {x} {y} {z}\n'
|
||||
return x, y, z
|
||||
|
||||
def _to_vertex(self, coordinate):
|
||||
x, y, z = self._ground(coordinate)
|
||||
return f'v {x} {z} {y}\n'
|
||||
|
||||
def _to_texture_vertex(self, coordinate):
|
||||
u, v, _ = self._ground(coordinate)
|
||||
return f'vt {u} {v}\n'
|
||||
|
||||
def _to_normal_vertex(self, coordinates):
|
||||
ground_vertex = []
|
||||
for coordinate in coordinates:
|
||||
x, y, z = self._ground(coordinate)
|
||||
ground_vertex.append(np.array([x, y, z]))
|
||||
# recalculate the normal to get grounded values
|
||||
edge_1 = ground_vertex[1] - ground_vertex[0]
|
||||
edge_2 = ground_vertex[2] - ground_vertex[0]
|
||||
normal = np.cross(edge_1, edge_2)
|
||||
normal = normal / np.linalg.norm(normal)
|
||||
return f'vn {normal[0]} {normal[1]} {normal[2]}\n'
|
||||
|
||||
def _export(self):
|
||||
if self._city.name is None:
|
||||
self._city.name = 'unknown_city'
|
||||
file_name = self._city.name + '.obj'
|
||||
file_path = (Path(self._path).resolve() / file_name).resolve()
|
||||
obj_name = f'{self._city.name}.obj'
|
||||
mtl_name = f'{self._city.name}.mtl'
|
||||
obj_file_path = (Path(self._path).resolve() / obj_name).resolve()
|
||||
mtl_file_path = (Path(self._path).resolve() / mtl_name).resolve()
|
||||
with open(mtl_file_path, 'w', encoding='utf-8') as mtl:
|
||||
mtl.write("newmtl cerc_base_material\n")
|
||||
mtl.write("Ka 1.0 1.0 1.0 # Ambient color (white)\n")
|
||||
mtl.write("Kd 0.3 0.8 0.3 # Diffuse color (greenish)\n")
|
||||
mtl.write("Ks 1.0 1.0 1.0 # Specular color (white)\n")
|
||||
mtl.write("Ns 400.0 # Specular exponent (defines shininess)\n")
|
||||
vertices = {}
|
||||
with open(file_path, 'w', encoding='utf-8') as obj:
|
||||
faces = []
|
||||
vertex_index = 0
|
||||
normal_index = 0
|
||||
with open(obj_file_path, 'w', encoding='utf-8') as obj:
|
||||
obj.write("# cerc-hub export\n")
|
||||
vertex_index = 0
|
||||
faces = []
|
||||
obj.write(f'mtllib {mtl_name}')
|
||||
|
||||
for building in self._city.buildings:
|
||||
obj.write(f'# building {building.name}\n')
|
||||
obj.write(f'g {building.name}\n')
|
||||
obj.write('s off\n')
|
||||
for surface in building.surfaces:
|
||||
obj.write(f'# surface {surface.name}\n')
|
||||
face = 'f '
|
||||
face = []
|
||||
normal = self._to_normal_vertex(surface.perimeter_polygon.coordinates)
|
||||
normal_index += 1
|
||||
textures = []
|
||||
for coordinate in surface.perimeter_polygon.coordinates:
|
||||
vertex = self._to_vertex(coordinate)
|
||||
|
||||
if vertex not in vertices:
|
||||
vertex_index += 1
|
||||
vertices[vertex] = vertex_index
|
||||
current = vertex_index
|
||||
obj.write(vertex)
|
||||
textures.append(self._to_texture_vertex(coordinate)) # only append if non-existing
|
||||
else:
|
||||
current = vertices[vertex]
|
||||
|
||||
face = f'{face} {current}'
|
||||
face.insert(0, f'{current}/{current}/{normal_index}') # insert counterclockwise
|
||||
obj.writelines(normal) # add the normal
|
||||
obj.writelines(textures) # add the texture vertex
|
||||
|
||||
faces.append(f'{face} {face.split(" ")[1]}\n')
|
||||
faces.append(f"f {' '.join(face)}\n")
|
||||
obj.writelines(faces)
|
||||
faces = []
|
||||
|
|
|
@ -49,36 +49,140 @@ WEEK_DAYS = 'Weekdays'
|
|||
WEEK_ENDS = 'Weekends'
|
||||
ALL_DAYS = 'Alldays'
|
||||
|
||||
WEEK_DAYS_A_MONTH = {'monday': [5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 5],
|
||||
'tuesday': [5, 4, 4, 4, 5, 4, 5, 4, 4, 5, 4, 4],
|
||||
'wednesday': [5, 4, 4, 4, 5, 4, 4, 5, 4, 5, 4, 4],
|
||||
'thursday': [4, 4, 5, 4, 5, 4, 4, 5, 4, 4, 5, 4],
|
||||
'friday': [4, 4, 5, 4, 4, 5, 4, 5, 4, 4, 5, 4],
|
||||
'saturday': [4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5],
|
||||
'sunday': [4, 4, 4, 5, 4, 4, 5, 4, 5, 4, 4, 5],
|
||||
'holiday': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}
|
||||
JANUARY = 'January'
|
||||
FEBRUARY = 'February'
|
||||
MARCH = 'March'
|
||||
APRIL = 'April'
|
||||
MAY = 'May'
|
||||
JUNE = 'June'
|
||||
JULY = 'July'
|
||||
AUGUST = 'August'
|
||||
SEPTEMBER = 'September'
|
||||
OCTOBER = 'October'
|
||||
NOVEMBER = 'November'
|
||||
DECEMBER = 'December'
|
||||
|
||||
WEEK_DAYS_A_YEAR = {'monday': 51,
|
||||
'tuesday': 50,
|
||||
'wednesday': 50,
|
||||
'thursday': 50,
|
||||
'friday': 50,
|
||||
'saturday': 52,
|
||||
'sunday': 52,
|
||||
'holiday': 10}
|
||||
MONTHS = [JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER]
|
||||
|
||||
DAYS_A_MONTH = {'January': 31,
|
||||
'February': 28,
|
||||
'March': 31,
|
||||
'April': 30,
|
||||
'May': 31,
|
||||
'June': 30,
|
||||
'July': 31,
|
||||
'August': 31,
|
||||
'September': 30,
|
||||
'October': 31,
|
||||
'November': 30,
|
||||
'December': 31}
|
||||
WEEK_DAYS_A_MONTH = {JANUARY: {MONDAY: 5,
|
||||
TUESDAY: 5,
|
||||
WEDNESDAY: 5,
|
||||
THURSDAY: 4,
|
||||
FRIDAY: 4,
|
||||
SATURDAY: 4,
|
||||
SUNDAY: 4,
|
||||
HOLIDAY: 0},
|
||||
FEBRUARY: {MONDAY: 4,
|
||||
TUESDAY: 4,
|
||||
WEDNESDAY: 4,
|
||||
THURSDAY: 4,
|
||||
FRIDAY: 4,
|
||||
SATURDAY: 4,
|
||||
SUNDAY: 4,
|
||||
HOLIDAY: 0},
|
||||
MARCH: {MONDAY: 4,
|
||||
TUESDAY: 4,
|
||||
WEDNESDAY: 4,
|
||||
THURSDAY: 5,
|
||||
FRIDAY: 5,
|
||||
SATURDAY: 5,
|
||||
SUNDAY: 4,
|
||||
HOLIDAY: 0},
|
||||
APRIL: {MONDAY: 5,
|
||||
TUESDAY: 4,
|
||||
WEDNESDAY: 4,
|
||||
THURSDAY: 4,
|
||||
FRIDAY: 4,
|
||||
SATURDAY: 4,
|
||||
SUNDAY: 5,
|
||||
HOLIDAY: 0},
|
||||
MAY: {MONDAY: 4,
|
||||
TUESDAY: 5,
|
||||
WEDNESDAY: 5,
|
||||
THURSDAY: 5,
|
||||
FRIDAY: 4,
|
||||
SATURDAY: 4,
|
||||
SUNDAY: 4,
|
||||
HOLIDAY: 0},
|
||||
JUNE: {MONDAY: 4,
|
||||
TUESDAY: 4,
|
||||
WEDNESDAY: 4,
|
||||
THURSDAY: 4,
|
||||
FRIDAY: 5,
|
||||
SATURDAY: 5,
|
||||
SUNDAY: 4,
|
||||
HOLIDAY: 0},
|
||||
JULY: {MONDAY: 5,
|
||||
TUESDAY: 5,
|
||||
WEDNESDAY: 4,
|
||||
THURSDAY: 4,
|
||||
FRIDAY: 4,
|
||||
SATURDAY: 4,
|
||||
SUNDAY: 5,
|
||||
HOLIDAY: 0},
|
||||
AUGUST: {MONDAY: 4,
|
||||
TUESDAY: 4,
|
||||
WEDNESDAY: 5,
|
||||
THURSDAY: 5,
|
||||
FRIDAY: 5,
|
||||
SATURDAY: 4,
|
||||
SUNDAY: 4,
|
||||
HOLIDAY: 0},
|
||||
SEPTEMBER: {MONDAY: 4,
|
||||
TUESDAY: 4,
|
||||
WEDNESDAY: 4,
|
||||
THURSDAY: 4,
|
||||
FRIDAY: 4,
|
||||
SATURDAY: 5,
|
||||
SUNDAY: 5,
|
||||
HOLIDAY: 0},
|
||||
OCTOBER: {MONDAY: 5,
|
||||
TUESDAY: 5,
|
||||
WEDNESDAY: 5,
|
||||
THURSDAY: 4,
|
||||
FRIDAY: 4,
|
||||
SATURDAY: 4,
|
||||
SUNDAY: 4,
|
||||
HOLIDAY: 0},
|
||||
NOVEMBER: {MONDAY: 4,
|
||||
TUESDAY: 4,
|
||||
WEDNESDAY: 4,
|
||||
THURSDAY: 5,
|
||||
FRIDAY: 5,
|
||||
SATURDAY: 4,
|
||||
SUNDAY: 4,
|
||||
HOLIDAY: 0},
|
||||
DECEMBER: {MONDAY: 5,
|
||||
TUESDAY: 4,
|
||||
WEDNESDAY: 4,
|
||||
THURSDAY: 4,
|
||||
FRIDAY: 4,
|
||||
SATURDAY: 5,
|
||||
SUNDAY: 5,
|
||||
HOLIDAY: 0},
|
||||
}
|
||||
|
||||
WEEK_DAYS_A_YEAR = {MONDAY: 51,
|
||||
TUESDAY: 50,
|
||||
WEDNESDAY: 50,
|
||||
THURSDAY: 50,
|
||||
FRIDAY: 50,
|
||||
SATURDAY: 52,
|
||||
SUNDAY: 52,
|
||||
HOLIDAY: 10}
|
||||
|
||||
DAYS_A_MONTH = {JANUARY: 31,
|
||||
FEBRUARY: 28,
|
||||
MARCH: 31,
|
||||
APRIL: 30,
|
||||
MAY: 31,
|
||||
JUNE: 30,
|
||||
JULY: 31,
|
||||
AUGUST: 31,
|
||||
SEPTEMBER: 30,
|
||||
OCTOBER: 31,
|
||||
NOVEMBER: 30,
|
||||
DECEMBER: 31}
|
||||
|
||||
# data types
|
||||
ANY_NUMBER = 'any_number'
|
||||
|
|
|
@ -16,7 +16,9 @@ class HubFunctionToEilatConstructionFunction:
|
|||
self._dictionary = {
|
||||
cte.RESIDENTIAL: 'Residential_building',
|
||||
cte.HOTEL: 'Residential_building',
|
||||
cte.DORMITORY: 'Residential_building'
|
||||
cte.DORMITORY: 'Residential_building',
|
||||
cte.DATACENTER: 'n/a',
|
||||
cte.FARM: 'n/a'
|
||||
}
|
||||
|
||||
@property
|
||||
|
|
|
@ -73,7 +73,9 @@ class HubFunctionToMontrealCustomCostsFunction:
|
|||
cte.AUTOMOTIVE_FACILITY: 'non-residential',
|
||||
cte.PARKING_GARAGE: 'non-residential',
|
||||
cte.RELIGIOUS: 'non-residential',
|
||||
cte.NON_HEATED: 'non-residential'
|
||||
cte.NON_HEATED: 'non-residential',
|
||||
cte.DATACENTER: 'n/a',
|
||||
cte.FARM: 'n/a'
|
||||
}
|
||||
|
||||
@property
|
||||
|
|
|
@ -72,7 +72,9 @@ class HubFunctionToNrcanConstructionFunction:
|
|||
cte.AUTOMOTIVE_FACILITY: 'n/a',
|
||||
cte.PARKING_GARAGE: 'n/a',
|
||||
cte.RELIGIOUS: 'n/a',
|
||||
cte.NON_HEATED: 'n/a'
|
||||
cte.NON_HEATED: 'n/a',
|
||||
cte.DATACENTER: 'n/a',
|
||||
cte.FARM: 'n/a'
|
||||
}
|
||||
|
||||
@property
|
||||
|
|
|
@ -73,7 +73,9 @@ class HubFunctionToNrelConstructionFunction:
|
|||
cte.AUTOMOTIVE_FACILITY: 'n/a',
|
||||
cte.PARKING_GARAGE: 'n/a',
|
||||
cte.RELIGIOUS: 'n/a',
|
||||
cte.NON_HEATED: 'n/a'
|
||||
cte.NON_HEATED: 'n/a',
|
||||
cte.DATACENTER: 'n/a',
|
||||
cte.FARM: 'n/a'
|
||||
}
|
||||
|
||||
@property
|
||||
|
|
|
@ -76,7 +76,6 @@ class HubUsageToNrcanUsage:
|
|||
cte.NON_HEATED: 'n/a',
|
||||
cte.DATACENTER: 'n/a',
|
||||
cte.FARM: 'n/a'
|
||||
|
||||
}
|
||||
|
||||
@property
|
||||
|
|
|
@ -32,7 +32,7 @@ class EilatPhysicsParameters:
|
|||
city = self._city
|
||||
eilat_catalog = ConstructionCatalogFactory('eilat').catalog
|
||||
for building in city.buildings:
|
||||
if building.function not in Dictionaries().hub_function_to_eilat_construction_function.keys():
|
||||
if building.function not in Dictionaries().hub_function_to_eilat_construction_function:
|
||||
logging.error('Building %s has an unknown building function %s', building.name, building.function)
|
||||
continue
|
||||
function = Dictionaries().hub_function_to_eilat_construction_function[building.function]
|
||||
|
|
|
@ -32,8 +32,8 @@ class NrcanPhysicsParameters:
|
|||
city = self._city
|
||||
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
||||
for building in city.buildings:
|
||||
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function.keys():
|
||||
logging.error(f'Building %s has an unknown building function %s', building.name, building.function)
|
||||
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
|
||||
logging.error('Building %s has an unknown building function %s', building.name, building.function)
|
||||
continue
|
||||
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
|
||||
try:
|
||||
|
|
|
@ -75,48 +75,48 @@ class MontrealCustomEnergySystemParameters:
|
|||
@staticmethod
|
||||
def _create_generic_systems(archetype, building,
|
||||
_energy_systems_connection_table, _generic_energy_systems):
|
||||
building_systems = []
|
||||
data = [archetype.name, building.name]
|
||||
_energy_systems_connection_table.loc[len(_energy_systems_connection_table)] = data
|
||||
for system in archetype.systems:
|
||||
energy_system = GenericEnergySystem()
|
||||
_hub_demand_types = []
|
||||
for demand_type in system.demand_types:
|
||||
_hub_demand_types.append(Dictionaries().montreal_demand_type_to_hub_energy_demand_type[demand_type])
|
||||
energy_system.name = system.name
|
||||
energy_system.demand_types = _hub_demand_types
|
||||
_generation_system = GenericGenerationSystem()
|
||||
archetype_generation_equipment = system.generation_systems
|
||||
_type = system.name
|
||||
_generation_system.type = Dictionaries().montreal_system_to_hub_energy_generation_system[
|
||||
_type]
|
||||
_fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_equipment.fuel_type]
|
||||
_generation_system.fuel_type = _fuel_type
|
||||
_generation_system.source_types = archetype_generation_equipment.source_medium
|
||||
_generation_system.heat_efficiency = archetype_generation_equipment.heat_efficiency
|
||||
_generation_system.cooling_efficiency = archetype_generation_equipment.cooling_efficiency
|
||||
_generation_system.electricity_efficiency = archetype_generation_equipment.electricity_efficiency
|
||||
_generation_system.source_temperature = archetype_generation_equipment.source_temperature
|
||||
_generation_system.source_mass_flow = archetype_generation_equipment.source_mass_flow
|
||||
_generation_system.storage = archetype_generation_equipment.storage
|
||||
_generation_system.auxiliary_equipment = None
|
||||
|
||||
energy_system.generation_systems = _generation_system
|
||||
|
||||
_distribution_system = GenericDistributionSystem()
|
||||
archetype_distribution_equipment = system.distribution_systems
|
||||
_distribution_system.type = archetype_distribution_equipment.type
|
||||
_distribution_system.supply_temperature = archetype_distribution_equipment.supply_temperature
|
||||
_distribution_system.distribution_consumption_fix_flow = \
|
||||
archetype_distribution_equipment.distribution_consumption_fix_flow
|
||||
_distribution_system.distribution_consumption_variable_flow = \
|
||||
archetype_distribution_equipment.distribution_consumption_variable_flow
|
||||
_distribution_system.heat_losses = archetype_distribution_equipment.heat_losses
|
||||
|
||||
energy_system.distribution_systems = _distribution_system
|
||||
|
||||
building_systems.append(energy_system)
|
||||
if archetype.name not in _generic_energy_systems:
|
||||
building_systems = []
|
||||
for system in archetype.systems:
|
||||
energy_system = GenericEnergySystem()
|
||||
_hub_demand_types = []
|
||||
for demand_type in system.demand_types:
|
||||
_hub_demand_types.append(Dictionaries().montreal_demand_type_to_hub_energy_demand_type[demand_type])
|
||||
energy_system.name = system.name
|
||||
energy_system.demand_types = _hub_demand_types
|
||||
_generation_system = GenericGenerationSystem()
|
||||
archetype_generation_equipment = system.generation_system
|
||||
_type = system.name
|
||||
_generation_system.type = Dictionaries().montreal_system_to_hub_energy_generation_system[
|
||||
_type]
|
||||
_fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_equipment.fuel_type]
|
||||
_generation_system.fuel_type = _fuel_type
|
||||
_generation_system.source_types = archetype_generation_equipment.source_medium
|
||||
_generation_system.heat_efficiency = archetype_generation_equipment.heat_efficiency
|
||||
_generation_system.cooling_efficiency = archetype_generation_equipment.cooling_efficiency
|
||||
_generation_system.electricity_efficiency = archetype_generation_equipment.electricity_efficiency
|
||||
_generation_system.source_temperature = archetype_generation_equipment.source_temperature
|
||||
_generation_system.source_mass_flow = archetype_generation_equipment.source_mass_flow
|
||||
_generation_system.storage = archetype_generation_equipment.storage
|
||||
_generation_system.auxiliary_equipment = None
|
||||
|
||||
energy_system.generation_system = _generation_system
|
||||
|
||||
_distribution_system = GenericDistributionSystem()
|
||||
archetype_distribution_equipment = system.distribution_systems
|
||||
_distribution_system.type = archetype_distribution_equipment.type
|
||||
_distribution_system.supply_temperature = archetype_distribution_equipment.supply_temperature
|
||||
_distribution_system.distribution_consumption_fix_flow = \
|
||||
archetype_distribution_equipment.distribution_consumption_fix_flow
|
||||
_distribution_system.distribution_consumption_variable_flow = \
|
||||
archetype_distribution_equipment.distribution_consumption_variable_flow
|
||||
_distribution_system.heat_losses = archetype_distribution_equipment.heat_losses
|
||||
|
||||
energy_system.distribution_system = _distribution_system
|
||||
|
||||
building_systems.append(energy_system)
|
||||
_generic_energy_systems[archetype.name] = building_systems
|
||||
|
||||
return _energy_systems_connection_table, _generic_energy_systems
|
||||
|
@ -145,11 +145,11 @@ class MontrealCustomEnergySystemParameters:
|
|||
copy.deepcopy(_generic_building_energy_system.emission_systems)
|
||||
_building_generation_system = GenerationSystem()
|
||||
_building_generation_system.generic_generation_system = \
|
||||
copy.deepcopy(_generic_building_energy_system.generation_system)
|
||||
copy.deepcopy(_generic_building_energy_system.generation_systems)
|
||||
|
||||
_building_energy_equipment.generation_system = _building_generation_system
|
||||
_building_energy_equipment.distribution_system = _building_distribution_system
|
||||
_building_energy_equipment.emission_system = _building_emission_system
|
||||
_building_energy_equipment.generation_systems = _building_generation_system
|
||||
_building_energy_equipment.distribution_systems = _building_distribution_system
|
||||
_building_energy_equipment.emission_systems = _building_emission_system
|
||||
|
||||
_building_energy_systems.append(_building_energy_equipment)
|
||||
building.energy_systems = _building_energy_systems
|
||||
|
|
|
@ -6,21 +6,20 @@ Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
|
|||
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
|
||||
import logging
|
||||
import copy
|
||||
import logging
|
||||
|
||||
from pandas import DataFrame
|
||||
|
||||
from hub.catalog_factories.energy_systems_catalog_factory import EnergySystemsCatalogFactory
|
||||
from hub.city_model_structure.energy_systems.generic_energy_system import GenericEnergySystem
|
||||
from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem
|
||||
from hub.city_model_structure.energy_systems.energy_system import EnergySystem
|
||||
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.helpers.dictionaries import Dictionaries
|
||||
from hub.city_model_structure.energy_systems.generic_storage_system import GenericStorageSystem
|
||||
from hub.city_model_structure.energy_systems.energy_system import EnergySystem
|
||||
from hub.city_model_structure.energy_systems.generation_system import GenerationSystem
|
||||
from hub.city_model_structure.energy_systems.generic_energy_system import GenericEnergySystem
|
||||
from hub.city_model_structure.energy_systems.generic_generation_system import GenericGenerationSystem
|
||||
from hub.city_model_structure.energy_systems.thermal_storage_system import ThermalStorageSystem
|
||||
from hub.helpers.dictionaries import Dictionaries
|
||||
|
||||
|
||||
class NorthAmericaCustomEnergySystemParameters:
|
||||
|
@ -83,7 +82,7 @@ class NorthAmericaCustomEnergySystemParameters:
|
|||
energy_system = GenericEnergySystem()
|
||||
_hub_demand_types = []
|
||||
demand_types = system.demand_types
|
||||
if type(demand_types) == str:
|
||||
if isinstance(demand_types, str):
|
||||
demand_types = [demand_types]
|
||||
for demand_type in demand_types:
|
||||
_hub_demand_types.append(Dictionaries().north_america_demand_type_to_hub_energy_demand_type[demand_type])
|
||||
|
@ -105,17 +104,17 @@ class NorthAmericaCustomEnergySystemParameters:
|
|||
_generation_system.source_mass_flow = archetype_generation_equipment.source_mass_flow
|
||||
_generation_system.storage = None
|
||||
_generation_system.auxiliary_equipment = None
|
||||
_generation_system._supply_medium = archetype_generation_equipment.supply_medium
|
||||
_generation_system._maximum_heat_supply_temperature = archetype_generation_equipment.maximum_heat_supply_temperature
|
||||
_generation_system._minimum_heat_supply_temperature = archetype_generation_equipment.minimum_heat_supply_temperature
|
||||
_generation_system._maximum_cooling_supply_temperature = archetype_generation_equipment.maximum_cooling_supply_temperature
|
||||
_generation_system._minimum_cooling_supply_temperature = archetype_generation_equipment.minimum_cooling_supply_temperature
|
||||
_generation_system._heat_output_curve = archetype_generation_equipment.heat_output_curve
|
||||
_generation_system._heat_fuel_consumption_curve = archetype_generation_equipment.heat_fuel_consumption_curve
|
||||
_generation_system._heat_efficiency_curve = archetype_generation_equipment.heat_efficiency_curve
|
||||
_generation_system._cooling_output_curve = archetype_generation_equipment.cooling_output_curve
|
||||
_generation_system._cooling_fuel_consumption_curve = archetype_generation_equipment.cooling_fuel_consumption_curve
|
||||
_generation_system._cooling_efficiency_curve = archetype_generation_equipment.cooling_efficiency_curve
|
||||
_generation_system.supply_medium = archetype_generation_equipment.supply_medium
|
||||
_generation_system.maximum_heat_supply_temperature = archetype_generation_equipment.maximum_heat_supply_temperature
|
||||
_generation_system.minimum_heat_supply_temperature = archetype_generation_equipment.minimum_heat_supply_temperature
|
||||
_generation_system.maximum_cooling_supply_temperature = archetype_generation_equipment.maximum_cooling_supply_temperature
|
||||
_generation_system.minimum_cooling_supply_temperature = archetype_generation_equipment.minimum_cooling_supply_temperature
|
||||
_generation_system.heat_output_curve = archetype_generation_equipment.heat_output_curve
|
||||
_generation_system.heat_fuel_consumption_curve = archetype_generation_equipment.heat_fuel_consumption_curve
|
||||
_generation_system.heat_efficiency_curve = archetype_generation_equipment.heat_efficiency_curve
|
||||
_generation_system.cooling_output_curve = archetype_generation_equipment.cooling_output_curve
|
||||
_generation_system.cooling_fuel_consumption_curve = archetype_generation_equipment.cooling_fuel_consumption_curve
|
||||
_generation_system.cooling_efficiency_curve = archetype_generation_equipment.cooling_efficiency_curve
|
||||
_generation_systems.append(_generation_system)
|
||||
|
||||
energy_system.generation_systems = _generation_systems
|
||||
|
@ -127,7 +126,7 @@ class NorthAmericaCustomEnergySystemParameters:
|
|||
_thermal_storage_system.maximum_operating_temperature = archetype_storage_equipment.maximum_operating_temperature
|
||||
_thermal_storage_system.height = archetype_storage_equipment.height
|
||||
_thermal_storage_system.layers = archetype_storage_equipment.layers
|
||||
energy_system.energy_storage_system = _thermal_storage_system
|
||||
energy_system.energy_storage_systems = _thermal_storage_system
|
||||
|
||||
building_systems.append(energy_system)
|
||||
if archetype.name not in _generic_energy_systems:
|
||||
|
@ -151,24 +150,20 @@ class NorthAmericaCustomEnergySystemParameters:
|
|||
_building_energy_equipment = EnergySystem()
|
||||
_building_energy_equipment.name = _generic_building_energy_system.name
|
||||
_building_energy_equipment.demand_types = _generic_building_energy_system.demand_types
|
||||
|
||||
_building_distribution_system = DistributionSystem()
|
||||
_building_distribution_system.generic_distribution_system = \
|
||||
copy.deepcopy(_generic_building_energy_system.distribution_system)
|
||||
_building_emission_system = EmissionSystem()
|
||||
_building_emission_system.generic_emission_system = \
|
||||
copy.deepcopy(_generic_building_energy_system.emission_system)
|
||||
_building_generation_system = GenerationSystem()
|
||||
_building_generation_system.generic_generation_system = \
|
||||
copy.deepcopy(_generic_building_energy_system.generation_system)
|
||||
_generation_systems = []
|
||||
_generic_building_generation_systems = _generic_building_energy_system.generation_systems
|
||||
for _generic_building_generation_system in _generic_building_generation_systems:
|
||||
_building_generation_system = GenerationSystem()
|
||||
_building_generation_system.generic_generation_system = \
|
||||
copy.deepcopy(_generic_building_generation_system)
|
||||
_generation_systems.append(_building_generation_system)
|
||||
_building_energy_equipment.generation_systems = _generation_systems
|
||||
_building_storage_system = ThermalStorageSystem()
|
||||
_building_storage_system.generic_storage_system = \
|
||||
copy.deepcopy(_generic_building_energy_system.energy_storage_system)
|
||||
copy.deepcopy(_generic_building_energy_system.energy_storage_systems)
|
||||
|
||||
_building_energy_equipment.generation_system = _building_generation_system
|
||||
_building_energy_equipment.distribution_system = _building_distribution_system
|
||||
_building_energy_equipment.emission_system = _building_emission_system
|
||||
_building_energy_equipment.energy_storage_system = _building_storage_system
|
||||
|
||||
_building_energy_equipment.energy_storage_systems = _building_storage_system
|
||||
|
||||
_building_energy_systems.append(_building_energy_equipment)
|
||||
building.energy_systems = _building_energy_systems
|
||||
|
|
|
@ -116,6 +116,7 @@ class Geojson:
|
|||
if self._extrusion_height_field is not None:
|
||||
extrusion_height = float(feature['properties'][self._extrusion_height_field])
|
||||
lod = 1
|
||||
self._max_z = max(self._max_z, extrusion_height)
|
||||
year_of_construction = None
|
||||
if self._year_of_construction_field is not None:
|
||||
year_of_construction = int(feature['properties'][self._year_of_construction_field])
|
||||
|
|
|
@ -6,13 +6,16 @@ Project Coder Saeed Ranjbar saeed.ranjbar@concordia.ca
|
|||
Project collaborator Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||
"""
|
||||
from pathlib import Path
|
||||
from hub.helpers.monthly_values import MonthlyValues
|
||||
import csv
|
||||
|
||||
from hub.helpers.monthly_values import MonthlyValues
|
||||
import hub.helpers.constants as cte
|
||||
|
||||
|
||||
class EnergyPlusWorkflow:
|
||||
class EnergyPlus:
|
||||
"""
|
||||
Energy plus class
|
||||
"""
|
||||
def __init__(self, city, base_path):
|
||||
self._city = city
|
||||
self._base_path = base_path
|
|
@ -59,7 +59,7 @@ class InselMonthlyEnergyBalance:
|
|||
lighting_density = thermal_zone.lighting.density
|
||||
appliances_density = thermal_zone.appliances.density
|
||||
|
||||
for month in range(0, 12):
|
||||
for i_month, month in enumerate(cte.MONTHS):
|
||||
total_dhw_demand = 0
|
||||
total_lighting = 0
|
||||
total_appliances = 0
|
||||
|
@ -69,7 +69,7 @@ class InselMonthlyEnergyBalance:
|
|||
for value in schedule.values:
|
||||
total_day += value
|
||||
for day_type in schedule.day_types:
|
||||
total_lighting += total_day * cte.WEEK_DAYS_A_MONTH[day_type][month] \
|
||||
total_lighting += total_day * cte.WEEK_DAYS_A_MONTH[month][day_type] \
|
||||
* lighting_density / cte.WATTS_HOUR_TO_JULES
|
||||
lighting_demand.append(total_lighting * area)
|
||||
|
||||
|
@ -78,7 +78,7 @@ class InselMonthlyEnergyBalance:
|
|||
for value in schedule.values:
|
||||
total_day += value
|
||||
for day_type in schedule.day_types:
|
||||
total_appliances += total_day * cte.WEEK_DAYS_A_MONTH[day_type][month] \
|
||||
total_appliances += total_day * cte.WEEK_DAYS_A_MONTH[month][day_type] \
|
||||
* appliances_density / cte.WATTS_HOUR_TO_JULES
|
||||
appliances_demand.append(total_appliances * area)
|
||||
|
||||
|
@ -89,9 +89,9 @@ class InselMonthlyEnergyBalance:
|
|||
for day_type in schedule.day_types:
|
||||
demand = (
|
||||
peak_flow * cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY
|
||||
* (service_temperature - cold_water[month]) / cte.WATTS_HOUR_TO_JULES
|
||||
* (service_temperature - cold_water[i_month]) / cte.WATTS_HOUR_TO_JULES
|
||||
)
|
||||
total_dhw_demand += total_day * cte.WEEK_DAYS_A_MONTH[day_type][month] * demand
|
||||
total_dhw_demand += total_day * cte.WEEK_DAYS_A_MONTH[month][day_type] * demand
|
||||
domestic_hot_water_demand.append(total_dhw_demand * area)
|
||||
except AttributeError:
|
||||
domestic_hot_water_demand = [0] * 12
|
||||
|
|
|
@ -10,7 +10,7 @@ from pathlib import Path
|
|||
from hub.helpers.utils import validate_import_export_type
|
||||
from hub.imports.results.insel_monthly_energry_balance import InselMonthlyEnergyBalance
|
||||
from hub.imports.results.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm
|
||||
from hub.imports.results.energy_plus_workflow import EnergyPlusWorkflow
|
||||
from hub.imports.results.energy_plus import EnergyPlus
|
||||
|
||||
class ResultFactory:
|
||||
"""
|
||||
|
@ -50,7 +50,7 @@ class ResultFactory:
|
|||
"""
|
||||
Enrich the city with energy plus results
|
||||
"""
|
||||
EnergyPlusWorkflow(self._city, self._base_path).enrich()
|
||||
EnergyPlus(self._city, self._base_path).enrich()
|
||||
|
||||
def enrich(self):
|
||||
"""
|
||||
|
|
|
@ -7,7 +7,7 @@ Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
|
|||
import datetime
|
||||
import logging
|
||||
|
||||
from sqlalchemy import select, or_
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"""
|
||||
Hub version number
|
||||
"""
|
||||
__version__ = '0.1.8.10'
|
||||
__version__ = '0.1.8.11'
|
||||
|
|
25
setup.py
|
@ -18,24 +18,22 @@ with open(version) as f:
|
|||
exec(f.read(), main_ns)
|
||||
|
||||
|
||||
|
||||
|
||||
setup(
|
||||
name='cerc-hub',
|
||||
version=main_ns['__version__'],
|
||||
description="CERC Hub consist in a set of classes (Central data model), importers and exporters to help researchers "
|
||||
"to create better and sustainable cities",
|
||||
long_description="CERC Hub consist in a set of classes (Central data model), importers and exporters to help "
|
||||
"researchers to create better and sustainable cities.\n\nDevelop at Concordia university in canada "
|
||||
"as part of the research group from the next generation cities institute our aim among others it's "
|
||||
description="CERC Hub consist of a set of classes (Central data model), importers and exporters to help researchers "
|
||||
"to create better and more sustainable cities",
|
||||
long_description="CERC Hub consist of a set of classes (Central data model), importers and exporters to help "
|
||||
"researchers to create better and more sustainable cities.\n\nDeveloped at Concordia university in Canada "
|
||||
"as part of the research group from the Next Generation Cities Institute, our aim among others is "
|
||||
"to provide a comprehensive set of tools to help researchers and urban developers to make decisions "
|
||||
"to improve the livability and efficiency of our cities",
|
||||
classifiers=[
|
||||
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
],
|
||||
include_package_data=True,
|
||||
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
|
||||
"Programming Language :: Python",
|
||||
"Programming Language :: Python :: 3",
|
||||
],
|
||||
include_package_data=True,
|
||||
packages=['hub',
|
||||
'hub.catalog_factories',
|
||||
'hub.catalog_factories.construction',
|
||||
|
@ -88,7 +86,8 @@ setup(
|
|||
data_files=[
|
||||
('hub', glob.glob('requirements.txt')),
|
||||
('hub/config', glob.glob('hub/config/*.ini')),
|
||||
('hub/catalog_factories/greenery/ecore_greenery', glob.glob('hub/catalog_factories/greenery/ecore_greenery/*.ecore')),
|
||||
('hub/catalog_factories/greenery/ecore_greenery',
|
||||
glob.glob('hub/catalog_factories/greenery/ecore_greenery/*.ecore')),
|
||||
('hub/data/construction', glob.glob('hub/data/construction/*')),
|
||||
('hub/data/costs', glob.glob('hub/data/costs/montreal_costs.xml')),
|
||||
('hub/data/customized_imports', glob.glob('hub/data/customized_imports/ashrae_archetypes.xml')),
|
||||
|
|
|
@ -66,12 +66,7 @@ class TestExports(TestCase):
|
|||
|
||||
def _export(self, export_type, from_pickle=False):
|
||||
self._complete_city = self._get_complete_city(from_pickle)
|
||||
try:
|
||||
ExportsFactory(export_type, self._complete_city, self._output_path).export()
|
||||
except ValueError as err:
|
||||
if export_type != 'stl':
|
||||
logging.warning('No backend export for STL test, skipped')
|
||||
raise err
|
||||
ExportsFactory(export_type, self._complete_city, self._output_path).export()
|
||||
|
||||
def _export_building_energy(self, export_type, from_pickle=False):
|
||||
self._complete_city = self._get_complete_city(from_pickle)
|
||||
|
@ -83,12 +78,6 @@ class TestExports(TestCase):
|
|||
"""
|
||||
self._export('obj', False)
|
||||
|
||||
def test_stl_export(self):
|
||||
"""
|
||||
export to stl
|
||||
"""
|
||||
self._export('stl', False)
|
||||
|
||||
def test_energy_ade_export(self):
|
||||
"""
|
||||
export to energy ADE
|
||||
|
|
|
@ -40,7 +40,7 @@ class TestResultsImport(TestCase):
|
|||
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
|
||||
|
||||
ConstructionFactory('nrcan', self._city).enrich()
|
||||
UsageFactory('nrcan', self._city).enrich()
|
||||
UsageFactory('comnet', self._city).enrich()
|
||||
|
||||
def test_sra_import(self):
|
||||
ExportsFactory('sra', self._city, self._output_path).export()
|
||||
|
|
|
@ -98,15 +98,15 @@ class TestSystemsFactory(TestCase):
|
|||
)
|
||||
_building_generation_system = GenerationSystem()
|
||||
_building_generation_system.generic_generation_system = (
|
||||
copy.deepcopy(_generic_building_energy_system.generation_system)
|
||||
copy.deepcopy(_generic_building_energy_system.generation_systems)
|
||||
)
|
||||
if cte.HEATING in _building_energy_equipment.demand_types:
|
||||
_building_generation_system.heat_power = building.heating_peak_load[cte.YEAR][0]
|
||||
if cte.COOLING in _building_energy_equipment.demand_types:
|
||||
_building_generation_system.cooling_power = building.cooling_peak_load[cte.YEAR][0]
|
||||
_building_energy_equipment.generation_system = _building_generation_system
|
||||
_building_energy_equipment.distribution_system = _building_distribution_system
|
||||
_building_energy_equipment.emission_system = _building_emission_system
|
||||
_building_energy_equipment.generation_systems = _building_generation_system
|
||||
_building_energy_equipment.distribution_systems = _building_distribution_system
|
||||
_building_energy_equipment.emission_systems = _building_emission_system
|
||||
|
||||
_building_energy_systems.append(_building_energy_equipment)
|
||||
building.energy_systems = _building_energy_systems
|
||||
|
@ -161,27 +161,27 @@ class TestSystemsFactory(TestCase):
|
|||
|
||||
_building_distribution_system = DistributionSystem()
|
||||
_building_distribution_system.generic_distribution_system = (
|
||||
copy.deepcopy(_generic_building_energy_system.distribution_system)
|
||||
copy.deepcopy(_generic_building_energy_system.distribution_systems)
|
||||
)
|
||||
_building_emission_system = EmissionSystem()
|
||||
_building_emission_system.generic_emission_system = (
|
||||
copy.deepcopy(_generic_building_energy_system.emission_system)
|
||||
copy.deepcopy(_generic_building_energy_system.emission_systems)
|
||||
)
|
||||
_building_generation_system = GenerationSystem()
|
||||
_building_generation_system.generic_generation_system = (
|
||||
copy.deepcopy(_generic_building_energy_system.generation_system)
|
||||
copy.deepcopy(_generic_building_energy_system.generation_systems)
|
||||
)
|
||||
_building_storage_system = ThermalStorageSystem()
|
||||
_building_storage_system.generic_storage_system = \
|
||||
copy.deepcopy(_generic_building_energy_system.energy_storage_system)
|
||||
copy.deepcopy(_generic_building_energy_system.energy_storage_systems)
|
||||
|
||||
if cte.HEATING in _building_energy_equipment.demand_types:
|
||||
_building_generation_system.heat_power = building.heating_peak_load[cte.YEAR][0]
|
||||
if cte.COOLING in _building_energy_equipment.demand_types:
|
||||
_building_generation_system.cooling_power = building.cooling_peak_load[cte.YEAR][0]
|
||||
_building_energy_equipment.generation_system = _building_generation_system
|
||||
_building_energy_equipment.distribution_system = _building_distribution_system
|
||||
_building_energy_equipment.emission_system = _building_emission_system
|
||||
_building_energy_equipment.generation_systems = _building_generation_system
|
||||
_building_energy_equipment.distribution_systems = _building_distribution_system
|
||||
_building_energy_equipment.emission_systems = _building_emission_system
|
||||
|
||||
_building_energy_systems.append(_building_energy_equipment)
|
||||
building.energy_systems = _building_energy_systems
|
||||
|
|