fix/multi-useage #77
@ -27,7 +27,7 @@ class Building(CityObject):
|
|||||||
"""
|
"""
|
||||||
Building(CityObject) class
|
Building(CityObject) class
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, surfaces, year_of_construction, function, terrains=None, city=None):
|
def __init__(self, name, surfaces, year_of_construction, function, usages=None, terrains=None, city=None):
|
||||||
super().__init__(name, surfaces)
|
super().__init__(name, surfaces)
|
||||||
self._city = city
|
self._city = city
|
||||||
self._households = None
|
self._households = None
|
||||||
@ -36,6 +36,7 @@ class Building(CityObject):
|
|||||||
self._terrains = terrains
|
self._terrains = terrains
|
||||||
self._year_of_construction = year_of_construction
|
self._year_of_construction = year_of_construction
|
||||||
self._function = function
|
self._function = function
|
||||||
|
self._usages = usages
|
||||||
self._average_storey_height = None
|
self._average_storey_height = None
|
||||||
self._storeys_above_ground = None
|
self._storeys_above_ground = None
|
||||||
self._floor_area = None
|
self._floor_area = None
|
||||||
@ -256,7 +257,17 @@ class Building(CityObject):
|
|||||||
:param value: str
|
:param value: str
|
||||||
"""
|
"""
|
||||||
if value is not None:
|
if value is not None:
|
||||||
self._function = str(value)
|
self._function = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def usages(self) -> Union[None, list]:
|
||||||
|
"""
|
||||||
|
Get building usages, if none, assume usage is function
|
||||||
|
:return: None or list of functions
|
||||||
|
"""
|
||||||
|
if self._usages is None and self._function is not None:
|
||||||
|
self._usages = [{'usage': self._function, 'ratio': 1 }]
|
||||||
|
return self._usages
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def average_storey_height(self) -> Union[None, float]:
|
def average_storey_height(self) -> Union[None, float]:
|
||||||
@ -593,19 +604,6 @@ class Building(CityObject):
|
|||||||
"""
|
"""
|
||||||
self._city = value
|
self._city = value
|
||||||
|
|
||||||
@property
|
|
||||||
def usages_percentage(self):
|
|
||||||
"""
|
|
||||||
Get the usages and percentages for the building
|
|
||||||
"""
|
|
||||||
_usage = ''
|
|
||||||
for internal_zone in self.internal_zones:
|
|
||||||
if internal_zone.usages is None:
|
|
||||||
continue
|
|
||||||
for usage in internal_zone.usages:
|
|
||||||
_usage = f'{_usage}{usage.name}_{usage.percentage} '
|
|
||||||
return _usage.rstrip()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def energy_systems(self) -> Union[None, List[EnergySystem]]:
|
def energy_systems(self) -> Union[None, List[EnergySystem]]:
|
||||||
"""
|
"""
|
||||||
|
@ -34,7 +34,7 @@ class ThermalZone:
|
|||||||
volume,
|
volume,
|
||||||
footprint_area,
|
footprint_area,
|
||||||
number_of_storeys,
|
number_of_storeys,
|
||||||
usage_name=None):
|
usages=None):
|
||||||
self._id = None
|
self._id = None
|
||||||
self._parent_internal_zone = parent_internal_zone
|
self._parent_internal_zone = parent_internal_zone
|
||||||
self._footprint_area = footprint_area
|
self._footprint_area = footprint_area
|
||||||
@ -51,10 +51,6 @@ class ThermalZone:
|
|||||||
self._view_factors_matrix = None
|
self._view_factors_matrix = None
|
||||||
self._total_floor_area = None
|
self._total_floor_area = None
|
||||||
self._number_of_storeys = number_of_storeys
|
self._number_of_storeys = number_of_storeys
|
||||||
self._usage_name = usage_name
|
|
||||||
self._usage_from_parent = False
|
|
||||||
if usage_name is None:
|
|
||||||
self._usage_from_parent = True
|
|
||||||
self._hours_day = None
|
self._hours_day = None
|
||||||
self._days_year = None
|
self._days_year = None
|
||||||
self._mechanical_air_change = None
|
self._mechanical_air_change = None
|
||||||
@ -64,7 +60,12 @@ class ThermalZone:
|
|||||||
self._internal_gains = None
|
self._internal_gains = None
|
||||||
self._thermal_control = None
|
self._thermal_control = None
|
||||||
self._domestic_hot_water = None
|
self._domestic_hot_water = None
|
||||||
self._usages = None
|
self._usage_name = None
|
||||||
|
self._usages = usages
|
||||||
|
self._usage_from_parent = False
|
||||||
|
if usages is None:
|
||||||
|
self._usage_from_parent = True
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parent_internal_zone(self) -> InternalZone:
|
def parent_internal_zone(self) -> InternalZone:
|
||||||
@ -77,24 +78,11 @@ class ThermalZone:
|
|||||||
@property
|
@property
|
||||||
def usages(self):
|
def usages(self):
|
||||||
"""
|
"""
|
||||||
Get the thermal zone usages including percentage with the format [percentage]-usage_[percentage]-usage...
|
Get the thermal zone usages
|
||||||
Eg: 70-office_30-residential
|
|
||||||
:return: str
|
:return: str
|
||||||
"""
|
"""
|
||||||
if self._usage_from_parent:
|
if self._usage_from_parent:
|
||||||
self._usages = copy.deepcopy(self._parent_internal_zone.usages)
|
self._usages = copy.deepcopy(self._parent_internal_zone.usages)
|
||||||
else:
|
|
||||||
values = self._usage_name.split('_')
|
|
||||||
usages = []
|
|
||||||
for value in values:
|
|
||||||
usages.append(value.split('-'))
|
|
||||||
self._usages = []
|
|
||||||
for parent_usage in self._parent_internal_zone.usages:
|
|
||||||
for value in usages:
|
|
||||||
if parent_usage.name == value[1]:
|
|
||||||
new_usage = copy.deepcopy(parent_usage)
|
|
||||||
new_usage.percentage = float(value[0]) / 100
|
|
||||||
self._usages.append(new_usage)
|
|
||||||
return self._usages
|
return self._usages
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
0
hub/helpers/parsers/__init__.py
Normal file
0
hub/helpers/parsers/__init__.py
Normal file
31
hub/helpers/parsers/list_usage_to_hub.py
Normal file
31
hub/helpers/parsers/list_usage_to_hub.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
class ListUsageToHub:
|
||||||
|
"""
|
||||||
|
Eilat function to hub function class
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, function_dictionary=None):
|
||||||
|
self._function_dictionary = function_dictionary
|
||||||
|
|
||||||
|
def _apply_function_dictionary(self, usages):
|
||||||
|
|
||||||
|
function_dictionary = self._function_dictionary
|
||||||
|
|
||||||
|
if function_dictionary is not None:
|
||||||
|
for usage in usages:
|
||||||
|
if usage['usage'] in function_dictionary:
|
||||||
|
usage['usage'] = function_dictionary[usage['usage']]
|
||||||
|
|
||||||
|
return usages
|
||||||
|
|
||||||
|
def parse(self, usages) -> list[dict]:
|
||||||
|
"""
|
||||||
|
Get the dictionary
|
||||||
|
:return: {}
|
||||||
|
"""
|
||||||
|
|
||||||
|
usages = [{"usage": str(i["usage"]), "ratio": float(i["ratio"])} for i in usages]
|
||||||
|
|
||||||
|
usages = self._apply_function_dictionary(usages)
|
||||||
|
|
||||||
|
return usages
|
19
hub/helpers/parsers/string_usage_to_hub.py
Normal file
19
hub/helpers/parsers/string_usage_to_hub.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
class StringUsageToHub:
|
||||||
|
"""
|
||||||
|
Eilat function to hub function class
|
||||||
|
"""
|
||||||
|
|
||||||
|
def parse(self, usages) -> list[dict]:
|
||||||
|
"""
|
||||||
|
Parse usage string in form residential-80_commercial-20
|
||||||
|
:usages: str
|
||||||
|
:return: {}
|
||||||
|
"""
|
||||||
|
|
||||||
|
parsed_usages = []
|
||||||
|
for usage in usages.split('_'):
|
||||||
|
usage_dict = {"usage": str(usage.split('-')[0]), "ratio": float(usage.split('-')[1])/100}
|
||||||
|
parsed_usages.append(usage_dict)
|
||||||
|
|
||||||
|
return parsed_usages
|
31
hub/helpers/usage_parsers.py
Normal file
31
hub/helpers/usage_parsers.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
"""
|
||||||
|
Dictionaries module saves all transformations of functions and usages to access the catalogs
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2023 Concordia CERC group
|
||||||
|
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
|
"""
|
||||||
|
|
||||||
|
from hub.helpers.parsers.list_usage_to_hub import ListUsageToHub
|
||||||
|
from hub.helpers.parsers.string_usage_to_hub import StringUsageToHub
|
||||||
|
|
||||||
|
class UsageParsers:
|
||||||
|
"""
|
||||||
|
Dictionaries class
|
||||||
|
"""
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def string_usage_to_hub() -> object:
|
||||||
|
"""
|
||||||
|
Hub usage to HfT usage, transformation dictionary
|
||||||
|
:return: dict
|
||||||
|
"""
|
||||||
|
return StringUsageToHub().parse
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def list_usage_to_hub(function_dictionary=None) -> object:
|
||||||
|
"""
|
||||||
|
Hub usage to HfT usage, transformation dictionary
|
||||||
|
:return: dict
|
||||||
|
"""
|
||||||
|
return ListUsageToHub(function_dictionary).parse
|
||||||
|
|
@ -33,21 +33,10 @@ class NrcanPhysicsParameters:
|
|||||||
city = self._city
|
city = self._city
|
||||||
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
main_function = None
|
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
|
||||||
functions = building.function.split('_')
|
logging.error('Building %s has an unknown building function %s', building.name, building.function)
|
||||||
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
|
continue
|
||||||
function = Dictionaries().hub_function_to_nrcan_construction_function[main_function]
|
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
|
||||||
try:
|
try:
|
||||||
archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone)
|
archetype = self._search_archetype(nrcan_catalog, function, building.year_of_construction, self._climate_zone)
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@ class Geojson:
|
|||||||
year_of_construction_field=None,
|
year_of_construction_field=None,
|
||||||
function_field=None,
|
function_field=None,
|
||||||
function_to_hub=None,
|
function_to_hub=None,
|
||||||
|
usages_field=None,
|
||||||
|
usages_to_hub=None,
|
||||||
hub_crs=None
|
hub_crs=None
|
||||||
):
|
):
|
||||||
self._hub_crs = hub_crs
|
self._hub_crs = hub_crs
|
||||||
@ -52,6 +54,8 @@ class Geojson:
|
|||||||
self._year_of_construction_field = year_of_construction_field
|
self._year_of_construction_field = year_of_construction_field
|
||||||
self._function_field = function_field
|
self._function_field = function_field
|
||||||
self._function_to_hub = function_to_hub
|
self._function_to_hub = function_to_hub
|
||||||
|
self._usages_field = usages_field
|
||||||
|
self._usages_to_hub = usages_to_hub
|
||||||
with open(path, 'r', encoding='utf8') as json_file:
|
with open(path, 'r', encoding='utf8') as json_file:
|
||||||
self._geojson = json.loads(json_file.read())
|
self._geojson = json.loads(json_file.read())
|
||||||
|
|
||||||
@ -117,41 +121,30 @@ class Geojson:
|
|||||||
lod = 0
|
lod = 0
|
||||||
for feature in self._geojson['features']:
|
for feature in self._geojson['features']:
|
||||||
extrusion_height = 0
|
extrusion_height = 0
|
||||||
|
|
||||||
if self._extrusion_height_field is not None:
|
if self._extrusion_height_field is not None:
|
||||||
extrusion_height = float(feature['properties'][self._extrusion_height_field])
|
extrusion_height = float(feature['properties'][self._extrusion_height_field])
|
||||||
lod = 1
|
lod = 1
|
||||||
self._max_z = max(self._max_z, extrusion_height)
|
self._max_z = max(self._max_z, extrusion_height)
|
||||||
year_of_construction = None
|
year_of_construction = None
|
||||||
|
|
||||||
if self._year_of_construction_field is not None:
|
if self._year_of_construction_field is not None:
|
||||||
year_of_construction = int(feature['properties'][self._year_of_construction_field])
|
year_of_construction = int(feature['properties'][self._year_of_construction_field])
|
||||||
|
|
||||||
function = None
|
function = None
|
||||||
if self._function_field is not None:
|
if self._function_field is not None:
|
||||||
function = str(feature['properties'][self._function_field])
|
function = str(feature['properties'][self._function_field])
|
||||||
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:
|
if self._function_to_hub is not None:
|
||||||
# use the transformation dictionary to retrieve the proper function
|
|
||||||
if function in self._function_to_hub:
|
if function in self._function_to_hub:
|
||||||
function = self._function_to_hub[function]
|
function = self._function_to_hub[function]
|
||||||
|
|
||||||
|
usages = None
|
||||||
|
if self._usages_field is not None:
|
||||||
|
if self._usages_field in feature['properties']:
|
||||||
|
usages = feature['properties'][self._usages_field]
|
||||||
|
if self._usages_to_hub is not None:
|
||||||
|
usages = self._usages_to_hub(usages)
|
||||||
|
|
||||||
geometry = feature['geometry']
|
geometry = feature['geometry']
|
||||||
building_aliases = []
|
building_aliases = []
|
||||||
if 'id' in feature:
|
if 'id' in feature:
|
||||||
@ -170,6 +163,7 @@ class Geojson:
|
|||||||
building_name,
|
building_name,
|
||||||
building_aliases,
|
building_aliases,
|
||||||
function,
|
function,
|
||||||
|
usages,
|
||||||
year_of_construction,
|
year_of_construction,
|
||||||
extrusion_height))
|
extrusion_height))
|
||||||
|
|
||||||
@ -178,6 +172,7 @@ class Geojson:
|
|||||||
building_name,
|
building_name,
|
||||||
building_aliases,
|
building_aliases,
|
||||||
function,
|
function,
|
||||||
|
usages,
|
||||||
year_of_construction,
|
year_of_construction,
|
||||||
extrusion_height))
|
extrusion_height))
|
||||||
else:
|
else:
|
||||||
@ -203,7 +198,7 @@ class Geojson:
|
|||||||
transformed_coordinates = f'{transformed_coordinates} {transformed[self._X]} {transformed[self._Y]} 0.0'
|
transformed_coordinates = f'{transformed_coordinates} {transformed[self._X]} {transformed[self._Y]} 0.0'
|
||||||
return transformed_coordinates.lstrip(' ')
|
return transformed_coordinates.lstrip(' ')
|
||||||
|
|
||||||
def _parse_polygon(self, coordinates, building_name, building_aliases, function, year_of_construction, extrusion_height):
|
def _parse_polygon(self, coordinates, building_name, building_aliases, function, usages, year_of_construction, extrusion_height):
|
||||||
surfaces = []
|
surfaces = []
|
||||||
for polygon_coordinates in coordinates:
|
for polygon_coordinates in coordinates:
|
||||||
points = igh.points_from_string(
|
points = igh.points_from_string(
|
||||||
@ -236,7 +231,7 @@ class Geojson:
|
|||||||
polygon = Polygon(coordinates)
|
polygon = Polygon(coordinates)
|
||||||
polygon.area = igh.ground_area(coordinates)
|
polygon.area = igh.ground_area(coordinates)
|
||||||
surfaces[-1] = Surface(polygon, polygon)
|
surfaces[-1] = Surface(polygon, polygon)
|
||||||
building = Building(f'{building_name}', surfaces, year_of_construction, function)
|
building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
|
||||||
for alias in building_aliases:
|
for alias in building_aliases:
|
||||||
building.add_alias(alias)
|
building.add_alias(alias)
|
||||||
if extrusion_height == 0:
|
if extrusion_height == 0:
|
||||||
@ -271,13 +266,13 @@ class Geojson:
|
|||||||
polygon = Polygon(wall_coordinates)
|
polygon = Polygon(wall_coordinates)
|
||||||
wall = Surface(polygon, polygon)
|
wall = Surface(polygon, polygon)
|
||||||
surfaces.append(wall)
|
surfaces.append(wall)
|
||||||
building = Building(f'{building_name}', surfaces, year_of_construction, function)
|
building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
|
||||||
for alias in building_aliases:
|
for alias in building_aliases:
|
||||||
building.add_alias(alias)
|
building.add_alias(alias)
|
||||||
building.volume = volume
|
building.volume = volume
|
||||||
return building
|
return building
|
||||||
|
|
||||||
def _parse_multi_polygon(self, polygons_coordinates, building_name, building_aliases, function, year_of_construction, extrusion_height):
|
def _parse_multi_polygon(self, polygons_coordinates, building_name, building_aliases, function, usages, year_of_construction, extrusion_height):
|
||||||
surfaces = []
|
surfaces = []
|
||||||
for coordinates in polygons_coordinates:
|
for coordinates in polygons_coordinates:
|
||||||
for polygon_coordinates in coordinates:
|
for polygon_coordinates in coordinates:
|
||||||
@ -310,7 +305,7 @@ class Geojson:
|
|||||||
polygon = Polygon(coordinates)
|
polygon = Polygon(coordinates)
|
||||||
polygon.area = igh.ground_area(coordinates)
|
polygon.area = igh.ground_area(coordinates)
|
||||||
surfaces[-1] = Surface(polygon, polygon)
|
surfaces[-1] = Surface(polygon, polygon)
|
||||||
building = Building(f'{building_name}', surfaces, year_of_construction, function)
|
building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
|
||||||
for alias in building_aliases:
|
for alias in building_aliases:
|
||||||
building.add_alias(alias)
|
building.add_alias(alias)
|
||||||
if extrusion_height == 0:
|
if extrusion_height == 0:
|
||||||
@ -345,7 +340,7 @@ class Geojson:
|
|||||||
polygon = Polygon(wall_coordinates)
|
polygon = Polygon(wall_coordinates)
|
||||||
wall = Surface(polygon, polygon)
|
wall = Surface(polygon, polygon)
|
||||||
surfaces.append(wall)
|
surfaces.append(wall)
|
||||||
building = Building(f'{building_name}', surfaces, year_of_construction, function)
|
building = Building(f'{building_name}', surfaces, year_of_construction, function, usages=usages)
|
||||||
for alias in building_aliases:
|
for alias in building_aliases:
|
||||||
building.add_alias(alias)
|
building.add_alias(alias)
|
||||||
building.volume = volume
|
building.volume = volume
|
||||||
|
@ -23,6 +23,8 @@ class GeometryFactory:
|
|||||||
year_of_construction_field=None,
|
year_of_construction_field=None,
|
||||||
function_field=None,
|
function_field=None,
|
||||||
function_to_hub=None,
|
function_to_hub=None,
|
||||||
|
usages_field=None,
|
||||||
|
usages_to_hub=None,
|
||||||
hub_crs=None):
|
hub_crs=None):
|
||||||
self._file_type = '_' + file_type.lower()
|
self._file_type = '_' + file_type.lower()
|
||||||
validate_import_export_type(GeometryFactory, file_type)
|
validate_import_export_type(GeometryFactory, file_type)
|
||||||
@ -32,6 +34,8 @@ class GeometryFactory:
|
|||||||
self._year_of_construction_field = year_of_construction_field
|
self._year_of_construction_field = year_of_construction_field
|
||||||
self._function_field = function_field
|
self._function_field = function_field
|
||||||
self._function_to_hub = function_to_hub
|
self._function_to_hub = function_to_hub
|
||||||
|
self._usages_field = usages_field
|
||||||
|
self._usages_to_hub = usages_to_hub
|
||||||
self._hub_crs = hub_crs
|
self._hub_crs = hub_crs
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -66,6 +70,8 @@ class GeometryFactory:
|
|||||||
self._year_of_construction_field,
|
self._year_of_construction_field,
|
||||||
self._function_field,
|
self._function_field,
|
||||||
self._function_to_hub,
|
self._function_to_hub,
|
||||||
|
self._usages_field,
|
||||||
|
self._usages_to_hub,
|
||||||
self._hub_crs).city
|
self._hub_crs).city
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -38,38 +38,36 @@ class ComnetUsageParameters:
|
|||||||
city = self._city
|
city = self._city
|
||||||
comnet_catalog = UsageCatalogFactory('comnet').catalog
|
comnet_catalog = UsageCatalogFactory('comnet').catalog
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
usages = []
|
|
||||||
comnet_archetype_usages = []
|
comnet_archetype_usages = []
|
||||||
building_functions = building.function.split('_')
|
usages = building.usages
|
||||||
for function in building_functions:
|
|
||||||
usages.append(function.split('-'))
|
|
||||||
for usage in usages:
|
for usage in usages:
|
||||||
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]]
|
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage['usage']]
|
||||||
try:
|
try:
|
||||||
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
|
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
|
||||||
comnet_archetype_usages.append(comnet_archetype_usage)
|
comnet_archetype_usages.append(comnet_archetype_usage)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
|
logging.error('Building %s has unknown usage archetype for usage %s', building.name, comnet_usage_name)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for (i, internal_zone) in enumerate(building.internal_zones):
|
for (i, internal_zone) in enumerate(building.internal_zones):
|
||||||
internal_zone_usages = []
|
internal_zone_usages = []
|
||||||
if len(building.internal_zones) > 1:
|
if len(building.internal_zones) > 1:
|
||||||
volume_per_area = 0
|
volume_per_area = 0
|
||||||
if internal_zone.area is None:
|
if internal_zone.area is None:
|
||||||
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
|
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
|
||||||
building.name, usages[i][-1])
|
building.name, usages[i]['usage'])
|
||||||
continue
|
continue
|
||||||
if internal_zone.volume is None:
|
if internal_zone.volume is None:
|
||||||
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
|
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
|
||||||
building.name, usages[i][-1])
|
building.name, usages[i]['usage'])
|
||||||
continue
|
continue
|
||||||
if internal_zone.area <= 0:
|
if internal_zone.area <= 0:
|
||||||
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
|
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
|
||||||
building.name, usages[i][-1])
|
building.name, usages[i]['usage'])
|
||||||
continue
|
continue
|
||||||
volume_per_area += internal_zone.volume / internal_zone.area
|
volume_per_area += internal_zone.volume / internal_zone.area
|
||||||
usage = Usage()
|
usage = Usage()
|
||||||
usage.name = usages[i][-1]
|
usage.name = usages[i]['usage']
|
||||||
self._assign_values(usage, comnet_archetype_usages[i], volume_per_area, building.cold_water_temperature)
|
self._assign_values(usage, comnet_archetype_usages[i], volume_per_area, building.cold_water_temperature)
|
||||||
usage.percentage = 1
|
usage.percentage = 1
|
||||||
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[i])
|
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[i])
|
||||||
@ -80,20 +78,24 @@ class ComnetUsageParameters:
|
|||||||
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s. '
|
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 '
|
'NRCAN construction data for the year %s is used to calculated number of storeys above '
|
||||||
'ground', building.name, usages, building.year_of_construction)
|
'ground', building.name, usages, building.year_of_construction)
|
||||||
|
try:
|
||||||
storeys_above_ground = self.average_storey_height_calculator(self._city, building)
|
storeys_above_ground = self.average_storey_height_calculator(self._city, building)
|
||||||
|
except ValueError as e:
|
||||||
|
logging.error(e)
|
||||||
|
continue
|
||||||
|
|
||||||
volume_per_area = building.volume / building.floor_area / storeys_above_ground
|
volume_per_area = building.volume / building.floor_area / storeys_above_ground
|
||||||
for (j, mixed_usage) in enumerate(usages):
|
for j, usage_type in enumerate(usages):
|
||||||
usage = Usage()
|
usage = Usage()
|
||||||
usage.name = mixed_usage[-1]
|
usage.name = usage_type['usage']
|
||||||
if len(usages) > 1:
|
usage.percentage = float(usage_type['ratio'])
|
||||||
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._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])
|
self._calculate_reduced_values_from_extended_library(usage, comnet_archetype_usages[j])
|
||||||
internal_zone_usages.append(usage)
|
internal_zone_usages.append(usage)
|
||||||
|
|
||||||
internal_zone.usages = internal_zone_usages
|
internal_zone.usages = internal_zone_usages
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _search_archetypes(comnet_catalog, usage_name):
|
def _search_archetypes(comnet_catalog, usage_name):
|
||||||
comnet_archetypes = comnet_catalog.entries('archetypes').usages
|
comnet_archetypes = comnet_catalog.entries('archetypes').usages
|
||||||
@ -270,20 +272,11 @@ class ComnetUsageParameters:
|
|||||||
def average_storey_height_calculator(city, building):
|
def average_storey_height_calculator(city, building):
|
||||||
climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
|
climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
|
||||||
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
||||||
main_function = None
|
|
||||||
functions = building.function.split('_')
|
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
|
||||||
if len(functions) > 1:
|
raise ValueError('Building %s has an unknown building function %s', building.name, building.function)
|
||||||
maximum_percentage = 0
|
|
||||||
for function in functions:
|
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
|
||||||
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
|
construction_archetype = None
|
||||||
average_storey_height = None
|
average_storey_height = None
|
||||||
nrcan_archetypes = nrcan_catalog.entries('archetypes')
|
nrcan_archetypes = nrcan_catalog.entries('archetypes')
|
||||||
@ -294,7 +287,7 @@ class ComnetUsageParameters:
|
|||||||
construction_archetype = building_archetype
|
construction_archetype = building_archetype
|
||||||
average_storey_height = building_archetype.average_storey_height
|
average_storey_height = building_archetype.average_storey_height
|
||||||
if construction_archetype is None:
|
if construction_archetype is None:
|
||||||
logging.error('Building %s has unknown construction archetype for building function: %s '
|
raise ValueError('Building %s has unknown construction archetype for building function: %s '
|
||||||
'[%s], building year of construction: %s and climate zone %s', building.name, function,
|
'[%s], building year of construction: %s and climate zone %s', building.name, function,
|
||||||
building.function, building.year_of_construction, climate_zone)
|
building.function, building.year_of_construction, climate_zone)
|
||||||
|
|
||||||
|
@ -37,21 +37,18 @@ class NrcanUsageParameters:
|
|||||||
nrcan_catalog = UsageCatalogFactory('nrcan').catalog
|
nrcan_catalog = UsageCatalogFactory('nrcan').catalog
|
||||||
comnet_catalog = UsageCatalogFactory('comnet').catalog
|
comnet_catalog = UsageCatalogFactory('comnet').catalog
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
usages = []
|
|
||||||
nrcan_archetype_usages = []
|
nrcan_archetype_usages = []
|
||||||
comnet_archetype_usages = []
|
comnet_archetype_usages = []
|
||||||
building_functions = building.function.split('_')
|
usages = building.usages
|
||||||
for function in building_functions:
|
|
||||||
usages.append(function.split('-'))
|
|
||||||
for usage in usages:
|
for usage in usages:
|
||||||
usage_name = Dictionaries().hub_usage_to_nrcan_usage[usage[-1]]
|
usage_name = Dictionaries().hub_usage_to_nrcan_usage[usage['usage']]
|
||||||
try:
|
try:
|
||||||
archetype_usage = self._search_archetypes(nrcan_catalog, usage_name)
|
archetype_usage = self._search_archetypes(nrcan_catalog, usage_name)
|
||||||
nrcan_archetype_usages.append(archetype_usage)
|
nrcan_archetype_usages.append(archetype_usage)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
|
logging.error('Building %s has unknown usage archetype for usage %s', building.name, usage_name)
|
||||||
continue
|
continue
|
||||||
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage[-1]]
|
comnet_usage_name = Dictionaries().hub_usage_to_comnet_usage[usage['usage']]
|
||||||
try:
|
try:
|
||||||
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
|
comnet_archetype_usage = self._search_archetypes(comnet_catalog, comnet_usage_name)
|
||||||
comnet_archetype_usages.append(comnet_archetype_usage)
|
comnet_archetype_usages.append(comnet_archetype_usage)
|
||||||
@ -65,19 +62,19 @@ class NrcanUsageParameters:
|
|||||||
volume_per_area = 0
|
volume_per_area = 0
|
||||||
if internal_zone.area is None:
|
if internal_zone.area is None:
|
||||||
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
|
logging.error('Building %s has internal zone area not defined, ACH cannot be calculated for usage %s',
|
||||||
building.name, usages[i][-1])
|
building.name, usages[i]['usage'])
|
||||||
continue
|
continue
|
||||||
if internal_zone.volume is None:
|
if internal_zone.volume is None:
|
||||||
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
|
logging.error('Building %s has internal zone volume not defined, ACH cannot be calculated for usage %s',
|
||||||
building.name, usages[i][-1])
|
building.name, usages[i]['usage'])
|
||||||
continue
|
continue
|
||||||
if internal_zone.area <= 0:
|
if internal_zone.area <= 0:
|
||||||
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
|
logging.error('Building %s has internal zone area equal to 0, ACH cannot be calculated for usage %s',
|
||||||
building.name, usages[i][-1])
|
building.name, usages[i]['usage'])
|
||||||
continue
|
continue
|
||||||
volume_per_area += internal_zone.volume / internal_zone.area
|
volume_per_area += internal_zone.volume / internal_zone.area
|
||||||
usage = Usage()
|
usage = Usage()
|
||||||
usage.name = usages[i][-1]
|
usage.name = usages[i]['usage']
|
||||||
self._assign_values(usage, nrcan_archetype_usages[i], volume_per_area, building.cold_water_temperature)
|
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)
|
self._assign_comnet_extra_values(usage, comnet_archetype_usages[i], nrcan_archetype_usages[i].occupancy.occupancy_density)
|
||||||
usage.percentage = 1
|
usage.percentage = 1
|
||||||
@ -86,19 +83,21 @@ class NrcanUsageParameters:
|
|||||||
else:
|
else:
|
||||||
storeys_above_ground = building.storeys_above_ground
|
storeys_above_ground = building.storeys_above_ground
|
||||||
if storeys_above_ground is None:
|
if storeys_above_ground is None:
|
||||||
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for usage %s. '
|
logging.error('Building %s no number of storeys assigned, ACH cannot be calculated for function %s. '
|
||||||
'NRCAN construction data for the year %s is used to calculated number of storeys above '
|
'NRCAN construction data for the year %s is used to calculated number of storeys above '
|
||||||
'ground', building.name, usages, building.year_of_construction)
|
'ground', building.name, building.function, building.year_of_construction)
|
||||||
|
try:
|
||||||
storeys_above_ground = self.average_storey_height_calculator(self._city, building)
|
storeys_above_ground = self.average_storey_height_calculator(self._city, building)
|
||||||
|
except ValueError as e:
|
||||||
|
logging.error(e)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
volume_per_area = building.volume / building.floor_area / storeys_above_ground
|
volume_per_area = building.volume / building.floor_area / storeys_above_ground
|
||||||
for (j, mixed_usage) in enumerate(usages):
|
for j, usage_type in enumerate(usages):
|
||||||
usage = Usage()
|
usage = Usage()
|
||||||
usage.name = mixed_usage[-1]
|
usage.name = usage_type['usage']
|
||||||
if len(usages) > 1:
|
usage.percentage = float(usage_type['ratio'])
|
||||||
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_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._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])
|
self._calculate_reduced_values_from_extended_library(usage, nrcan_archetype_usages[j])
|
||||||
@ -227,20 +226,11 @@ class NrcanUsageParameters:
|
|||||||
def average_storey_height_calculator(city, building):
|
def average_storey_height_calculator(city, building):
|
||||||
climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
|
climate_zone = ConstructionHelper.city_to_nrcan_climate_zone(city.climate_reference_city)
|
||||||
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
nrcan_catalog = ConstructionCatalogFactory('nrcan').catalog
|
||||||
main_function = None
|
|
||||||
functions = building.function.split('_')
|
if building.function not in Dictionaries().hub_function_to_nrcan_construction_function:
|
||||||
if len(functions) > 1:
|
raise ValueError('Building %s has an unknown building function %s', building.name, building.function)
|
||||||
maximum_percentage = 0
|
|
||||||
for function in functions:
|
function = Dictionaries().hub_function_to_nrcan_construction_function[building.function]
|
||||||
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
|
construction_archetype = None
|
||||||
average_storey_height = None
|
average_storey_height = None
|
||||||
nrcan_archetypes = nrcan_catalog.entries('archetypes')
|
nrcan_archetypes = nrcan_catalog.entries('archetypes')
|
||||||
@ -251,7 +241,7 @@ class NrcanUsageParameters:
|
|||||||
construction_archetype = building_archetype
|
construction_archetype = building_archetype
|
||||||
average_storey_height = building_archetype.average_storey_height
|
average_storey_height = building_archetype.average_storey_height
|
||||||
if construction_archetype is None:
|
if construction_archetype is None:
|
||||||
logging.error('Building %s has unknown construction archetype for building function: %s '
|
raise ValueError('Building %s has unknown construction archetype for building function: %s '
|
||||||
'[%s], building year of construction: %s and climate zone %s', building.name, function,
|
'[%s], building year of construction: %s and climate zone %s', building.name, function,
|
||||||
building.function, building.year_of_construction, climate_zone)
|
building.function, building.year_of_construction, climate_zone)
|
||||||
|
|
||||||
|
1
setup.py
1
setup.py
@ -65,6 +65,7 @@ setup(
|
|||||||
'hub.helpers',
|
'hub.helpers',
|
||||||
'hub.helpers.peak_calculation',
|
'hub.helpers.peak_calculation',
|
||||||
'hub.helpers.data',
|
'hub.helpers.data',
|
||||||
|
'hub.helpers.parsers',
|
||||||
'hub.imports',
|
'hub.imports',
|
||||||
'hub.imports.construction',
|
'hub.imports.construction',
|
||||||
'hub.imports.construction.helpers',
|
'hub.imports.construction.helpers',
|
||||||
|
@ -11,6 +11,7 @@ from hub.imports.geometry_factory import GeometryFactory
|
|||||||
from hub.imports.construction_factory import ConstructionFactory
|
from hub.imports.construction_factory import ConstructionFactory
|
||||||
from hub.imports.usage_factory import UsageFactory
|
from hub.imports.usage_factory import UsageFactory
|
||||||
from hub.helpers.dictionaries import Dictionaries
|
from hub.helpers.dictionaries import Dictionaries
|
||||||
|
from hub.helpers.usage_parsers import UsageParsers
|
||||||
|
|
||||||
|
|
||||||
class TestUsageFactory(TestCase):
|
class TestUsageFactory(TestCase):
|
||||||
@ -75,22 +76,6 @@ class TestUsageFactory(TestCase):
|
|||||||
self.assertIsNotNone(usage.thermal_control.heating_set_back, 'control heating set back is none')
|
self.assertIsNotNone(usage.thermal_control.heating_set_back, 'control heating set back is none')
|
||||||
self.assertIsNotNone(usage.thermal_control.mean_cooling_set_point, 'control cooling set point is none')
|
self.assertIsNotNone(usage.thermal_control.mean_cooling_set_point, 'control cooling set point is none')
|
||||||
|
|
||||||
def test_import_comnet(self):
|
|
||||||
"""
|
|
||||||
Enrich the city with the usage information from comnet and verify it
|
|
||||||
"""
|
|
||||||
file = 'pluto_building.gml'
|
|
||||||
city = self._get_citygml(file)
|
|
||||||
for building in city.buildings:
|
|
||||||
building.function = Dictionaries().pluto_function_to_hub_function[building.function]
|
|
||||||
|
|
||||||
UsageFactory('comnet', city).enrich()
|
|
||||||
self._check_buildings(city)
|
|
||||||
for building in city.buildings:
|
|
||||||
for internal_zone in building.internal_zones:
|
|
||||||
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
|
|
||||||
for usage in internal_zone.usages:
|
|
||||||
self._check_usage(usage)
|
|
||||||
self.assertIsNotNone(usage.mechanical_air_change, 'mechanical air change is none')
|
self.assertIsNotNone(usage.mechanical_air_change, 'mechanical air change is none')
|
||||||
self.assertIsNotNone(usage.thermal_control.heating_set_point_schedules,
|
self.assertIsNotNone(usage.thermal_control.heating_set_point_schedules,
|
||||||
'control heating set point schedule is none')
|
'control heating set point schedule is none')
|
||||||
@ -121,11 +106,28 @@ class TestUsageFactory(TestCase):
|
|||||||
self.assertIsNotNone(appliances.schedules, 'appliances schedule is none')
|
self.assertIsNotNone(appliances.schedules, 'appliances schedule is none')
|
||||||
self.assertIsNotNone(usage.thermal_control.hvac_availability_schedules,
|
self.assertIsNotNone(usage.thermal_control.hvac_availability_schedules,
|
||||||
'control hvac availability is none')
|
'control hvac availability is none')
|
||||||
self.assertIsNotNone(usage.domestic_hot_water.density, 'domestic hot water density is none')
|
|
||||||
self.assertIsNotNone(usage.domestic_hot_water.service_temperature,
|
self.assertIsNotNone(usage.domestic_hot_water.service_temperature,
|
||||||
'domestic hot water service temperature is none')
|
'domestic hot water service temperature is none')
|
||||||
self.assertIsNotNone(usage.domestic_hot_water.schedules, 'domestic hot water schedules is none')
|
self.assertIsNotNone(usage.domestic_hot_water.schedules, 'domestic hot water schedules is none')
|
||||||
|
|
||||||
|
def test_import_comnet(self):
|
||||||
|
"""
|
||||||
|
Enrich the city with the usage information from comnet and verify it
|
||||||
|
"""
|
||||||
|
file = 'pluto_building.gml'
|
||||||
|
city = self._get_citygml(file)
|
||||||
|
for building in city.buildings:
|
||||||
|
building.function = Dictionaries().pluto_function_to_hub_function[building.function]
|
||||||
|
|
||||||
|
UsageFactory('comnet', city).enrich()
|
||||||
|
self._check_buildings(city)
|
||||||
|
for building in city.buildings:
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
|
||||||
|
for usage in internal_zone.usages:
|
||||||
|
self._check_usage(usage)
|
||||||
|
self.assertIsNotNone(usage.domestic_hot_water.density, 'domestic hot water density is none')
|
||||||
|
|
||||||
def test_import_nrcan(self):
|
def test_import_nrcan(self):
|
||||||
"""
|
"""
|
||||||
Enrich the city with the usage information from nrcan and verify it
|
Enrich the city with the usage information from nrcan and verify it
|
||||||
@ -148,40 +150,6 @@ class TestUsageFactory(TestCase):
|
|||||||
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
|
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
|
||||||
for usage in internal_zone.usages:
|
for usage in internal_zone.usages:
|
||||||
self._check_usage(usage)
|
self._check_usage(usage)
|
||||||
self.assertIsNotNone(usage.mechanical_air_change, 'mechanical air change is none')
|
|
||||||
self.assertIsNotNone(usage.thermal_control.heating_set_point_schedules,
|
|
||||||
'control heating set point schedule is none')
|
|
||||||
self.assertIsNotNone(usage.thermal_control.cooling_set_point_schedules,
|
|
||||||
'control cooling set point schedule is none')
|
|
||||||
self.assertIsNotNone(usage.occupancy, 'occupancy is none')
|
|
||||||
occupancy = usage.occupancy
|
|
||||||
self.assertIsNotNone(occupancy.occupancy_density, 'occupancy density is none')
|
|
||||||
self.assertIsNotNone(occupancy.latent_internal_gain, 'occupancy latent internal gain is none')
|
|
||||||
self.assertIsNotNone(occupancy.sensible_convective_internal_gain,
|
|
||||||
'occupancy sensible convective internal gain is none')
|
|
||||||
self.assertIsNotNone(occupancy.sensible_radiative_internal_gain,
|
|
||||||
'occupancy sensible radiant internal gain is none')
|
|
||||||
self.assertIsNotNone(occupancy.occupancy_schedules, 'occupancy schedule is none')
|
|
||||||
self.assertIsNotNone(usage.lighting, 'lighting is none')
|
|
||||||
lighting = usage.lighting
|
|
||||||
self.assertIsNotNone(lighting.density, 'lighting density is none')
|
|
||||||
self.assertIsNotNone(lighting.latent_fraction, 'lighting latent fraction is none')
|
|
||||||
self.assertIsNotNone(lighting.convective_fraction, 'lighting convective fraction is none')
|
|
||||||
self.assertIsNotNone(lighting.radiative_fraction, 'lighting radiant fraction is none')
|
|
||||||
self.assertIsNotNone(lighting.schedules, 'lighting schedule is none')
|
|
||||||
self.assertIsNotNone(usage.appliances, 'appliances is none')
|
|
||||||
appliances = usage.appliances
|
|
||||||
self.assertIsNotNone(appliances.density, 'appliances density is none')
|
|
||||||
self.assertIsNotNone(appliances.latent_fraction, 'appliances latent fraction is none')
|
|
||||||
self.assertIsNotNone(appliances.convective_fraction, 'appliances convective fraction is none')
|
|
||||||
self.assertIsNotNone(appliances.radiative_fraction, 'appliances radiant fraction is none')
|
|
||||||
self.assertIsNotNone(appliances.schedules, 'appliances schedule is none')
|
|
||||||
self.assertIsNotNone(usage.thermal_control.hvac_availability_schedules,
|
|
||||||
'control hvac availability is none')
|
|
||||||
self.assertIsNotNone(usage.domestic_hot_water.peak_flow, 'domestic hot water peak flow is none')
|
|
||||||
self.assertIsNotNone(usage.domestic_hot_water.service_temperature,
|
|
||||||
'domestic hot water service temperature is none')
|
|
||||||
self.assertIsNotNone(usage.domestic_hot_water.schedules, 'domestic hot water schedules is none')
|
|
||||||
|
|
||||||
def test_import_palma(self):
|
def test_import_palma(self):
|
||||||
"""
|
"""
|
||||||
@ -205,38 +173,35 @@ class TestUsageFactory(TestCase):
|
|||||||
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
|
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
|
||||||
for usage in internal_zone.usages:
|
for usage in internal_zone.usages:
|
||||||
self._check_usage(usage)
|
self._check_usage(usage)
|
||||||
self.assertIsNotNone(usage.mechanical_air_change, 'mechanical air change is none')
|
|
||||||
self.assertIsNotNone(usage.thermal_control.heating_set_point_schedules,
|
|
||||||
'control heating set point schedule is none')
|
|
||||||
self.assertIsNotNone(usage.thermal_control.cooling_set_point_schedules,
|
|
||||||
'control cooling set point schedule is none')
|
|
||||||
self.assertIsNotNone(usage.occupancy, 'occupancy is none')
|
|
||||||
occupancy = usage.occupancy
|
|
||||||
self.assertIsNotNone(occupancy.occupancy_density, 'occupancy density is none')
|
|
||||||
self.assertIsNotNone(occupancy.latent_internal_gain, 'occupancy latent internal gain is none')
|
|
||||||
self.assertIsNotNone(occupancy.sensible_convective_internal_gain,
|
|
||||||
'occupancy sensible convective internal gain is none')
|
|
||||||
self.assertIsNotNone(occupancy.sensible_radiative_internal_gain,
|
|
||||||
'occupancy sensible radiant internal gain is none')
|
|
||||||
self.assertIsNotNone(occupancy.occupancy_schedules, 'occupancy schedule is none')
|
|
||||||
self.assertIsNotNone(usage.lighting, 'lighting is none')
|
|
||||||
lighting = usage.lighting
|
|
||||||
self.assertIsNotNone(lighting.density, 'lighting density is none')
|
|
||||||
self.assertIsNotNone(lighting.latent_fraction, 'lighting latent fraction is none')
|
|
||||||
self.assertIsNotNone(lighting.convective_fraction, 'lighting convective fraction is none')
|
|
||||||
self.assertIsNotNone(lighting.radiative_fraction, 'lighting radiant fraction is none')
|
|
||||||
self.assertIsNotNone(lighting.schedules, 'lighting schedule is none')
|
|
||||||
self.assertIsNotNone(usage.appliances, 'appliances is none')
|
|
||||||
appliances = usage.appliances
|
|
||||||
self.assertIsNotNone(appliances.density, 'appliances density is none')
|
|
||||||
self.assertIsNotNone(appliances.latent_fraction, 'appliances latent fraction is none')
|
|
||||||
self.assertIsNotNone(appliances.convective_fraction, 'appliances convective fraction is none')
|
|
||||||
self.assertIsNotNone(appliances.radiative_fraction, 'appliances radiant fraction is none')
|
|
||||||
self.assertIsNotNone(appliances.schedules, 'appliances schedule is none')
|
|
||||||
self.assertIsNotNone(usage.thermal_control.hvac_availability_schedules,
|
|
||||||
'control hvac availability is none')
|
|
||||||
self.assertIsNotNone(usage.domestic_hot_water.peak_flow, 'domestic hot water peak flow is none')
|
self.assertIsNotNone(usage.domestic_hot_water.peak_flow, 'domestic hot water peak flow is none')
|
||||||
self.assertIsNotNone(usage.domestic_hot_water.service_temperature,
|
|
||||||
'domestic hot water service temperature is none')
|
|
||||||
self.assertIsNotNone(usage.domestic_hot_water.schedules, 'domestic hot water schedules is none')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_import_nrcan_multiusage(self):
|
||||||
|
"""
|
||||||
|
Enrich the city with the usage information from nrcan and verify it
|
||||||
|
"""
|
||||||
|
file = 'test.geojson'
|
||||||
|
file_path = (self._example_path / file).resolve()
|
||||||
|
|
||||||
|
function_dictionary = Dictionaries().montreal_function_to_hub_function
|
||||||
|
usage_parser = UsageParsers().list_usage_to_hub(function_dictionary=function_dictionary)
|
||||||
|
|
||||||
|
city = GeometryFactory('geojson',
|
||||||
|
path=file_path,
|
||||||
|
height_field='citygml_me',
|
||||||
|
year_of_construction_field='ANNEE_CONS',
|
||||||
|
function_field='CODE_UTILI',
|
||||||
|
function_to_hub=function_dictionary,
|
||||||
|
usages_field='usages',
|
||||||
|
usages_to_hub=usage_parser).city
|
||||||
|
|
||||||
|
ConstructionFactory('nrcan', city).enrich()
|
||||||
|
UsageFactory('nrcan', city).enrich()
|
||||||
|
self._check_buildings(city)
|
||||||
|
for building in city.buildings:
|
||||||
|
for internal_zone in building.internal_zones:
|
||||||
|
if internal_zone.usages is not None:
|
||||||
|
self.assertIsNot(len(internal_zone.usages), 0, 'no building usage defined')
|
||||||
|
for usage in internal_zone.usages:
|
||||||
|
self._check_usage(usage)
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user