Compare commits

...

58 Commits

Author SHA1 Message Date
941206e273 Merge pull request 'fix: infiltration_rate_area values for the new cerc archetypes are added' (#3) from infiltration_cerc_catalogues into main
Reviewed-on: s_ranjbar/city_retrofit#3
2024-11-03 05:29:08 -05:00
7952fe8a8e fix: infiltration_rate_area values for the new cerc archetypes are added 2024-11-03 11:27:40 +01:00
57cefc2f30 fix: latest Oriol changes and some updates in energy system catalog are implemented 2024-10-31 10:09:22 +00:00
73b779747e fix: redundant files are removed. 2024-10-31 09:46:33 +00:00
2e7723c65f Merge pull request 'OMHM_system_simulation' (#2) from OMHM_system_simulation into main
Reviewed-on: s_ranjbar/city_retrofit#2
2024-10-31 05:39:44 -04:00
77a1f08ae4 fix: current_status is fixed 2024-10-31 09:37:56 +00:00
e65496efa0 fix: system simulation done 2024-10-31 09:37:55 +00:00
0c5b64c0cf Merge pull request 'MOsman' (#1) from MOsman into main
Reviewed-on: s_ranjbar/city_retrofit#1
2024-10-31 05:32:25 -04:00
Mohamed_Osman
35204ed2a5 add_Single_familyhouse 2024-10-31 09:30:56 +00:00
Mohamed_Osman
e53c506e73 Select building based on height 2024-10-31 09:30:55 +00:00
Mohamed_Osman
ef9ff1d4d9 Retrofit Factory 2024-10-31 09:28:00 +00:00
Mohamed_Osman
8c46a629b9 nrcan catalog 2024-10-31 09:28:00 +00:00
Mohamed_Osman
cbba9f30f1 add_retrofit_input_file 2024-10-31 09:28:00 +00:00
Mohamed_Osman
f9d27627e9 Retrofit_window and infiltration 2024-10-31 09:28:00 +00:00
Mohamed_Osman
eba82b9cac Working_retrofit 2024-10-31 09:28:00 +00:00
Mohamed_Osman
9de0f48d9d basic and advanced retrofit 2024-10-31 09:28:00 +00:00
Mohamed_Osman
20b6167245 forced_u_value_change 2024-10-31 09:28:00 +00:00
Mohamed_Osman
47401f2e30 add_cerc catalogs 2024-10-31 09:28:00 +00:00
6f9c7397df Merge branch 'hub_branch'
# Conflicts:
#	hub/exports/building_energy/idf.py
2024-10-21 10:33:20 +02:00
bf4018a649 Update version number 2024-10-20 17:39:54 +02:00
6c7f652390 Merge pull request 'fix: the small bug in test units is resolved, the construction and usage factories can be loaded without any order' (#71) from small_bugs_in_user_tests into main
Reviewed-on: CERC/hub#71
2024-10-20 11:15:40 -04:00
4e46b6bc0d fix: the small bug in test units is resolved, the construction and usage factories can be loaded without any order 2024-10-18 12:28:38 +02:00
4ac9ccda81 Update hub/version.py 2024-10-17 08:05:13 -04:00
df2d7a3054 Geojson class modified for the geojson format Guille suggested 2024-10-17 07:40:13 -04:00
47810737fa geojson, construction and usage importers are all modified for mixed use buildings 2024-10-17 07:40:13 -04:00
99535a979c Update hub/version.py 2024-10-17 00:19:27 -04:00
9986552ec1 Merge remote-tracking branch 'origin/main' 2024-10-17 06:17:48 +02:00
d1719b50ed Merge branch 'infilt_availability_oriol' 2024-10-17 06:15:04 +02:00
5e01f4eb7f Merge pull request 'Remove build from setup.py and add it to requirements.txt' (#69) from fix/fix-build into main
Reviewed-on: CERC/hub#69
2024-10-03 14:08:37 -04:00
d38150ac2d Remove build from setup.py and add it to requirements.txt 2024-10-03 13:05:56 -05:00
5e5129ecd7 Merge pull request 'Add build package to setup.py and remove texttest' (#68) from fix/update-setup.py into main
Reviewed-on: CERC/hub#68
2024-10-02 12:07:55 -04:00
3905f228dc correct unittests 2024-10-02 06:30:43 +02:00
33049441f0 Add build package to setup.py and remove texttest 2024-10-01 14:35:08 -05:00
70dd9f7c6a Merge pull request 'fix: change building names in ep_multiple_buildings.py to upper case' (#66) from fix/ep-result-factory-naming-bug into main
Reviewed-on: CERC/hub#66
2024-10-01 10:15:40 -04:00
0ce392ea06 fix: change building names in ep_multiple_buildings.py to upper case 2024-10-01 09:43:57 -04:00
ogavalda
4b6a942324 Small change. test 2024-09-30 15:58:21 -04:00
2495046c44 correct typo 2024-09-30 19:46:07 +02:00
4738de0d8c Merge branch 'infilt_availability_oriol' 2024-09-30 15:17:05 +02:00
e220bf2c0d Merge remote-tracking branch 'origin/main' 2024-09-23 18:26:33 +02:00
a45cf02b28 Update hub/version.py 2024-09-23 11:57:33 -04:00
ef62e2531f add weather file to the EnergyBuildingsExportsFactory 2024-09-23 17:56:58 +02:00
ogavalda
cd34435a9f Including air temperature output 2024-09-16 15:49:18 -04:00
ogavalda
15b96fe154 Changing the full structure to incorporate a second way of entering infiltration (infiltration per outdoor area) 2024-09-16 15:41:27 -04:00
ogavalda
54a6e6b2db Adding infiltration per m2 2024-09-15 10:22:07 -04:00
ogavalda
a7375f0b53 Adding infiltration per m2 2024-09-15 10:15:41 -04:00
ogavalda
725746fbcb Changes in infiltration profiles and the source of values for infiltration 2024-09-15 09:44:07 -04:00
ec320a2e1c Merge pull request 'fix: small bugs in the irradiance units were fixed.' (#65) from irradiance_unit_fixing into main
Reviewed-on: CERC/hub#65
2024-09-09 13:27:05 -04:00
8a68118503 fix: small bugs in the irradiance units were fixed. 2024-09-09 11:11:33 -04:00
a3ec3c7e19 Merge pull request 'Add version number to numpy' (#64) from fix/downgrade-numpy into main
Reviewed-on: https://nextgenerations-cities.encs.concordia.ca/gitea/CERC/hub/pulls/64

Hi Connor, I have accepted the change, but some additional review will be needed, it creates a hard dependency from a specific version of numpy with almost sure will create issues with other libraries, will be nice if you could keep an eye on the issue resolution from sqlalchemy
2024-09-02 12:35:30 -04:00
connor
ace666553a Add version number to numpy 2024-08-30 18:01:26 -04:00
c4636c2c3c Merge remote-tracking branch 'origin/main' 2024-07-25 18:11:10 +02:00
4a01ac51d8 Remove the building from the targets if needed 2024-07-25 18:10:51 +02:00
ee846a6225 Update hub/version.py 2024-07-16 01:25:01 -04:00
a4f3b48617 Merge remote-tracking branch 'origin/main' 2024-07-16 07:24:41 +02:00
abc3fc48dd Add type to constructions to avoid collisions in constructions names 2024-07-16 07:24:22 +02:00
db371aecf3 Update hub/version.py 2024-07-10 05:57:01 -04:00
998df80b63 Correct shading object selection and idd file 2024-07-10 11:55:13 +02:00
446c7fa4ce Correct correct shadding object selection and idd file 2024-07-10 07:39:53 +02:00
72 changed files with 89101 additions and 1058 deletions

5
.gitignore vendored
View File

@ -11,4 +11,7 @@
**/.idea/
cerc_hub.egg-info
/out_files
/input_files
/CitRetrofitEnv
/cityretrofit_env
/.eggs

View File

@ -0,0 +1,187 @@
RetrofitFactory Documentation
Overview
RetrofitFactory is a tool designed to apply energy efficiency retrofits to buildings within a city model. It supports multiple retrofit types, including construction improvements, infiltration reduction, and window upgrades.
Usage
Basic Implementation
```python
from hub.imports.retrofit_factory import RetrofitFactory
# Load retrofit data from JSON file
with open('retrofit_scenarios.json', 'r') as f:
retrofit_data = json.load(f)
# Apply retrofits to a city
retrofit_factory = RetrofitFactory(retrofit_data, city)
retrofit_factory.enrich()
```
Retrofit Data Structure
The retrofit data is stored as a JSON object where building IDs serve as keys and retrofit specifications as values:
```json
{
"building_id": {
"retrofit_types": ["construction", "infiltration", "windows"],
"wall_u_value": 0.3,
"roof_u_value": 0.2,
"ground_u_value": 0.25,
"infiltration_reduction": 30,
"window_u_value": 1.5,
"window_g_value": 0.6
}
}
```
Supported Retrofit Types
RetrofitFactory supports the following types of retrofits:
1. Construction Retrofits
Modifies U-values for walls, roofs, and ground surfaces, but only if the new U-value is lower than the existing one. The retrofit improves thermal resistance of building materials.
Parameters:
- wall_u_value: Target U-value for walls (W/m²K)
- roof_u_value: Target U-value for roofs (W/m²K)
- ground_u_value: Target U-value for ground surfaces (W/m²K)
2. Infiltration Retrofits
Reduces air infiltration rate as a percentage, applied to the ventilation system when off.
Parameters:
- infiltration_reduction: Percentage reduction in infiltration rate (0-100)
3. Window Retrofits
Updates window thermal properties by modifying the U-value and solar heat gain coefficient (g-value).
Parameters:
- window_u_value: Target U-value for windows (W/m²K)
- window_g_value: Target solar heat gain coefficient (0-1)
Implementation Details
Class Structure
```python
class RetrofitFactory:
def __init__(self, retrofit_data: dict, city: City):
self._retrofit_data = retrofit_data
self._city = city
```
Main Methods
1. enrich()
Applies retrofits to all buildings in the city. It iterates over each building, retrieves its corresponding retrofit data, and applies the specified retrofits.
```python
def enrich(self):
for building in self._city.buildings:
building_id = str(building.name)
if building_id in self._retrofit_data:
building_retrofit_data = self._retrofit_data[building_id]
retrofit_types = building_retrofit_data.get('retrofit_types', [])
self._apply_retrofits_to_building(building, retrofit_types, building_retrofit_data)
```
2. _apply_retrofits_to_building()
Handles applying the specified retrofits to an individual building based on its retrofit data.
3. _apply_construction_retrofit_to_building()
Applies construction retrofits by modifying U-values for walls, roofs, and ground surfaces. Only updates if the new U-value is lower than the existing value.
```python
def _apply_construction_retrofit_to_building(self, building: Building, retrofit_params):
wall_u_value = retrofit_params.get('wall_u_value')
roof_u_value = retrofit_params.get('roof_u_value')
ground_u_value = retrofit_params.get('ground_u_value')
```
Thermal resistance is calculated as:
ΔR = (1 / U_new) - (1 / U_old)
```python
def _change_thermal_resistance(self, thermal_boundary, new_u_value):
old_u_value = thermal_boundary.u_value
if new_u_value < old_u_value:
delta_r = (1 / new_u_value) - (1 / old_u_value)
```
4. _reduce_infiltration_rate_by_percentage()
Reduces the infiltration rate by the specified percentage.
```python
def _reduce_infiltration_rate_by_percentage(self, building: Building, retrofit_params):
percentage = retrofit_params.get('infiltration_reduction')
if percentage is not None:
new_rate = old_rate * (1 - percentage / 100)
```
5. _apply_window_retrofit_to_building()
Updates the overall U-value and g-value of windows.
```python
def _apply_window_retrofit_to_building(self, building: Building, retrofit_params):
overall_u_value = retrofit_params.get('window_u_value')
g_value = retrofit_params.get('window_g_value')
```
Error Handling
RetrofitFactory includes various error prevention mechanisms:
- Building ID Validation: Logs missing retrofit data for buildings not found in the input.
- U-value Validation: Only applies if the new U-value is lower than the old one.
- Null Checks: Ensures that parameters like infiltration_reduction are not null.
- Type Validation: Checks for required attributes, such as thermal boundaries and openings.
Data Validation
1. Building ID Validation
```python
building_id = str(building.name)
if building_id in self._retrofit_data:
# Process building
else:
print(f"No retrofit data for building ID {building_id}")
```
2. U-value and Window Value Validation
```python
if new_u_value < old_u_value:
# Apply change
else:
print(f"New U-value {new_u_value} is not less than old U-value {old_u_value}")
if overall_u_value is not None and overall_u_value != 0:
# Apply change
```
Building Model Integration
RetrofitFactory relies on the city model to access thermal zones, boundaries, and construction properties of buildings. For example:
- Thermal Zone Access:
```python
for thermal_zone in building.thermal_zones_from_internal_zones:
thermal_archetype = thermal_zone.parent_internal_zone.thermal_archetype
```
- Construction Properties Access:
```python
construction_archetype = thermal_boundary._construction_archetype
construction_archetype.window_overall_u_value = overall_u_value
construction_archetype.window_g_value = g_value
```
Logging and Debugging
RetrofitFactory includes detailed logging for tracking the progress and results of retrofits:
- Logs retrofit application: print(f"Applying retrofits to building ID {building_id}")
- Logs property updates: print(f"Updated wall U-value to {wall_u_value} in building {building.name}")
- Logs missing data: print(f"No retrofit data for building ID {building_id}")
Performance Considerations
- Memory Efficiency: Directly modifies existing objects instead of creating new copies.
- Computational Efficiency: Only processes buildings with available retrofit data and skips unnecessary thermal boundaries.
Integration Requirements
To function correctly, the city model must provide:
- Unique building names convertible to strings.
- Buildings with thermal zones and boundaries that contain layers for construction retrofits.
- Access to thermal zone properties and boundary layers.

File diff suppressed because it is too large Load Diff

View File

@ -6,9 +6,11 @@ Output formats accepted:
* Function:
* nrel
* nrcan
* cerc
* eilat
* Usage:
* nrcan
* cerc
* comnet
* eilat

View File

@ -0,0 +1,244 @@
"""
Cerc construction catalog (Copy of Nrcan catalog)
Catlog Coder Mohamed Osman mohamed.osman@mail.concordia.ca
"""
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 CercCatalog(Catalog):
"""
Cerc catalog class copy of Cerc catalog (Copy of Nrcan catalog)
"""
def __init__(self, path):
_path_archetypes = Path(path / 'cerc_archetypes.json').resolve()
_path_constructions = Path(path / 'cerc_constructions.json').resolve()
with open(_path_archetypes, 'r', encoding='utf-8') as file:
self._archetypes = json.load(file)
with open(_path_constructions, 'r', encoding='utf-8') as file:
self._constructions = json.load(file)
self._catalog_windows = self._load_windows()
self._catalog_materials = self._load_materials()
self._catalog_constructions = self._load_constructions()
self._catalog_archetypes = self._load_archetypes()
# store the full catalog data model in self._content
self._content = Content(self._catalog_archetypes,
self._catalog_constructions,
self._catalog_materials,
self._catalog_windows)
def _load_windows(self):
_catalog_windows = []
windows = self._constructions['transparent_surfaces']
for window in windows:
name = list(window.keys())[0]
window_id = name
g_value = window[name]['shgc']
window_type = window[name]['type']
frame_ratio = window[name]['frame_ratio']
overall_u_value = window[name]['u_value']
_catalog_windows.append(Window(window_id, frame_ratio, g_value, overall_u_value, name, window_type))
return _catalog_windows
def _load_materials(self):
_catalog_materials = []
materials = self._constructions['materials']
for material in materials:
name = list(material.keys())[0]
material_id = name
no_mass = material[name]['no_mass']
thermal_resistance = None
conductivity = None
density = None
specific_heat = None
solar_absorptance = None
thermal_absorptance = None
visible_absorptance = None
if no_mass:
thermal_resistance = material[name]['thermal_resistance']
else:
solar_absorptance = material[name]['solar_absorptance']
thermal_absorptance = str(1 - float(material[name]['thermal_emittance']))
visible_absorptance = material[name]['visible_absorptance']
conductivity = material[name]['conductivity']
density = material[name]['density']
specific_heat = material[name]['specific_heat']
_material = Material(material_id,
name,
solar_absorptance,
thermal_absorptance,
visible_absorptance,
no_mass,
thermal_resistance,
conductivity,
density,
specific_heat)
_catalog_materials.append(_material)
return _catalog_materials
def _load_constructions(self):
_catalog_constructions = []
constructions = self._constructions['opaque_surfaces']
for construction in constructions:
name = list(construction.keys())[0]
construction_id = name
construction_type = ConstructionHelper().nrcan_surfaces_types_to_hub_types[construction[name]['type']]
layers = []
for layer in construction[name]['layers']:
layer_id = layer
layer_name = layer
material_id = layer
thickness = construction[name]['layers'][layer]
for material in self._catalog_materials:
if str(material_id) == str(material.id):
layers.append(Layer(layer_id, layer_name, material, thickness))
break
_catalog_constructions.append(Construction(construction_id, construction_type, name, layers))
return _catalog_constructions
def _load_archetypes(self):
_catalog_archetypes = []
archetypes = self._archetypes['archetypes']
for archetype in archetypes:
archetype_id = f'{archetype["function"]}_{archetype["period_of_construction"]}_{archetype["climate_zone"]}'
function = archetype['function']
name = archetype_id
climate_zone = archetype['climate_zone']
construction_period = archetype['period_of_construction']
average_storey_height = archetype['average_storey_height']
thermal_capacity = float(archetype['thermal_capacity']) * 1000
extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges']
infiltration_rate_for_ventilation_system_off = (
archetype['infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
)
infiltration_rate_for_ventilation_system_on = (
archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
)
infiltration_rate_area_for_ventilation_system_off = (
archetype['infiltration_rate_area_for_ventilation_system_off'] * 1
)
infiltration_rate_area_for_ventilation_system_on = (
archetype['infiltration_rate_area_for_ventilation_system_on'] * 1
)
archetype_constructions = []
for archetype_construction in archetype['constructions']:
archetype_construction_type = ConstructionHelper().nrcan_surfaces_types_to_hub_types[archetype_construction]
archetype_construction_name = archetype['constructions'][archetype_construction]['opaque_surface_name']
for construction in self._catalog_constructions:
if archetype_construction_type == construction.type and construction.name == archetype_construction_name:
_construction = None
_window = None
_window_ratio = None
if 'transparent_surface_name' in archetype['constructions'][archetype_construction].keys():
_window_ratio = archetype['constructions'][archetype_construction]['transparent_ratio']
_window_id = archetype['constructions'][archetype_construction]['transparent_surface_name']
for window in self._catalog_windows:
if _window_id == window.id:
_window = window
break
_construction = Construction(construction.id,
construction.type,
construction.name,
construction.layers,
_window_ratio,
_window)
archetype_constructions.append(_construction)
break
_catalog_archetypes.append(Archetype(archetype_id,
name,
function,
climate_zone,
construction_period,
archetype_constructions,
average_storey_height,
thermal_capacity,
extra_loses_due_to_thermal_bridges,
None,
infiltration_rate_for_ventilation_system_off,
infiltration_rate_for_ventilation_system_on,
infiltration_rate_area_for_ventilation_system_off,
infiltration_rate_area_for_ventilation_system_on))
return _catalog_archetypes
def names(self, category=None):
"""
Get the catalog elements names
:parm: optional category filter
"""
if category is None:
_names = {'archetypes': [], 'constructions': [], 'materials': [], 'windows': []}
for archetype in self._content.archetypes:
_names['archetypes'].append(archetype.name)
for construction in self._content.constructions:
_names['constructions'].append(construction.name)
for material in self._content.materials:
_names['materials'].append(material.name)
for window in self._content.windows:
_names['windows'].append(window.name)
else:
_names = {category: []}
if category.lower() == 'archetypes':
for archetype in self._content.archetypes:
_names[category].append(archetype.name)
elif category.lower() == 'constructions':
for construction in self._content.constructions:
_names[category].append(construction.name)
elif category.lower() == 'materials':
for material in self._content.materials:
_names[category].append(material.name)
elif category.lower() == 'windows':
for window in self._content.windows:
_names[category].append(window.name)
else:
raise ValueError(f'Unknown category [{category}]')
return _names
def entries(self, category=None):
"""
Get the catalog elements
:parm: optional category filter
"""
if category is None:
return self._content
if category.lower() == 'archetypes':
return self._content.archetypes
if category.lower() == 'constructions':
return self._content.constructions
if category.lower() == 'materials':
return self._content.materials
if category.lower() == 'windows':
return self._content.windows
raise ValueError(f'Unknown category [{category}]')
def get_entry(self, name):
"""
Get one catalog element by names
:parm: entry name
"""
for entry in self._content.archetypes:
if entry.name.lower() == name.lower():
return entry
for entry in self._content.constructions:
if entry.name.lower() == name.lower():
return entry
for entry in self._content.materials:
if entry.name.lower() == name.lower():
return entry
for entry in self._content.windows:
if entry.name.lower() == name.lower():
return entry
raise IndexError(f"{name} doesn't exists in the catalog")

View File

@ -22,6 +22,7 @@ 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()
@ -121,8 +122,14 @@ class EilatCatalog(Catalog):
construction_period = archetype['period_of_construction']
average_storey_height = archetype['average_storey_height']
extra_loses_due_to_thermal_bridges = archetype['extra_loses_due_thermal_bridges']
infiltration_rate_for_ventilation_system_off = archetype['infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_on = archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_off = archetype[
'infiltration_rate_for_ventilation_system_off'] / cte.HOUR_TO_SECONDS
infiltration_rate_for_ventilation_system_on = archetype[
'infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
infiltration_rate_area_for_ventilation_system_off = archetype[
'infiltration_rate_area_for_ventilation_system_off']
infiltration_rate_area_for_ventilation_system_on = archetype[
'infiltration_rate_area_for_ventilation_system_on']
archetype_constructions = []
for archetype_construction in archetype['constructions']:
@ -160,7 +167,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,
infiltration_rate_area_for_ventilation_system_off,
infiltration_rate_area_for_ventilation_system_on))
return _catalog_archetypes
def names(self, category=None):

View File

@ -128,6 +128,12 @@ class NrcanCatalog(Catalog):
infiltration_rate_for_ventilation_system_on = (
archetype['infiltration_rate_for_ventilation_system_on'] / cte.HOUR_TO_SECONDS
)
infiltration_rate_area_for_ventilation_system_off = (
archetype['infiltration_rate_area_for_ventilation_system_off'] * 1
)
infiltration_rate_area_for_ventilation_system_on = (
archetype['infiltration_rate_area_for_ventilation_system_on'] * 1
)
archetype_constructions = []
for archetype_construction in archetype['constructions']:
@ -153,7 +159,6 @@ class NrcanCatalog(Catalog):
_window)
archetype_constructions.append(_construction)
break
_catalog_archetypes.append(Archetype(archetype_id,
name,
function,
@ -165,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):

View File

@ -129,6 +129,12 @@ class NrelCatalog(Catalog):
infiltration_rate_for_ventilation_system_on = float(
archetype['infiltration_rate_for_ventilation_system_on']['#text']
) / cte.HOUR_TO_SECONDS
infiltration_rate_area_for_ventilation_system_off = float(
archetype['infiltration_rate_area_for_ventilation_system_on']['#text']
)
infiltration_rate_area_for_ventilation_system_on = float(
archetype['infiltration_rate_area_for_ventilation_system_on']['#text']
)
archetype_constructions = []
for archetype_construction in archetype['constructions']['construction']:
@ -162,7 +168,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,
infiltration_rate_area_for_ventilation_system_off,
infiltration_rate_area_for_ventilation_system_on))
return _catalog_archetypes
def names(self, category=None):

View File

@ -9,6 +9,8 @@ from pathlib import Path
from typing import TypeVar
from hub.catalog_factories.construction.nrcan_catalog import NrcanCatalog
from hub.catalog_factories.construction.cerc_catalog import CercCatalog
from hub.catalog_factories.construction.nrel_catalog import NrelCatalog
from hub.catalog_factories.construction.eilat_catalog import EilatCatalog
from hub.helpers.utils import validate_import_export_type
@ -40,6 +42,13 @@ class ConstructionCatalogFactory:
Retrieve NRCAN catalog
"""
return NrcanCatalog(self._path)
@property
def _cerc(self):
"""
Retrieve CERC catalog
"""
return CercCatalog(self._path)
@property
def _eilat(self):

View File

@ -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):
@ -133,6 +138,22 @@ class Archetype:
"""
return self._infiltration_rate_for_ventilation_system_on
@property
def infiltration_rate_area_for_ventilation_system_off(self):
"""
Get archetype infiltration rate for ventilation system off in m3/sm2
:return: float
"""
return self._infiltration_rate_area_for_ventilation_system_off
@property
def infiltration_rate_area_for_ventilation_system_on(self):
"""
Get archetype infiltration rate for ventilation system on in m3/sm2
:return: float
"""
return self._infiltration_rate_for_ventilation_system_on
def to_dictionary(self):
"""Class content to dictionary"""
_constructions = []
@ -149,6 +170,8 @@ class Archetype:
'indirect heated ratio': self.indirect_heated_ratio,
'infiltration rate for ventilation off [1/s]': self.infiltration_rate_for_ventilation_system_off,
'infiltration rate for ventilation on [1/s]': self.infiltration_rate_for_ventilation_system_on,
'infiltration rate area for ventilation off [m3/sm2]': self.infiltration_rate_area_for_ventilation_system_off,
'infiltration rate area for ventilation on [m3/sm2]': self.infiltration_rate_area_for_ventilation_system_on,
'constructions': _constructions
}
}

View File

@ -15,11 +15,20 @@ class Archetype:
"""
Archetype class
"""
def __init__(self, name, systems):
def __init__(self, name, systems, archetype_cluster_id=None):
self._cluster_id = archetype_cluster_id
self._name = name
self._systems = systems
@property
def cluster_id(self):
"""
Get id
:return: string
"""
return self._cluster_id
@property
def name(self):
"""
@ -43,8 +52,9 @@ class Archetype:
_systems.append(_system.to_dictionary())
content = {
'Archetype': {
'cluster_id': self.cluster_id,
'name': self.name,
'systems': _systems
}
}
}
return content

View File

@ -20,7 +20,7 @@ class GenerationSystem(ABC):
"""
def __init__(self, system_id, name, model_name=None, manufacturer=None, fuel_type=None,
distribution_systems=None, energy_storage_systems=None):
distribution_systems=None, energy_storage_systems=None, number_of_units=None):
self._system_id = system_id
self._name = name
self._model_name = model_name
@ -28,6 +28,7 @@ class GenerationSystem(ABC):
self._fuel_type = fuel_type
self._distribution_systems = distribution_systems
self._energy_storage_systems = energy_storage_systems
self._number_of_units = number_of_units
@property
def id(self):

View File

@ -17,8 +17,9 @@ class PvGenerationSystem(GenerationSystem):
def __init__(self, system_id, name, system_type, model_name=None, manufacturer=None, electricity_efficiency=None,
nominal_electricity_output=None, nominal_ambient_temperature=None, nominal_cell_temperature=None,
nominal_radiation=None, standard_test_condition_cell_temperature=None,
standard_test_condition_maximum_power=None, cell_temperature_coefficient=None, width=None, height=None,
distribution_systems=None, energy_storage_systems=None):
standard_test_condition_maximum_power=None, standard_test_condition_radiation=None,
cell_temperature_coefficient=None, width=None, height=None, distribution_systems=None,
energy_storage_systems=None):
super().__init__(system_id=system_id, name=name, model_name=model_name,
manufacturer=manufacturer, fuel_type='renewable', distribution_systems=distribution_systems,
energy_storage_systems=energy_storage_systems)
@ -30,6 +31,7 @@ class PvGenerationSystem(GenerationSystem):
self._nominal_radiation = nominal_radiation
self._standard_test_condition_cell_temperature = standard_test_condition_cell_temperature
self._standard_test_condition_maximum_power = standard_test_condition_maximum_power
self._standard_test_condition_radiation = standard_test_condition_radiation
self._cell_temperature_coefficient = cell_temperature_coefficient
self._width = width
self._height = height
@ -98,6 +100,15 @@ class PvGenerationSystem(GenerationSystem):
"""
return self._standard_test_condition_maximum_power
@property
def standard_test_condition_radiation(self):
"""
Get standard test condition cell temperature of PV panels in W/m2
:return: float
"""
return self._standard_test_condition_radiation
@property
def cell_temperature_coefficient(self):
"""
@ -143,6 +154,7 @@ class PvGenerationSystem(GenerationSystem):
'nominal radiation [W/m2]': self.nominal_radiation,
'standard test condition cell temperature [Celsius]': self.standard_test_condition_cell_temperature,
'standard test condition maximum power [W]': self.standard_test_condition_maximum_power,
'standard test condition radiation [W/m2]': self.standard_test_condition_radiation,
'cell temperature coefficient': self.cell_temperature_coefficient,
'width': self.width,
'height': self.height,

View File

@ -193,6 +193,7 @@ class MontrealFutureSystemCatalogue(Catalog):
nominal_radiation = pv['nominal_radiation']
standard_test_condition_cell_temperature = pv['standard_test_condition_cell_temperature']
standard_test_condition_maximum_power = pv['standard_test_condition_maximum_power']
standard_test_condition_radiation = pv['standard_test_condition_radiation']
cell_temperature_coefficient = pv['cell_temperature_coefficient']
width = pv['width']
height = pv['height']
@ -215,6 +216,7 @@ class MontrealFutureSystemCatalogue(Catalog):
standard_test_condition_cell_temperature=
standard_test_condition_cell_temperature,
standard_test_condition_maximum_power=standard_test_condition_maximum_power,
standard_test_condition_radiation=standard_test_condition_radiation,
cell_temperature_coefficient=cell_temperature_coefficient,
width=width,
height=height,
@ -379,6 +381,7 @@ class MontrealFutureSystemCatalogue(Catalog):
_system_archetypes = []
system_clusters = self._archetypes['EnergySystemCatalog']['system_archetypes']['system_archetype']
for system_cluster in system_clusters:
archetype_id = system_cluster['@cluster_id']
name = system_cluster['name']
systems = system_cluster['systems']['system_id']
integer_system_ids = [int(item) for item in systems]
@ -386,7 +389,7 @@ class MontrealFutureSystemCatalogue(Catalog):
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))
_system_archetypes.append(Archetype(archetype_cluster_id=archetype_id, name=name, systems=_systems))
return _system_archetypes
def _load_materials(self):

View File

@ -0,0 +1,220 @@
"""
NRCAN usage catalog
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez guillermo.gutierrezmorote@concordia.ca
Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
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 CercCatalog(Catalog):
"""
Cerc catalog class (copy of NrcanCatalog)
"""
def __init__(self, path):
self._schedules_path = Path(path / 'nrcan_schedules.json').resolve()
self._space_types_path = Path(path / 'nrcan_space_types.json').resolve()
self._space_compliance_path = Path(path / 'nrcan_space_compliance_2015.json').resolve()
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 = CercCatalog._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']
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 'FAN' in hvac_schedule_name:
hvac_schedule_name = hvac_schedule_name.replace('FAN', 'Fan')
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,
None,
None,
None,
occupancy_schedule)
lighting = Lighting(lighting_density,
lighting_convective_fraction,
lighting_radiative_fraction,
lighting_latent_fraction,
lighting_schedule)
appliances = Appliances(appliances_density,
appliances_convective_fraction,
appliances_radiative_fraction,
appliances_latent_fraction,
appliance_schedule)
thermal_control = ThermalControl(None,
None,
None,
hvac_availability,
heating_schedule,
cooling_schedule)
domestic_hot_water = DomesticHotWater(None,
domestic_hot_water_peak_flow,
domestic_hot_water_service_temperature,
domestic_hot_water_load_schedule)
hours_day = None
days_year = None
usages.append(Usage(usage_type,
hours_day,
days_year,
mechanical_air_change,
ventilation_rate,
occupancy,
lighting,
appliances,
thermal_control,
domestic_hot_water))
return usages
def names(self, category=None):
"""
Get the catalog elements names
:parm: for usage catalog category filter does nothing as there is only one category (usages)
"""
_names = {'usages': []}
for usage in self._content.usages:
_names['usages'].append(usage.name)
return _names
def entries(self, category=None):
"""
Get the catalog elements
:parm: for usage catalog category filter does nothing as there is only one category (usages)
"""
return self._content
def get_entry(self, name):
"""
Get one catalog element by names
:parm: entry name
"""
for usage in self._content.usages:
if usage.name.lower() == name.lower():
return usage
raise IndexError(f"{name} doesn't exists in the catalog")

View File

@ -10,6 +10,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.cerc_catalog import CercCatalog
from hub.catalog_factories.usage.eilat_catalog import EilatCatalog
from hub.helpers.utils import validate_import_export_type
@ -41,7 +42,15 @@ class UsageCatalogFactory:
"""
# nrcan retrieves the data directly from github
return NrcanCatalog(self._path)
@property
def _cerc(self):
"""
Retrieve cerc catalog
"""
# nrcan retrieves the data directly from github
return CercCatalog(self._path)
@property
def _eilat(self):
"""

View File

@ -92,7 +92,7 @@ class Building(CityObject):
logging.error('Building %s [%s] has an unexpected surface type %s.', self.name, self.aliases, surface.type)
self._domestic_hot_water_peak_load = None
self._fuel_consumption_breakdown = {}
self._pv_generation = {}
self._systems_archetype_cluster_id = None
@property
def shell(self) -> Polyhedron:
@ -880,8 +880,8 @@ class Building(CityObject):
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]
if storage_system.type_energy_stored == 'thermal' and storage_system.heating_coil_capacity is not None:
fuel_breakdown[cte.ELECTRICITY][f'{demand_type}'] += storage_system.heating_coil_energy_consumption[f'{demand_type}'][cte.YEAR][0]
#TODO: When simulation models of all energy system archetypes are created, this part can be removed
heating_fuels = []
dhw_fuels = []
@ -913,3 +913,19 @@ class Building(CityObject):
self._fuel_consumption_breakdown = fuel_breakdown
return self._fuel_consumption_breakdown
@property
def energy_systems_archetype_cluster_id(self):
"""
Get energy systems archetype id
:return: str
"""
return self._systems_archetype_cluster_id
@energy_systems_archetype_cluster_id.setter
def energy_systems_archetype_cluster_id(self, value):
"""
Set energy systems archetype id
:param value: str
"""
self._systems_archetype_cluster_id = value

View File

@ -157,6 +157,7 @@ class Surface:
if self._inclination is None:
self._inclination = np.arccos(self.perimeter_polygon.normal[2])
return self._inclination
@property
def type(self):
"""
@ -180,7 +181,7 @@ class Surface:
@property
def global_irradiance(self) -> dict:
"""
Get global irradiance on surface in J/m2
Get global irradiance on surface in W/m2
:return: dict
"""
return self._global_irradiance
@ -188,7 +189,7 @@ class Surface:
@global_irradiance.setter
def global_irradiance(self, value):
"""
Set global irradiance on surface in J/m2
Set global irradiance on surface in W/m2
:param value: dict
"""
self._global_irradiance = value
@ -390,7 +391,7 @@ class Surface:
@property
def global_irradiance_tilted(self) -> dict:
"""
Get global irradiance on a tilted surface in J/m2
Get global irradiance on a tilted surface in W/m2
:return: dict
"""
return self._global_irradiance_tilted
@ -398,7 +399,7 @@ class Surface:
@global_irradiance_tilted.setter
def global_irradiance_tilted(self, value):
"""
Set global irradiance on a tilted surface in J/m2
Set global irradiance on a tilted surface in W/m2
:param value: dict
"""
self._global_irradiance_tilted = value

View File

@ -20,6 +20,8 @@ class ThermalArchetype:
self._indirect_heated_ratio = None
self._infiltration_rate_for_ventilation_system_off = None
self._infiltration_rate_for_ventilation_system_on = None
self._infiltration_rate_area_for_ventilation_system_off = None
self._infiltration_rate_area_for_ventilation_system_on = None
@property
def constructions(self) -> [Construction]:
@ -132,3 +134,35 @@ class ThermalArchetype:
:param value: float
"""
self._infiltration_rate_for_ventilation_system_on = value
@property
def infiltration_rate_area_for_ventilation_system_off(self):
"""
Get infiltration rate for ventilation system off in l/s/m2
:return: float
"""
return self._infiltration_rate_area_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_area_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_area_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_area_for_ventilation_system_on = value

View File

@ -44,6 +44,8 @@ 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
@ -166,6 +168,24 @@ class ThermalZone:
self._infiltration_rate_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_for_ventilation_system_off
return self._infiltration_rate_system_off
@property
def infiltration_rate_area_system_on(self):
"""
Get thermal zone infiltration rate system on in air changes per second (1/s)
:return: None or float
"""
self._infiltration_rate_area_system_on = self._parent_internal_zone.thermal_archetype.infiltration_rate_area_for_ventilation_system_on
return self._infiltration_rate_area_system_on
@property
def infiltration_rate_area_system_off(self):
"""
Get thermal zone infiltration rate system off in air changes per second (1/s)
:return: None or float
"""
self._infiltration_rate_area_system_off = self._parent_internal_zone.thermal_archetype.infiltration_rate_area_for_ventilation_system_off
return self._infiltration_rate_area_system_off
@property
def volume(self):
"""

View File

@ -11,6 +11,7 @@ from abc import ABC
from typing import Union, List
from hub.city_model_structure.energy_systems.distribution_system import DistributionSystem
from hub.city_model_structure.energy_systems.energy_storage_system import EnergyStorageSystem
from hub.city_model_structure.energy_systems.thermal_storage_system import ThermalStorageSystem
from hub.city_model_structure.energy_systems.electrical_storage_system import ElectricalStorageSystem

View File

@ -24,7 +24,7 @@ class ThermalStorageSystem(EnergyStorageSystem):
self._maximum_operating_temperature = None
self._heating_coil_capacity = None
self._temperature = None
self._heating_coil_energy_consumption = None
self._heating_coil_energy_consumption = {}
@property
def volume(self):

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,8 @@
"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": "residential_1000_1980_BWh",
@ -42,6 +44,8 @@
"extra_loses_due_thermal_bridges": 0.1,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.31,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.002,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "dormitory_2011_3000_BWh",
@ -76,6 +80,8 @@
"extra_loses_due_thermal_bridges": 0.09,
"infiltration_rate_for_ventilation_system_on": 0,
"infiltration_rate_for_ventilation_system_off": 0.65,
"infiltration_rate_area_for_ventilation_system_on": 0,
"infiltration_rate_area_for_ventilation_system_off": 0.004,
"constructions": {
"OutdoorsWall": {
"opaque_surface_name": "hotel_employees_1981_2010_BWh",

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.5</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="2" building_type="medium office" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -44,6 +46,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="3" building_type="large office" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -67,6 +71,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="4" building_type="primary school" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -89,6 +95,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="5" building_type="secondary school" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -111,6 +119,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="6" building_type="stand-alone retail" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -133,6 +143,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="7" building_type="strip mall" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -155,6 +167,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="8" building_type="supermarket" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -177,6 +191,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="9" building_type="quick service restaurant" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -199,6 +215,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="10" building_type="full service restaurant" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -221,6 +239,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="11" building_type="small hotel" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -243,6 +263,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="12" building_type="large hotel" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -265,6 +287,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="13" building_type="hospital" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -287,6 +311,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="14" building_type="outpatient healthcare" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -309,6 +335,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="15" building_type="warehouse" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -331,6 +359,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="16" building_type="midrise apartment" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -353,6 +383,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="17" building_type="high-rise apartment" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -375,6 +407,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="18" building_type="small office" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -397,6 +431,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.1</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="19" building_type="medium office" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -419,6 +455,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.1</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="20" building_type="large office" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -441,6 +479,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.1</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="21" building_type="primary school" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -463,6 +503,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.1</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="22" building_type="secondary school" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -485,6 +527,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.1</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="23" building_type="stand-alone retail" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -507,6 +551,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.1</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="24" building_type="strip mall" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -529,6 +575,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.1</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="25" building_type="supermarket" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -551,6 +599,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="26" building_type="quick service restaurant" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -573,6 +623,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="27" building_type="full service restaurant" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -595,6 +647,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="28" building_type="small hotel" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -617,6 +671,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="29" building_type="large hotel" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -639,6 +695,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="30" building_type="hospital" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -661,6 +719,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="31" building_type="outpatient healthcare" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -683,6 +743,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="32" building_type="warehouse" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -705,6 +767,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="33" building_type="midrise apartment" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -727,6 +791,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="34" building_type="high-rise apartment" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -749,6 +815,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="35" building_type="residential" reference_standard="ASHRAE 189.1_2009" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -771,6 +839,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="36" building_type="residential" reference_standard="ASHRAE 90.1_2004" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -793,6 +863,8 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.50</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.003</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
<archetype id="37" building_type="industry" reference_standard="non_standard_dompark" climate_zone="ASHRAE_2004:4A">
<constructions>
@ -815,5 +887,7 @@
<indirect_heated_ratio units="-">0.15</indirect_heated_ratio>
<infiltration_rate_for_ventilation_system_off units="ACH">0.10</infiltration_rate_for_ventilation_system_off>
<infiltration_rate_for_ventilation_system_on units="ACH">0</infiltration_rate_for_ventilation_system_on>
<infiltration_rate_area_for_ventilation_system_off units="ACH">0.0005</infiltration_rate_area_for_ventilation_system_off>
<infiltration_rate_area_for_ventilation_system_on units="ACH">0</infiltration_rate_area_for_ventilation_system_on>
</archetype>
</archetypes>

View File

@ -22,7 +22,7 @@
</equipment>
<equipment id="5" type="cooler" fuel_type="electricity">
<name>Air cooled DX with external condenser</name>
<cooling_efficiency>3.23</cooling_efficiency>
<cooling_efficiency>2.5</cooling_efficiency>
<storage>false</storage>
</equipment>
<equipment id="6" type="electricity generator" fuel_type="renewable">
@ -32,8 +32,8 @@
</equipment>
<equipment id="7" type="heat pump" fuel_type="electricity">
<name>Heat Pump</name>
<heating_efficiency>2.79</heating_efficiency>
<cooling_efficiency>3.23</cooling_efficiency>
<heating_efficiency>2.5</heating_efficiency>
<cooling_efficiency>3</cooling_efficiency>
<storage>false</storage>
</equipment>
</generation_equipments>
@ -198,7 +198,7 @@
<equipments>
<generation_id>3</generation_id>
<distribution_id>8</distribution_id>
g </equipments>
</equipments>
</system>
<system id="5">
<name>Single zone packaged rooftop unit with electrical resistance furnace and baseboards and fuel boiler for acs</name>

View File

@ -911,7 +911,7 @@
<nominal_cooling_output/>
<minimum_cooling_output/>
<maximum_cooling_output/>
<cooling_efficiency>4.5</cooling_efficiency>
<cooling_efficiency>4</cooling_efficiency>
<electricity_efficiency/>
<source_temperature/>
<source_mass_flow/>
@ -1411,7 +1411,7 @@
</demands>
<components>
<generation_id>23</generation_id>
<generation_id>16</generation_id>
<generation_id>17</generation_id>
</components>
</system>
<system>

View File

@ -392,9 +392,9 @@ class Idf:
thermostat = self._add_thermostat(thermal_zone)
self._idf.newidfobject(self._IDEAL_LOAD_AIR_SYSTEM,
Zone_Name=zone_name,
System_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
Heating_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
Cooling_Availability_Schedule_Name=f'HVAC AVAIL SCHEDULES {thermal_zone.usage_name}',
System_Availability_Schedule_Name=f'Thermostat_availability schedules {thermal_zone.usage_name}',
Heating_Availability_Schedule_Name=f'Thermostat_availability schedules {thermal_zone.usage_name}',
Cooling_Availability_Schedule_Name=f'Thermostat_availability schedules {thermal_zone.usage_name}',
Template_Thermostat_Name=thermostat.Name)
def _add_occupancy(self, thermal_zone, zone_name):
@ -454,7 +454,7 @@ class Idf:
)
def _add_infiltration(self, thermal_zone, zone_name):
schedule = f'Infiltration schedules {thermal_zone.usage_name}'
schedule = f'INF_CONST schedules {thermal_zone.usage_name}'
_infiltration = thermal_zone.infiltration_rate_system_off * cte.HOUR_TO_SECONDS
self._idf.newidfobject(self._INFILTRATION,
Name=f'{zone_name}_infiltration',
@ -464,6 +464,17 @@ class Idf:
Air_Changes_per_Hour=_infiltration
)
def _add_infiltration_surface(self, thermal_zone, zone_name):
schedule = f'INF_CONST schedules {thermal_zone.usage_name}'
_infiltration = thermal_zone.infiltration_rate_area_system_off*cte.INFILTRATION_75PA_TO_4PA
self._idf.newidfobject(self._INFILTRATION,
Name=f'{zone_name}_infiltration',
Zone_or_ZoneList_or_Space_or_SpaceList_Name=zone_name,
Schedule_Name=schedule,
Design_Flow_Rate_Calculation_Method='Flow/ExteriorWallArea',
Flow_Rate_per_Exterior_Surface_Area=_infiltration
)
def _add_ventilation(self, thermal_zone, zone_name):
schedule = f'Ventilation schedules {thermal_zone.usage_name}'
_air_change = thermal_zone.mechanical_air_change * cte.HOUR_TO_SECONDS
@ -549,9 +560,12 @@ class Idf:
self._add_schedules(usage, 'DHW_prof', thermal_zone.domestic_hot_water.schedules)
_new_schedules = self._create_yearly_values_schedules('cold_temp', building.cold_water_temperature[cte.HOUR])
self._add_schedules(usage, 'cold_temp', _new_schedules)
_new_schedules = self._create_constant_value_schedules('DHW_temp', service_temperature)
self._add_schedules(usage, 'DHW_temp', _new_schedules)
_new_schedules = self._create_constant_value_schedules('INF_CONST', 1)
self._add_schedules(usage, 'INF_CONST', _new_schedules)
_new_schedules = self._create_constant_value_schedules('Thermostat_availability', 1)
self._add_schedules(usage, 'Thermostat_availability', _new_schedules)
_occ = thermal_zone.occupancy
if _occ.occupancy_density == 0:
_total_heat = 0
@ -562,7 +576,7 @@ class Idf:
self._add_schedules(usage, 'Activity Level', _new_schedules)
self._add_zone(thermal_zone, building.name)
self._add_heating_system(thermal_zone, building.name)
self._add_infiltration(thermal_zone, building.name)
self._add_infiltration_surface(thermal_zone, building.name)
self._add_ventilation(thermal_zone, building.name)
self._add_occupancy(thermal_zone, building.name)
self._add_lighting(thermal_zone, building.name)
@ -611,6 +625,18 @@ class Idf:
Reporting_Frequency="Hourly",
)
self._idf.newidfobject(
"OUTPUT:VARIABLE",
Variable_Name="Zone Air Temperature",
Reporting_Frequency="Hourly",
)
self._idf.newidfobject(
"OUTPUT:VARIABLE",
Variable_Name="Zone Air Relative Humidity",
Reporting_Frequency="Hourly",
)
# post-process to erase windows associated to adiabatic walls
windows_list = []
for window in self._idf.idfobjects[self._WINDOW]:

View File

@ -1,4 +1,4 @@
!IDD_Version 23.2.0
!IDD_Version 24.1.0
!IDD_BUILD 7636e6b3e9
! ***************************************************************************
! This file is the Input Data Dictionary (IDD) for EnergyPlus.
@ -30002,10 +30002,10 @@ People,
A7 , \field Mean Radiant Temperature Calculation Type
\note optional (only required for thermal comfort runs)
\type choice
\key ZoneAveraged
\key EnclosureAveraged
\key SurfaceWeighted
\key AngleFactor
\default ZoneAveraged
\default EnclosureAveraged
A8 , \field Surface Name/Angle Factor List Name
\type object-list
\object-list AllHeatTranAngFacNames

View File

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

View File

@ -24,6 +24,8 @@ BTU_H_TO_WATTS = 0.29307107
KILO_WATTS_HOUR_TO_JULES = 3600000
WATTS_HOUR_TO_JULES = 3600
GALLONS_TO_QUBIC_METERS = 0.0037854117954011185
INFILTRATION_75PA_TO_4PA = (4/75)**0.65
# time
SECOND = 'second'
@ -310,7 +312,8 @@ LATENT = 'Latent'
LITHIUMION = 'Lithium Ion'
NICD = 'NiCd'
LEADACID = 'Lead Acid'
THERMAL = 'thermal'
ELECTRICAL = 'electrical'
# Geometry
EPSILON = 0.0000001

View File

@ -0,0 +1,86 @@
"""
Dictionaries module for hub function to nrcan construction function
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import hub.helpers.constants as cte
class HubFunctionToCercConstructionFunction:
"""
Hub function to cerc construction function class (copy of HubFunctionToNrcanConstructionFunction)
"""
def __init__(self):
self._dictionary = {
cte.RESIDENTIAL: 'MURB_MidRiseApartment',
cte.SINGLE_FAMILY_HOUSE: 'SingleFamilyHouse',
cte.MULTI_FAMILY_HOUSE: 'HighriseApartment',
cte.ROW_HOUSE: 'MidriseApartment',
cte.MID_RISE_APARTMENT: 'MURB_MidRiseApartment',
cte.HIGH_RISE_APARTMENT: 'MURB_HighRiseApartment',
cte.OFFICE_AND_ADMINISTRATION: 'MediumOffice',
cte.SMALL_OFFICE: 'SmallOffice',
cte.MEDIUM_OFFICE: 'MediumOffice',
cte.LARGE_OFFICE: 'LargeOffice',
cte.COURTHOUSE: 'MediumOffice',
cte.FIRE_STATION: 'n/a',
cte.PENITENTIARY: 'LargeHotel',
cte.POLICE_STATION: 'n/a',
cte.POST_OFFICE: 'MediumOffice',
cte.LIBRARY: 'MediumOffice',
cte.EDUCATION: 'SecondarySchool',
cte.PRIMARY_SCHOOL: 'PrimarySchool',
cte.PRIMARY_SCHOOL_WITH_SHOWER: 'PrimarySchool',
cte.SECONDARY_SCHOOL: 'SecondarySchool',
cte.UNIVERSITY: 'SecondarySchool',
cte.LABORATORY_AND_RESEARCH_CENTER: 'SecondarySchool',
cte.STAND_ALONE_RETAIL: 'RetailStandalone',
cte.HOSPITAL: 'Hospital',
cte.OUT_PATIENT_HEALTH_CARE: 'Outpatient',
cte.HEALTH_CARE: 'Outpatient',
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'SmallHotel',
cte.COMMERCIAL: 'RetailStripmall',
cte.STRIP_MALL: 'RetailStripmall',
cte.SUPERMARKET: 'RetailStripmall',
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'RetailStandalone',
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'RetailStandalone',
cte.RESTAURANT: 'FullServiceRestaurant',
cte.QUICK_SERVICE_RESTAURANT: 'QuickServiceRestaurant',
cte.FULL_SERVICE_RESTAURANT: 'FullServiceRestaurant',
cte.HOTEL: 'SmallHotel',
cte.HOTEL_MEDIUM_CLASS: 'SmallHotel',
cte.SMALL_HOTEL: 'SmallHotel',
cte.LARGE_HOTEL: 'LargeHotel',
cte.DORMITORY: 'SmallHotel',
cte.EVENT_LOCATION: 'n/a',
cte.CONVENTION_CENTER: 'n/a',
cte.HALL: 'n/a',
cte.GREEN_HOUSE: 'n/a',
cte.INDUSTRY: 'n/a',
cte.WORKSHOP: 'n/a',
cte.WAREHOUSE: 'Warehouse',
cte.WAREHOUSE_REFRIGERATED: 'Warehouse',
cte.SPORTS_LOCATION: 'n/a',
cte.SPORTS_ARENA: 'n/a',
cte.GYMNASIUM: 'n/a',
cte.MOTION_PICTURE_THEATRE: 'n/a',
cte.MUSEUM: 'n/a',
cte.PERFORMING_ARTS_THEATRE: 'n/a',
cte.TRANSPORTATION: 'n/a',
cte.AUTOMOTIVE_FACILITY: 'n/a',
cte.PARKING_GARAGE: 'n/a',
cte.RELIGIOUS: 'n/a',
cte.NON_HEATED: 'n/a',
cte.DATACENTER: 'n/a',
cte.FARM: 'n/a'
}
@property
def dictionary(self) -> dict:
"""
Get the dictionary
:return: {}
"""
return self._dictionary

View File

@ -0,0 +1,87 @@
"""
Dictionaries module for hub usage to NRCAN usage
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import hub.helpers.constants as cte
class HubUsageToCercUsage:
"""
Hub usage to cerc usage class (copy of HubUsageToNrcanUsage)
"""
def __init__(self):
self._dictionary = {
cte.RESIDENTIAL: 'Multi-unit residential building',
cte.SINGLE_FAMILY_HOUSE: 'Multi-unit residential building',
cte.MULTI_FAMILY_HOUSE: 'Multi-unit residential building',
cte.ROW_HOUSE: 'Multi-unit residential building',
cte.MID_RISE_APARTMENT: 'Multi-unit residential building',
cte.HIGH_RISE_APARTMENT: 'Multi-unit residential building',
cte.OFFICE_AND_ADMINISTRATION: 'Office',
cte.SMALL_OFFICE: 'Office',
cte.MEDIUM_OFFICE: 'Office',
cte.LARGE_OFFICE: 'Office',
cte.COURTHOUSE: 'Courthouse',
cte.FIRE_STATION: 'Fire station',
cte.PENITENTIARY: 'Penitentiary',
cte.POLICE_STATION: 'Police station',
cte.POST_OFFICE: 'Post office',
cte.LIBRARY: 'Library',
cte.EDUCATION: 'School/university',
cte.PRIMARY_SCHOOL: 'School/university',
cte.PRIMARY_SCHOOL_WITH_SHOWER: 'School/university',
cte.SECONDARY_SCHOOL: 'School/university',
cte.UNIVERSITY: 'School/university',
cte.LABORATORY_AND_RESEARCH_CENTER: 'School/university',
cte.STAND_ALONE_RETAIL: 'Retail area',
cte.HOSPITAL: 'Hospital',
cte.OUT_PATIENT_HEALTH_CARE: 'Health care clinic',
cte.HEALTH_CARE: 'Health care clinic',
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'Health care clinic',
cte.COMMERCIAL: 'Retail area',
cte.STRIP_MALL: 'Retail area',
cte.SUPERMARKET: 'Retail area',
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'Retail area',
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'Retail area',
cte.RESTAURANT: 'Dining - bar lounge/leisure',
cte.QUICK_SERVICE_RESTAURANT: 'Dining - cafeteria/fast food',
cte.FULL_SERVICE_RESTAURANT: 'Dining - bar lounge/leisure',
cte.HOTEL: 'Hotel/Motel',
cte.HOTEL_MEDIUM_CLASS: 'Hotel/Motel',
cte.SMALL_HOTEL: 'Hotel/Motel',
cte.LARGE_HOTEL: 'Hotel/Motel',
cte.DORMITORY: 'Dormitory',
cte.EVENT_LOCATION: 'Convention centre',
cte.CONVENTION_CENTER: 'Convention centre',
cte.HALL: 'Town hall',
cte.GREEN_HOUSE: 'n/a',
cte.INDUSTRY: 'Manufacturing facility',
cte.WORKSHOP: 'Workshop',
cte.WAREHOUSE: 'Warehouse',
cte.WAREHOUSE_REFRIGERATED: 'Warehouse',
cte.SPORTS_LOCATION: 'Exercise centre',
cte.SPORTS_ARENA: 'Sports arena',
cte.GYMNASIUM: 'Gymnasium',
cte.MOTION_PICTURE_THEATRE: 'Motion picture theatre',
cte.MUSEUM: 'Museum',
cte.PERFORMING_ARTS_THEATRE: 'Performing arts theatre',
cte.TRANSPORTATION: 'Transportation facility',
cte.AUTOMOTIVE_FACILITY: 'Automotive facility',
cte.PARKING_GARAGE: 'Storage garage',
cte.RELIGIOUS: 'Religious building',
cte.NON_HEATED: 'n/a',
cte.DATACENTER: 'n/a',
cte.FARM: 'n/a'
}
@property
def dictionary(self) -> dict:
"""
Get the dictionary
:return: {}
"""
return self._dictionary

View File

@ -33,6 +33,7 @@ class MontrealFunctionToHubFunction:
'6911': cte.CONVENTION_CENTER,
'9510': cte.RESIDENTIAL,
'1990': cte.MID_RISE_APARTMENT,
'2100': cte.HIGH_RISE_APARTMENT,
'1923': cte.NON_HEATED,
'7222': cte.SPORTS_LOCATION,
'5002': cte.STRIP_MALL,

View File

@ -18,7 +18,7 @@ class MontrealGenerationSystemToHubEnergyGenerationSystem:
'furnace': cte.BASEBOARD,
'cooler': cte.CHILLER,
'electricity generator': cte.ELECTRICITY_GENERATOR,
'PV system': cte.PHOTOVOLTAIC,
'photovoltaic': cte.PHOTOVOLTAIC,
'heat pump': cte.HEAT_PUMP
}

View File

@ -13,11 +13,15 @@ from hub.helpers.data.alkis_function_to_hub_function import AlkisFunctionToHubFu
from hub.helpers.data.pluto_function_to_hub_function import PlutoFunctionToHubFunction
from hub.helpers.data.hub_function_to_nrel_construction_function import HubFunctionToNrelConstructionFunction
from hub.helpers.data.hub_function_to_nrcan_construction_function import HubFunctionToNrcanConstructionFunction
from hub.helpers.data.hub_function_to_cerc_construction_function import HubFunctionToCercConstructionFunction
from hub.helpers.data.hub_function_to_eilat_construction_function import HubFunctionToEilatConstructionFunction
from hub.helpers.data.hub_usage_to_comnet_usage import HubUsageToComnetUsage
from hub.helpers.data.hub_usage_to_hft_usage import HubUsageToHftUsage
from hub.helpers.data.hub_usage_to_nrcan_usage import HubUsageToNrcanUsage
from hub.helpers.data.hub_usage_to_eilat_usage import HubUsageToEilatUsage
from hub.helpers.data.hub_usage_to_cerc_usage import HubUsageToCercUsage
from hub.helpers.data.montreal_system_to_hub_energy_generation_system import MontrealSystemToHubEnergyGenerationSystem
from hub.helpers.data.montreal_generation_system_to_hub_energy_generation_system import MontrealGenerationSystemToHubEnergyGenerationSystem
from hub.helpers.data.montreal_demand_type_to_hub_energy_demand_type import MontrealDemandTypeToHubEnergyDemandType
@ -56,7 +60,13 @@ class Dictionaries:
:return: dict
"""
return HubUsageToNrcanUsage().dictionary
@property
def hub_usage_to_cerc_usage(self) -> dict:
"""
Get hub usage to CERC usage, transformation dictionary
:return: dict
"""
return HubUsageToCercUsage().dictionary
@property
def hub_usage_to_eilat_usage(self) -> dict:
"""
@ -80,7 +90,13 @@ class Dictionaries:
:return: dict
"""
return HubFunctionToEilatConstructionFunction().dictionary
@property
def hub_function_to_cerc_construction_function(self) -> dict:
"""
Get hub function to Cerc construction function, transformation dictionary (copy of HubFunctionToNrcanConstructionFunction)
:return: dict
"""
return HubFunctionToCercConstructionFunction().dictionary
@property
def hub_function_to_nrel_construction_function(self) -> dict:
"""

View File

@ -0,0 +1,109 @@
"""
CercPhysicsParameters import the construction and material information defined by Cerc
this is a copy of NrcanPhysicsParameters.py with the necessary changes to adapt it to the Cerc catalog
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import logging
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
from hub.city_model_structure.building_demand.thermal_archetype import ThermalArchetype
from hub.city_model_structure.building_demand.construction import Construction
from hub.city_model_structure.building_demand.layer import Layer
from hub.helpers.dictionaries import Dictionaries
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
class CercPhysicsParameters:
"""
CercPhysicsParameters class
"""
def __init__(self, city, divide_in_storeys=False):
self._city = city
self._divide_in_storeys = divide_in_storeys
self._climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
def enrich_buildings(self):
"""
Returns the city with the construction parameters assigned to the buildings
"""
city = self._city
cerc_catalog = ConstructionCatalogFactory('cerc').catalog
for building in city.buildings:
if building.function not in Dictionaries().hub_function_to_cerc_construction_function:
logging.error('Building %s has an unknown building function %s', building.name, building.function)
continue
function = Dictionaries().hub_function_to_cerc_construction_function[building.function]
try:
archetype = self._search_archetype(cerc_catalog, function, building.year_of_construction, self._climate_zone)
except KeyError:
logging.error('Building %s has unknown construction archetype for building function: %s '
'[%s], building year of construction: %s and climate zone %s', building.name, function,
building.function, building.year_of_construction, self._climate_zone)
continue
thermal_archetype = ThermalArchetype()
self._assign_values(thermal_archetype, archetype)
for internal_zone in building.internal_zones:
internal_zone.thermal_archetype = thermal_archetype
@staticmethod
def _search_archetype(cerc_catalog, function, year_of_construction, climate_zone):
cerc_archetypes = cerc_catalog.entries('archetypes')
for building_archetype in cerc_archetypes:
construction_period_limits = building_archetype.construction_period.split('_')
if int(construction_period_limits[0]) <= int(year_of_construction) <= int(construction_period_limits[1]):
if str(function) == str(building_archetype.function) and climate_zone == str(building_archetype.climate_zone):
return building_archetype
raise KeyError('archetype not found')
@staticmethod
def _assign_values(thermal_archetype, catalog_archetype):
thermal_archetype.average_storey_height = catalog_archetype.average_storey_height
thermal_archetype.extra_loses_due_to_thermal_bridges = catalog_archetype.extra_loses_due_to_thermal_bridges
thermal_archetype.thermal_capacity = catalog_archetype.thermal_capacity
thermal_archetype.indirect_heated_ratio = 0
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
thermal_archetype.infiltration_rate_area_for_ventilation_system_on = catalog_archetype.infiltration_rate_area_for_ventilation_system_on
thermal_archetype.infiltration_rate_area_for_ventilation_system_off = catalog_archetype.infiltration_rate_area_for_ventilation_system_off
_constructions = []
for catalog_construction in catalog_archetype.constructions:
construction = Construction()
construction.type = catalog_construction.type
construction.name = catalog_construction.name
if catalog_construction.window_ratio is not None:
for _orientation in catalog_construction.window_ratio:
if catalog_construction.window_ratio[_orientation] is None:
catalog_construction.window_ratio[_orientation] = 0
construction.window_ratio = catalog_construction.window_ratio
_layers = []
for layer_archetype in catalog_construction.layers:
layer = Layer()
layer.thickness = layer_archetype.thickness
archetype_material = layer_archetype.material
layer.material_name = archetype_material.name
layer.no_mass = archetype_material.no_mass
if archetype_material.no_mass:
layer.thermal_resistance = archetype_material.thermal_resistance
else:
layer.density = archetype_material.density
layer.conductivity = archetype_material.conductivity
layer.specific_heat = archetype_material.specific_heat
layer.solar_absorptance = archetype_material.solar_absorptance
layer.thermal_absorptance = archetype_material.thermal_absorptance
layer.visible_absorptance = archetype_material.visible_absorptance
_layers.append(layer)
construction.layers = _layers
if catalog_construction.window is not None:
window_archetype = catalog_construction.window
construction.window_frame_ratio = window_archetype.frame_ratio
construction.window_g_value = window_archetype.g_value
construction.window_overall_u_value = window_archetype.overall_u_value
_constructions.append(construction)
thermal_archetype.constructions = _constructions

View File

@ -66,6 +66,8 @@ class EilatPhysicsParameters:
thermal_archetype.indirect_heated_ratio = 0
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
thermal_archetype.infiltration_rate_area_for_ventilation_system_on = catalog_archetype.infiltration_rate_area_for_ventilation_system_on
thermal_archetype.infiltration_rate_area_for_ventilation_system_off = catalog_archetype.infiltration_rate_area_for_ventilation_system_off
effective_thermal_capacity = 0
_constructions = []
for catalog_construction in catalog_archetype.constructions:

View File

@ -3,6 +3,7 @@ NrcanPhysicsParameters import the construction and material information defined
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Project Collaborator Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import logging
@ -32,10 +33,21 @@ 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:
logging.error('Building %s has an unknown building function %s', building.name, building.function)
main_function = None
functions = building.function.split('_')
if len(functions) > 1:
maximum_percentage = 0
for function in functions:
percentage_and_function = function.split('-')
if float(percentage_and_function[0]) > maximum_percentage:
maximum_percentage = float(percentage_and_function[0])
main_function = percentage_and_function[-1]
else:
main_function = functions[-1]
if main_function not in Dictionaries().hub_function_to_nrcan_construction_function:
logging.error('Building %s has an unknown building function %s', building.name, main_function)
continue
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
function = Dictionaries().hub_function_to_nrcan_construction_function[main_function]
try:
archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone)
@ -67,6 +79,9 @@ class NrcanPhysicsParameters:
thermal_archetype.indirect_heated_ratio = 0
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
thermal_archetype.infiltration_rate_area_for_ventilation_system_on = catalog_archetype.infiltration_rate_area_for_ventilation_system_on
thermal_archetype.infiltration_rate_area_for_ventilation_system_off = catalog_archetype.infiltration_rate_area_for_ventilation_system_off
_constructions = []
for catalog_construction in catalog_archetype.constructions:
construction = Construction()

View File

@ -69,6 +69,8 @@ class NrelPhysicsParameters:
thermal_archetype.indirect_heated_ratio = catalog_archetype.indirect_heated_ratio
thermal_archetype.infiltration_rate_for_ventilation_system_on = catalog_archetype.infiltration_rate_for_ventilation_system_on
thermal_archetype.infiltration_rate_for_ventilation_system_off = catalog_archetype.infiltration_rate_for_ventilation_system_off
thermal_archetype.infiltration_rate_area_for_ventilation_system_on = catalog_archetype.infiltration_rate_area_for_ventilation_system_on
thermal_archetype.infiltration_rate_area_for_ventilation_system_off = catalog_archetype.infiltration_rate_area_for_ventilation_system_off
_constructions = []
for catalog_construction in catalog_archetype.constructions:
construction = Construction()

View File

@ -10,6 +10,8 @@ from hub.helpers.utils import validate_import_export_type
from hub.imports.construction.nrcan_physics_parameters import NrcanPhysicsParameters
from hub.imports.construction.nrel_physics_parameters import NrelPhysicsParameters
from hub.imports.construction.eilat_physics_parameters import EilatPhysicsParameters
from hub.imports.construction.cerc_physics_parameters import CercPhysicsParameters
class ConstructionFactory:
@ -38,6 +40,15 @@ class ConstructionFactory:
self._city.level_of_detail.construction = 2
for building in self._city.buildings:
building.level_of_detail.construction = 2
def _cerc(self):
"""
Enrich the city by using CERC information
"""
CercPhysicsParameters(self._city).enrich_buildings()
self._city.level_of_detail.construction = 2
for building in self._city.buildings:
building.level_of_detail.construction = 2
def _eilat(self):
"""

View File

@ -136,14 +136,14 @@ class MontrealCustomEnergySystemParameters:
_distribution_system.distribution_consumption_variable_flow = \
archetype_distribution_system.distribution_consumption_variable_flow
_distribution_system.heat_losses = archetype_distribution_system.heat_losses
_emission_system = None
_generic_emission_system = None
if archetype_distribution_system.emission_systems is not None:
_emission_systems = []
for emission_system in archetype_distribution_system.emission_systems:
_emission_system = EmissionSystem()
_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_emission_system)
_distribution_system.emission_systems = _emission_systems
_generic_emission_system = EmissionSystem()
_generic_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_generic_emission_system)
_distribution_system.emission_systems = _emission_systems
_distribution_systems.append(_distribution_system)
return _distribution_systems

View File

@ -43,6 +43,7 @@ class MontrealFutureEnergySystemParameters:
archetype_name = building.energy_systems_archetype_name
try:
archetype = self._search_archetypes(montreal_custom_catalog, archetype_name)
building.energy_systems_archetype_cluster_id = archetype.cluster_id
except KeyError:
logging.error('Building %s has unknown energy system archetype for system name %s', building.name,
archetype_name)
@ -87,12 +88,12 @@ class MontrealFutureEnergySystemParameters:
archetype_generation_systems = archetype_system.generation_systems
if archetype_generation_systems is not None:
for archetype_generation_system in archetype_system.generation_systems:
if archetype_generation_system.system_type == 'Photovoltaic':
if archetype_generation_system.system_type == 'photovoltaic':
_generation_system = PvGenerationSystem()
_generation_system.name = archetype_generation_system.name
_generation_system.model_name = archetype_generation_system.model_name
_generation_system.manufacturer = archetype_generation_system.manufacturer
_type = 'PV system'
_type = archetype_generation_system.system_type
_generation_system.system_type = Dictionaries().montreal_generation_system_to_hub_energy_generation_system[_type]
_fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type]
_generation_system.fuel_type = _fuel_type
@ -103,15 +104,21 @@ class MontrealFutureEnergySystemParameters:
_generation_system.nominal_radiation = archetype_generation_system.nominal_radiation
_generation_system.standard_test_condition_cell_temperature = archetype_generation_system.standard_test_condition_cell_temperature
_generation_system.standard_test_condition_maximum_power = archetype_generation_system.standard_test_condition_maximum_power
_generation_system.standard_test_condition_radiation = archetype_generation_system.standard_test_condition_radiation
_generation_system.cell_temperature_coefficient = archetype_generation_system.cell_temperature_coefficient
_generation_system.width = archetype_generation_system.width
_generation_system.height = archetype_generation_system.height
_generation_system.tilt_angle = self._city.latitude
_generic_storage_system = None
if archetype_generation_system.energy_storage_systems is not None:
_generic_storage_system = ElectricalStorageSystem()
_generic_storage_system.type_energy_stored = 'electrical'
_generation_system.energy_storage_systems = [_generic_storage_system]
_storage_systems = []
for storage_system in archetype_generation_system.energy_storage_systems:
if storage_system.type_energy_stored == 'electrical':
_generic_storage_system = ElectricalStorageSystem()
_generic_storage_system.type_energy_stored = 'electrical'
_storage_systems.append(_generic_storage_system)
_generation_system.energy_storage_systems = _storage_systems
else:
_generation_system = NonPvGenerationSystem()
_generation_system.name = archetype_generation_system.name
@ -119,7 +126,7 @@ class MontrealFutureEnergySystemParameters:
_generation_system.manufacturer = archetype_generation_system.manufacturer
_type = archetype_generation_system.system_type
_generation_system.system_type = Dictionaries().montreal_generation_system_to_hub_energy_generation_system[_type]
_fuel_type = Dictionaries().north_america_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type]
_fuel_type = Dictionaries().montreal_custom_fuel_to_hub_fuel[archetype_generation_system.fuel_type]
_generation_system.fuel_type = _fuel_type
_generation_system.nominal_heat_output = archetype_generation_system.nominal_heat_output
_generation_system.nominal_cooling_output = archetype_generation_system.nominal_cooling_output
@ -185,14 +192,14 @@ class MontrealFutureEnergySystemParameters:
_distribution_system.distribution_consumption_variable_flow = \
archetype_distribution_system.distribution_consumption_variable_flow
_distribution_system.heat_losses = archetype_distribution_system.heat_losses
_emission_system = None
_generic_emission_system = None
if archetype_distribution_system.emission_systems is not None:
_emission_systems = []
for emission_system in archetype_distribution_system.emission_systems:
_emission_system = EmissionSystem()
_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_emission_system)
_distribution_system.emission_systems = _emission_systems
_generic_emission_system = EmissionSystem()
_generic_emission_system.parasitic_energy_consumption = emission_system.parasitic_energy_consumption
_emission_systems.append(_generic_emission_system)
_distribution_system.emission_systems = _emission_systems
_distribution_systems.append(_distribution_system)
return _distribution_systems

View File

@ -127,6 +127,31 @@ class Geojson:
function = None
if self._function_field is not None:
function = str(feature['properties'][self._function_field])
if function == '1000':
height = float(feature['properties'][self._extrusion_height_field])
function = self._define_building_function(height, function)
if function == 'Mixed use' or function == 'mixed use':
function_parts = []
if 'usages' in feature['properties']:
usages = feature['properties']['usages']
for usage in usages:
if self._function_to_hub is not None and usage['usage'] in self._function_to_hub:
function_parts.append(f"{usage['percentage']}-{self._function_to_hub[usage['usage']]}")
else:
function_parts.append(f"{usage['percentage']}-{usage['usage']}")
else:
for key, value in feature['properties'].items():
if key.startswith("mixed_type_") and not key.endswith("_percentage"):
type_key = key
percentage_key = f"{key}_percentage"
if percentage_key in feature['properties']:
if self._function_to_hub is not None and feature['properties'][type_key] in self._function_to_hub:
usage_function = self._function_to_hub[feature['properties'][type_key]]
function_parts.append(f"{feature['properties'][percentage_key]}-{usage_function}")
else:
function_parts.append(f"{feature['properties'][percentage_key]}-{feature['properties'][type_key]}")
function = "_".join(function_parts)
if self._function_to_hub is not None:
# use the transformation dictionary to retrieve the proper function
if function in self._function_to_hub:
@ -329,3 +354,14 @@ class Geojson:
building.add_alias(alias)
building.volume = volume
return building
def _define_building_function(self, height, function):
if height < 10:
return '1100'
if height < 20 and height > 10:
return '1990'
if height > 20:
return '2100'
else:
return '1000'

View File

@ -24,7 +24,7 @@ class EnergyPlusMultipleBuildings:
csv_output = list(csv.DictReader(csv_file))
for building in self._city.buildings:
building_name = building.name
building_name = building.name.upper()
buildings_energy_demands[f'Building {building_name} Heating Demand (J)'] = [
float(
row[f"{building_name} IDEAL LOADS AIR SYSTEM:Zone Ideal Loads Supply Air Total Heating Energy [J](Hourly)"])
@ -36,7 +36,7 @@ class EnergyPlusMultipleBuildings:
for row in csv_output
]
buildings_energy_demands[f'Building {building_name} DHW Demand (W)'] = [
float(row[f"DHW {building.name}:Water Use Equipment Heating Rate [W](Hourly)"])
float(row[f"DHW {building_name}:Water Use Equipment Heating Rate [W](Hourly)"])
for row in csv_output
]
buildings_energy_demands[f'Building {building_name} Appliances (W)'] = [
@ -58,14 +58,15 @@ class EnergyPlusMultipleBuildings:
if energy_plus_output_file_path.is_file():
building_energy_demands = self._building_energy_demands(energy_plus_output_file_path)
for building in self._city.buildings:
building.heating_demand[cte.HOUR] = building_energy_demands[f'Building {building.name} Heating Demand (J)']
building.cooling_demand[cte.HOUR] = building_energy_demands[f'Building {building.name} Cooling Demand (J)']
building_name = building.name.upper()
building.heating_demand[cte.HOUR] = building_energy_demands[f'Building {building_name} Heating Demand (J)']
building.cooling_demand[cte.HOUR] = building_energy_demands[f'Building {building_name} Cooling Demand (J)']
building.domestic_hot_water_heat_demand[cte.HOUR] = \
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building.name} DHW Demand (W)']]
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building_name} DHW Demand (W)']]
building.appliances_electrical_demand[cte.HOUR] = \
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building.name} Appliances (W)']]
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building_name} Appliances (W)']]
building.lighting_electrical_demand[cte.HOUR] = \
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building.name} Lighting (W)']]
[x * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[f'Building {building_name} Lighting (W)']]
building.heating_demand[cte.MONTH] = MonthlyValues.get_total_month(building.heating_demand[cte.HOUR])
building.cooling_demand[cte.MONTH] = MonthlyValues.get_total_month(building.cooling_demand[cte.HOUR])
building.domestic_hot_water_heat_demand[cte.MONTH] = (

View File

@ -34,7 +34,7 @@ class SimplifiedRadiosityAlgorithm:
for key in self._results:
_irradiance = {}
header_name = key.split(':')
result = [x * cte.WATTS_HOUR_TO_JULES for x in self._results[key]]
result = [x for x in self._results[key]]
city_object_name = header_name[1]
building = self._city.city_object(city_object_name)
surface_id = header_name[2]

View File

@ -0,0 +1,110 @@
"""
RetrofitFactory retrieve the specific construction module for the given region
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2024 Concordia CERC group
Project Coder mohamed Osman mohamed.osman@mail.concordia.ca
"""
from hub.city_model_structure.building import Building
from hub.city_model_structure.city import City
import hub.helpers.constants as cte
# from hub.data.retrofit_data import retrofit_data
class RetrofitFactory:
def __init__(self, retrofit_data, city):
"""
:param retrofit_data: Dictionary mapping building IDs to their retrofit data.
:param city: The City object containing the buildings to retrofit.
"""
self._retrofit_data = retrofit_data
self._city = city
def enrich(self):
for building in self._city.buildings:
building_id = str(building.name) # Convert ID to string to match JSON keys
if building_id in self._retrofit_data:
print(f"Applying retrofits to building ID {building_id}")
building_retrofit_data = self._retrofit_data[building_id]
retrofit_types = building_retrofit_data.get('retrofit_types', [])
self._apply_retrofits_to_building(building, retrofit_types, building_retrofit_data)
else:
print(f"No retrofit data for building ID {building_id}")
def _apply_retrofits_to_building(self, building, retrofit_types, retrofit_params):
if 'construction' in retrofit_types:
self._apply_construction_retrofit_to_building(building, retrofit_params)
if 'infiltration' in retrofit_types:
self._reduce_infiltration_rate_by_percentage(building, retrofit_params)
if 'windows' in retrofit_types:
self._apply_window_retrofit_to_building(building, retrofit_params)
def _apply_construction_retrofit_to_building(self, building: Building, retrofit_params):
wall_u_value = retrofit_params.get('wall_u_value')
roof_u_value = retrofit_params.get('roof_u_value')
ground_u_value = retrofit_params.get('ground_u_value')
for thermal_zone in building.thermal_zones_from_internal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries:
if wall_u_value is not None and thermal_boundary.type == cte.WALL and thermal_boundary.u_value > wall_u_value:
self._change_thermal_resistance(thermal_boundary, wall_u_value)
thermal_boundary.u_value = wall_u_value
print(f"Updated wall U-value to {wall_u_value} in building {building.name}")
elif roof_u_value is not None and thermal_boundary.type == cte.ROOF and thermal_boundary.u_value > roof_u_value:
self._change_thermal_resistance(thermal_boundary, roof_u_value)
thermal_boundary.u_value = roof_u_value
print(f"Updated roof U-value to {roof_u_value} in building {building.name}")
elif ground_u_value is not None and thermal_boundary.type == cte.GROUND and thermal_boundary.u_value > ground_u_value:
self._change_thermal_resistance(thermal_boundary, ground_u_value)
thermal_boundary.u_value = ground_u_value
print(f"Updated ground U-value to {ground_u_value} in building {building.name}")
def _change_thermal_resistance(self, thermal_boundary, new_u_value):
old_u_value = thermal_boundary.u_value
if new_u_value < old_u_value:
delta_r = (1 / new_u_value) - (1 / old_u_value)
for layer in thermal_boundary.layers:
if "virtual_no_mass" in layer.material_name.lower():
new_thermal_resistance = layer.thermal_resistance + delta_r
layer.thermal_resistance = new_thermal_resistance
print(f"Increased thermal resistance by {delta_r} in layer {layer.material_name}")
else:
print(f"New U-value {new_u_value} is not less than old U-value {old_u_value} for thermal boundary type {thermal_boundary.type}")
def _reduce_infiltration_rate_by_percentage(self, building: Building, retrofit_params):
percentage = retrofit_params.get('infiltration_reduction')
if percentage is None:
return
for thermal_zone in building.thermal_zones_from_internal_zones:
thermal_archetype = thermal_zone.parent_internal_zone.thermal_archetype
old_rate = thermal_archetype.infiltration_rate_for_ventilation_system_off
new_rate = old_rate * (1 - percentage / 100)
thermal_archetype.infiltration_rate_for_ventilation_system_off = new_rate
print(f"Reduced infiltration rate from {old_rate} to {new_rate} in building {building.name}")
def _apply_window_retrofit_to_building(self, building: Building, retrofit_params):
overall_u_value = retrofit_params.get('window_u_value')
g_value = retrofit_params.get('window_g_value')
for thermal_zone in building.thermal_zones_from_internal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries:
if thermal_boundary.type == cte.WALL:
construction_archetype = thermal_boundary._construction_archetype
construction_archetype.window_overall_u_value = overall_u_value
construction_archetype.window_g_value = g_value
if hasattr(thermal_boundary, 'thermal_openings') and thermal_boundary.thermal_openings:
for opening in thermal_boundary.thermal_openings:
if overall_u_value is not None and overall_u_value != 0:
old_u_value = opening.overall_u_value
opening.overall_u_value = overall_u_value
print(f"Changed window U-value from {old_u_value} to {opening.overall_u_value} in building {building.name}")
if g_value is not None and g_value != 0:
old_g_value = opening.g_value
opening.g_value = g_value
print(f"Changed window g-value from {old_g_value} to {opening.g_value} in building {building.name}")
else:
print(f"No thermal openings in thermal boundary {thermal_boundary} of type {thermal_boundary.type} in building {building.name}")
else:
# Skip thermal boundaries that are not walls
continue

View File

@ -0,0 +1,105 @@
from hub.city_model_structure.building import Building
from hub.city_model_structure.city import City
import hub.helpers.constants as cte
class RetrofitFactory:
def __init__(self, retrofit_data, city):
"""
:param retrofit_data: Dictionary mapping building IDs to their retrofit data.
:param city: The City object containing the buildings to retrofit.
"""
self._retrofit_data = retrofit_data
self._city = city
def enrich(self):
for building in self._city.buildings:
building_id = str(building.name) # Convert ID to string to match JSON keys
if building_id in self._retrofit_data:
print(f"Applying retrofits to building ID {building_id}")
building_retrofit_data = self._retrofit_data[building_id]
retrofit_types = building_retrofit_data.get('retrofit_types', [])
self._apply_retrofits_to_building(building, retrofit_types, building_retrofit_data)
else:
print(f"No retrofit data for building ID {building_id}")
def _apply_retrofits_to_building(self, building, retrofit_types, retrofit_params):
if 'construction' in retrofit_types:
self._apply_construction_retrofit_to_building(building, retrofit_params)
if 'infiltration' in retrofit_types:
self._reduce_infiltration_rate_by_percentage(building, retrofit_params)
if 'windows' in retrofit_types:
self._apply_window_retrofit_to_building(building, retrofit_params)
def _apply_construction_retrofit_to_building(self, building: Building, retrofit_params):
wall_u_value = retrofit_params.get('wall_u_value')
roof_u_value = retrofit_params.get('roof_u_value')
ground_u_value = retrofit_params.get('ground_u_value')
for thermal_zone in building.thermal_zones_from_internal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries:
if wall_u_value is not None and thermal_boundary.type == cte.WALL and thermal_boundary.u_value > wall_u_value:
self._change_thermal_resistance(thermal_boundary, wall_u_value)
thermal_boundary.u_value = wall_u_value
print(f"Updated wall U-value to {wall_u_value} in building {building.name}")
elif roof_u_value is not None and thermal_boundary.type == cte.ROOF and thermal_boundary.u_value > roof_u_value:
self._change_thermal_resistance(thermal_boundary, roof_u_value)
thermal_boundary.u_value = roof_u_value
print(f"Updated roof U-value to {roof_u_value} in building {building.name}")
elif ground_u_value is not None and thermal_boundary.type == cte.GROUND and thermal_boundary.u_value > ground_u_value:
self._change_thermal_resistance(thermal_boundary, ground_u_value)
thermal_boundary.u_value = ground_u_value
print(f"Updated ground U-value to {ground_u_value} in building {building.name}")
def _change_thermal_resistance(self, thermal_boundary, new_u_value):
old_u_value = thermal_boundary.u_value
if new_u_value < old_u_value:
delta_r = (1 / new_u_value) - (1 / old_u_value)
for layer in thermal_boundary.layers:
if "virtual_no_mass" in layer.material_name.lower():
new_thermal_resistance = layer.thermal_resistance + delta_r
layer.thermal_resistance = new_thermal_resistance
print(f"Increased thermal resistance by {delta_r} in layer {layer.material_name}")
else:
print(f"New U-value {new_u_value} is not less than old U-value {old_u_value} for thermal boundary type {thermal_boundary.type}")
def _reduce_infiltration_rate_by_percentage(self, building: Building, retrofit_params):
percentage = retrofit_params.get('infiltration_reduction')
if percentage is None:
return
for thermal_zone in building.thermal_zones_from_internal_zones:
#change infiltration rate in thermal_zone.parent_internal_zone.thermal_archetype.
thermal_archetype = thermal_zone.parent_internal_zone.thermal_archetype
old_rate = thermal_archetype.infiltration_rate_for_ventilation_system_off
new_rate = old_rate * (1 - percentage / 100)
thermal_archetype.infiltration_rate_for_ventilation_system_off = new_rate
print(f"Reduced infiltration rate from {old_rate} to {new_rate} in building {building.name}")
def _apply_window_retrofit_to_building(self, building: Building, retrofit_params):
overall_u_value = retrofit_params.get('window_u_value')
g_value = retrofit_params.get('window_g_value')
for thermal_zone in building.thermal_zones_from_internal_zones:
for thermal_boundary in thermal_zone.thermal_boundaries:
if thermal_boundary.type == cte.WALL:
#change window u_value and g_value in _construction_archetype
construction_archetype = thermal_boundary._construction_archetype
construction_archetype.window_overall_u_value = overall_u_value
construction_archetype.window_g_value = g_value
if hasattr(thermal_boundary, 'thermal_openings') and thermal_boundary.thermal_openings:
for opening in thermal_boundary.thermal_openings:
if overall_u_value is not None and overall_u_value != 0:
old_u_value = opening.overall_u_value
opening.overall_u_value = overall_u_value
print(f"Changed window U-value from {old_u_value} to {opening.overall_u_value} in building {building.name}")
if g_value is not None and g_value != 0:
old_g_value = opening.g_value
opening.g_value = g_value
print(f"Changed window g-value from {old_g_value} to {opening.g_value} in building {building.name}")
else:
print(f"No thermal openings in thermal boundary {thermal_boundary} of type {thermal_boundary.type} in building {building.name}")
else:
# Skip thermal boundaries that are not walls
continue

View File

@ -0,0 +1,199 @@
"""
NrcanUsageParameters extracts the usage properties from NRCAN catalog and assigns to each building
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
"""
import logging
import hub.helpers.constants as cte
from hub.helpers.dictionaries import Dictionaries
from hub.city_model_structure.building_demand.usage import Usage
from hub.city_model_structure.building_demand.lighting import Lighting
from hub.city_model_structure.building_demand.occupancy import Occupancy
from hub.city_model_structure.building_demand.appliances import Appliances
from hub.city_model_structure.building_demand.thermal_control import ThermalControl
from hub.city_model_structure.building_demand.domestic_hot_water import DomesticHotWater
from hub.catalog_factories.usage_catalog_factory import UsageCatalogFactory
class CercUsageParameters:
"""
CercUsageParameters class (Copy of NrcanUsageParameters)
"""
def __init__(self, city):
self._city = city
def enrich_buildings(self):
"""
Returns the city with the usage parameters assigned to the buildings
:return:
"""
city = self._city
cerc_catalog = UsageCatalogFactory('cerc').catalog
comnet_catalog = UsageCatalogFactory('comnet').catalog
for building in city.buildings:
usage_name = Dictionaries().hub_usage_to_cerc_usage[building.function]
try:
archetype_usage = self._search_archetypes(cerc_catalog, usage_name)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
continue
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
try:
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
continue
for internal_zone in building.internal_zones:
if len(building.internal_zones) > 1:
volume_per_area = 0
if internal_zone.area is None:
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
building.name, usage_name)
continue
if internal_zone.volume is None:
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
building.name, usage_name)
continue
if internal_zone.area <= 0:
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
building.name, usage_name)
continue
volume_per_area += internal_zone.volume / internal_zone.area
else:
if building.storeys_above_ground is None:
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s',
building.name, usage_name)
continue
volume_per_area = building.volume / building.floor_area / building.storeys_above_ground
usage = Usage()
usage.name = usage_name
self._assign_values(usage, archetype_usage, volume_per_area, building.cold_water_temperature)
self._assign_comnet_extra_values(usage, comnet_archetype_usage, archetype_usage.occupancy.occupancy_density)
usage.percentage = 1
self._calculate_reduced_values_from_extended_library(usage, archetype_usage)
internal_zone.usages = [usage]
@staticmethod
def _search_archetypes(catalog, usage_name):
archetypes = catalog.entries('archetypes').usages
for building_archetype in archetypes:
if str(usage_name) == str(building_archetype.name):
return building_archetype
raise KeyError('archetype not found')
@staticmethod
def _assign_values(usage, archetype, volume_per_area, cold_water_temperature):
if archetype.mechanical_air_change > 0:
# 1/s
usage.mechanical_air_change = archetype.mechanical_air_change
elif archetype.ventilation_rate > 0:
# m3/m2.s to 1/s
usage.mechanical_air_change = archetype.ventilation_rate / volume_per_area
else:
usage.mechanical_air_change = 0
_occupancy = Occupancy()
_occupancy.occupancy_density = archetype.occupancy.occupancy_density
_occupancy.sensible_radiative_internal_gain = archetype.occupancy.sensible_radiative_internal_gain
_occupancy.latent_internal_gain = archetype.occupancy.latent_internal_gain
_occupancy.sensible_convective_internal_gain = archetype.occupancy.sensible_convective_internal_gain
_occupancy.occupancy_schedules = archetype.occupancy.schedules
usage.occupancy = _occupancy
_lighting = Lighting()
_lighting.density = archetype.lighting.density
_lighting.convective_fraction = archetype.lighting.convective_fraction
_lighting.radiative_fraction = archetype.lighting.radiative_fraction
_lighting.latent_fraction = archetype.lighting.latent_fraction
_lighting.schedules = archetype.lighting.schedules
usage.lighting = _lighting
_appliances = Appliances()
_appliances.density = archetype.appliances.density
_appliances.convective_fraction = archetype.appliances.convective_fraction
_appliances.radiative_fraction = archetype.appliances.radiative_fraction
_appliances.latent_fraction = archetype.appliances.latent_fraction
_appliances.schedules = archetype.appliances.schedules
usage.appliances = _appliances
_control = ThermalControl()
_control.cooling_set_point_schedules = archetype.thermal_control.cooling_set_point_schedules
_control.heating_set_point_schedules = archetype.thermal_control.heating_set_point_schedules
_control.hvac_availability_schedules = archetype.thermal_control.hvac_availability_schedules
usage.thermal_control = _control
_domestic_hot_water = DomesticHotWater()
_domestic_hot_water.peak_flow = archetype.domestic_hot_water.peak_flow
_domestic_hot_water.service_temperature = archetype.domestic_hot_water.service_temperature
density = None
if len(cold_water_temperature) > 0:
cold_temperature = cold_water_temperature[cte.YEAR][0]
density = (
archetype.domestic_hot_water.peak_flow * cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY *
(archetype.domestic_hot_water.service_temperature - cold_temperature)
)
_domestic_hot_water.density = density
_domestic_hot_water.schedules = archetype.domestic_hot_water.schedules
usage.domestic_hot_water = _domestic_hot_water
@staticmethod
def _assign_comnet_extra_values(usage, archetype, occupancy_density):
_occupancy = usage.occupancy
archetype_density = archetype.occupancy.occupancy_density
if archetype_density == 0:
_occupancy.sensible_radiative_internal_gain = 0
_occupancy.latent_internal_gain = 0
_occupancy.sensible_convective_internal_gain = 0
else:
_occupancy.sensible_radiative_internal_gain = archetype.occupancy.sensible_radiative_internal_gain \
* occupancy_density / archetype_density
_occupancy.latent_internal_gain = archetype.occupancy.latent_internal_gain * occupancy_density / archetype_density
_occupancy.sensible_convective_internal_gain = (
archetype.occupancy.sensible_convective_internal_gain * occupancy_density / archetype_density
)
@staticmethod
def _calculate_reduced_values_from_extended_library(usage, archetype):
number_of_days_per_type = {'WD': 251, 'Sat': 52, 'Sun': 62}
total = 0
for schedule in archetype.thermal_control.hvac_availability_schedules:
if schedule.day_types[0] == cte.SATURDAY:
for value in schedule.values:
total += value * number_of_days_per_type['Sat']
elif schedule.day_types[0] == cte.SUNDAY:
for value in schedule.values:
total += value * number_of_days_per_type['Sun']
else:
for value in schedule.values:
total += value * number_of_days_per_type['WD']
usage.hours_day = total / 365
usage.days_year = 365
max_heating_setpoint = cte.MIN_FLOAT
min_heating_setpoint = cte.MAX_FLOAT
for schedule in archetype.thermal_control.heating_set_point_schedules:
if schedule.values is None:
max_heating_setpoint = None
min_heating_setpoint = None
break
if max(schedule.values) > max_heating_setpoint:
max_heating_setpoint = max(schedule.values)
if min(schedule.values) < min_heating_setpoint:
min_heating_setpoint = min(schedule.values)
min_cooling_setpoint = cte.MAX_FLOAT
for schedule in archetype.thermal_control.cooling_set_point_schedules:
if schedule.values is None:
min_cooling_setpoint = None
break
if min(schedule.values) < min_cooling_setpoint:
min_cooling_setpoint = min(schedule.values)
usage.thermal_control.mean_heating_set_point = max_heating_setpoint
usage.thermal_control.heating_set_back = min_heating_setpoint
usage.thermal_control.mean_cooling_set_point = min_cooling_setpoint

View File

@ -3,6 +3,7 @@ ComnetUsageParameters extracts the usage properties from Comnet catalog and assi
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Project Collaborator Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import copy
import logging
@ -18,6 +19,8 @@ from hub.city_model_structure.building_demand.domestic_hot_water import Domestic
from hub.city_model_structure.attributes.schedule import Schedule
from hub.city_model_structure.building_demand.internal_gain import InternalGain
from hub.catalog_factories.usage_catalog_factory import UsageCatalogFactory
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
class ComnetUsageParameters:
@ -35,29 +38,62 @@ class ComnetUsageParameters:
city = self._city
comnet_catalog = UsageCatalogFactory('comnet').catalog
for building in city.buildings:
usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
try:
archetype_usage = self._search_archetypes(comnet_catalog, usage_name)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
continue
for internal_zone in building.internal_zones:
if internal_zone.area is None:
raise TypeError('Internal zone area not defined, ACH cannot be calculated')
if internal_zone.volume is None:
raise TypeError('Internal zone volume not defined, ACH cannot be calculated')
if internal_zone.area <= 0:
raise TypeError('Internal zone area is zero, ACH cannot be calculated')
volume_per_area = internal_zone.volume / internal_zone.area
usage = Usage()
usage.name = usage_name
self._assign_values(usage, archetype_usage, volume_per_area, building.cold_water_temperature)
usage.percentage = 1
self._calculate_reduced_values_from_extended_library(usage, archetype_usage)
internal_zone.usages = [usage]
usages = []
comnet_archetype_usages = []
building_functions = building.function.split('_')
for function in building_functions:
usages.append(function.split('-'))
for usage in usages:
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]]
try:
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
comnet_archetype_usages.append(comnet_archetype_usage)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
continue
for (i, internal_zone) in enumerate(building.internal_zones):
internal_zone_usages = []
if len(building.internal_zones) > 1:
volume_per_area = 0
if internal_zone.area is None:
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
building.name, usages[i][-1])
continue
if internal_zone.volume is None:
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
building.name, usages[i][-1])
continue
if internal_zone.area <= 0:
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
building.name, usages[i][-1])
continue
volume_per_area += internal_zone.volume / internal_zone.area
usage = Usage()
usage.name = usages[i][-1]
self._assign_values(usage, comnet_archetype_usages[i], volume_per_area, building.cold_water_temperature)
usage.percentage = 1
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[i])
internal_zone_usages.append(usage)
else:
storeys_above_ground = building.storeys_above_ground
if storeys_above_ground is None:
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s. '
'NRCAN construction data for the year %s is used to calculated number of storeys above '
'ground', building.name, usages, building.year_of_construction)
storeys_above_ground = self.average_storey_height_calculator(self._city, building)
volume_per_area = building.volume / building.floor_area / storeys_above_ground
for (j, mixed_usage) in enumerate(usages):
usage = Usage()
usage.name = mixed_usage[-1]
if len(usages) > 1:
usage.percentage = float(mixed_usage[0]) / 100
else:
usage.percentage = 1
self._assign_values(usage, comnet_archetype_usages[j], volume_per_area, building.cold_water_temperature)
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[j])
internal_zone_usages.append(usage)
internal_zone.usages = internal_zone_usages
@staticmethod
def _search_archetypes(comnet_catalog, usage_name):
comnet_archetypes = comnet_catalog.entries('archetypes').usages
@ -229,3 +265,37 @@ class ComnetUsageParameters:
_mean_internal_gain.schedules = _schedules
return [_mean_internal_gain]
@staticmethod
def average_storey_height_calculator(city, building):
climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
main_function = None
functions = building.function.split('_')
if len(functions) > 1:
maximum_percentage = 0
for function in functions:
percentage_and_function = function.split('-')
if float(percentage_and_function[0]) > maximum_percentage:
maximum_percentage = float(percentage_and_function[0])
main_function = percentage_and_function[-1]
else:
main_function = functions[-1]
if main_function not in Dictionaries().hub_function_to_nrcan_construction_function:
logging.error('Building %s has an unknown building function %s', building.name, main_function)
function = Dictionaries().hub_function_to_nrcan_construction_function[main_function]
construction_archetype = None
average_storey_height = None
nrcan_archetypes = nrcan_catalog.entries('archetypes')
for building_archetype in nrcan_archetypes:
construction_period_limits = building_archetype.construction_period.split('_')
if int(construction_period_limits[0]) <= int(building.year_of_construction) <= int(construction_period_limits[1]):
if str(function) == str(building_archetype.function) and climate_zone == str(building_archetype.climate_zone):
construction_archetype = building_archetype
average_storey_height = building_archetype.average_storey_height
if construction_archetype is None:
logging.error('Building %s has unknown construction archetype for building function: %s '
'[%s], building year of construction: %s and climate zone %s', building.name, function,
building.function, building.year_of_construction, climate_zone)
return average_storey_height

View File

@ -3,11 +3,13 @@ NrcanUsageParameters extracts the usage properties from NRCAN catalog and assign
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
Project Collaborator Saeed Ranjbar saeed.ranjbar@concordia.ca
"""
import logging
import hub.helpers.constants as cte
from hub.catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
from hub.helpers.dictionaries import Dictionaries
from hub.city_model_structure.building_demand.usage import Usage
from hub.city_model_structure.building_demand.lighting import Lighting
@ -16,6 +18,7 @@ from hub.city_model_structure.building_demand.appliances import Appliances
from hub.city_model_structure.building_demand.thermal_control import ThermalControl
from hub.city_model_structure.building_demand.domestic_hot_water import DomesticHotWater
from hub.catalog_factories.usage_catalog_factory import UsageCatalogFactory
from hub.imports.construction.helpers.construction_helper import ConstructionHelper
class NrcanUsageParameters:
@ -33,53 +36,75 @@ class NrcanUsageParameters:
city = self._city
nrcan_catalog = UsageCatalogFactory('nrcan').catalog
comnet_catalog = UsageCatalogFactory('comnet').catalog
for building in city.buildings:
usage_name = Dictionaries().hub_usage_to_nrcan_usage[building.function]
try:
archetype_usage = self._search_archetypes(nrcan_catalog, usage_name)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
continue
usages = []
nrcan_archetype_usages = []
comnet_archetype_usages = []
building_functions = building.function.split('_')
for function in building_functions:
usages.append(function.split('-'))
for usage in usages:
usage_name = Dictionaries().hub_usage_to_nrcan_usage[usage[-1]]
try:
archetype_usage = self._search_archetypes(nrcan_catalog, usage_name)
nrcan_archetype_usages.append(archetype_usage)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
continue
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]]
try:
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
comnet_archetype_usages.append(comnet_archetype_usage)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
continue
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[building.function]
try:
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
except KeyError:
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
continue
for internal_zone in building.internal_zones:
for (i, internal_zone) in enumerate(building.internal_zones):
internal_zone_usages = []
if len(building.internal_zones) > 1:
volume_per_area = 0
if internal_zone.area is None:
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
building.name, usage_name)
building.name, usages[i][-1])
continue
if internal_zone.volume is None:
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
building.name, usage_name)
building.name, usages[i][-1])
continue
if internal_zone.area <= 0:
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
building.name, usage_name)
building.name, usages[i][-1])
continue
volume_per_area += internal_zone.volume / internal_zone.area
usage = Usage()
usage.name = usages[i][-1]
self._assign_values(usage, nrcan_archetype_usages[i], volume_per_area, building.cold_water_temperature)
self._assign_comnet_extra_values(usage, comnet_archetype_usages[i], nrcan_archetype_usages[i].occupancy.occupancy_density)
usage.percentage = 1
self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[i])
internal_zone_usages.append(usage)
else:
if building.storeys_above_ground is None:
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s',
building.name, usage_name)
storeys_above_ground = building.storeys_above_ground
if storeys_above_ground is None:
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s. '
'NRCAN construction data for the year %s is used to calculated number of storeys above '
'ground', building.name, usages, building.year_of_construction)
storeys_above_ground = self.average_storey_height_calculator(self._city, building)
continue
volume_per_area = building.volume / building.floor_area / building.storeys_above_ground
volume_per_area = building.volume / building.floor_area / storeys_above_ground
for (j, mixed_usage) in enumerate(usages):
usage = Usage()
usage.name = mixed_usage[-1]
if len(usages) > 1:
usage.percentage = float(mixed_usage[0]) / 100
else:
usage.percentage = 1
self._assign_values(usage, nrcan_archetype_usages[j], volume_per_area, building.cold_water_temperature)
self._assign_comnet_extra_values(usage, comnet_archetype_usages[j], nrcan_archetype_usages[j].occupancy.occupancy_density)
self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[j])
internal_zone_usages.append(usage)
usage = Usage()
usage.name = usage_name
self._assign_values(usage, archetype_usage, volume_per_area, building.cold_water_temperature)
self._assign_comnet_extra_values(usage, comnet_archetype_usage, archetype_usage.occupancy.occupancy_density)
usage.percentage = 1
self._calculate_reduced_values_from_extended_library(usage, archetype_usage)
internal_zone.usages = [usage]
internal_zone.usages = internal_zone_usages
@staticmethod
def _search_archetypes(catalog, usage_name):
@ -197,3 +222,39 @@ class NrcanUsageParameters:
usage.thermal_control.mean_heating_set_point = max_heating_setpoint
usage.thermal_control.heating_set_back = min_heating_setpoint
usage.thermal_control.mean_cooling_set_point = min_cooling_setpoint
@staticmethod
def average_storey_height_calculator(city, building):
climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
main_function = None
functions = building.function.split('_')
if len(functions) > 1:
maximum_percentage = 0
for function in functions:
percentage_and_function = function.split('-')
if float(percentage_and_function[0]) > maximum_percentage:
maximum_percentage = float(percentage_and_function[0])
main_function = percentage_and_function[-1]
else:
main_function = functions[-1]
if main_function not in Dictionaries().hub_function_to_nrcan_construction_function:
logging.error('Building %s has an unknown building function %s', building.name, main_function)
function = Dictionaries().hub_function_to_nrcan_construction_function[main_function]
construction_archetype = None
average_storey_height = None
nrcan_archetypes = nrcan_catalog.entries('archetypes')
for building_archetype in nrcan_archetypes:
construction_period_limits = building_archetype.construction_period.split('_')
if int(construction_period_limits[0]) <= int(building.year_of_construction) <= int(construction_period_limits[1]):
if str(function) == str(building_archetype.function) and climate_zone == str(building_archetype.climate_zone):
construction_archetype = building_archetype
average_storey_height = building_archetype.average_storey_height
if construction_archetype is None:
logging.error('Building %s has unknown construction archetype for building function: %s '
'[%s], building year of construction: %s and climate zone %s', building.name, function,
building.function, building.year_of_construction, climate_zone)
return average_storey_height

View File

@ -9,6 +9,8 @@ Code contributors: Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concord
from hub.helpers.utils import validate_import_export_type
from hub.imports.usage.comnet_usage_parameters import ComnetUsageParameters
from hub.imports.usage.nrcan_usage_parameters import NrcanUsageParameters
from hub.imports.usage.cerc_usage_parameters import CercUsageParameters
from hub.imports.usage.eilat_usage_parameters import EilatUsageParameters
@ -38,7 +40,16 @@ class UsageFactory:
self._city.level_of_detail.usage = 2
for building in self._city.buildings:
building.level_of_detail.usage = 2
def _cerc(self):
"""
Enrich the city with cerc usage library (copy of NRCAN)
"""
CercUsageParameters(self._city).enrich_buildings()
self._city.level_of_detail.usage = 2
for building in self._city.buildings:
building.level_of_detail.usage = 2
def _eilat(self):
"""
Enrich the city with Eilat usage library

View File

View File

@ -1,4 +1,4 @@
"""
Hub version number
"""
__version__ = '0.2.0.6'
__version__ = '0.2.0.12'

View File

@ -0,0 +1,46 @@
{
"type": "FeatureCollection",
"name": "OMHM_results_modified",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "OBJECTID": "161053", "ID_UEV": "01029234", "CIVIQUE_DE": "6109", "CIVIQUE_FI": "6119", "NOM_RUE": "rue Jeanne-Mance (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "9", "AREA_NEW": "118", "MBG_Width": "8", "MBG_Length": "16", "MBG_Orientation": "32", "Shape_Length": "48", "Shape_Area": "125", "BuildingCategory": "fully-attached", "BuildingVolume": "1062", "AspectRatio": 2.152, "SurfacetoVolumeRatio": 0.111, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "354", "ANNEE_CONS": "1910", "address": "6109 à 6119" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.60889457783199, 45.526279673418671 ], [ -73.608784596113864, 45.526401895432073 ], [ -73.608808785594334, 45.526414045422094 ], [ -73.608811385760049, 45.526411446008474 ], [ -73.60882178517528, 45.526397746843365 ], [ -73.608847485482059, 45.526407346140566 ], [ -73.608832885254159, 45.526426746194332 ], [ -73.608864684978954, 45.526438645964845 ], [ -73.608864884687591, 45.526438645774512 ], [ -73.60887972027291, 45.526424456462976 ], [ -73.608977080705117, 45.52631626050087 ], [ -73.60889457783199, 45.526279673418671 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "162168", "ID_UEV": "01001944", "CIVIQUE_DE": "4820", "CIVIQUE_FI": "4850", "NOM_RUE": "rue de Grand-Pré (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "11", "AREA_NEW": "504", "MBG_Width": "16", "MBG_Length": "42", "MBG_Orientation": "123", "Shape_Length": "116", "Shape_Area": "669", "BuildingCategory": "fully-attached", "BuildingVolume": "5544", "AspectRatio": 2.648, "SurfacetoVolumeRatio": 0.091, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "1512", "ANNEE_CONS": "1980", "address": "4820 à 4850" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.586673951057165, 45.524838247152971 ], [ -73.586568305570552, 45.524952686098082 ], [ -73.58662307714782, 45.524979547084882 ], [ -73.586731877320233, 45.525032846618785 ], [ -73.586815478124791, 45.525073847297307 ], [ -73.586820877038548, 45.525068346972965 ], [ -73.586874077743531, 45.525094146322125 ], [ -73.586895378594193, 45.525104346900406 ], [ -73.586943277305565, 45.525127046703169 ], [ -73.587016976014752, 45.525161993449707 ], [ -73.587125015986871, 45.525044959829344 ], [ -73.587121277851907, 45.525043246686081 ], [ -73.587092777275416, 45.525074446965931 ], [ -73.587032277294412, 45.525047146948445 ], [ -73.587039678023586, 45.525038947369048 ], [ -73.587033777622878, 45.525036346828877 ], [ -73.586929477897286, 45.524990346357107 ], [ -73.58664877714105, 45.524866746179505 ], [ -73.586674177796809, 45.524838346863149 ], [ -73.586673951057165, 45.524838247152971 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "135557", "ID_UEV": "01016997", "CIVIQUE_DE": "4110", "CIVIQUE_FI": "4118", "NOM_RUE": "rue de Mentana (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "35", "AREA_NEW": "368", "MBG_Width": "9", "MBG_Length": "40", "MBG_Orientation": "123", "Shape_Length": "99", "Shape_Area": "373", "BuildingCategory": "semi-attached", "BuildingVolume": "12880", "AspectRatio": 4.269, "SurfacetoVolumeRatio": 0.029, "FloorNu_RawTax": "9", "FloorNu_RawTax.1": "9", "Floor_frmHieght": "9", "TotalFloorArea": "2772", "ANNEE_CONS": "1974", "address": "4110 à 4118" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.574418873676947, 45.524231847193803 ], [ -73.574414973518913, 45.524236046587689 ], [ -73.574353274210182, 45.524302647018288 ], [ -73.574672473801854, 45.524454446940965 ], [ -73.574677173550853, 45.524456647576301 ], [ -73.574697801390826, 45.524465086284231 ], [ -73.574764053316215, 45.524393192531484 ], [ -73.574747073263296, 45.52438524726022 ], [ -73.574418873676947, 45.524231847193803 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "135557", "ID_UEV": "01016997", "CIVIQUE_DE": "4110", "CIVIQUE_FI": "4118", "NOM_RUE": "rue de Mentana (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "35", "AREA_NEW": "368", "MBG_Width": "9", "MBG_Length": "40", "MBG_Orientation": "123", "Shape_Length": "99", "Shape_Area": "373", "BuildingCategory": "semi-attached", "BuildingVolume": "12880", "AspectRatio": 4.269, "SurfacetoVolumeRatio": 0.029, "FloorNu_RawTax": "9", "FloorNu_RawTax.1": "9", "Floor_frmHieght": "9", "TotalFloorArea": "3312", "ANNEE_CONS": "1974", "address": "4110 à 4118" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.574737072648617, 45.523887246433162 ], [ -73.574675173652651, 45.523951346517343 ], [ -73.574680474005618, 45.523953747424365 ], [ -73.575101273632313, 45.524149446764156 ], [ -73.575104673865866, 45.524145747086607 ], [ -73.575166773945583, 45.524079047002189 ], [ -73.574740673605703, 45.523883346870491 ], [ -73.574737072648617, 45.523887246433162 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "135557", "ID_UEV": "01016997", "CIVIQUE_DE": "4110", "CIVIQUE_FI": "4118", "NOM_RUE": "rue de Mentana (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "35", "AREA_NEW": "368", "MBG_Width": "9", "MBG_Length": "40", "MBG_Orientation": "123", "Shape_Length": "99", "Shape_Area": "373", "BuildingCategory": "semi-attached", "BuildingVolume": "12880", "AspectRatio": 4.269, "SurfacetoVolumeRatio": 0.029, "FloorNu_RawTax": "9", "FloorNu_RawTax.1": "9", "Floor_frmHieght": "9", "TotalFloorArea": "3519", "ANNEE_CONS": "1974", "address": "4110 à 4118" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.573938673130883, 45.523514747274078 ], [ -73.573871573257321, 45.523587247599714 ], [ -73.573971273166705, 45.523632346946712 ], [ -73.574299873176656, 45.523781346937724 ], [ -73.574367473166163, 45.523709747676989 ], [ -73.573942173382605, 45.523511147448218 ], [ -73.573938673130883, 45.523514747274078 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "135557", "ID_UEV": "01016997", "CIVIQUE_DE": "4110", "CIVIQUE_FI": "4118", "NOM_RUE": "rue de Mentana (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "35", "AREA_NEW": "368", "MBG_Width": "9", "MBG_Length": "40", "MBG_Orientation": "123", "Shape_Length": "99", "Shape_Area": "373", "BuildingCategory": "semi-attached", "BuildingVolume": "12880", "AspectRatio": 4.269, "SurfacetoVolumeRatio": 0.029, "FloorNu_RawTax": "9", "FloorNu_RawTax.1": "9", "Floor_frmHieght": "9", "TotalFloorArea": "8595", "ANNEE_CONS": "1974", "address": "4110 à 4118" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.574246972941793, 45.524254046524938 ], [ -73.574263673619157, 45.52423654728122 ], [ -73.574264472950247, 45.524236947190275 ], [ -73.574618373497202, 45.523877146844328 ], [ -73.574618574080972, 45.52387684706661 ], [ -73.574597274105017, 45.523866247366996 ], [ -73.574629374517983, 45.523834246988898 ], [ -73.574482473360447, 45.523761346956533 ], [ -73.57447857399373, 45.523765147723324 ], [ -73.574450274413095, 45.523795346802238 ], [ -73.574425873110769, 45.523784046316848 ], [ -73.574425773393941, 45.52378414716388 ], [ -73.574229973500437, 45.523994747121513 ], [ -73.574083373708532, 45.524152346664444 ], [ -73.574083272709117, 45.524152446612156 ], [ -73.574109573296937, 45.524167247214692 ], [ -73.574093573484291, 45.524181347286358 ], [ -73.574093773316264, 45.524181447038956 ], [ -73.574246972941793, 45.524254046524938 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "139141", "ID_UEV": "01093226", "CIVIQUE_DE": "5170", "CIVIQUE_FI": "5174", "NOM_RUE": "rue Drolet (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "13", "AREA_NEW": "257", "MBG_Width": "13", "MBG_Length": "22", "MBG_Orientation": "122", "Shape_Length": "69", "Shape_Area": "280", "BuildingCategory": "semi-attached", "BuildingVolume": "3341", "AspectRatio": 1.702, "SurfacetoVolumeRatio": 0.077, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "4", "TotalFloorArea": "1028", "ANNEE_CONS": "1979", "address": "5170 à 5174" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.591167479030972, 45.526556546423869 ], [ -73.591164679307127, 45.526559746687838 ], [ -73.5910896795654, 45.526649446727895 ], [ -73.591295579388301, 45.526742246566478 ], [ -73.591295779261202, 45.526742347188751 ], [ -73.591314679498396, 45.526721447707658 ], [ -73.591337579606474, 45.526731746958284 ], [ -73.591316078712723, 45.526755447022836 ], [ -73.591316180009443, 45.52675554682402 ], [ -73.591320310492023, 45.526757487175246 ], [ -73.591400782956626, 45.526656800065901 ], [ -73.591377879748123, 45.526646946250843 ], [ -73.591167479030972, 45.526556546423869 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "159710", "ID_UEV": "01031526", "CIVIQUE_DE": "5301", "CIVIQUE_FI": "5321", "NOM_RUE": "rue Saint-Dominique (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "10", "AREA_NEW": "426", "MBG_Width": "15", "MBG_Length": "29", "MBG_Orientation": "123", "Shape_Length": "88", "Shape_Area": "429", "BuildingCategory": "semi-attached", "BuildingVolume": "4260", "AspectRatio": 1.958, "SurfacetoVolumeRatio": 0.1, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "1278", "ANNEE_CONS": "1983", "address": "5301 à 5321" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.595280179779778, 45.525306046544578 ], [ -73.59527857988931, 45.52530774677637 ], [ -73.595176680986739, 45.525416646636465 ], [ -73.595180880565678, 45.525418547198015 ], [ -73.59547958119505, 45.525555646742482 ], [ -73.59548398066913, 45.52555764700795 ], [ -73.595498280971185, 45.525540746863108 ], [ -73.595502899198962, 45.525542656061162 ], [ -73.595583619277193, 45.525455274404962 ], [ -73.595580081047061, 45.525453846620529 ], [ -73.595586980381867, 45.525445846671893 ], [ -73.595586180882805, 45.525445446912236 ], [ -73.595549980649665, 45.525428947143965 ], [ -73.595461581229586, 45.525388646147597 ], [ -73.595333880363981, 45.525330546666602 ], [ -73.595280179779778, 45.525306046544578 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "160314", "ID_UEV": "01027192", "CIVIQUE_DE": "3876", "CIVIQUE_FI": "3880", "NOM_RUE": "rue de Mentana (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "12", "AREA_NEW": "366", "MBG_Width": "16", "MBG_Length": "32", "MBG_Orientation": "110", "Shape_Length": "96", "Shape_Area": "507", "BuildingCategory": "semi-attached", "BuildingVolume": "4392", "AspectRatio": 2.009, "SurfacetoVolumeRatio": 0.083, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "1098", "ANNEE_CONS": "1980", "address": "3876 à 3880" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.570800071665957, 45.522686946460304 ], [ -73.57093107256577, 45.522726047825749 ], [ -73.571028271866595, 45.522613046698432 ], [ -73.570955272361019, 45.522582046683695 ], [ -73.57092677184869, 45.522615346769584 ], [ -73.570836471663341, 45.522577047118958 ], [ -73.570681923964358, 45.522511513915816 ], [ -73.570599160784397, 45.522601741674258 ], [ -73.57068447255547, 45.522631046198299 ], [ -73.570683872035971, 45.52263194640998 ], [ -73.5706905727058, 45.522641647038853 ], [ -73.570695971264669, 45.522651146908998 ], [ -73.570720172024352, 45.522643346512112 ], [ -73.570741072289536, 45.522674046912528 ], [ -73.570768873124834, 45.522664547177342 ], [ -73.570786672496425, 45.522690747590424 ], [ -73.570800772812049, 45.522685647556457 ], [ -73.570800071665957, 45.522686946460304 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "133286", "ID_UEV": "01042232", "CIVIQUE_DE": "3620", "CIVIQUE_FI": "3622", "NOM_RUE": "rue De Bullion (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "12", "AREA_NEW": "109", "MBG_Width": "11", "MBG_Length": "21", "MBG_Orientation": "33", "Shape_Length": "63", "Shape_Area": "227", "BuildingCategory": "fully-attached", "BuildingVolume": "1308", "AspectRatio": 1.922, "SurfacetoVolumeRatio": 0.083, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "4", "Floor_frmHieght": "3", "TotalFloorArea": "327", "ANNEE_CONS": "1973", "address": "3620 à 3622" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.572164341489696, 45.515081822522674 ], [ -73.572094272716726, 45.515157711689952 ], [ -73.572209872164805, 45.515210745503666 ], [ -73.572134672171586, 45.515291745436613 ], [ -73.572135230576137, 45.51529202223508 ], [ -73.572281114453887, 45.515134786235819 ], [ -73.572204771880109, 45.515100845713491 ], [ -73.572178971858364, 45.515089445732698 ], [ -73.572180471934672, 45.515089445684659 ], [ -73.572164341489696, 45.515081822522674 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "133286", "ID_UEV": "01042232", "CIVIQUE_DE": "3620", "CIVIQUE_FI": "3622", "NOM_RUE": "rue De Bullion (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "12", "AREA_NEW": "109", "MBG_Width": "11", "MBG_Length": "21", "MBG_Orientation": "33", "Shape_Length": "63", "Shape_Area": "227", "BuildingCategory": "fully-attached", "BuildingVolume": "1308", "AspectRatio": 1.922, "SurfacetoVolumeRatio": 0.083, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "4", "Floor_frmHieght": "3", "TotalFloorArea": "747", "ANNEE_CONS": "1973", "address": "3620 à 3622" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.571849371673082, 45.515246845899775 ], [ -73.571836472027769, 45.515260545097711 ], [ -73.571831897393437, 45.515258410851573 ], [ -73.571762868307985, 45.51533411649163 ], [ -73.571848271367159, 45.515361846304067 ], [ -73.571844472998734, 45.515366245317459 ], [ -73.571872972464163, 45.51537764637429 ], [ -73.57191147153371, 45.515393645616861 ], [ -73.571937271130409, 45.515404645228365 ], [ -73.571977672212782, 45.515422645397422 ], [ -73.572003423820092, 45.515434132738157 ], [ -73.572084162422797, 45.515347082465453 ], [ -73.571955671586991, 45.515292245266785 ], [ -73.571849772545761, 45.515247045412366 ], [ -73.571849371673082, 45.515246845899775 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "137144", "ID_UEV": "01026386", "CIVIQUE_DE": "3880", "CIVIQUE_FI": "3884", "NOM_RUE": "rue Rivard (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "11", "AREA_NEW": "279", "MBG_Width": "12", "MBG_Length": "24", "MBG_Orientation": "123", "Shape_Length": "73", "Shape_Area": "293", "BuildingCategory": "fully-attached", "BuildingVolume": "3069", "AspectRatio": 2.03, "SurfacetoVolumeRatio": 0.091, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "837", "ANNEE_CONS": "1973", "address": "3880 à 3884" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.573353708862498, 45.520196602777794 ], [ -73.573276577128638, 45.520280345545878 ], [ -73.573329872184814, 45.520304246201597 ], [ -73.57333967282041, 45.52030864642829 ], [ -73.573340873356017, 45.520307546952274 ], [ -73.573381173081884, 45.520327246473251 ], [ -73.573425172976741, 45.520348547117237 ], [ -73.57353603634354, 45.520402360047079 ], [ -73.573619608896152, 45.520311623893825 ], [ -73.573353708862498, 45.520196602777794 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "163186", "ID_UEV": "01119792", "CIVIQUE_DE": "4061", "CIVIQUE_FI": "4077", "NOM_RUE": "rue Saint-Dominique (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "7", "AREA_NEW": "221", "MBG_Width": "18", "MBG_Length": "22", "MBG_Orientation": "33", "Shape_Length": "80", "Shape_Area": "396", "BuildingCategory": "semi-attached", "BuildingVolume": "1547", "AspectRatio": 1.168, "SurfacetoVolumeRatio": 0.143, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "2", "TotalFloorArea": "442", "ANNEE_CONS": "1991", "address": "4061 à 4077" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.579222473921035, 45.517682445429905 ], [ -73.57921957540006, 45.517685645474607 ], [ -73.579140174767261, 45.51777754547107 ], [ -73.579176274152303, 45.517792945526899 ], [ -73.579181774936004, 45.517795246206369 ], [ -73.579333574702929, 45.517858545466083 ], [ -73.579284573890149, 45.517916746099729 ], [ -73.579286272260887, 45.517917529582121 ], [ -73.579436178141819, 45.517755275011176 ], [ -73.579435075326558, 45.517754745771832 ], [ -73.579434874227942, 45.517754646029331 ], [ -73.579417574180937, 45.517773046306672 ], [ -73.579265575000605, 45.517702545869504 ], [ -73.579222473921035, 45.517682445429905 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "154720", "ID_UEV": "05064145", "CIVIQUE_DE": "4420", "CIVIQUE_FI": "4430", "NOM_RUE": "avenue Laval (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "17", "AREA_NEW": "436", "MBG_Width": "18", "MBG_Length": "33", "MBG_Orientation": "123", "Shape_Length": "103", "Shape_Area": "603", "BuildingCategory": "fully-attached", "BuildingVolume": "7412", "AspectRatio": 1.857, "SurfacetoVolumeRatio": 0.059, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "5", "TotalFloorArea": "2180", "ANNEE_CONS": "1976", "address": "4420 à 4430" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.583418376368257, 45.521926846073086 ], [ -73.583410871213744, 45.521934626173078 ], [ -73.583415285356651, 45.521936638591818 ], [ -73.583540763954659, 45.52180061432945 ], [ -73.583534276101659, 45.521797746784124 ], [ -73.583497976598821, 45.521838247237362 ], [ -73.583450676123846, 45.521817347020011 ], [ -73.583459675520473, 45.52180724603739 ], [ -73.583430076048643, 45.521794147089594 ], [ -73.583442975894727, 45.521779746522277 ], [ -73.583418675529643, 45.521768946391582 ], [ -73.583418276143746, 45.521768945783407 ], [ -73.583400876220367, 45.521782946505205 ], [ -73.583380276474088, 45.521770345783594 ], [ -73.583367076878588, 45.521781146301812 ], [ -73.583279576431195, 45.521727846002946 ], [ -73.583230675562717, 45.521697946658719 ], [ -73.583230476163919, 45.521698145668701 ], [ -73.583189275693698, 45.521686946574711 ], [ -73.583146114497453, 45.521675107306947 ], [ -73.583061055890823, 45.521769066618106 ], [ -73.583104776617077, 45.521787046920331 ], [ -73.583103276304072, 45.521788746010351 ], [ -73.583108175851521, 45.521790946154496 ], [ -73.583143075657262, 45.52180724655878 ], [ -73.583311476230662, 45.521885846383761 ], [ -73.583318176092817, 45.521878847039105 ], [ -73.583364176497497, 45.521900946847047 ], [ -73.583418376368257, 45.521926846073086 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "160236", "ID_UEV": "01014249", "CIVIQUE_DE": "4400", "CIVIQUE_FI": "4420", "NOM_RUE": "avenue Coloniale (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "10", "AREA_NEW": "491", "MBG_Width": "18", "MBG_Length": "42", "MBG_Orientation": "123", "Shape_Length": "120", "Shape_Area": "756", "BuildingCategory": "semi-attached", "BuildingVolume": "4910", "AspectRatio": 2.332, "SurfacetoVolumeRatio": 0.1, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "1473", "ANNEE_CONS": "1977", "address": "4400 à 4420" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.584476976684684, 45.52050394605542 ], [ -73.584477076379102, 45.520503846099416 ], [ -73.584518677152431, 45.520459645758464 ], [ -73.584509176430757, 45.520455245369249 ], [ -73.584542276416371, 45.520419645684242 ], [ -73.58410347634215, 45.520218345949942 ], [ -73.584141776596113, 45.520177145542746 ], [ -73.58413976427444, 45.520176224688534 ], [ -73.584018659314424, 45.520309527113092 ], [ -73.584061176623379, 45.520327946161288 ], [ -73.584057576685794, 45.520331945901759 ], [ -73.584063377000206, 45.520333946477898 ], [ -73.584122976229509, 45.520353846665969 ], [ -73.584118576684915, 45.520359846442709 ], [ -73.584153676741153, 45.520374346713979 ], [ -73.584238676293069, 45.520409845756852 ], [ -73.584276976364279, 45.520425946246036 ], [ -73.584327376707691, 45.520447146184345 ], [ -73.584328475587654, 45.520447545802099 ], [ -73.584336176450975, 45.520440746321363 ], [ -73.58443967693627, 45.520499446536846 ], [ -73.584440176454549, 45.520499645932155 ], [ -73.584451776529221, 45.520489545646065 ], [ -73.584476976684684, 45.52050394605542 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "156402", "ID_UEV": "01017181", "CIVIQUE_DE": "4111", "CIVIQUE_FI": "4111", "NOM_RUE": "rue de Mentana (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "14", "AREA_NEW": "178", "MBG_Width": "8", "MBG_Length": "24", "MBG_Orientation": "33", "Shape_Length": "62", "Shape_Area": "180", "BuildingCategory": "fully-attached", "BuildingVolume": "2492", "AspectRatio": 3.1, "SurfacetoVolumeRatio": 0.071, "FloorNu_RawTax": "2", "FloorNu_RawTax.1": "2", "Floor_frmHieght": "4", "TotalFloorArea": "712", "ANNEE_CONS": "1885", "address": "4111" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.574150749847661, 45.524412599616312 ], [ -73.573986662086028, 45.524590780711918 ], [ -73.574071708035248, 45.524624598264325 ], [ -73.57423282482344, 45.524449644004257 ], [ -73.574177972891334, 45.524424946640266 ], [ -73.574171573500891, 45.524422047912516 ], [ -73.574150749847661, 45.524412599616312 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "156386", "ID_UEV": "01017179", "CIVIQUE_DE": "4115", "CIVIQUE_FI": "4115", "NOM_RUE": "rue de Mentana (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "13", "AREA_NEW": "175", "MBG_Width": "8", "MBG_Length": "23", "MBG_Orientation": "33", "Shape_Length": "62", "Shape_Area": "177", "BuildingCategory": "fully-attached", "BuildingVolume": "2275", "AspectRatio": 3.045, "SurfacetoVolumeRatio": 0.077, "FloorNu_RawTax": "2", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "4", "TotalFloorArea": "700", "ANNEE_CONS": "1985", "address": "4115" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.57423282482344, 45.524449644004257 ], [ -73.574071708035248, 45.524624598264325 ], [ -73.574146772698484, 45.524654447640323 ], [ -73.574156760478772, 45.524658409450126 ], [ -73.574314958709209, 45.524486624406023 ], [ -73.57423282482344, 45.524449644004257 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "164746", "ID_UEV": "01016729", "CIVIQUE_DE": "4080", "CIVIQUE_FI": "4080", "NOM_RUE": "rue Saint-André (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "7", "AREA_NEW": "62", "MBG_Width": "7", "MBG_Length": "9", "MBG_Orientation": "33", "Shape_Length": "32", "Shape_Area": "62", "BuildingCategory": "detached", "BuildingVolume": "434", "AspectRatio": 1.233, "SurfacetoVolumeRatio": 0.143, "FloorNu_RawTax": "2", "FloorNu_RawTax.1": "2", "Floor_frmHieght": "2", "TotalFloorArea": "124", "ANNEE_CONS": "1885", "address": "4080" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.574329403251156, 45.523187518837055 ], [ -73.574268326464789, 45.523253620317639 ], [ -73.574345073535241, 45.523287946980233 ], [ -73.574404679473531, 45.523221886909894 ], [ -73.574329403251156, 45.523187518837055 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "147446", "ID_UEV": "01016731", "CIVIQUE_DE": "4082", "CIVIQUE_FI": "4082", "NOM_RUE": "rue Saint-André (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "12", "AREA_NEW": "48", "MBG_Width": "5", "MBG_Length": "14", "MBG_Orientation": "33", "Shape_Length": "38", "Shape_Area": "69", "BuildingCategory": "semi-attached", "BuildingVolume": "576", "AspectRatio": 2.958, "SurfacetoVolumeRatio": 0.083, "FloorNu_RawTax": "2", "FloorNu_RawTax.1": "2", "Floor_frmHieght": "3", "TotalFloorArea": "144", "ANNEE_CONS": "1900", "address": "4082" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.574303534631341, 45.523329405340668 ], [ -73.57427757285474, 45.523359746832789 ], [ -73.574235273212906, 45.52334164705406 ], [ -73.574229072621719, 45.523338947064417 ], [ -73.574163632341296, 45.52341922560192 ], [ -73.574188089582307, 45.523430392031578 ], [ -73.574205073710715, 45.523436847249627 ], [ -73.574205873030081, 45.523437247159158 ], [ -73.574211373945062, 45.523429647136467 ], [ -73.574217234545372, 45.523431762451963 ], [ -73.574309357535597, 45.523332063279497 ], [ -73.574303534631341, 45.523329405340668 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "160240", "ID_UEV": "01016734", "CIVIQUE_DE": "4100", "CIVIQUE_FI": "4100", "NOM_RUE": "rue Saint-André (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "13", "AREA_NEW": "168", "MBG_Width": "12", "MBG_Length": "14", "MBG_Orientation": "122", "Shape_Length": "53", "Shape_Area": "176", "BuildingCategory": "semi-attached", "BuildingVolume": "2184", "AspectRatio": 1.138, "SurfacetoVolumeRatio": 0.077, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "4", "TotalFloorArea": "672", "ANNEE_CONS": "1980", "address": "4100" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.574356272806085, 45.523481946989229 ], [ -73.574403173171007, 45.523498946821199 ], [ -73.574398273101949, 45.523504946546268 ], [ -73.574399974024317, 45.523505647313577 ], [ -73.574456672878796, 45.523526846593043 ], [ -73.574458173233609, 45.523524946952762 ], [ -73.574537773937536, 45.523434046296167 ], [ -73.574494873518475, 45.523415747241344 ], [ -73.574425174074207, 45.523385947682591 ], [ -73.574386445466175, 45.523369468944523 ], [ -73.574300962029042, 45.523461983137004 ], [ -73.574356272806085, 45.523481946989229 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "139578", "ID_UEV": "01104023", "CIVIQUE_DE": "5320", "CIVIQUE_FI": "5320", "NOM_RUE": "rue Saint-Dominique (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Condominium", "Hieght_LiD": "14", "AREA_NEW": "512", "MBG_Width": "17", "MBG_Length": "34", "MBG_Orientation": "123", "Shape_Length": "101", "Shape_Area": "560", "BuildingCategory": "fully-attached", "BuildingVolume": "7168", "AspectRatio": 2.031, "SurfacetoVolumeRatio": 0.071, "FloorNu_RawTax": "1", "FloorNu_RawTax.1": "14", "Floor_frmHieght": "4", "TotalFloorArea": "2048", "ANNEE_CONS": "1988", "address": "5320" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.595845270435873, 45.525129489567512 ], [ -73.595729793915169, 45.525254009935331 ], [ -73.595737081119012, 45.525257345832664 ], [ -73.595938281141557, 45.525348446866509 ], [ -73.596091924064353, 45.525417930219319 ], [ -73.596207672736583, 45.525292624599579 ], [ -73.596138780168857, 45.525275646837358 ], [ -73.596042881484848, 45.525251946544827 ], [ -73.596052580238393, 45.525232546844478 ], [ -73.596052480384614, 45.525232546028597 ], [ -73.595979580480218, 45.525203946510729 ], [ -73.595963780129694, 45.525197546628121 ], [ -73.595865180748319, 45.525156646219315 ], [ -73.5958766816196, 45.525143047187569 ], [ -73.595845270435873, 45.525129489567512 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "132548", "ID_UEV": "01001550", "CIVIQUE_DE": "4575", "CIVIQUE_FI": "4575", "NOM_RUE": "rue Saint-Dominique (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "11", "AREA_NEW": "158", "MBG_Width": "13", "MBG_Length": "13", "MBG_Orientation": "123", "Shape_Length": "52", "Shape_Area": "167", "BuildingCategory": "fully-attached", "BuildingVolume": "1738", "AspectRatio": 1.006, "SurfacetoVolumeRatio": 0.091, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "474", "ANNEE_CONS": "1973", "address": "4575" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.586958475376164, 45.521164531123041 ], [ -73.586889800866061, 45.521239225136924 ], [ -73.586916477872222, 45.521251946580492 ], [ -73.586899376525309, 45.521269645953026 ], [ -73.586895677346433, 45.521273946404456 ], [ -73.587009982857751, 45.521323254327505 ], [ -73.587097731596344, 45.521227812479403 ], [ -73.587083277180113, 45.521221245667 ], [ -73.586960877218203, 45.521165645996419 ], [ -73.586958475376164, 45.521164531123041 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "163117", "ID_UEV": "01096852", "CIVIQUE_DE": "4580", "CIVIQUE_FI": "4580", "NOM_RUE": "rue Saint-Dominique (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "9", "AREA_NEW": "175", "MBG_Width": "11", "MBG_Length": "16", "MBG_Orientation": "33", "Shape_Length": "56", "Shape_Area": "187", "BuildingCategory": "fully-attached", "BuildingVolume": "1575", "AspectRatio": 1.42, "SurfacetoVolumeRatio": 0.111, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "525", "ANNEE_CONS": "1988", "address": "4580" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.587353626853371, 45.521008262997164 ], [ -73.587246055601639, 45.521125108492377 ], [ -73.587251377732215, 45.521127345929564 ], [ -73.587245878376862, 45.521133846077404 ], [ -73.587247177291019, 45.521134446178642 ], [ -73.587295177530677, 45.521152045477081 ], [ -73.587370554753917, 45.521179679534363 ], [ -73.587470291319093, 45.521071571973422 ], [ -73.587457878355508, 45.521064846172926 ], [ -73.587413777696426, 45.521040945975884 ], [ -73.587353626853371, 45.521008262997164 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "131179", "ID_UEV": "01001538", "CIVIQUE_DE": "4588", "CIVIQUE_FI": "4588", "NOM_RUE": "rue Saint-Dominique (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "8", "AREA_NEW": "165", "MBG_Width": "12", "MBG_Length": "14", "MBG_Orientation": "33", "Shape_Length": "53", "Shape_Area": "176", "BuildingCategory": "fully-attached", "BuildingVolume": "1320", "AspectRatio": 1.185, "SurfacetoVolumeRatio": 0.125, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "2", "TotalFloorArea": "330", "ANNEE_CONS": "1987", "address": "4588" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.587470291319093, 45.521071571973422 ], [ -73.587370554753917, 45.521179679534363 ], [ -73.587399377737384, 45.521190246805801 ], [ -73.587467177789705, 45.521215045800488 ], [ -73.58746167744097, 45.521222546581811 ], [ -73.58746267779172, 45.521222945344967 ], [ -73.5875010011558, 45.521239910379478 ], [ -73.587594212536828, 45.521138875055662 ], [ -73.587590177646462, 45.521137145957013 ], [ -73.587590577686598, 45.521136746121172 ], [ -73.587470291319093, 45.521071571973422 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "131178", "ID_UEV": "01001537", "CIVIQUE_DE": "4600", "CIVIQUE_FI": "4600", "NOM_RUE": "rue Saint-Dominique (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "8", "AREA_NEW": "164", "MBG_Width": "12", "MBG_Length": "14", "MBG_Orientation": "33", "Shape_Length": "52", "Shape_Area": "167", "BuildingCategory": "fully-attached", "BuildingVolume": "1312", "AspectRatio": 1.125, "SurfacetoVolumeRatio": 0.125, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "2", "TotalFloorArea": "328", "ANNEE_CONS": "1965", "address": "4600" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.587594212536828, 45.521138875055662 ], [ -73.5875010011558, 45.521239910379478 ], [ -73.587544677625672, 45.521259245977191 ], [ -73.587633128297782, 45.521298318508791 ], [ -73.587727458986549, 45.521196066534301 ], [ -73.587668577536562, 45.521170746140839 ], [ -73.587594212536828, 45.521138875055662 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "153638", "ID_UEV": "05036130", "CIVIQUE_DE": "4605", "CIVIQUE_FI": "4605", "NOM_RUE": "rue Saint-Dominique (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Condominium", "Hieght_LiD": "8", "AREA_NEW": "72", "MBG_Width": "6", "MBG_Length": "13", "MBG_Orientation": "33", "Shape_Length": "40", "Shape_Area": "87", "BuildingCategory": "fully-attached", "BuildingVolume": "576", "AspectRatio": 2.064, "SurfacetoVolumeRatio": 0.125, "FloorNu_RawTax": "1", "FloorNu_RawTax.1": "4", "Floor_frmHieght": "2", "TotalFloorArea": "144", "ANNEE_CONS": "1885", "address": "4605" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.587376211751007, 45.521354413398619 ], [ -73.587283342644369, 45.521455423083637 ], [ -73.587293078217897, 45.521447545641031 ], [ -73.58730407808774, 45.521437746072287 ], [ -73.587366749815743, 45.52147207745368 ], [ -73.587445827511161, 45.521386067799433 ], [ -73.587376211751007, 45.521354413398619 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "131727", "ID_UEV": "01001536", "CIVIQUE_DE": "4610", "CIVIQUE_FI": "4610", "NOM_RUE": "rue Saint-Dominique (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "8", "AREA_NEW": "157", "MBG_Width": "12", "MBG_Length": "14", "MBG_Orientation": "32", "Shape_Length": "50", "Shape_Area": "158", "BuildingCategory": "semi-attached", "BuildingVolume": "1256", "AspectRatio": 1.171, "SurfacetoVolumeRatio": 0.125, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "2", "TotalFloorArea": "314", "ANNEE_CONS": "1965", "address": "4610" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.587727458986549, 45.521196066534301 ], [ -73.587633128297782, 45.521298318508791 ], [ -73.58771717774853, 45.521335446197163 ], [ -73.587759177609982, 45.521354046030808 ], [ -73.587852077664792, 45.521250546075173 ], [ -73.587776678344412, 45.521217146176149 ], [ -73.587776478654106, 45.52121714632959 ], [ -73.587727458986549, 45.521196066534301 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "157628", "ID_UEV": "01001554", "CIVIQUE_DE": "4611", "CIVIQUE_FI": "4611", "NOM_RUE": "rue Saint-Dominique (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "7", "AREA_NEW": "75", "MBG_Width": "6", "MBG_Length": "12", "MBG_Orientation": "33", "Shape_Length": "37", "Shape_Area": "77", "BuildingCategory": "fully-attached", "BuildingVolume": "525", "AspectRatio": 1.845, "SurfacetoVolumeRatio": 0.143, "FloorNu_RawTax": "2", "FloorNu_RawTax.1": "2", "Floor_frmHieght": "2", "TotalFloorArea": "150", "ANNEE_CONS": "1957", "address": "4611" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.587445827511161, 45.521386067799433 ], [ -73.587366749815743, 45.52147207745368 ], [ -73.587432404160182, 45.521508040627523 ], [ -73.587497759527309, 45.521436957192954 ], [ -73.587494878457719, 45.521435546650515 ], [ -73.587513377233805, 45.521416845496361 ], [ -73.58751307738757, 45.521416645961537 ], [ -73.587445827511161, 45.521386067799433 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "139181", "ID_UEV": "01093152", "CIVIQUE_DE": "5155", "CIVIQUE_FI": "5155", "NOM_RUE": "avenue Henri-Julien (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "8", "AREA_NEW": "64", "MBG_Width": "6", "MBG_Length": "11", "MBG_Orientation": "31", "Shape_Length": "35", "Shape_Area": "69", "BuildingCategory": "fully-attached", "BuildingVolume": "512", "AspectRatio": 1.857, "SurfacetoVolumeRatio": 0.125, "FloorNu_RawTax": "2", "FloorNu_RawTax.1": "2", "Floor_frmHieght": "2", "TotalFloorArea": "128", "ANNEE_CONS": "1900", "address": "5155" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.591263464151851, 45.526287638226613 ], [ -73.59119570372313, 45.526365845205341 ], [ -73.591188575795925, 45.526374646826952 ], [ -73.591249879395875, 45.526396446875381 ], [ -73.591270279854825, 45.526372346372639 ], [ -73.591277706501771, 45.526375695939961 ], [ -73.591328157813678, 45.526318265650033 ], [ -73.591271079392968, 45.526291246797555 ], [ -73.591263464151851, 45.526287638226613 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "166967", "ID_UEV": "01093155", "CIVIQUE_DE": "5159", "CIVIQUE_FI": "5159", "NOM_RUE": "avenue Henri-Julien (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "8", "AREA_NEW": "51", "MBG_Width": "7", "MBG_Length": "7", "MBG_Orientation": "34", "Shape_Length": "29", "Shape_Area": "52", "BuildingCategory": "semi-attached", "BuildingVolume": "408", "AspectRatio": 1.071, "SurfacetoVolumeRatio": 0.125, "FloorNu_RawTax": "2", "FloorNu_RawTax.1": "2", "Floor_frmHieght": "2", "TotalFloorArea": "102", "ANNEE_CONS": "1900", "address": "5159" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.591325279587622, 45.526397146983008 ], [ -73.591349479456341, 45.526408547496082 ], [ -73.591402479502975, 45.526353446619567 ], [ -73.591328157813678, 45.526318265650033 ], [ -73.591277706501771, 45.526375695939961 ], [ -73.591325279587622, 45.526397146983008 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "139056", "ID_UEV": "01093163", "CIVIQUE_DE": "5179", "CIVIQUE_FI": "5179", "NOM_RUE": "avenue Henri-Julien (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "11", "AREA_NEW": "114", "MBG_Width": "9", "MBG_Length": "14", "MBG_Orientation": "33", "Shape_Length": "45", "Shape_Area": "119", "BuildingCategory": "semi-attached", "BuildingVolume": "1254", "AspectRatio": 1.565, "SurfacetoVolumeRatio": 0.091, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "342", "ANNEE_CONS": "1959", "address": "5179" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.591514279645494, 45.526551847301953 ], [ -73.591578379026345, 45.526581246777468 ], [ -73.591673979158003, 45.526478447118251 ], [ -73.591580518563475, 45.526435507058615 ], [ -73.591493427647137, 45.526542194330432 ], [ -73.591514279645494, 45.526551847301953 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "161696", "ID_UEV": "01128422", "CIVIQUE_DE": "220", "CIVIQUE_FI": "220", "NOM_RUE": "avenue Laurier Est (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "14", "AREA_NEW": "98", "MBG_Width": "7", "MBG_Length": "14", "MBG_Orientation": "123", "Shape_Length": "42", "Shape_Area": "101", "BuildingCategory": "fully-attached", "BuildingVolume": "1372", "AspectRatio": 1.961, "SurfacetoVolumeRatio": 0.071, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "4", "TotalFloorArea": "392", "ANNEE_CONS": "1995", "address": "220" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.590557624742658, 45.525262900234246 ], [ -73.590504720664725, 45.5253154559067 ], [ -73.590655481713327, 45.525384235282189 ], [ -73.590702512986454, 45.525328897400449 ], [ -73.590557624742658, 45.525262900234246 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "139317", "ID_UEV": "01117392", "CIVIQUE_DE": "3850", "CIVIQUE_FI": "3850", "NOM_RUE": "rue Rivard (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "11", "AREA_NEW": "222", "MBG_Width": "18", "MBG_Length": "19", "MBG_Orientation": "33", "Shape_Length": "75", "Shape_Area": "354", "BuildingCategory": "fully-attached", "BuildingVolume": "2442", "AspectRatio": 1.059, "SurfacetoVolumeRatio": 0.091, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "666", "ANNEE_CONS": "1976", "address": "3850" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.572950668327593, 45.519927696096673 ], [ -73.572816112255566, 45.520073782872913 ], [ -73.572930373562485, 45.52012504677861 ], [ -73.573013449184259, 45.520162315491831 ], [ -73.573092141885695, 45.520076879300881 ], [ -73.573014572629674, 45.520041246634179 ], [ -73.573034772909978, 45.520019445882191 ], [ -73.573027172622233, 45.52001594586261 ], [ -73.573008373584798, 45.520007745934983 ], [ -73.572987472882531, 45.520031345911057 ], [ -73.572906072638432, 45.519995746212771 ], [ -73.572961972343933, 45.519932646098347 ], [ -73.572950668327593, 45.519927696096673 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "162708", "ID_UEV": "01042262", "CIVIQUE_DE": "3800", "CIVIQUE_FI": "3800", "NOM_RUE": "rue De Bullion (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "10", "AREA_NEW": "127", "MBG_Width": "10", "MBG_Length": "18", "MBG_Orientation": "34", "Shape_Length": "57", "Shape_Area": "191", "BuildingCategory": "semi-attached", "BuildingVolume": "1270", "AspectRatio": 1.756, "SurfacetoVolumeRatio": 0.1, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "381", "ANNEE_CONS": "1980", "address": "3800" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.575085773410947, 45.51670754522258 ], [ -73.575005973265348, 45.51679564619446 ], [ -73.575006073102728, 45.516795646128905 ], [ -73.575112351973885, 45.516849027749167 ], [ -73.575241840130744, 45.516711797758802 ], [ -73.575233873745177, 45.51670804526983 ], [ -73.575230873051282, 45.516711545828073 ], [ -73.575191673035178, 45.516754945775844 ], [ -73.575085773410947, 45.51670754522258 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "162718", "ID_UEV": "01042296", "CIVIQUE_DE": "3995", "CIVIQUE_FI": "3995", "NOM_RUE": "rue De Bullion (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "17", "AREA_NEW": "100", "MBG_Width": "9", "MBG_Length": "11", "MBG_Orientation": "34", "Shape_Length": "40", "Shape_Area": "101", "BuildingCategory": "semi-attached", "BuildingVolume": "1700", "AspectRatio": 1.197, "SurfacetoVolumeRatio": 0.059, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "5", "TotalFloorArea": "500", "ANNEE_CONS": "1980", "address": "3995" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.577362113034951, 45.518097894771202 ], [ -73.577285031417759, 45.51818095636402 ], [ -73.577380173814277, 45.518225846199066 ], [ -73.577382873335154, 45.518223045865469 ], [ -73.57745927404018, 45.518144745726659 ], [ -73.577362113034951, 45.518097894771202 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "162726", "ID_UEV": "01001802", "CIVIQUE_DE": "4530", "CIVIQUE_FI": "4530", "NOM_RUE": "avenue Henri-Julien (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "9", "AREA_NEW": "158", "MBG_Width": "12", "MBG_Length": "13", "MBG_Orientation": "122", "Shape_Length": "50", "Shape_Area": "158", "BuildingCategory": "detached", "BuildingVolume": "1422", "AspectRatio": 1.034, "SurfacetoVolumeRatio": 0.111, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "3", "TotalFloorArea": "474", "ANNEE_CONS": "1980", "address": "4530" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.584529976107675, 45.523035946589552 ], [ -73.584668476667062, 45.523096845969846 ], [ -73.584752377018077, 45.523002646985603 ], [ -73.584613876598254, 45.522941746806083 ], [ -73.584529976107675, 45.523035946589552 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "162727", "ID_UEV": "01001804", "CIVIQUE_DE": "4535", "CIVIQUE_FI": "4535", "NOM_RUE": "avenue Henri-Julien (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "11", "AREA_NEW": "161", "MBG_Width": "12", "MBG_Length": "14", "MBG_Orientation": "118", "Shape_Length": "52", "Shape_Area": "169", "BuildingCategory": "semi-attached", "BuildingVolume": "1771", "AspectRatio": 1.118, "SurfacetoVolumeRatio": 0.091, "FloorNu_RawTax": "2", "FloorNu_RawTax.1": "2", "Floor_frmHieght": "3", "TotalFloorArea": "483", "ANNEE_CONS": "1980", "address": "4535" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.584504328100977, 45.523318275073017 ], [ -73.584470063117109, 45.523357528940657 ], [ -73.584430877357136, 45.523409646947947 ], [ -73.584428076873849, 45.52341334646033 ], [ -73.584574755505997, 45.523468170484847 ], [ -73.584656456001568, 45.523374796559551 ], [ -73.584574577402094, 45.523346746210301 ], [ -73.584576876816001, 45.523343546476525 ], [ -73.584505377070585, 45.523318645930914 ], [ -73.584504328100977, 45.523318275073017 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "131611", "ID_UEV": "01042169", "CIVIQUE_DE": "3625", "CIVIQUE_FI": "3625", "NOM_RUE": "avenue Coloniale (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "13", "AREA_NEW": "108", "MBG_Width": "10", "MBG_Length": "11", "MBG_Orientation": "123", "Shape_Length": "42", "Shape_Area": "110", "BuildingCategory": "semi-attached", "BuildingVolume": "1404", "AspectRatio": 1.049, "SurfacetoVolumeRatio": 0.077, "FloorNu_RawTax": "2", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "4", "TotalFloorArea": "432", "ANNEE_CONS": "1973", "address": "3625" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.57205237165654, 45.515028345450077 ], [ -73.572048772358755, 45.515032245832877 ], [ -73.571978971923485, 45.515104845840966 ], [ -73.571984272609697, 45.515107245976758 ], [ -73.572094272716726, 45.515157711689952 ], [ -73.572164341489696, 45.515081822522674 ], [ -73.572142172541405, 45.515071346176207 ], [ -73.57205237165654, 45.515028345450077 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": "134547", "ID_UEV": "01042129", "CIVIQUE_DE": "3875", "CIVIQUE_FI": "3875", "NOM_RUE": "avenue Coloniale (MTL)", "MUNICIPALI": "50", "CODE_UTILI": "1000", "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": "27", "AREA_NEW": "112", "MBG_Width": "11", "MBG_Length": "14", "MBG_Orientation": "33", "Shape_Length": "50", "Shape_Area": "155", "BuildingCategory": "fully-attached", "BuildingVolume": "3024", "AspectRatio": 1.289, "SurfacetoVolumeRatio": 0.037, "FloorNu_RawTax": "3", "FloorNu_RawTax.1": "3", "Floor_frmHieght": "7", "TotalFloorArea": "784", "ANNEE_CONS": "1973", "address": "3875" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.576000098523508, 45.516821494809243 ], [ -73.575908548254077, 45.516921029508254 ], [ -73.575935773506615, 45.516893646348187 ], [ -73.576049597104998, 45.516949519138542 ], [ -73.576124280154033, 45.516868322630735 ], [ -73.576119173713266, 45.516865945954223 ], [ -73.576052272640453, 45.516834845219037 ], [ -73.576044972979702, 45.516842445636847 ], [ -73.576000098523508, 45.516821494809243 ] ] ] } }
]
}

View File

@ -0,0 +1,135 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.5680637695714,
45.49212884162544
],
[
-73.56802228176146,
45.49217205619571
],
[
-73.56815668696326,
45.49223626189717
],
[
-73.56815766959974,
45.49223524178655
],
[
-73.56818746886172,
45.49224944155107
],
[
-73.56822816806918,
45.49220694186927
],
[
-73.5680637695714,
45.49212884162544
]
]
]
},
"id": 175785,
"properties": {
"name": "01044602",
"address": "rue Victor-Hugo (MTL) 1630",
"function": "1000",
"height": 12,
"year_of_construction": 1950
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.56802228176146,
45.49217205619571
],
[
-73.56798225825526,
45.492213743742184
],
[
-73.56811660206223,
45.49227791893211
],
[
-73.56815668696326,
45.49223626189717
],
[
-73.56802228176146,
45.49217205619571
]
]
]
},
"id": 176293,
"properties": {
"name": "01044604",
"address": "rue Victor-Hugo (MTL) 1636",
"function": "1000",
"height": 22,
"year_of_construction": 1986
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.56809506939487,
45.49209624228538
],
[
-73.56809246893268,
45.4920988416879
],
[
-73.56821287000538,
45.49216124158406
],
[
-73.56822186852654,
45.49216584161625
],
[
-73.56826745951075,
45.492118613912375
],
[
-73.56813497596143,
45.49205532773507
],
[
-73.56809506939487,
45.49209624228538
]
]
]
},
"id": 182393,
"properties": {
"name": "01044601",
"address": "rue Victor-Hugo (MTL) 1626",
"function": "1000",
"height": 8,
"year_of_construction": 1901
}
}
]
}

View File

@ -0,0 +1,52 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.5680637695714,
45.49212884162544
],
[
-73.56802228176146,
45.49217205619571
],
[
-73.56815668696326,
45.49223626189717
],
[
-73.56815766959974,
45.49223524178655
],
[
-73.56818746886172,
45.49224944155107
],
[
-73.56822816806918,
45.49220694186927
],
[
-73.5680637695714,
45.49212884162544
]
]
]
},
"id": 175785,
"properties": {
"name": "01044602",
"address": "rue Victor-Hugo (MTL) 1630",
"function": "1000",
"height": 12,
"year_of_construction": 2010
}
}
]
}

View File

@ -0,0 +1,16 @@
{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "OBJECTID": 162726, "id": "01001802", "CIVIQUE_DE": 4530, "CIVIQUE_FI": 4530, "NOM_RUE": "avenue Henri-Julien (MTL)", "MUNICIPALI": 50, "CODE_UTILI": 1000, "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": 9, "AREA_NEW": 158, "MBG_Width": 12, "MBG_Length": 13, "MBG_Orientation": 122, "Shape_Length": 50, "Shape_Area": 158, "BuildingCategory": "detached", "BuildingVolume": 1422, "AspectRatio": 1.034, "SurfacetoVolumeRatio": 0.111, "FloorNu_RawTax": 3, "FloorNu_RawTax.1": 3, "Floor_frmHieght": 3, "TotalFloorArea": 474, "ANNEE_CONS": 1980 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.584529976107675, 45.523035946589552 ], [ -73.584668476667062, 45.523096845969846 ], [ -73.584752377018077, 45.523002646985603 ], [ -73.584613876598254, 45.522941746806083 ], [ -73.584529976107675, 45.523035946589552 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 162727, "id": "01001804", "CIVIQUE_DE": 4535, "CIVIQUE_FI": 4535, "NOM_RUE": "avenue Henri-Julien (MTL)", "MUNICIPALI": 50, "CODE_UTILI": 1000, "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": 11, "AREA_NEW": 161, "MBG_Width": 12, "MBG_Length": 14, "MBG_Orientation": 118, "Shape_Length": 52, "Shape_Area": 169, "BuildingCategory": "semi-attached", "BuildingVolume": 1771, "AspectRatio": 1.118, "SurfacetoVolumeRatio": 0.091, "FloorNu_RawTax": 2, "FloorNu_RawTax.1": 2, "Floor_frmHieght": 3, "TotalFloorArea": 483, "ANNEE_CONS": 1980 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.584504328100977, 45.523318275073017 ], [ -73.584470063117109, 45.523357528940657 ], [ -73.584430877357136, 45.523409646947947 ], [ -73.584428076873849, 45.52341334646033 ], [ -73.584574755505997, 45.523468170484847 ], [ -73.584656456001568, 45.523374796559551 ], [ -73.584574577402094, 45.523346746210301 ], [ -73.584576876816001, 45.523343546476525 ], [ -73.584505377070585, 45.523318645930914 ], [ -73.584504328100977, 45.523318275073017 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 162168, "id": "01001944", "CIVIQUE_DE": 4820, "CIVIQUE_FI": 4850, "NOM_RUE": "rue de Grand-Pré (MTL)", "MUNICIPALI": 50, "CODE_UTILI": 1000, "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": 11, "AREA_NEW": 504, "MBG_Width": 16, "MBG_Length": 42, "MBG_Orientation": 123, "Shape_Length": 116, "Shape_Area": 669, "BuildingCategory": "fully-attached", "BuildingVolume": 5544, "AspectRatio": 2.648, "SurfacetoVolumeRatio": 0.091, "FloorNu_RawTax": 3, "FloorNu_RawTax.1": 3, "Floor_frmHieght": 3, "TotalFloorArea": 1512, "ANNEE_CONS": 1980 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.586673951057165, 45.524838247152971 ], [ -73.586568305570552, 45.524952686098082 ], [ -73.58662307714782, 45.524979547084882 ], [ -73.586731877320233, 45.525032846618785 ], [ -73.586815478124791, 45.525073847297307 ], [ -73.586820877038548, 45.525068346972965 ], [ -73.586874077743531, 45.525094146322125 ], [ -73.586895378594193, 45.525104346900406 ], [ -73.586943277305565, 45.525127046703169 ], [ -73.587016976014752, 45.525161993449707 ], [ -73.587125015986871, 45.525044959829344 ], [ -73.587121277851907, 45.525043246686081 ], [ -73.587092777275416, 45.525074446965931 ], [ -73.587032277294412, 45.525047146948445 ], [ -73.587039678023586, 45.525038947369048 ], [ -73.587033777622878, 45.525036346828877 ], [ -73.586929477897286, 45.524990346357107 ], [ -73.58664877714105, 45.524866746179505 ], [ -73.586674177796809, 45.524838346863149 ], [ -73.586673951057165, 45.524838247152971 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 160896, "id": "01024652", "CIVIQUE_DE": 350, "CIVIQUE_FI": 350, "NOM_RUE": "rue Boucher (MTL)", "MUNICIPALI": 50, "CODE_UTILI": 1000, "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": 22, "AREA_NEW": 863, "MBG_Width": 23, "MBG_Length": 48, "MBG_Orientation": 121, "Shape_Length": 142, "Shape_Area": 1115, "BuildingCategory": "detached", "BuildingVolume": 18986, "AspectRatio": 2.038, "SurfacetoVolumeRatio": 0.045, "FloorNu_RawTax": 4, "FloorNu_RawTax.1": 4, "Floor_frmHieght": 6, "TotalFloorArea": 5178, "ANNEE_CONS": 1991 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.591937079830473, 45.5275066477327 ], [ -73.591937179849452, 45.52750674753436 ], [ -73.591964178776365, 45.527466247428634 ], [ -73.592026878777105, 45.527486947227878 ], [ -73.592027580168264, 45.527486846780647 ], [ -73.592013879829011, 45.527422746963936 ], [ -73.591984880030196, 45.527286547239505 ], [ -73.591984579182366, 45.527286547481765 ], [ -73.591875879019881, 45.527239846914121 ], [ -73.591626180051733, 45.527132446482739 ], [ -73.591624679856523, 45.527134147482663 ], [ -73.591472379004458, 45.527302947133734 ], [ -73.59147727935661, 45.527305146916163 ], [ -73.591543180175734, 45.527334146336074 ], [ -73.59156227958276, 45.527312847127916 ], [ -73.591817879694347, 45.527425747269653 ], [ -73.591794879188384, 45.527451547052145 ], [ -73.591794980324778, 45.52745154697088 ], [ -73.591937079830473, 45.5275066477327 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 158453, "id": "01026412", "CIVIQUE_DE": 3964, "CIVIQUE_FI": 3964, "NOM_RUE": "rue Rivard (MTL)", "MUNICIPALI": 50, "CODE_UTILI": 1000, "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": 13, "AREA_NEW": 155, "MBG_Width": 12, "MBG_Length": 13, "MBG_Orientation": 33, "Shape_Length": 51, "Shape_Area": 161, "BuildingCategory": "semi-attached", "BuildingVolume": 2015, "AspectRatio": 1.053, "SurfacetoVolumeRatio": 0.077, "FloorNu_RawTax": 3, "FloorNu_RawTax.1": 3, "Floor_frmHieght": 4, "TotalFloorArea": 620, "ANNEE_CONS": 1981 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.574691673036824, 45.520801446234479 ], [ -73.574606373743563, 45.520895346331137 ], [ -73.574608572928923, 45.520896346417111 ], [ -73.574741150104259, 45.52095245567763 ], [ -73.574829542976886, 45.520856483821881 ], [ -73.574691673036824, 45.520801446234479 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 160314, "id": "01027192", "CIVIQUE_DE": 3876, "CIVIQUE_FI": 3880, "NOM_RUE": "rue de Mentana (MTL)", "MUNICIPALI": 50, "CODE_UTILI": 1000, "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": 12, "AREA_NEW": 366, "MBG_Width": 16, "MBG_Length": 32, "MBG_Orientation": 110, "Shape_Length": 96, "Shape_Area": 507, "BuildingCategory": "semi-attached", "BuildingVolume": 4392, "AspectRatio": 2.009, "SurfacetoVolumeRatio": 0.083, "FloorNu_RawTax": 3, "FloorNu_RawTax.1": 3, "Floor_frmHieght": 3, "TotalFloorArea": 1098, "ANNEE_CONS": 1980 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.570800071665957, 45.522686946460304 ], [ -73.57093107256577, 45.522726047825749 ], [ -73.571028271866595, 45.522613046698432 ], [ -73.570955272361019, 45.522582046683695 ], [ -73.57092677184869, 45.522615346769584 ], [ -73.570836471663341, 45.522577047118958 ], [ -73.570681923964358, 45.522511513915816 ], [ -73.570599160784397, 45.522601741674258 ], [ -73.57068447255547, 45.522631046198299 ], [ -73.570683872035971, 45.52263194640998 ], [ -73.5706905727058, 45.522641647038853 ], [ -73.570695971264669, 45.522651146908998 ], [ -73.570720172024352, 45.522643346512112 ], [ -73.570741072289536, 45.522674046912528 ], [ -73.570768873124834, 45.522664547177342 ], [ -73.570786672496425, 45.522690747590424 ], [ -73.570800772812049, 45.522685647556457 ], [ -73.570800071665957, 45.522686946460304 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 160961, "id": "01027868", "CIVIQUE_DE": 1315, "CIVIQUE_FI": 1315, "NOM_RUE": "rue Gilford (MTL)", "MUNICIPALI": 50, "CODE_UTILI": 1000, "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": 25, "AREA_NEW": 792, "MBG_Width": 21, "MBG_Length": 39, "MBG_Orientation": 33, "Shape_Length": 119, "Shape_Area": 799, "BuildingCategory": "detached", "BuildingVolume": 19800, "AspectRatio": 1.892, "SurfacetoVolumeRatio": 0.04, "FloorNu_RawTax": 7, "FloorNu_RawTax.1": 7, "Floor_frmHieght": 7, "TotalFloorArea": 5544, "ANNEE_CONS": 1982 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.58083517681375, 45.531873048325558 ], [ -73.580835076949739, 45.531873048396221 ], [ -73.580854575894378, 45.531884548031371 ], [ -73.580836876619628, 45.53189954827026 ], [ -73.580834276336617, 45.531902247826601 ], [ -73.581032076072006, 45.531993748148139 ], [ -73.581035576182472, 45.531995348277754 ], [ -73.581308475569898, 45.531702748189019 ], [ -73.581094575638417, 45.5316043481116 ], [ -73.58108917684747, 45.531601847693175 ], [ -73.58083517681375, 45.531873048325558 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 160929, "id": "01030953", "CIVIQUE_DE": 5115, "CIVIQUE_FI": 5115, "NOM_RUE": "rue Clark (MTL)", "MUNICIPALI": 50, "CODE_UTILI": 1000, "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": 14, "AREA_NEW": 181, "MBG_Width": 13, "MBG_Length": 17, "MBG_Orientation": 33, "Shape_Length": 60, "Shape_Area": 217, "BuildingCategory": "semi-attached", "BuildingVolume": 2534, "AspectRatio": 1.366, "SurfacetoVolumeRatio": 0.071, "FloorNu_RawTax": 2, "FloorNu_RawTax.1": 2, "Floor_frmHieght": 4, "TotalFloorArea": 724, "ANNEE_CONS": 1983 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.593727979935949, 45.522833645694313 ], [ -73.593622379981483, 45.522943045763455 ], [ -73.593627979641539, 45.5229456462108 ], [ -73.593757046904472, 45.523005285227981 ], [ -73.59376545085415, 45.522996062168147 ], [ -73.593790280472035, 45.522967946078182 ], [ -73.593790847971491, 45.522968193968069 ], [ -73.593875827697602, 45.522874944824011 ], [ -73.59387543312792, 45.522874766080079 ], [ -73.593855979643365, 45.52289494658158 ], [ -73.593791679795828, 45.52286404669664 ], [ -73.593727979935949, 45.522833645694313 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 159711, "id": "01031631", "CIVIQUE_DE": 5222, "CIVIQUE_FI": 5222, "NOM_RUE": "avenue Casgrain (MTL)", "MUNICIPALI": 50, "CODE_UTILI": 1000, "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": 10, "AREA_NEW": 146, "MBG_Width": 10, "MBG_Length": 15, "MBG_Orientation": 32, "Shape_Length": 50, "Shape_Area": 147, "BuildingCategory": "semi-attached", "BuildingVolume": 1460, "AspectRatio": 1.607, "SurfacetoVolumeRatio": 0.1, "FloorNu_RawTax": 2, "FloorNu_RawTax.1": 2, "Floor_frmHieght": 3, "TotalFloorArea": 438, "ANNEE_CONS": 1983 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.594000879767933, 45.525218447055174 ], [ -73.594043080289808, 45.525236947218026 ], [ -73.5941039805478, 45.525264146909009 ], [ -73.594208881213859, 45.52514714696995 ], [ -73.594107197565634, 45.525102137119283 ], [ -73.594000390389937, 45.525218232396192 ], [ -73.594000879767933, 45.525218447055174 ] ] ] } },
{ "type": "Feature", "properties": { "OBJECTID": 162724, "id": "01093229", "CIVIQUE_DE": 5180, "CIVIQUE_FI": 5180, "NOM_RUE": "rue Drolet (MTL)", "MUNICIPALI": 50, "CODE_UTILI": 1000, "LIBELLE_UT": "Logement", "CATEGORIE_": "Régulier", "Hieght_LiD": 13, "AREA_NEW": 162, "MBG_Width": 13, "MBG_Length": 13, "MBG_Orientation": 32, "Shape_Length": 52, "Shape_Area": 171, "BuildingCategory": "fully-attached", "BuildingVolume": 2106, "AspectRatio": 1.061, "SurfacetoVolumeRatio": 0.077, "FloorNu_RawTax": 3, "FloorNu_RawTax.1": 3, "Floor_frmHieght": 4, "TotalFloorArea": 648, "ANNEE_CONS": 1989 }, "geometry": { "type": "Polygon", "coordinates": [ [ [ -73.591401779194541, 45.526781846358489 ], [ -73.591391179875345, 45.526792546731429 ], [ -73.591396178918018, 45.526794847220536 ], [ -73.591449340007159, 45.526819974082471 ], [ -73.591532003408886, 45.52672522496804 ], [ -73.591538651998277, 45.526716092568755 ], [ -73.591526179377823, 45.526710747618488 ], [ -73.591400782956626, 45.526656800065901 ], [ -73.591320310492023, 45.526757487175246 ], [ -73.591374078538919, 45.526782746763345 ], [ -73.59137467927394, 45.526782946946994 ], [ -73.591384179409957, 45.526773347058757 ], [ -73.591401779194541, 45.526781846358489 ] ] ] } }
]
}

View File

@ -0,0 +1,135 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.5680637695714,
45.49212884162544
],
[
-73.56802228176146,
45.49217205619571
],
[
-73.56815668696326,
45.49223626189717
],
[
-73.56815766959974,
45.49223524178655
],
[
-73.56818746886172,
45.49224944155107
],
[
-73.56822816806918,
45.49220694186927
],
[
-73.5680637695714,
45.49212884162544
]
]
]
},
"id": 175785,
"properties": {
"name": "01044602",
"address": "rue Victor-Hugo (MTL) 1630",
"function": "1000",
"height": 12,
"year_of_construction": 1986
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.56802228176146,
45.49217205619571
],
[
-73.56798225825526,
45.492213743742184
],
[
-73.56811660206223,
45.49227791893211
],
[
-73.56815668696326,
45.49223626189717
],
[
-73.56802228176146,
45.49217205619571
]
]
]
},
"id": 176293,
"properties": {
"name": "01044604",
"address": "rue Victor-Hugo (MTL) 1636",
"function": "1000",
"height": 12,
"year_of_construction": 1986
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.56809506939487,
45.49209624228538
],
[
-73.56809246893268,
45.4920988416879
],
[
-73.56821287000538,
45.49216124158406
],
[
-73.56822186852654,
45.49216584161625
],
[
-73.56826745951075,
45.492118613912375
],
[
-73.56813497596143,
45.49205532773507
],
[
-73.56809506939487,
45.49209624228538
]
]
]
},
"id": 182393,
"properties": {
"name": "01044601",
"address": "rue Victor-Hugo (MTL) 1626",
"function": "1000",
"height": 8,
"year_of_construction": 1986
}
}
]
}

View File

@ -0,0 +1,20 @@
{
"175785": {
"retrofit_types": ["construction", "windows", "infiltration"],
"wall_u_value": 0.2,
"roof_u_value": 0.15,
"ground_u_value": 0.18,
"infiltration_reduction": 30,
"window_u_value": 0.8,
"window_g_value": 0.4
},
"176293": {
"retrofit_types": ["windows"],
"window_u_value": 1.3,
"window_g_value": 0.5
},
"182393": {
"retrofit_types": ["infiltration"],
"infiltration_reduction": 25
}
}

16
main.py
View File

@ -6,11 +6,17 @@ from hub.helpers.dictionaries import Dictionaries
from hub.imports.construction_factory import ConstructionFactory
from hub.imports.usage_factory import UsageFactory
from hub.imports.weather_factory import WeatherFactory
from hub.imports.retrofit_factory import RetrofitFactory
import json
# Specify the GeoJSON file path
input_files_path = (Path(__file__).parent / 'input_files')
input_files_path.mkdir(parents=True, exist_ok=True)
geojson_file = process_geojson(x=-73.5681295982132, y=45.49218262677643, diff=0.0001)
geojson_file_path = input_files_path / 'output_buildings.geojson'
geojson_file_path = input_files_path / 'input_buildings.geojson'
retrofit_json_file_path = input_files_path / 'retrofit_scenarios.json'
with open(retrofit_json_file_path, 'r') as f:
retrofit_data = json.load(f)
output_path = (Path(__file__).parent / 'out_files').resolve()
output_path.mkdir(parents=True, exist_ok=True)
# Create city object from GeoJSON file
@ -21,8 +27,12 @@ city = GeometryFactory('geojson',
function_field='function',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
# Enrich city data
ConstructionFactory('nrcan', city).enrich()
UsageFactory('nrcan', city).enrich()
ConstructionFactory('cerc', city).enrich()
UsageFactory('cerc', city).enrich()
RetrofitFactory(retrofit_data, city).enrich()
WeatherFactory('epw', city).enrich()
energy_plus_workflow(city)

View File

@ -1,5 +1,5 @@
xmltodict
numpy
numpy==1.26.4
trimesh[all]
pyproj
pandas
@ -24,4 +24,5 @@ triangle
psycopg2-binary
Pillow
pathlib
sqlalchemy_utils
sqlalchemy_utils
build

View File

@ -0,0 +1,80 @@
from hub.imports.energy_systems_factory import EnergySystemsFactory
from hub.imports.results_factory import ResultFactory
from pathlib import Path
from hub.imports.geometry_factory import GeometryFactory
from hub.helpers.dictionaries import Dictionaries
from hub.imports.construction_factory import ConstructionFactory
from hub.imports.usage_factory import UsageFactory
from hub.imports.weather_factory import WeatherFactory
import json
import hub.helpers.constants as cte
from scripts.energy_system_sizing_and_simulation_factory import EnergySystemsSimulationFactory
# Specify the GeoJSON file path
input_files_path = (Path(__file__).parent / 'input_files')
geojson_file_path = input_files_path / 'omhm_selected_buildings.geojson'
output_path = (Path(__file__).parent / 'out_files').resolve()
output_path.mkdir(parents=True, exist_ok=True)
ep_output_path = output_path / 'ep_outputs'
ep_output_path.mkdir(parents=True, exist_ok=True)
# Create city object from GeoJSON file
city = GeometryFactory('geojson',
path=geojson_file_path,
height_field='Hieght_LiD',
year_of_construction_field='ANNEE_CONS',
function_field='CODE_UTILI',
function_to_hub=Dictionaries().montreal_function_to_hub_function).city
# Enrich city data
ConstructionFactory('nrcan', city).enrich()
UsageFactory('nrcan', city).enrich()
WeatherFactory('epw', city).enrich()
ResultFactory('energy_plus_multiple_buildings', city, ep_output_path).enrich()
# for building in city.buildings:
# building.energy_systems_archetype_name = 'system 7 electricity pv'
# EnergySystemsFactory('montreal_custom', city).enrich()
for building in city.buildings:
building.energy_systems_archetype_name = 'PV+4Pipe+DHW'
EnergySystemsFactory('montreal_future', city).enrich()
for building in city.buildings:
EnergySystemsSimulationFactory('archetype13', building=building, output_path=output_path).enrich()
month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
building_data = {}
for building in city.buildings:
building_data[f'building_{building.name}'] = {'id': building.name,
'total_floor_area':
building.thermal_zones_from_internal_zones[0].total_floor_area,
'yearly_heating_consumption_kWh':
building.heating_consumption[cte.YEAR][0] / 3.6e6,
'yearly_cooling_consumption_kWh':
building.cooling_consumption[cte.YEAR][0] / 3.6e6,
'yearly_dhw_consumption_kWh':
building.domestic_hot_water_consumption[cte.YEAR][0] / 3.6e6,
'yearly_appliance_electricity_consumption_kWh':
building.appliances_electrical_demand[cte.YEAR][0] / 3.6e6,
'yearly_lighting_electricity_consumption_kWh':
building.lighting_electrical_demand[cte.YEAR][0] / 3.6e6,
'heating_peak_load_kW': max(
building.heating_consumption[cte.HOUR]) / 3.6e6,
'cooling_peak_load_kW': max(
building.cooling_consumption[cte.HOUR]) / 3.6e6,
'monthly_heating_demand':
{month_name: building.heating_demand[cte.MONTH][i] / 3.6e6
for (i, month_name) in enumerate(month_names)},
'monthly_heating_consumption_kWh':
{month_name: building.heating_consumption[cte.MONTH][i] / 3.6e6
for (i, month_name) in enumerate(month_names)},
'monthly_cooling_demand_kWh':
{month_name: building.cooling_demand[cte.MONTH][i] / 3.6e6
for (i, month_name) in enumerate(month_names)},
'monthly_cooling_consumption_kWh':
{month_name: building.cooling_consumption[cte.MONTH][i] / 3.6e6
for (i, month_name) in enumerate(month_names)},
'monthly_dhw_demand_kWh':
{month_name: building.domestic_hot_water_heat_demand[cte.MONTH][i] / 3.6e6
for (i, month_name) in enumerate(month_names)},
'monthly_dhw_consumption_kWh':
{month_name: building.domestic_hot_water_consumption[cte.MONTH][i] /
3.6e6 for (i, month_name) in enumerate(month_names)}}
with open(output_path / "air_to_water_hp_buildings_data.json", "w") as json_file:
json.dump(building_data, json_file, indent=4)

View File

@ -0,0 +1,35 @@
"""
EnergySystemSizingSimulationFactory retrieve the energy system archetype sizing and simulation module
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Saeed Ranjbar saeed.ranjbar@mail.concordia.ca
"""
from scripts.system_simulation_models.archetype13 import Archetype13
class EnergySystemsSimulationFactory:
"""
EnergySystemsFactory class
"""
def __init__(self, handler, building, output_path):
self._output_path = output_path
self._handler = '_' + handler.lower()
self._building = building
def _archetype13(self):
"""
Enrich the city by using the sizing and simulation model developed for archetype13 of montreal_future_systems
"""
Archetype13(self._building, self._output_path).enrich_buildings()
self._building.level_of_detail.energy_systems = 2
self._building.level_of_detail.energy_systems = 2
def enrich(self):
"""
Enrich the city given to the class using the class given handler
:return: None
"""
getattr(self, self._handler, lambda: None)()

56
scripts/monthly_dhw.py Normal file
View File

@ -0,0 +1,56 @@
import json
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import MaxNLocator
output_path = (Path(__file__).parent / 'out_files').resolve()
# File paths for the three JSON files
file1 = output_path / 'base_case_buildings_data.json'
file2 = output_path / 'air_to_air_hp_buildings_data.json'
file3 = output_path / 'air_to_water_hp_buildings_data.json'
# Opening and reading all three JSON files at the same time
with open(file1) as f1, open(file2) as f2, open(file3) as f3:
base_case = json.load(f1)
air = json.load(f2)
water = json.load(f3)
month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
x = np.arange(len(month_names)) # the label locations
width = 0.25 # the width of the bars
# Prettier colors for each scenario
colors = ['#66B2FF', '#e74c3c'] # Blue, Red, Green
# Plotting heating data for all buildings in a 2x5 grid
fig, axes = plt.subplots(2, 5, figsize=(20, 10), dpi=96)
fig.suptitle('Monthly DHW Consumption Comparison Across Buildings', fontsize=16, weight='bold', alpha=0.8)
axes = axes.flatten()
for idx, building_name in enumerate(base_case.keys()):
heating_data = [list(data["monthly_dhw_consumption_kWh"].values()) for data in
[base_case[building_name], water[building_name]]]
ax = axes[idx]
for i, data in enumerate(heating_data):
ax.bar(x + (i - 1) * width, data, width, label=f'Scenario {i+1}', color=colors[i], zorder=2)
# Grid settings
ax.grid(which="major", axis='x', color='#DAD8D7', alpha=0.5, zorder=1)
ax.grid(which="major", axis='y', color='#DAD8D7', alpha=0.5, zorder=1)
# Axis labels and title
ax.set_title(building_name, fontsize=14, weight='bold', alpha=0.8, pad=10)
ax.set_xticks(x)
ax.set_xticklabels(month_names, rotation=45, ha='right')
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
ax.yaxis.set_major_locator(MaxNLocator(integer=True))
if idx % 5 == 0:
ax.set_ylabel('DHW Consumption (kWh)', fontsize=12, labelpad=10)
fig.legend(['Base Case', 'Scenario 1&2'], loc='upper right', ncol=3)
plt.tight_layout(rect=[0, 0.03, 1, 0.95])
plt.savefig(output_path / 'monthly_dhw.png')

View File

@ -0,0 +1,87 @@
import json
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import MaxNLocator
output_path = (Path(__file__).parent / 'out_files').resolve()
# File paths for the three JSON files
file1 = output_path / 'base_case_buildings_data.json'
file2 = output_path / 'air_to_air_hp_buildings_data.json'
file3 = output_path / 'air_to_water_hp_buildings_data.json'
# Opening and reading all three JSON files at the same time
with open(file1) as f1, open(file2) as f2, open(file3) as f3:
base_case = json.load(f1)
air = json.load(f2)
water = json.load(f3)
month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
x = np.arange(len(month_names)) # the label locations
width = 0.25 # the width of the bars
# Prettier colors for each scenario
colors = ['#66B2FF', '#e74c3c', '#2ecc71'] # Blue, Red, Green
# Plotting heating data for all buildings in a 2x5 grid
fig, axes = plt.subplots(2, 5, figsize=(20, 10), dpi=96)
fig.suptitle('Monthly Heating Consumption Comparison Across Buildings', fontsize=16, weight='bold', alpha=0.8)
axes = axes.flatten()
for idx, building_name in enumerate(base_case.keys()):
heating_data = [list(data["monthly_heating_consumption_kWh"].values()) for data in
[base_case[building_name], air[building_name], water[building_name]]]
ax = axes[idx]
for i, data in enumerate(heating_data):
ax.bar(x + (i - 1) * width, data, width, label=f'Scenario {i+1}', color=colors[i], zorder=2)
# Grid settings
ax.grid(which="major", axis='x', color='#DAD8D7', alpha=0.5, zorder=1)
ax.grid(which="major", axis='y', color='#DAD8D7', alpha=0.5, zorder=1)
# Axis labels and title
ax.set_title(building_name, fontsize=14, weight='bold', alpha=0.8, pad=10)
ax.set_xticks(x)
ax.set_xticklabels(month_names, rotation=45, ha='right')
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
ax.yaxis.set_major_locator(MaxNLocator(integer=True))
if idx % 5 == 0:
ax.set_ylabel('Heating Consumption (kWh)', fontsize=12, labelpad=10)
fig.legend(['Base Case', 'Scenario 1', 'Scenario 2'], loc='upper right', ncol=3)
plt.tight_layout(rect=[0, 0.03, 1, 0.95])
plt.savefig(output_path / 'monthly_heating.png')
# Plotting cooling data for all buildings in a 2x5 grid
# Plotting cooling data for all buildings in a 2x5 grid
fig, axes = plt.subplots(2, 5, figsize=(20, 10), dpi=96)
fig.suptitle('Monthly Cooling Consumption Comparison Across Buildings', fontsize=16, weight='bold', alpha=0.8)
axes = axes.flatten()
for idx, building_name in enumerate(base_case.keys()):
cooling_data = [list(data["monthly_cooling_consumption_kWh"].values()) for data in
[base_case[building_name], air[building_name], water[building_name]]]
ax = axes[idx]
for i, data in enumerate(cooling_data):
ax.bar(x + (i - 1) * width, data, width, label=f'Scenario {i+1}', color=colors[i], zorder=2)
# Grid settings
ax.grid(which="major", axis='x', color='#DAD8D7', alpha=0.5, zorder=1)
ax.grid(which="major", axis='y', color='#DAD8D7', alpha=0.5, zorder=1)
# Axis labels and title
ax.set_title(building_name, fontsize=14, weight='bold', alpha=0.8, pad=10)
ax.set_xticks(x)
ax.set_xticklabels(month_names, rotation=45, ha='right')
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
ax.yaxis.set_major_locator(MaxNLocator(integer=True))
if idx % 5 == 0:
ax.set_ylabel('Cooling Consumption (kWh)', fontsize=12, labelpad=10)
fig.legend(['Base Case', 'Scenario 1', 'Scenario 2'], loc='upper right', ncol=3)
plt.tight_layout(rect=[0, 0.03, 1, 0.95])
plt.savefig(output_path / 'monthly_cooling.png')

73
scripts/peak_load.py Normal file
View File

@ -0,0 +1,73 @@
import json
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import MaxNLocator
from matplotlib.patches import Patch
output_path = (Path(__file__).parent / 'out_files').resolve()
# File paths for the three JSON files
file1 = output_path / 'base_case_buildings_data.json'
file2 = output_path / 'air_to_air_hp_buildings_data.json'
file3 = output_path / 'air_to_water_hp_buildings_data.json'
# Opening and reading all three JSON files at the same time
with open(file1) as f1, open(file2) as f2, open(file3) as f3:
base_case = json.load(f1)
air = json.load(f2)
water = json.load(f3)
month_names = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
x = np.arange(len(month_names)) # the label locations
# Scenario labels and color palette
scenarios = ['Scenario 1', 'Scenario 2']
colors = ['#66B2FF', '#e74c3c'] # Blue for Scenario 1, Red for Scenario 2
width = 0.25 # Width for each bar
# Creating the grid for peak load comparisons across buildings
fig, axes = plt.subplots(2, 5, figsize=(20, 10), dpi=96)
fig.suptitle('Yearly Heating and Cooling Peak Load Comparison Across Buildings', fontsize=16, weight='bold', alpha=0.8)
axes = axes.flatten()
for idx, building_name in enumerate(base_case.keys()):
# Extracting heating and cooling peak loads for each scenario
heating_peak_load = [
air[building_name]["heating_peak_load_kW"],
water[building_name]["heating_peak_load_kW"]
]
cooling_peak_load = [
air[building_name]["cooling_peak_load_kW"],
water[building_name]["cooling_peak_load_kW"]
]
ax = axes[idx]
x = np.arange(2) # X locations for the "Heating" and "Cooling" groups
# Plotting each scenario for heating and cooling
for i in range(len(scenarios)):
ax.bar(x[0] - width + i * width, heating_peak_load[i], width, color=colors[i], zorder=2)
ax.bar(x[1] - width + i * width, cooling_peak_load[i], width, color=colors[i], zorder=2)
# Grid and styling
ax.grid(which="major", axis='x', color='#DAD8D7', alpha=0.5, zorder=1)
ax.grid(which="major", axis='y', color='#DAD8D7', alpha=0.5, zorder=1)
# Axis and title settings
ax.set_title(building_name, fontsize=14, weight='bold', alpha=0.8, pad=10)
ax.set_xticks(x)
ax.set_xticklabels(['Heating Peak Load', 'Cooling Peak Load'])
ax.xaxis.set_major_locator(MaxNLocator(integer=True))
ax.yaxis.set_major_locator(MaxNLocator(integer=True))
if idx % 5 == 0:
ax.set_ylabel('Peak Load (kW)', fontsize=12, labelpad=10)
# Custom legend handles to ensure color match with scenarios
legend_handles = [Patch(color=colors[i], label=scenarios[i]) for i in range(len(scenarios))]
# Global legend and layout adjustments
fig.legend(handles=legend_handles, loc='upper right', ncol=1)
plt.tight_layout(rect=[0, 0.03, 1, 0.95])
plt.savefig(output_path / 'peak_loads.png')

View File

@ -0,0 +1,391 @@
import math
import hub.helpers.constants as cte
import csv
from hub.helpers.monthly_values import MonthlyValues
class Archetype13:
def __init__(self, building, output_path):
self._building = building
self._name = building.name
self._pv_system = building.energy_systems[0]
self._hvac_system = building.energy_systems[1]
self._dhw_system = building.energy_systems[-1]
self._dhw_peak_flow_rate = (building.thermal_zones_from_internal_zones[0].total_floor_area *
building.thermal_zones_from_internal_zones[0].domestic_hot_water.peak_flow *
cte.WATER_DENSITY)
self._heating_peak_load = building.heating_peak_load[cte.YEAR][0]
self._cooling_peak_load = building.cooling_peak_load[cte.YEAR][0]
self._domestic_hot_water_peak_load = building.domestic_hot_water_peak_load[cte.YEAR][0]
self._hourly_heating_demand = [demand / cte.HOUR_TO_SECONDS for demand in building.heating_demand[cte.HOUR]]
self._hourly_cooling_demand = [demand / cte.HOUR_TO_SECONDS for demand in building.cooling_demand[cte.HOUR]]
self._hourly_dhw_demand = [demand / cte.WATTS_HOUR_TO_JULES for demand in
building.domestic_hot_water_heat_demand[cte.HOUR]]
self._output_path = output_path
self._t_out = building.external_temperature[cte.HOUR]
self.results = {}
self.dt = 900
def hvac_sizing(self):
storage_factor = 1.5
heat_pump = self._hvac_system.generation_systems[1]
boiler = self._hvac_system.generation_systems[0]
thermal_storage = boiler.energy_storage_systems[0]
heat_pump.nominal_heat_output = round(self._heating_peak_load)
heat_pump.nominal_cooling_output = round(self._cooling_peak_load)
boiler.nominal_heat_output = 0
thermal_storage.volume = round(
(self._heating_peak_load * storage_factor * cte.WATTS_HOUR_TO_JULES) /
(cte.WATER_HEAT_CAPACITY * cte.WATER_DENSITY * 25))
return heat_pump, boiler, thermal_storage
def dhw_sizing(self):
storage_factor = 3
dhw_hp = self._dhw_system.generation_systems[0]
dhw_hp.nominal_heat_output = 0.7 * self._domestic_hot_water_peak_load
dhw_hp.source_temperature = self._t_out
dhw_tes = dhw_hp.energy_storage_systems[0]
dhw_tes.volume = round(
(self._domestic_hot_water_peak_load * storage_factor * 3600) / (cte.WATER_HEAT_CAPACITY * cte.WATER_DENSITY * 10))
if dhw_tes.volume == 0:
dhw_tes.volume = 1
return dhw_hp, dhw_tes
def heating_system_simulation(self):
hp, boiler, tes = self.hvac_sizing()
heat_efficiency = float(hp.heat_efficiency)
cop_curve_coefficients = [float(coefficient) for coefficient in hp.heat_efficiency_curve.coefficients]
number_of_ts = int(cte.HOUR_TO_SECONDS / self.dt)
demand = [0] + [x for x in self._hourly_heating_demand for _ in range(number_of_ts)]
t_out = [0] + [x for x in self._t_out for _ in range(number_of_ts)]
hp.source_temperature = self._t_out
variable_names = ["t_sup_hp", "t_tank", "t_ret", "m_ch", "m_dis", "q_hp", "q_boiler", "hp_cop",
"hp_electricity", "boiler_gas_consumption", "t_sup_boiler", "boiler_energy_consumption",
"heating_consumption"]
num_hours = len(demand)
variables = {name: [0] * num_hours for name in variable_names}
(t_sup_hp, t_tank, t_ret, m_ch, m_dis, q_hp, q_boiler, hp_cop,
hp_electricity, boiler_gas_consumption, t_sup_boiler, boiler_energy_consumption, heating_consumption) = \
[variables[name] for name in variable_names]
t_tank[0] = 55
hp_heating_cap = hp.nominal_heat_output
boiler_heating_cap = boiler.nominal_heat_output
hp_delta_t = 7
boiler_efficiency = float(boiler.heat_efficiency)
v, h = float(tes.volume), float(tes.height)
r_tot = sum(float(layer.thickness) / float(layer.material.conductivity) for layer in
tes.layers)
u_tot = 1 / r_tot
d = math.sqrt((4 * v) / (math.pi * h))
a_side = math.pi * d * h
a_top = math.pi * d ** 2 / 4
ua = u_tot * (2 * a_top + a_side)
# storage temperature prediction
for i in range(len(demand) - 1):
t_tank[i + 1] = (t_tank[i] +
(m_ch[i] * (t_sup_boiler[i] - t_tank[i]) +
(ua * (t_out[i] - t_tank[i])) / cte.WATER_HEAT_CAPACITY -
m_dis[i] * (t_tank[i] - t_ret[i])) * (self.dt / (cte.WATER_DENSITY * v)))
# hp operation
if t_tank[i + 1] < 40:
q_hp[i + 1] = hp_heating_cap
m_ch[i + 1] = q_hp[i + 1] / (cte.WATER_HEAT_CAPACITY * hp_delta_t)
t_sup_hp[i + 1] = (q_hp[i + 1] / (m_ch[i + 1] * cte.WATER_HEAT_CAPACITY)) + t_tank[i + 1]
elif 40 <= t_tank[i + 1] < 55 and q_hp[i] == 0:
q_hp[i + 1] = 0
m_ch[i + 1] = 0
t_sup_hp[i + 1] = t_tank[i + 1]
elif 40 <= t_tank[i + 1] < 55 and q_hp[i] > 0:
q_hp[i + 1] = hp_heating_cap
m_ch[i + 1] = q_hp[i + 1] / (cte.WATER_HEAT_CAPACITY * hp_delta_t)
t_sup_hp[i + 1] = (q_hp[i + 1] / (m_ch[i + 1] * cte.WATER_HEAT_CAPACITY)) + t_tank[i + 1]
else:
q_hp[i + 1], m_ch[i + 1], t_sup_hp[i + 1] = 0, 0, t_tank[i + 1]
t_sup_hp_fahrenheit = 1.8 * t_sup_hp[i + 1] + 32
t_out_fahrenheit = 1.8 * t_out[i + 1] + 32
if q_hp[i + 1] > 0:
hp_cop[i + 1] = (cop_curve_coefficients[0] +
cop_curve_coefficients[1] * t_sup_hp_fahrenheit +
cop_curve_coefficients[2] * t_sup_hp_fahrenheit ** 2 +
cop_curve_coefficients[3] * t_out_fahrenheit +
cop_curve_coefficients[4] * t_out_fahrenheit ** 2 +
cop_curve_coefficients[5] * t_sup_hp_fahrenheit * t_out_fahrenheit)
hp_electricity[i + 1] = q_hp[i + 1] / heat_efficiency
else:
hp_cop[i + 1] = 0
hp_electricity[i + 1] = 0
# boiler operation
if q_hp[i + 1] > 0:
if t_sup_hp[i + 1] < 45:
q_boiler[i + 1] = boiler_heating_cap
elif demand[i + 1] > 0.5 * self._heating_peak_load / self.dt:
q_boiler[i + 1] = 0.5 * boiler_heating_cap
boiler_energy_consumption[i + 1] = q_boiler[i + 1] / boiler_efficiency
# boiler_gas_consumption[i + 1] = (q_boiler[i + 1] * self.dt) / (boiler_efficiency * cte.NATURAL_GAS_LHV)
t_sup_boiler[i + 1] = t_sup_hp[i + 1] + (q_boiler[i + 1] / (m_ch[i + 1] * cte.WATER_HEAT_CAPACITY))
# storage discharging
if demand[i + 1] == 0:
m_dis[i + 1] = 0
t_ret[i + 1] = t_tank[i + 1]
else:
if demand[i + 1] > 0.5 * self._heating_peak_load / cte.HOUR_TO_SECONDS:
factor = 8
else:
factor = 4
m_dis[i + 1] = self._heating_peak_load / (cte.WATER_HEAT_CAPACITY * factor * cte.HOUR_TO_SECONDS)
t_ret[i + 1] = t_tank[i + 1] - demand[i + 1] / (m_dis[i + 1] * cte.WATER_HEAT_CAPACITY)
tes.temperature = []
hp_electricity_j = [(x * cte.WATTS_HOUR_TO_JULES) / number_of_ts for x in hp_electricity]
boiler_consumption_j = [(x * cte.WATTS_HOUR_TO_JULES) / number_of_ts for x in boiler_energy_consumption]
hp_hourly = []
boiler_hourly = []
boiler_sum = 0
hp_sum = 0
for i in range(1, len(demand)):
hp_sum += hp_electricity_j[i]
boiler_sum += boiler_consumption_j[i]
if (i - 1) % number_of_ts == 0:
tes.temperature.append(t_tank[i])
hp_hourly.append(hp_sum)
boiler_hourly.append(boiler_sum)
hp_sum = 0
boiler_sum = 0
hp.energy_consumption[cte.HEATING] = {}
hp.energy_consumption[cte.HEATING][cte.HOUR] = hp_hourly
hp.energy_consumption[cte.HEATING][cte.MONTH] = MonthlyValues.get_total_month(
hp.energy_consumption[cte.HEATING][cte.HOUR])
hp.energy_consumption[cte.HEATING][cte.YEAR] = [
sum(hp.energy_consumption[cte.HEATING][cte.MONTH])]
boiler.energy_consumption[cte.HEATING] = {}
boiler.energy_consumption[cte.HEATING][cte.HOUR] = boiler_hourly
boiler.energy_consumption[cte.HEATING][cte.MONTH] = MonthlyValues.get_total_month(
boiler.energy_consumption[cte.HEATING][cte.HOUR])
boiler.energy_consumption[cte.HEATING][cte.YEAR] = [
sum(boiler.energy_consumption[cte.HEATING][cte.MONTH])]
self.results['Heating Demand (W)'] = demand
self.results['HP Heat Output (W)'] = q_hp
self.results['HP Source Temperature'] = t_out
self.results['HP Supply Temperature'] = t_sup_hp
self.results['HP COP'] = hp_cop
self.results['HP Electricity Consumption (W)'] = hp_electricity
self.results['Boiler Heat Output (W)'] = q_boiler
self.results['Boiler Supply Temperature'] = t_sup_boiler
self.results['Boiler Gas Consumption'] = boiler_gas_consumption
self.results['TES Temperature'] = t_tank
self.results['TES Charging Flow Rate (kg/s)'] = m_ch
self.results['TES Discharge Flow Rate (kg/s)'] = m_dis
self.results['Heating Loop Return Temperature'] = t_ret
return hp_hourly, boiler_hourly
def cooling_system_simulation(self):
hp = self.hvac_sizing()[0]
eer_curve_coefficients = [float(coefficient) for coefficient in hp.cooling_efficiency_curve.coefficients]
cooling_efficiency = float(hp.cooling_efficiency)
number_of_ts = int(cte.HOUR_TO_SECONDS / self.dt)
demand = [0] + [x for x in self._hourly_cooling_demand for _ in range(number_of_ts)]
t_out = [0] + [x for x in self._t_out for _ in range(number_of_ts)]
hp.source_temperature = self._t_out
variable_names = ["t_sup_hp", "t_ret", "m", "q_hp", "hp_electricity", "hp_eer"]
num_hours = len(demand)
variables = {name: [0] * num_hours for name in variable_names}
(t_sup_hp, t_ret, m, q_hp, hp_electricity, hp_eer) = [variables[name] for name in variable_names]
t_ret[0] = 13
for i in range(1, len(demand)):
if demand[i] > 0:
m[i] = self._cooling_peak_load / (cte.WATER_HEAT_CAPACITY * 5 * cte.HOUR_TO_SECONDS)
if t_ret[i - 1] >= 13:
if demand[i] < 0.25 * self._cooling_peak_load / cte.HOUR_TO_SECONDS:
q_hp[i] = 0.25 * hp.nominal_cooling_output
elif demand[i] < 0.5 * self._cooling_peak_load / cte.HOUR_TO_SECONDS:
q_hp[i] = 0.5 * hp.nominal_cooling_output
else:
q_hp[i] = hp.nominal_cooling_output
t_sup_hp[i] = t_ret[i - 1] - q_hp[i] / (m[i] * cte.WATER_HEAT_CAPACITY)
else:
q_hp[i] = 0
t_sup_hp[i] = t_ret[i - 1]
if m[i] == 0:
t_ret[i] = t_sup_hp[i]
else:
t_ret[i] = t_sup_hp[i] + demand[i] / (m[i] * cte.WATER_HEAT_CAPACITY)
else:
m[i] = 0
q_hp[i] = 0
t_sup_hp[i] = t_ret[i -1]
t_ret[i] = t_ret[i - 1]
t_sup_hp_fahrenheit = 1.8 * t_sup_hp[i] + 32
t_out_fahrenheit = 1.8 * t_out[i] + 32
if q_hp[i] > 0:
hp_eer[i] = (eer_curve_coefficients[0] +
eer_curve_coefficients[1] * t_sup_hp_fahrenheit +
eer_curve_coefficients[2] * t_sup_hp_fahrenheit ** 2 +
eer_curve_coefficients[3] * t_out_fahrenheit +
eer_curve_coefficients[4] * t_out_fahrenheit ** 2 +
eer_curve_coefficients[5] * t_sup_hp_fahrenheit * t_out_fahrenheit)
hp_electricity[i] = q_hp[i] / cooling_efficiency
else:
hp_eer[i] = 0
hp_electricity[i] = 0
hp_electricity_j = [(x * cte.WATTS_HOUR_TO_JULES) / number_of_ts for x in hp_electricity]
hp_hourly = []
hp_sum = 0
for i in range(1, len(demand)):
hp_sum += hp_electricity_j[i]
if (i - 1) % number_of_ts == 0:
hp_hourly.append(hp_sum)
hp_sum = 0
hp.energy_consumption[cte.COOLING] = {}
hp.energy_consumption[cte.COOLING][cte.HOUR] = hp_hourly
hp.energy_consumption[cte.COOLING][cte.MONTH] = MonthlyValues.get_total_month(
hp.energy_consumption[cte.COOLING][cte.HOUR])
hp.energy_consumption[cte.COOLING][cte.YEAR] = [
sum(hp.energy_consumption[cte.COOLING][cte.MONTH])]
self.results['Cooling Demand (W)'] = demand
self.results['HP Cooling Output (W)'] = q_hp
self.results['HP Cooling Supply Temperature'] = t_sup_hp
self.results['HP Cooling COP'] = hp_eer
self.results['HP Electricity Consumption'] = hp_electricity
self.results['Cooling Loop Flow Rate (kg/s)'] = m
self.results['Cooling Loop Return Temperature'] = t_ret
return hp_hourly
def dhw_system_simulation(self):
hp, tes = self.dhw_sizing()
heat_efficiency = float(hp.heat_efficiency)
cop_curve_coefficients = [float(coefficient) for coefficient in hp.heat_efficiency_curve.coefficients]
number_of_ts = int(cte.HOUR_TO_SECONDS / self.dt)
demand = [0] + [x for x in self._hourly_dhw_demand for _ in range(number_of_ts)]
t_out = [0] + [x for x in self._t_out for _ in range(number_of_ts)]
variable_names = ["t_sup_hp", "t_tank", "m_ch", "m_dis", "q_hp", "q_coil", "hp_cop",
"hp_electricity", "available hot water (m3)", "refill flow rate (kg/s)"]
num_hours = len(demand)
variables = {name: [0] * num_hours for name in variable_names}
(t_sup_hp, t_tank, m_ch, m_dis, m_refill, q_hp, q_coil, hp_cop, hp_electricity, v_dhw) = \
[variables[name] for name in variable_names]
t_tank[0] = 70
v_dhw[0] = tes.volume
hp_heating_cap = hp.nominal_heat_output
hp_delta_t = 8
v, h = float(tes.volume), float(tes.height)
r_tot = sum(float(layer.thickness) / float(layer.material.conductivity) for layer in
tes.layers)
u_tot = 1 / r_tot
d = math.sqrt((4 * v) / (math.pi * h))
a_side = math.pi * d * h
a_top = math.pi * d ** 2 / 4
ua = u_tot * (2 * a_top + a_side)
freshwater_temperature = 18
for i in range(len(demand) - 1):
delta_t_demand = demand[i] * (self.dt / (cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY * v))
if t_tank[i] < 65:
q_hp[i] = hp_heating_cap
delta_t_hp = q_hp[i] * (self.dt / (cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY * v))
if demand[i] > 0:
dhw_needed = (demand[i] * cte.HOUR_TO_SECONDS) / (cte.WATER_HEAT_CAPACITY * t_tank[i] * cte.WATER_DENSITY)
m_dis[i] = dhw_needed * cte.WATER_DENSITY / cte.HOUR_TO_SECONDS
m_refill[i] = m_dis[i]
delta_t_freshwater = m_refill[i] * (t_tank[i] - freshwater_temperature) * (self.dt / (v * cte.WATER_DENSITY))
diff = delta_t_freshwater + delta_t_demand - delta_t_hp
if diff > 0:
if diff > 0:
power = diff * (cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY * v) / self.dt
if power <= float(tes.heating_coil_capacity):
q_coil[i] = power
else:
q_coil[i] = float(tes.heating_coil_capacity)
delta_t_coil = q_coil[i] * (self.dt / (cte.WATER_DENSITY * cte.WATER_HEAT_CAPACITY * v))
if q_hp[i] > 0:
m_ch[i] = q_hp[i] / (cte.WATER_HEAT_CAPACITY * hp_delta_t)
t_sup_hp[i] = (q_hp[i] / (m_ch[i] * cte.WATER_HEAT_CAPACITY)) + t_tank[i]
else:
m_ch[i] = 0
t_sup_hp[i] = t_tank[i]
t_sup_hp_fahrenheit = 1.8 * t_sup_hp[i] + 32
t_out_fahrenheit = 1.8 * t_out[i] + 32
if q_hp[i] > 0:
hp_cop[i] = (cop_curve_coefficients[0] +
cop_curve_coefficients[1] * t_sup_hp_fahrenheit +
cop_curve_coefficients[2] * t_sup_hp_fahrenheit ** 2 +
cop_curve_coefficients[3] * t_out_fahrenheit +
cop_curve_coefficients[4] * t_out_fahrenheit ** 2 +
cop_curve_coefficients[5] * t_sup_hp_fahrenheit * t_out_fahrenheit)
hp_electricity[i] = q_hp[i] / heat_efficiency
else:
hp_cop[i] = 0
hp_electricity[i] = 0
t_tank[i + 1] = t_tank[i] + (delta_t_hp - delta_t_freshwater - delta_t_demand + delta_t_coil)
tes.temperature = []
hp_electricity_j = [(x * cte.WATTS_HOUR_TO_JULES) / number_of_ts for x in hp_electricity]
heating_coil_j = [(x * cte.WATTS_HOUR_TO_JULES) / number_of_ts for x in q_coil]
hp_hourly = []
coil_hourly = []
coil_sum = 0
hp_sum = 0
for i in range(1, len(demand)):
hp_sum += hp_electricity_j[i]
coil_sum += heating_coil_j[i]
if (i - 1) % number_of_ts == 0:
tes.temperature.append(t_tank[i])
hp_hourly.append(hp_sum)
coil_hourly.append(coil_sum)
hp_sum = 0
coil_sum = 0
hp.energy_consumption[cte.DOMESTIC_HOT_WATER] = {}
hp.energy_consumption[cte.DOMESTIC_HOT_WATER][cte.HOUR] = hp_hourly
hp.energy_consumption[cte.DOMESTIC_HOT_WATER][cte.MONTH] = MonthlyValues.get_total_month(
hp.energy_consumption[cte.DOMESTIC_HOT_WATER][cte.HOUR])
hp.energy_consumption[cte.DOMESTIC_HOT_WATER][cte.YEAR] = [
sum(hp.energy_consumption[cte.DOMESTIC_HOT_WATER][cte.MONTH])]
tes.heating_coil_energy_consumption = {}
tes.heating_coil_energy_consumption[cte.HOUR] = coil_hourly
tes.heating_coil_energy_consumption[cte.MONTH] = MonthlyValues.get_total_month(
tes.heating_coil_energy_consumption[cte.HOUR])
tes.heating_coil_energy_consumption[cte.YEAR] = [
sum(tes.heating_coil_energy_consumption[cte.MONTH])]
tes.temperature = t_tank
self.results['DHW Demand (W)'] = demand
self.results['DHW HP Heat Output (W)'] = q_hp
self.results['DHW HP Electricity Consumption (W)'] = hp_electricity
self.results['DHW HP Source Temperature'] = t_out
self.results['DHW HP Supply Temperature'] = t_sup_hp
self.results['DHW HP COP'] = hp_cop
self.results['DHW TES Heating Coil Heat Output (W)'] = q_coil
self.results['DHW TES Temperature'] = t_tank
self.results['DHW TES Charging Flow Rate (kg/s)'] = m_ch
self.results['DHW Flow Rate (kg/s)'] = m_dis
self.results['DHW TES Refill Flow Rate (kg/s)'] = m_refill
self.results['Available Water in Tank (m3)'] = v_dhw
return hp_hourly, coil_hourly
def enrich_buildings(self):
hp_heating, boiler_consumption = self.heating_system_simulation()
hp_cooling = self.cooling_system_simulation()
hp_dhw, heating_coil = self.dhw_system_simulation()
heating_consumption = [hp_heating[i] + boiler_consumption[i] for i in range(len(hp_heating))]
dhw_consumption = [hp_dhw[i] + heating_coil[i] for i in range(len(hp_dhw))]
self._building.heating_consumption[cte.HOUR] = heating_consumption
self._building.heating_consumption[cte.MONTH] = (
MonthlyValues.get_total_month(self._building.heating_consumption[cte.HOUR]))
self._building.heating_consumption[cte.YEAR] = [sum(self._building.heating_consumption[cte.MONTH])]
self._building.cooling_consumption[cte.HOUR] = hp_cooling
self._building.cooling_consumption[cte.MONTH] = (
MonthlyValues.get_total_month(self._building.cooling_consumption[cte.HOUR]))
self._building.cooling_consumption[cte.YEAR] = [sum(self._building.cooling_consumption[cte.MONTH])]
self._building.domestic_hot_water_consumption[cte.HOUR] = dhw_consumption
self._building.domestic_hot_water_consumption[cte.MONTH] = (
MonthlyValues.get_total_month(self._building.domestic_hot_water_consumption[cte.HOUR]))
self._building.domestic_hot_water_consumption[cte.YEAR] = [sum(self._building.domestic_hot_water_consumption[cte.MONTH])]
file_name = f'energy_system_simulation_results_{self._name}.csv'
with open(self._output_path / file_name, 'w', newline='') as csvfile:
output_file = csv.writer(csvfile)
# Write header
output_file.writerow(self.results.keys())
# Write data
output_file.writerows(zip(*self.results.values()))

View File

@ -83,7 +83,7 @@ class TestUsageFactory(TestCase):
city = self._get_citygml(file)
for building in city.buildings:
building.function = Dictionaries().pluto_function_to_hub_function[building.function]
ConstructionFactory('nrcan', city).enrich()
UsageFactory('comnet', city).enrich()
self._check_buildings(city)
for building in city.buildings:

142
texttest
View File

@ -1,142 +0,0 @@
ZoneControl:Thermostat,
Room_180_7ad8616b Thermostat, !- Name
Room_180_7ad8616b, !- Zone or ZoneList Name
Room_180_7ad8616b Thermostat Schedule, !- Control Type Schedule Name
ThermostatSetpoint:DualSetpoint, !- Control 1 Object Type
LargeOffice Building_Setpoint 26, !- Control 1 Name
, !- Control 2 Object Type
, !- Control 2 Name
, !- Control 3 Object Type
, !- Control 3 Name
, !- Control 4 Object Type
, !- Control 4 Name
0; !- Temperature Difference Between Cutout And Setpoint {deltaC}
Schedule:Compact,
Room_180_7ad8616b Thermostat Schedule, !- Name
Room_180_7ad8616b Thermostat Schedule Type Limits, !- Schedule Type Limits Name
Through: 12/31, !- Field 1
For: AllDays, !- Field 2
Until: 24:00, !- Field 3
4; !- Field 4
ScheduleTypeLimits,
Room_180_7ad8616b Thermostat Schedule Type Limits, !- Name
0, !- Lower Limit Value {BasedOnField A3}
4, !- Upper Limit Value {BasedOnField A3}
DISCRETE; !- Numeric Type
ThermostatSetpoint:DualSetpoint,
LargeOffice Building_Setpoint 26, !- Name
LargeOffice Building_Setpoint_HtgSetp Schedule, !- Heating Setpoint Temperature Schedule Name
LargeOffice Building_Setpoint_ClgSetp Schedule; !- Cooling Setpoint Temperature Schedule Name
ZoneHVAC:EquipmentConnections,
Room_180_7ad8616b, !- Zone Name
Room_180_7ad8616b Equipment List, !- Zone Conditioning Equipment List Name
Room_180_7ad8616b Inlet Node List, !- Zone Air Inlet Node or NodeList Name
, !- Zone Air Exhaust Node or NodeList Name
Node 27, !- Zone Air Node Name
Room_180_7ad8616b Return Node List; !- Zone Return Air Node or NodeList Name
NodeList,
Room_180_7ad8616b Inlet Node List, !- Name
Node 305; !- Node Name 1
NodeList,
Room_180_7ad8616b Return Node List, !- Name
Node 308; !- Node Name 1
ZoneHVAC:Baseboard:Convective:Electric,
Elec Baseboard 1, !- Name
Always On Discrete hvac_library, !- Availability Schedule Name
, !- Heating Design Capacity Method
Autosize, !- Heating Design Capacity {W}
, !- Heating Design Capacity Per Floor Area {W/m2}
, !- Fraction of Autosized Heating Design Capacity
1; !- Efficiency
AirTerminal:SingleDuct:ConstantVolume:NoReheat,
Diffuser 21, !- Name
Always On Discrete hvac_library, !- Availability Schedule Name
Node 307, !- Air Inlet Node Name
Node 305, !- Air Outlet Node Name
AutoSize; !- Maximum Air Flow Rate {m3/s}
ZoneHVAC:AirDistributionUnit,
ADU Diffuser 21, !- Name
Node 305, !- Air Distribution Unit Outlet Node Name
AirTerminal:SingleDuct:ConstantVolume:NoReheat, !- Air Terminal Object Type
Diffuser 21; !- Air Terminal Name
ZoneHVAC:EquipmentList,
Room_180_7ad8616b Equipment List, !- Name
SequentialLoad, !- Load Distribution Scheme
ZoneHVAC:Baseboard:Convective:Electric, !- Zone Equipment Object Type 1
Elec Baseboard 1, !- Zone Equipment Name 1
1, !- Zone Equipment Cooling Sequence 1
1, !- Zone Equipment Heating or No-Load Sequence 1
, !- Zone Equipment Sequential Cooling Fraction Schedule Name 1
, !- Zone Equipment Sequential Heating Fraction Schedule Name 1
ZoneHVAC:AirDistributionUnit, !- Zone Equipment Object Type 2
ADU Diffuser 21, !- Zone Equipment Name 2
2, !- Zone Equipment Cooling Sequence 2
2, !- Zone Equipment Heating or No-Load Sequence 2
, !- Zone Equipment Sequential Cooling Fraction Schedule Name 2
; !- Zone Equipment Sequential Heating Fraction Schedule Name 2
Sizing:Zone,
Room_180_7ad8616b, !- Zone or ZoneList Name
SupplyAirTemperature, !- Zone Cooling Design Supply Air Temperature Input Method
14, !- Zone Cooling Design Supply Air Temperature {C}
11.11, !- Zone Cooling Design Supply Air Temperature Difference {deltaC}
SupplyAirTemperature, !- Zone Heating Design Supply Air Temperature Input Method
40, !- Zone Heating Design Supply Air Temperature {C}
11.11, !- Zone Heating Design Supply Air Temperature Difference {deltaC}
0.0085, !- Zone Cooling Design Supply Air Humidity Ratio {kgWater/kgDryAir}
0.008, !- Zone Heating Design Supply Air Humidity Ratio {kgWater/kgDryAir}
Room_180_7ad8616b DSOA Space List, !- Design Specification Outdoor Air Object Name
, !- Zone Heating Sizing Factor
, !- Zone Cooling Sizing Factor
DesignDay, !- Cooling Design Air Flow Method
0, !- Cooling Design Air Flow Rate {m3/s}
0.000762, !- Cooling Minimum Air Flow per Zone Floor Area {m3/s-m2}
0, !- Cooling Minimum Air Flow {m3/s}
0, !- Cooling Minimum Air Flow Fraction
DesignDay, !- Heating Design Air Flow Method
0, !- Heating Design Air Flow Rate {m3/s}
0.002032, !- Heating Maximum Air Flow per Zone Floor Area {m3/s-m2}
0.1415762, !- Heating Maximum Air Flow {m3/s}
0.3, !- Heating Maximum Air Flow Fraction
, !- Design Specification Zone Air Distribution Object Name
No, !- Account for Dedicated Outdoor Air System
, !- Dedicated Outdoor Air System Control Strategy
, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C}
, !- Dedicated Outdoor Air High Setpoint Temperature for Design {C}
Sensible Load Only No Latent Load, !- Zone Load Sizing Method
HumidityRatioDifference, !- Zone Latent Cooling Design Supply Air Humidity Ratio Input Method
, !- Zone Dehumidification Design Supply Air Humidity Ratio {kgWater/kgDryAir}
0.005, !- Zone Cooling Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir}
HumidityRatioDifference, !- Zone Latent Heating Design Supply Air Humidity Ratio Input Method
, !- Zone Humidification Design Supply Air Humidity Ratio {kgWater/kgDryAir}
0.005; !- Zone Humidification Design Supply Air Humidity Ratio Difference {kgWater/kgDryAir}
DesignSpecification:OutdoorAir:SpaceList,
Room_180_7ad8616b DSOA Space List, !- Name
Room_180_7ad8616b_Space, !- Space Name 1
MidriseApartment Apartment Ventilation; !- Space Design Specification Outdoor Air Object Name 1
Zone,
Room_181_3a411b5d, !- Name
, !- Direction of Relative North {deg}
0, !- X Origin {m}
0, !- Y Origin {m}
0, !- Z Origin {m}
, !- Type
1, !- Multiplier
4, !- Ceiling Height {m}
291.62935408288, !- Volume {m3}
, !- Floor Area {m2}
, !- Zone Inside Convection Algorithm
, !- Zone Outside Convection Algorithm
Yes; !- Part of Total Floor Area