Merge branch 'master' into more_errors_from_merge

This commit is contained in:
Pilar 2023-02-09 04:31:13 -05:00
commit e66bac33ae
56 changed files with 2901 additions and 1329 deletions

View File

@ -74,7 +74,7 @@ from hub.persistence import DBSetup
from pathlib import Path from pathlib import Path
dotenv_path = (Path(__file__).parent / '.env').resolve() dotenv_path = (Path(__file__).parent / '.env').resolve()
DBSetup(db_name='hub_db', app_env='PROD', dotenv_path=dotenv_path) DBSetup(db_name='hub_db', app_env='PROD', dotenv_path=dotenv_path, admin_password="your password here", application_uuid="your admin application uuid")
``` ```
The *DBSetUp* class also creates a default admin user with default credentials that can be changed. The *DBSetUp* class also creates a default admin user with default credentials that can be changed.
with the import UserFactory class. The admin user (name, email, password and role) is logged into the console after it is created by the with the import UserFactory class. The admin user (name, email, password and role) is logged into the console after it is created by the

View File

@ -34,7 +34,7 @@ class Building(CityObject):
self._roof_type = None self._roof_type = None
self._internal_zones = None self._internal_zones = None
self._shell = None self._shell = None
self._human_readable_name = None self._alias = None
self._type = 'building' self._type = 'building'
self._heating = dict() self._heating = dict()
self._cooling = dict() self._cooling = dict()
@ -404,16 +404,27 @@ class Building(CityObject):
return False return False
@property @property
def human_readable_name(self): def alias(self):
""" """
Get the human-readable name for the building Get the alias name for the building
:return: str :return: str
""" """
return self._human_readable_name return self._alias
@human_readable_name.setter @alias.setter
def human_readable_name(self, value): def alias(self, value):
""" """
Set the human-readable name for the building Set the alias name for the building
""" """
self._human_readable_name = value self._alias = value
@property
def usages_percentage(self):
"""
Get the usages and percentages for the building
"""
_usage = ''
for internal_zone in self.internal_zones:
for usage in internal_zone.usages:
_usage = f'{_usage}{usage.name}_{usage.percentage} '
return _usage.rstrip()

View File

@ -101,13 +101,19 @@ class City:
""" """
return self._get_location().country return self._get_location().country
@property
def location(self):
return self._get_location().city
@property @property
def name(self): def name(self):
""" """
Get city name Get city name
:return: str :return: str
""" """
if self._name is None:
return self._get_location().city return self._get_location().city
return self._name
@property @property
def climate_reference_city(self) -> Union[None, str]: def climate_reference_city(self) -> Union[None, str]:

View File

@ -14,6 +14,8 @@ class LevelOfDetail:
self._geometry = None self._geometry = None
self._construction = None self._construction = None
self._usage = None self._usage = None
self._weather = None
self._surface_radiation = None
@property @property
def geometry(self): def geometry(self):
@ -59,3 +61,33 @@ class LevelOfDetail:
Set the city minimal usage level of detail, 1 or 2 Set the city minimal usage level of detail, 1 or 2
""" """
self._usage = value self._usage = value
@property
def weather(self):
"""
Get the city minimal weather level of detail, 0 (yearly), 1 (monthly), 2 (hourly)
:return: int
"""
return self._weather
@weather.setter
def weather(self, value):
"""
Set the city minimal weather level of detail, 0 (yearly), 1 (monthly), 2 (hourly)
"""
self._usage = value
@property
def surface_radiation(self):
"""
Get the city minimal surface radiation level of detail, 0 (yearly), 1 (monthly), 2 (hourly)
:return: int
"""
return self._surface_radiation
@surface_radiation.setter
def surface_radiation(self, value):
"""
Set the city minimal surface radiation level of detail, 0 (yearly), 1 (monthly), 2 (hourly)
"""
self._surface_radiation = value

View File

@ -75,7 +75,7 @@ class EnergyAde:
'energy:type': 'grossVolume', 'energy:type': 'grossVolume',
'energy:value': { 'energy:value': {
'@uom': 'm3', '@uom': 'm3',
'energy:value': building.volume '#text': f'{building.volume}'
} }
} }
} }
@ -169,7 +169,7 @@ class EnergyAde:
def _building_geometry(self, building, building_dic, city): def _building_geometry(self, building, building_dic, city):
building_dic['bldg:Building']['bldg:function'] = building.function building_dic['bldg:Building']['bldg:function'] = building.function
building_dic['bldg:Building']['bldg:usage'] = ', '.join([u.name for u in building.usages]) building_dic['bldg:Building']['bldg:usage'] = building.usages_percentage
building_dic['bldg:Building']['bldg:yearOfConstruction'] = building.year_of_construction building_dic['bldg:Building']['bldg:yearOfConstruction'] = building.year_of_construction
building_dic['bldg:Building']['bldg:roofType'] = building.roof_type building_dic['bldg:Building']['bldg:roofType'] = building.roof_type
building_dic['bldg:Building']['bldg:measuredHeight'] = { building_dic['bldg:Building']['bldg:measuredHeight'] = {
@ -178,16 +178,86 @@ class EnergyAde:
} }
building_dic['bldg:Building']['bldg:storeysAboveGround'] = building.storeys_above_ground building_dic['bldg:Building']['bldg:storeysAboveGround'] = building.storeys_above_ground
if building.lod == 1: if city.level_of_detail.geometry == 1:
building_dic = self._lod1(building, building_dic, city) building_dic = self._lod1(building, building_dic, city)
elif building.lod == 2: elif city.level_of_detail.geometry == 2:
building_dic = self._lod2(building, building_dic, city) building_dic = self._lod2(building, building_dic, city)
else: else:
raise NotImplementedError('Only lod 1 and 2 can be exported') raise NotImplementedError('Only lod 1 and 2 can be exported')
return building_dic return building_dic
def _lod1(self, building, building_dic, city): def _lod1(self, building, building_dic, city):
raise NotImplementedError('Only lod 1 and 2 can be exported') self._surface_members = []
boundaries = [{
'gml:Envelope': {
'@srsName': city.srs_name,
'@srsDimension': 3,
'gml:lowerCorner': ' '.join([str(e) for e in city.lower_corner]),
'gml:upperCorner': ' '.join([str(e) for e in city.upper_corner])
}}]
for surface in building.surfaces:
surface_member = {'@xlink:href': f'#PolyId{surface.name}'}
self._surface_members.append(surface_member)
if surface.type == 'Wall':
surface_type = 'bldg:WallSurface'
elif surface.type == 'Ground':
surface_type = 'bldg:GroundSurface'
else:
surface_type = 'bldg:RoofSurface'
surface_dic = {
surface_type: {
'@gml:id': f'GML_{uuid.uuid4()}',
'gml:name': f'{surface.name} ({surface.type})',
'gml:boundedBy': {
'gml:Envelope': {
'@srsName': city.srs_name,
'gml:lowerCorner': f'{surface.lower_corner[0]} {surface.lower_corner[1]}'
f' {surface.lower_corner[2]}',
'gml:upperCorner': f'{surface.upper_corner[0]} {surface.upper_corner[1]}'
f' {surface.upper_corner[2]}'
}
},
'bldg:lod1MultiSurface': {
'gml:MultiSurface': {
'@srsName': city.srs_name,
'@gml:id': f'GML_{uuid.uuid4()}',
'surfaceMember': {
'gml:Polygon': {
'@srsName': city.srs_name,
'@gml:id': f'PolyId{surface.name}',
'gml:exterior': {
'gml:LinearRing': {
'@gml:id': f'PolyId{surface.name}_0',
'gml:posList': {
'@srsDimension': '3',
'@count': len(surface.solid_polygon.coordinates) + 1,
'#text': f'{" ".join(map(str, surface.solid_polygon.points_list))} '
f'{" ".join(map(str, surface.solid_polygon.coordinates[0]))}'
}
}
}
}
}
}
}
}
}
boundaries.append(surface_dic)
building_dic['bldg:Building']['bldg:lod1Solid'] = {
'gml:Solid': {
'@gml:id': f'GML_{uuid.uuid4()}',
'gml:exterior': {
'gml:CompositeSurface': {
'@srsName': city.srs_name,
'@gml:id': f'GML_{uuid.uuid4()}',
'gml:surfaceMember': self._surface_members
}
}
}
}
building_dic['bldg:Building']['gml:boundedBy'] = boundaries
return building_dic
def _lod2(self, building, building_dic, city): def _lod2(self, building, building_dic, city):
self._surface_members = [] self._surface_members = []
@ -264,9 +334,10 @@ class EnergyAde:
def _thermal_zones(self, building, city): def _thermal_zones(self, building, city):
thermal_zones = [] thermal_zones = []
for index, thermal_zone in enumerate(building.thermal_zones): for internal_zone in building.internal_zones:
for index, thermal_zone in enumerate(internal_zone.thermal_zones):
usages = [] usages = []
for usage in thermal_zone.usages: for usage in internal_zone.usages:
usages.append({'@xlink:href': f'#GML_{usage.id}'}) usages.append({'@xlink:href': f'#GML_{usage.id}'})
thermal_zone_dic = { thermal_zone_dic = {
'energy:ThermalZone': { 'energy:ThermalZone': {
@ -287,13 +358,12 @@ class EnergyAde:
'energy:type': 'grossVolume', 'energy:type': 'grossVolume',
'energy:value': { 'energy:value': {
'@uom': 'm3', '@uom': 'm3',
# todo: for now we have just one thermal zone, therefore is the building volume, this need to be changed '#text': f'{thermal_zone.volume}'
'#text': f'{building.volume}'
} }
} }
}, },
'energy:isCooled': f'{thermal_zone.is_cooled}', 'energy:isCooled': f'{building.is_conditioned}'.lower(),
'energy:isHeated': f'{thermal_zone.is_heated}', 'energy:isHeated': f'{building.is_conditioned}'.lower(),
'energy:volumeGeometry': { 'energy:volumeGeometry': {
'gml:Solid': { 'gml:Solid': {
'@gml:id': f'GML_{uuid.uuid4()}', '@gml:id': f'GML_{uuid.uuid4()}',
@ -323,11 +393,11 @@ class EnergyAde:
'energy:thermalBoundaryType': thermal_boundary.type, 'energy:thermalBoundaryType': thermal_boundary.type,
'energy:azumuth': { 'energy:azumuth': {
'@uom': 'rad', '@uom': 'rad',
'#text': f'{thermal_boundary.azimuth}' '#text': f'{thermal_boundary.parent_surface.azimuth}'
}, },
'energy:inclination': { 'energy:inclination': {
'@uom': 'rad', '@uom': 'rad',
'#text': f'{thermal_boundary.inclination}' '#text': f'{thermal_boundary.parent_surface.inclination}'
}, },
'energy:area': { 'energy:area': {
'@uom': 'm2', '@uom': 'm2',
@ -346,9 +416,9 @@ class EnergyAde:
'@gml:id': f'GML_{uuid.uuid4()}', '@gml:id': f'GML_{uuid.uuid4()}',
'gml:posList': { 'gml:posList': {
'@srsDimension': '3', '@srsDimension': '3',
'@count': len(thermal_boundary.surface.solid_polygon.coordinates) + 1, '@count': len(thermal_boundary.parent_surface.solid_polygon.coordinates) + 1,
'#text': f'{" ".join(map(str, thermal_boundary.surface.solid_polygon.points_list))} ' '#text': f'{" ".join(map(str, thermal_boundary.parent_surface.solid_polygon.points_list))} '
f'{" ".join(map(str, thermal_boundary.surface.solid_polygon.coordinates[0]))}' f'{" ".join(map(str, thermal_boundary.parent_surface.solid_polygon.coordinates[0]))}'
} }
} }
} }

View File

@ -4,8 +4,10 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project CoderPeter Yefi peteryefi@gmail.com Project CoderPeter Yefi peteryefi@gmail.com
""" """
from hub.persistence import CityRepo from hub.persistence import City
from hub.persistence import HeatPumpSimulationRepo from hub.persistence import Application
from hub.persistence import User
from hub.persistence import CityObject
class DBFactory: class DBFactory:
@ -14,40 +16,38 @@ class DBFactory:
""" """
def __init__(self, db_name, app_env, dotenv_path): def __init__(self, db_name, app_env, dotenv_path):
self._city_repo = CityRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path) self._city = City(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
self._hp_simulation_repo = HeatPumpSimulationRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path) self._application = Application(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
self._user = User(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
self._city_object = CityObject(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
def get_city(self, city_id): def get_city(self, city_id):
""" """
Retrieve a single city from postgres Retrieve a single city from postgres
:param city_id: the id of the city to get :param city_id: the id of the city to get
""" """
return self._city_repo.get_by_id(city_id) return self._city.get_by_id(city_id)
def get_city_by_name(self, city_name): def get_city_by_name(self, city_name):
""" """
Retrieve a single city from postgres Retrieve a single city from postgres
:param city_name: the name of the city to get :param city_name: the name of the city to get
""" """
return self._city_repo.get_by_name(city_name) return self._city.get_by_name(city_name)
def get_city_by_user(self, user_id): def get_city_by_user(self, user_id):
""" """
Retrieve cities created by user Retrieve cities created by user
:param user_id: the id of the user :param user_id: the id of the user
""" """
return self._city_repo.get_by_user(user_id) return self._city.get_by_user(user_id)
def get_hp_simulation(self, hp_sim_id: int): def application_info(self, application_uuid):
""" return self._application.get_by_uuid(application_uuid)
Retrieve a single heat pump simulation from postgres
:param hp_sim_id: the id of the heat pump to get def user_info(self, name, password, application_id):
""" return self._user.get_by_name_application_and_password(name, password, application_id)
return self._hp_simulation_repo.get_by_id(hp_sim_id)
def building_info(self, name, city_id):
return self._city_object.get_by_name_and_city(name, city_id)
def get_hp_simulation_by_city(self, city_id: int):
"""
Retrieve a single city from postgres
:param city_id: the id of the city
"""
return self._hp_simulation_repo.get_by_city(city_id)

View File

@ -17,7 +17,11 @@ class ExportsFactory:
""" """
Exports factory class Exports factory class
""" """
def __init__(self, export_type, city, path, target_buildings=None, adjacent_buildings=None): def __init__(self, export_type, city, path,
target_buildings=None,
adjacent_buildings=None,
weather_file=None,
weather_format=None):
self._city = city self._city = city
self._export_type = '_' + export_type.lower() self._export_type = '_' + export_type.lower()
class_funcs = validate_import_export_type(ExportsFactory) class_funcs = validate_import_export_type(ExportsFactory)
@ -30,6 +34,8 @@ class ExportsFactory:
self._path = path self._path = path
self._target_buildings = target_buildings self._target_buildings = target_buildings
self._adjacent_buildings = adjacent_buildings self._adjacent_buildings = adjacent_buildings
self._weather_file = weather_file
self._weather_format = weather_format
@property @property
def _citygml(self): def _citygml(self):
@ -73,7 +79,10 @@ class ExportsFactory:
Export the city to Simplified Radiosity Algorithm xml format Export the city to Simplified Radiosity Algorithm xml format
:return: None :return: None
""" """
return SimplifiedRadiosityAlgorithm(self._city, (self._path / f'{self._city.name}_sra.xml'), return SimplifiedRadiosityAlgorithm(self._city,
(self._path / f'{self._city.name}_sra.xml'),
self._weather_file,
self._weather_format,
target_buildings=self._target_buildings) target_buildings=self._target_buildings)
def export(self): def export(self):

View File

@ -6,12 +6,25 @@ Project Coder Guillermo.GutierrezMorote@concordia.ca
""" """
import xmltodict import xmltodict
from hub.imports.weather_factory import WeatherFactory
import hub.helpers.constants as cte
class SimplifiedRadiosityAlgorithm: class SimplifiedRadiosityAlgorithm:
""" """
Export to SRA format Export to SRA format
""" """
def __init__(self, city, file_name, target_buildings=None, begin_month=1, begin_day=1, end_month=12, end_day=31):
def __init__(self,
city,
file_name,
weather_file,
weather_format,
target_buildings=None,
begin_month=1,
begin_day=1,
end_month=12,
end_day=31):
self._file_name = file_name self._file_name = file_name
self._begin_month = begin_month self._begin_month = begin_month
self._begin_day = begin_day self._begin_day = begin_day
@ -19,6 +32,8 @@ class SimplifiedRadiosityAlgorithm:
self._end_day = end_day self._end_day = end_day
self._city = city self._city = city
self._target_buildings = target_buildings self._target_buildings = target_buildings
self._weather_format = weather_format
self._weather_file = weather_file
self._export() self._export()
def _correct_point(self, point): def _correct_point(self, point):
@ -29,6 +44,34 @@ class SimplifiedRadiosityAlgorithm:
return [x, y, z] return [x, y, z]
def _export(self): def _export(self):
self._export_sra_xml()
self._export_sra_cli()
def _export_sra_cli(self):
file = self._city.climate_file
days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
WeatherFactory(self._weather_format, self._city, file_name=self._weather_file).enrich()
content = self._city.name + '\n'
content += str(self._city.latitude) + ',' + str(self._city.longitude) + ',0.0,' + str(self._city.time_zone) + '\n'
content += '\ndm m h G_Dh G_Bn\n'
total_days = 0
for month in range(1, 13):
if month > 1:
total_days += days_in_month[month - 2]
for day in range(1, days_in_month[month - 1] + 1):
for hour in range(1, 25):
if month == 1:
i = 24 * (day - 1) + hour - 1
else:
i = (total_days + day - 1) * 24 + hour - 1
representative_building = self._city.buildings[0]
content += str(day) + ' ' + str(month) + ' ' + str(hour) + ' ' \
+ str(representative_building.global_horizontal[cte.HOUR].epw[i]) + ' ' \
+ str(representative_building.beam[cte.HOUR].epw[i]) + '\n'
with open(file, "w") as file:
file.write(content)
def _export_sra_xml(self):
buildings = [] buildings = []
for building_index, building in enumerate(self._city.buildings): for building_index, building in enumerate(self._city.buildings):
if self._target_buildings is None: if self._target_buildings is None:

View File

@ -11,20 +11,6 @@ import re
class Auth(object): class Auth(object):
@staticmethod
def validate_password(password: str) -> bool:
"""
Validates a password
:param password: the password to validate
:return:
"""
pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!#%*?&]{6,20}$"
pattern = re.compile(pattern)
if not re.search(pattern, password):
raise ValueError("Password must be between 6 to 20 characters and must have at least a number, an uppercase "
"letter, a lowercase letter, and a special character")
return True
@staticmethod @staticmethod
def hash_password(password: str) -> str: def hash_password(password: str) -> str:
""" """

View File

@ -152,3 +152,7 @@ FULL_HVAC = 'Heating and cooling and ventilation'
# Floats # Floats
MAX_FLOAT = float('inf') MAX_FLOAT = float('inf')
MIN_FLOAT = float('-inf') MIN_FLOAT = float('-inf')
# Tools
SRA = 'sra'
INSEL_MEB = 'insel meb'

View File

@ -0,0 +1,185 @@
"""
Dictionaries module for Alkis function to hub 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 AlkisFunctionToHubFunction:
def __init__(self):
self._dictionary = {"1000": cte.RESIDENTIAL,
"1010": "tenement",
"1020": "hostel",
"1030": "residential- and administration building",
"1040": "residential- and office building",
"1050": "residential- and business building",
"1060": "residential- and plant building",
"1070": "agrarian- and forestry building",
"1080": "residential- and commercial building",
"1090": "forester's lodge",
"1100": "holiday house",
"1110": "summer house",
"1120": "office building",
"1130": "credit institution",
"1140": "insurance",
"1150": "business building",
"1160": "department store",
"1170": "shopping centre",
"1180": "kiosk",
"1190": "pharmacy",
"1200": "pavilion",
"1210": cte.HOTEL,
"1220": "youth hostel",
"1230": "campsite building",
"1240": "restaurant",
"1250": "cantine",
"1260": "recreational site",
"1270": "function room",
"1280": "cinema",
"1290": "bowling alley",
"1300": "casino",
"1310": "industrial building",
"1320": "factory",
"1330": cte.WORKSHOP,
"1340": "petrol / gas station",
"1350": "washing plant",
"1360": "cold store",
"1370": "depot",
"1380": "building for research purposes",
"1390": "quarry",
"1400": "salt works",
"1410": "miscellaneous industrial building",
"1420": "mill",
"1430": "windmill",
"1440": "water mill",
"1450": "bucket elevator",
"1460": "weather station",
"1470": "traffic assets office",
"1480": "street maintenance",
"1490": "waiting hall",
"1500": "signal control box",
"1510": "engine shed",
"1520": "signal box or stop signal",
"1530": "plant building for air traffic",
"1540": "hangar",
"1550": "plant building for shipping",
"1560": "shipyard",
"1570": "dock",
"1580": "plant building for canal lock",
"1590": "boathouse",
"1600": "plant building for cablecar",
"1610": "multi-storey car park",
"1620": "parking level",
"1630": "garage",
"1640": "vehicle hall",
"1650": "underground garage",
"1660": "building for supply",
"1670": "waterworks",
"1680": "pump station",
"1690": "water basin",
"1700": "electric power station",
"1710": "transformer station",
"1720": "converter",
"1730": "reactor",
"1740": "turbine house",
"1750": "boiler house",
"1760": "building for telecommunications",
"1770": "gas works",
"1780": "heat plant",
"1790": "pumping station",
"1800": "building for disposal",
"1810": "building for effluent disposal",
"1820": "building for filter plant",
"1830": "toilet",
"1840": "rubbish bunker",
"1850": "building for rubbish incineration",
"1860": "building for rubbish disposal",
"1870": "building for agrarian and forestry",
"1880": "barn",
"1890": "stall",
"1900": "equestrian hall",
"1910": "alpine cabin",
"1920": "hunting lodge",
"1930": "arboretum",
"1940": "glass house",
"1950": "moveable glass house",
"1960": "public building",
"1970": "administration building",
"1980": "parliament",
"1990": "guildhall",
"2000": "post office",
"2010": "customs office",
"2020": "court",
"2030": "embassy or consulate",
"2040": "district administration",
"2050": "district government",
"2060": "tax office",
"2070": "building for education and research",
"2080": "comprehensive school",
"2090": "vocational school",
"2100": "college or university",
"2110": "research establishment",
"2120": "building for cultural purposes",
"2130": "castle",
"2140": "theatre or opera",
"2150": "concert building",
"2160": cte.MUSEUM,
"2170": "broadcasting building",
"2180": "activity building",
"2190": cte.LIBRARY,
"2200": "fort",
"2210": "religious building",
"2220": "church",
"2230": "synagogue",
"2240": "chapel",
"2250": "community center",
"2260": "place of worship",
"2270": "mosque",
"2280": "temple",
"2290": "convent",
"2300": "building for health care",
"2310": cte.HOSPITAL,
"2320": "healing centre or care home",
"2330": "health centre or outpatients clinic",
"2340": "building for social purposes",
"2350": "youth centre",
"2360": "seniors centre",
"2370": "homeless shelter",
"2380": "kindergarten or nursery",
"2390": "asylum seekers home",
"2400": cte.POLICE_STATION,
"2410": cte.FIRE_STATION,
"2420": "barracks",
"2430": "bunker",
"2440": cte.PENITENTIARY,
"2450": "cemetery building",
"2460": "funeral parlor",
"2470": "crematorium",
"2480": "train station",
"2490": "airport building",
"2500": "building for underground station",
"2510": "building for tramway",
"2520": "building for bus station",
"2530": "shipping terminal",
"2540": "building for recuperation purposes",
"2550": "building for sport purposes",
"2560": "sports hall",
"2570": "building for sports field",
"2580": "swimming baths",
"2590": "indoor swimming pool",
"2600": "sanatorium",
"2610": "zoo building",
"2620": cte.GREEN_HOUSE,
"2630": "botanical show house",
"2640": "bothy",
"2650": "tourist information centre",
"2700": "others",
}
@property
def dictionary(self) -> dict:
return self._dictionary

View File

@ -0,0 +1,32 @@
"""
Dictionaries module for Hft function to hub 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 HftFunctionToHubFunction:
def __init__(self):
self._dictionary = {
'residential': cte.RESIDENTIAL,
'single family house': cte.SINGLE_FAMILY_HOUSE,
'multifamily house': cte.MULTI_FAMILY_HOUSE,
'hotel': cte.HOTEL,
'hospital': cte.HOSPITAL,
'outpatient': cte.OUT_PATIENT_HEALTH_CARE,
'commercial': cte.SUPERMARKET,
'strip mall': cte.STRIP_MALL,
'warehouse': cte.WAREHOUSE,
'primary school': cte.PRIMARY_SCHOOL,
'secondary school': cte.EDUCATION,
'office': cte.MEDIUM_OFFICE,
'large office': cte.LARGE_OFFICE
}
@property
def dictionary(self) -> dict:
return self._dictionary

View File

@ -0,0 +1,78 @@
"""
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 HubFunctionToNrcanConstructionFunction:
def __init__(self):
self._dictionary = {
cte.RESIDENTIAL: 'MidriseApartment',
cte.SINGLE_FAMILY_HOUSE: 'MidriseApartment',
cte.MULTI_FAMILY_HOUSE: 'HighriseApartment',
cte.ROW_HOUSE: 'MidriseApartment',
cte.MID_RISE_APARTMENT: 'MidriseApartment',
cte.HIGH_RISE_APARTMENT: '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'
}
@property
def dictionary(self) -> dict:
return self._dictionary

View File

@ -0,0 +1,78 @@
"""
Dictionaries module for hub function to NREL 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 HubFunctionToNrelConstructionFunction:
def __init__(self):
self._dictionary = {
cte.RESIDENTIAL: 'residential',
cte.SINGLE_FAMILY_HOUSE: 'residential',
cte.MULTI_FAMILY_HOUSE: 'midrise apartment',
cte.ROW_HOUSE: 'midrise apartment',
cte.MID_RISE_APARTMENT: 'midrise apartment',
cte.HIGH_RISE_APARTMENT: 'high-rise apartment',
cte.OFFICE_AND_ADMINISTRATION: 'medium office',
cte.SMALL_OFFICE: 'small office',
cte.MEDIUM_OFFICE: 'medium office',
cte.LARGE_OFFICE: 'large office',
cte.COURTHOUSE: 'medium office',
cte.FIRE_STATION: 'n/a',
cte.PENITENTIARY: 'large hotel',
cte.POLICE_STATION: 'n/a',
cte.POST_OFFICE: 'medium office',
cte.LIBRARY: 'medium office',
cte.EDUCATION: 'secondary school',
cte.PRIMARY_SCHOOL: 'primary school',
cte.PRIMARY_SCHOOL_WITH_SHOWER: 'primary school',
cte.SECONDARY_SCHOOL: 'secondary school',
cte.UNIVERSITY: 'secondary school',
cte.LABORATORY_AND_RESEARCH_CENTER: 'secondary school',
cte.STAND_ALONE_RETAIL: 'stand-alone retail',
cte.HOSPITAL: 'hospital',
cte.OUT_PATIENT_HEALTH_CARE: 'outpatient healthcare',
cte.HEALTH_CARE: 'outpatient healthcare',
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'small hotel',
cte.COMMERCIAL: 'strip mall',
cte.STRIP_MALL: 'strip mall',
cte.SUPERMARKET: 'supermarket',
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'stand-alone retail',
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'stand-alone retail',
cte.RESTAURANT: 'full service restaurant',
cte.QUICK_SERVICE_RESTAURANT: 'quick service restaurant',
cte.FULL_SERVICE_RESTAURANT: 'full service restaurant',
cte.HOTEL: 'small hotel',
cte.HOTEL_MEDIUM_CLASS: 'small hotel',
cte.SMALL_HOTEL: 'small hotel',
cte.LARGE_HOTEL: 'large hotel',
cte.DORMITORY: 'small hotel',
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/aquebec_to_hub',
cte.PARKING_GARAGE: 'n/a',
cte.RELIGIOUS: 'n/a',
cte.NON_HEATED: 'n/a'
}
@property
def dictionary(self) -> dict:
return self._dictionary

View File

@ -0,0 +1,78 @@
"""
Dictionaries module for hub usage to Comnet 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 HubUsageToComnetUsage:
def __init__(self):
self._dictionary = {
cte.RESIDENTIAL: 'BA Multifamily',
cte.SINGLE_FAMILY_HOUSE: 'BA Multifamily',
cte.MULTI_FAMILY_HOUSE: 'BA Multifamily',
cte.ROW_HOUSE: 'BA Multifamily',
cte.MID_RISE_APARTMENT: 'BA Multifamily',
cte.HIGH_RISE_APARTMENT: 'BA Multifamily',
cte.OFFICE_AND_ADMINISTRATION: 'BA Office',
cte.SMALL_OFFICE: 'BA Office',
cte.MEDIUM_OFFICE: 'BA Office',
cte.LARGE_OFFICE: 'BA Office',
cte.COURTHOUSE: 'BA Courthouse',
cte.FIRE_STATION: 'BA Fire Station',
cte.PENITENTIARY: 'BA Penitentiary',
cte.POLICE_STATION: 'BA Police Station',
cte.POST_OFFICE: 'BA Post Office',
cte.LIBRARY: 'BA Library',
cte.EDUCATION: 'BA School/University',
cte.PRIMARY_SCHOOL: 'BA School/University',
cte.PRIMARY_SCHOOL_WITH_SHOWER: 'BA School/University',
cte.SECONDARY_SCHOOL: 'BA School/University',
cte.UNIVERSITY: 'BA School/University',
cte.LABORATORY_AND_RESEARCH_CENTER: 'BA School/University',
cte.STAND_ALONE_RETAIL: 'BA Retail',
cte.HOSPITAL: 'BA Hospital',
cte.OUT_PATIENT_HEALTH_CARE: 'BA Healthcare Clinic',
cte.HEALTH_CARE: 'BA Healthcare Clinic',
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'BA Healthcare Clinic',
cte.COMMERCIAL: 'BA Retail',
cte.STRIP_MALL: 'BA Retail',
cte.SUPERMARKET: 'BA Retail',
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'BA Retail',
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'BA Retail',
cte.RESTAURANT: 'BA Dining: Bar Lounge/Leisure',
cte.QUICK_SERVICE_RESTAURANT: 'BA Dining: Cafeteria/Fast Food',
cte.FULL_SERVICE_RESTAURANT: 'BA Dining: Bar Lounge/Leisure',
cte.HOTEL: 'BA Hotel',
cte.HOTEL_MEDIUM_CLASS: 'BA Motel',
cte.SMALL_HOTEL: 'BA Motel',
cte.LARGE_HOTEL: 'BA Hotel',
cte.DORMITORY: 'BA Dormitory',
cte.EVENT_LOCATION: 'BA Convention Center',
cte.CONVENTION_CENTER: 'BA Convention Center',
cte.HALL: 'BA Town Hall',
cte.GREEN_HOUSE: 'n/a',
cte.INDUSTRY: 'BA Manufacturing Facility',
cte.WORKSHOP: 'BA Workshop',
cte.WAREHOUSE: 'BA Warehouse',
cte.WAREHOUSE_REFRIGERATED: 'BA Warehouse',
cte.SPORTS_LOCATION: 'BA Exercise Center',
cte.SPORTS_ARENA: 'BA Sports Arena',
cte.GYMNASIUM: 'BA Gymnasium',
cte.MOTION_PICTURE_THEATRE: 'BA Motion Picture Theater',
cte.MUSEUM: 'BA Museum',
cte.PERFORMING_ARTS_THEATRE: 'BA Performing Arts Theater',
cte.TRANSPORTATION: 'BA Transportation',
cte.AUTOMOTIVE_FACILITY: 'BA Automotive Facility',
cte.PARKING_GARAGE: 'BA Parking Garage',
cte.RELIGIOUS: 'BA Religious Building',
cte.NON_HEATED: 'n/a'
}
@property
def dictionary(self) -> dict:
return self._dictionary

View File

@ -0,0 +1,78 @@
"""
Dictionaries module for hub usage to Hft 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 HubUsageToHftUsage:
def __init__(self):
self._dictionary = {
cte.RESIDENTIAL: 'residential',
cte.SINGLE_FAMILY_HOUSE: 'single family house',
cte.MULTI_FAMILY_HOUSE: 'multifamily house',
cte.ROW_HOUSE: 'single family house',
cte.MID_RISE_APARTMENT: 'multifamily house',
cte.HIGH_RISE_APARTMENT: 'multifamily house',
cte.OFFICE_AND_ADMINISTRATION: 'office and administration',
cte.SMALL_OFFICE: 'office and administration',
cte.MEDIUM_OFFICE: 'office and administration',
cte.LARGE_OFFICE: 'office and administration',
cte.COURTHOUSE: 'office and administration',
cte.FIRE_STATION: 'office and administration',
cte.PENITENTIARY: 'school with shower',
cte.POLICE_STATION: 'office and administration',
cte.POST_OFFICE: 'office and administration',
cte.LIBRARY: 'office and administration',
cte.EDUCATION: 'education',
cte.PRIMARY_SCHOOL: 'school without shower',
cte.PRIMARY_SCHOOL_WITH_SHOWER: 'school with shower',
cte.SECONDARY_SCHOOL: 'education',
cte.UNIVERSITY: 'education',
cte.LABORATORY_AND_RESEARCH_CENTER: 'laboratory and research centers',
cte.STAND_ALONE_RETAIL: 'retail',
cte.HOSPITAL: 'health care',
cte.OUT_PATIENT_HEALTH_CARE: 'health care',
cte.HEALTH_CARE: 'health care',
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'Home for the aged or orphanage',
cte.COMMERCIAL: 'retail',
cte.STRIP_MALL: 'retail',
cte.SUPERMARKET: 'retail shop / refrigerated food',
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'retail',
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'retail shop / refrigerated food',
cte.RESTAURANT: 'restaurant',
cte.QUICK_SERVICE_RESTAURANT: 'restaurant',
cte.FULL_SERVICE_RESTAURANT: 'restaurant',
cte.HOTEL: 'hotel',
cte.HOTEL_MEDIUM_CLASS: 'hotel (Medium-class)',
cte.SMALL_HOTEL: 'hotel',
cte.LARGE_HOTEL: 'hotel',
cte.DORMITORY: 'dormitory',
cte.EVENT_LOCATION: 'event location',
cte.CONVENTION_CENTER: 'event location',
cte.HALL: 'hall',
cte.GREEN_HOUSE: 'green house',
cte.INDUSTRY: 'industry',
cte.WORKSHOP: 'industry',
cte.WAREHOUSE: 'industry',
cte.WAREHOUSE_REFRIGERATED: 'industry',
cte.SPORTS_LOCATION: 'sport location',
cte.SPORTS_ARENA: 'sport location',
cte.GYMNASIUM: 'sport location',
cte.MOTION_PICTURE_THEATRE: 'event location',
cte.MUSEUM: 'event location',
cte.PERFORMING_ARTS_THEATRE: 'event location',
cte.TRANSPORTATION: 'n/a',
cte.AUTOMOTIVE_FACILITY: 'n/a',
cte.PARKING_GARAGE: 'n/a',
cte.RELIGIOUS: 'event location',
cte.NON_HEATED: 'non-heated'
}
@property
def dictionary(self) -> dict:
return self._dictionary

View File

@ -0,0 +1,78 @@
"""
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 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',
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',
cte.STRIP_MALL: 'Retail',
cte.SUPERMARKET: 'Retail',
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'Retail',
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'Retail',
cte.RESTAURANT: 'Dining - bar/lounge',
cte.QUICK_SERVICE_RESTAURANT: 'Dining - cafeteria',
cte.FULL_SERVICE_RESTAURANT: 'Dining - bar/lounge',
cte.HOTEL: 'Hotel',
cte.HOTEL_MEDIUM_CLASS: 'Motel',
cte.SMALL_HOTEL: 'Motel',
cte.LARGE_HOTEL: 'Hotel',
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 - refrigerated',
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',
cte.AUTOMOTIVE_FACILITY: 'Automotive facility',
cte.PARKING_GARAGE: 'Parking garage',
cte.RELIGIOUS: 'Religious',
cte.NON_HEATED: 'n/a'
}
@property
def dictionary(self) -> dict:
return self._dictionary

View File

@ -0,0 +1,550 @@
"""
Dictionaries module for Montreal function to hub 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 MontrealFunctionToHubFunction:
# Todo: "office" and "hotel/motel" need to be replaced for a constant value.
def __init__(self):
self._dictionary = {
"Administration publique municipale et régionale": "Office",
"Administration publique provinciale": "Office",
"Agence de voyages ou d'expéditions": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Aiguillage et cour de triage de chemins de fer": cte.WAREHOUSE,
"Amphithéâtre et auditorium": cte.EVENT_LOCATION,
"Archives (incluant cinémathèquevidéothèque)": cte.EVENT_LOCATION,
"Aréna et activités connexes (patinage sur glace)": cte.SPORTS_LOCATION,
"Association civiquesociale et fraternelle": cte.OFFICE_AND_ADMINISTRATION,
"Associationunion ou coop d'épargne et de prêt (inclus caisses populaires locales)": cte.OFFICE_AND_ADMINISTRATION,
"Atelier d'artiste": cte.WAREHOUSE,
"Atelier d'artiste ou d'artisan": cte.WAREHOUSE,
"Atelier d'usinage": cte.WAREHOUSE,
"Atelier de mécanicien-dentiste": cte.WAREHOUSE,
"Auberge ou gîte touristique (Hôtel à caractère familiald'au plus 3 étages en hauteur de bâtiment)": cte.SMALL_HOTEL,
"Autoroute": cte.WAREHOUSE,
"Autres activités agricoles": cte.INDUSTRY,
"Autres activités culturelles": cte.EVENT_LOCATION,
"Autres activités d'hébergement": cte.MULTI_FAMILY_HOUSE,
"Autres activités d'impression commerciale": cte.WAREHOUSE,
"Autres activités de la restauration": cte.WAREHOUSE,
"Autres activités de récupération et de triage": cte.WAREHOUSE,
"Autres activités de vente au détail (inclus les kiosques d'autres choses que vêtements et accessoires de vêtements)": cte.STAND_ALONE_RETAIL,
"Autres activités de vente au détail de produits de l'alimentation": cte.STAND_ALONE_RETAIL,
"Autres activités de vente au détail de vêtements comme les accessoires": cte.STAND_ALONE_RETAIL,
"Autres activités de vente au détail reliées aux automobilesaux embarcationsaux avions et à leurs accessoires": cte.STAND_ALONE_RETAIL,
"Autres activités de vente en gros": cte.WAREHOUSE,
"Autres activités minières et extraction de carrières de minerais non métalliques (sauf le pétrole)": cte.INDUSTRY,
"Autres activités nautiques": cte.WAREHOUSE,
"Autres activités religieuses": cte.OFFICE_AND_ADMINISTRATION,
"Autres activités reliées au transport de matériaux par camion": cte.WAREHOUSE,
"Autres activités reliées au transport par autobus": cte.WAREHOUSE,
"Autres activités reliées au transport par chemin de fer": cte.WAREHOUSE,
"Autres activités sportives (inclus centres de tir à l'arc)": cte.SPORTS_LOCATION,
"Autres aménagements d'assemblées publiques": cte.OFFICE_AND_ADMINISTRATION,
"Autres aménagements publics pour différentes activités": cte.OFFICE_AND_ADMINISTRATION,
"Autres aéroports": cte.WAREHOUSE,
"Autres bases et réserves militaires": cte.WAREHOUSE,
"Autres centres de recherche": cte.SECONDARY_SCHOOL,
"Autres centres de services sociaux ou bureaux de travailleurs sociaux": cte.OFFICE_AND_ADMINISTRATION,
"Autres centres et réseaux de télévision et de radiodiffusion (système combiné)": "Office",
"Autres entreposages": cte.WAREHOUSE,
"Autres espaces de plancher inoccupé": cte.WAREHOUSE,
"Autres espaces de terrain et étendues d'eau inexploités": cte.WAREHOUSE,
"Autres expositions d'objets culturels": cte.EVENT_LOCATION,
"Autres immeubles résidentiels": cte.MID_RISE_APARTMENT,
"Autres industries d'appareils d'éclairage": cte.INDUSTRY,
"Autres industries de boissons": cte.INDUSTRY,
"Autres industries de la fabrication d'éléments de charpentes métalliques": cte.INDUSTRY,
"Autres industries de la fonte et de l'affinage de métaux non-ferreux": cte.INDUSTRY,
"Autres industries de la machinerie industrielle et de l'équipement industriel": cte.INDUSTRY,
"Autres industries de pièces et d'accessoires pour véhicules automobiles": cte.INDUSTRY,
"Autres industries de produits alimentaires": cte.INDUSTRY,
"Autres industries de produits alimentaires à base de fruits et de légumes": cte.INDUSTRY,
"Autres industries de produits chimiques": cte.INDUSTRY,
"Autres industries de produits du pétrole et du charbon": cte.INDUSTRY,
"Autres industries de produits en béton": cte.INDUSTRY,
"Autres industries de produits en caoutchouc": cte.INDUSTRY,
"Autres industries de produits en fil métallique": cte.INDUSTRY,
"Autres industries de produits en plastique": cte.INDUSTRY,
"Autres industries de produits manufacturés": cte.INDUSTRY,
"Autres industries de produits métalliques d'ornement et d'architecture": cte.INDUSTRY,
"Autres industries de produits métalliques divers": cte.INDUSTRY,
"Autres industries de produits textiles": cte.INDUSTRY,
"Autres industries de produits électriques.": cte.INDUSTRY,
"Autres industries de vêtements coupés cousus pour femmes et filles": cte.INDUSTRY,
"Autres industries du bois": cte.INDUSTRY,
"Autres industries du laminagedu moulage et de l'extrusion de métaux non-ferreux": cte.INDUSTRY,
"Autres industries du matériel de transport": cte.INDUSTRY,
"Autres industries du matériel scientifique et professionnel": cte.INDUSTRY,
"Autres industries du matériel électrique d'usage industriel": cte.INDUSTRY,
"Autres industries du matériel électronique et de communication": cte.INDUSTRY,
"Autres industries du meuble de bureau": cte.INDUSTRY,
"Autres industries du meuble et d'articles d'ameublement": cte.INDUSTRY,
"Autres industries du meuble résidentiel.": cte.INDUSTRY,
"Autres industries du papier": cte.INDUSTRY,
"Autres industries sidérurgiques": cte.INDUSTRY,
"Autres infrastructures de transport maritime": cte.INDUSTRY,
"Autres installations inhérentes aux ordures": cte.WAREHOUSE,
"Autres installations pour les sports": cte.SPORTS_LOCATION,
"Autres institutions de formation spécialisée (inclus écoles de langues de coutured'arts martiaux de combats et autres)": cte.SECONDARY_SCHOOL,
"Autres lieux d'assemblée pour les loisirs": cte.OFFICE_AND_ADMINISTRATION,
"Autres locaux de groupes": cte.OFFICE_AND_ADMINISTRATION,
"Autres maisons d'institutions religieuses": cte.OFFICE_AND_ADMINISTRATION,
"Autres maisons et locaux fraternels": cte.OFFICE_AND_ADMINISTRATION,
"Autres maisons pour personnes retraitées": cte.OFFICE_AND_ADMINISTRATION,
"Autres parcs": cte.WAREHOUSE,
"Autres routes et voies publiques": "Office",
"Autres résidences d'étudiants": "Office",
"Autres résidences provisoires": "Office",
"Autres services connexes aux valeurs mobilières et aux marchandises": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Autres services d'affaires": "Office",
"Autres services d'aqueduc et d'irrigation": cte.WAREHOUSE,
"Autres services de construction de bâtiments": cte.WAREHOUSE,
"Autres services de génie civil (entrepreneur général)": cte.WAREHOUSE,
"Autres services de l'automobile": cte.WAREHOUSE,
"Autres services de location (sauf entreposage)": cte.WAREHOUSE,
"Autres services de nettoyage": cte.WAREHOUSE,
"Autres services de réparation et d'entretien d'articles personnels et ménagers": cte.STAND_ALONE_RETAIL,
"Autres services de soins thérapeutiques": cte.OUT_PATIENT_HEALTH_CARE,
"Autres services de travaux de construction spécialisés": cte.WAREHOUSE,
"Autres services de travaux de finition de bâtiment (entrepreneur spécialisé)": cte.WAREHOUSE,
"Autres services de télécommunications": cte.STAND_ALONE_RETAIL,
"Autres services divers": cte.WAREHOUSE,
"Autres services du pétrole": cte.WAREHOUSE,
"Autres services gouvernementaux": cte.OFFICE_AND_ADMINISTRATION,
"Autres services immobiliersfinanciers et d'assurance": cte.OFFICE_AND_ADMINISTRATION,
"Autres services médicaux et de santé": cte.OUT_PATIENT_HEALTH_CARE,
"Autres services personnels": cte.OUT_PATIENT_HEALTH_CARE,
"Autres services pour animaux domestiques": cte.OUT_PATIENT_HEALTH_CARE,
"Autres services pour le transport": cte.WAREHOUSE,
"Autres services pour les bâtiments": cte.WAREHOUSE,
"Autres services professionnels": cte.OFFICE_AND_ADMINISTRATION,
"Autres services publics (infrastructure)": cte.WAREHOUSE,
"Autres services reliés à la foresterie": cte.WAREHOUSE,
"Autres terrains de jeux et pistes athlétiques": cte.SPORTS_LOCATION,
"Autres transports par avion (infrastructure)": cte.WAREHOUSE,
"Autres transports par véhicule automobile": cte.WAREHOUSE,
"Autres transportscommunications et services publics (infrastructure)": cte.GREEN_HOUSE,
"Autres types de production végétale": cte.GREEN_HOUSE,
"Autres ventes au détail de marchandises en général": cte.STAND_ALONE_RETAIL,
"Autres établissements avec service complet ou restreint": cte.STAND_ALONE_RETAIL,
"Autres établissements de débits de boissons alcoolisées": cte.STAND_ALONE_RETAIL,
"Aéroport et aérodrome": cte.EVENT_LOCATION,
"Bar à crème glacée": cte.QUICK_SERVICE_RESTAURANT,
"Bar à spectacles": cte.FULL_SERVICE_RESTAURANT,
"Bibliothèque": cte.OFFICE_AND_ADMINISTRATION,
"Bureau de poste": cte.OFFICE_AND_ADMINISTRATION,
"Bâtiment incendié et inutilisable": cte.NON_HEATED,
"C.E.G.E.P. (collège d'enseignement général et professionnel)": cte.SECONDARY_SCHOOL,
"Centre commercial de quartier (15 à 44 magasins)": cte.STRIP_MALL,
"Centre commercial de voisinage (14 magasins et moins)": cte.STAND_ALONE_RETAIL,
"Centre commercial local (45 à 99 magasins)": cte.STRIP_MALL,
"Centre commercial régional (100 à 199 magasins)": cte.STRIP_MALL,
"Centre commercial super régional (200 magasins et plus)": cte.STRIP_MALL,
"Centre communautaire ou de quartier (inclus Centre diocésain)": cte.OFFICE_AND_ADMINISTRATION,
"Centre d'accueil ou établissement curatif (inclus centre de réadaptation pour handicapés physiques et mentaux)": cte.OUT_PATIENT_HEALTH_CARE,
"Centre d'appels téléphoniques": "Office",
"Centre d'entraide et de ressources communautaires (inclus ressources d'hébergement de meubles et d'alimentation)": cte.OUT_PATIENT_HEALTH_CARE,
"Centre d'entreposage de produits pétroliers (pétrole brutgaz pétrole liquéfiémazout domestique et autres produits raffinés)": cte.WAREHOUSE,
"Centre d'entreposage du gaz (avant distrib.aux consommateurs)": cte.WAREHOUSE,
"Centre de distribution ou d'expédition de marchandises diverses": cte.WAREHOUSE,
"Centre de recherche d'activités émergentes (inclus technologies langagières et la photonique)": cte.SECONDARY_SCHOOL,
"Centre de santé (inclus saunas spas et bains thérapeutiques ou turcs)": cte.OUT_PATIENT_HEALTH_CARE,
"Centre de services sociaux (C.S.S. et C.R.S.S.S.)": cte.OUT_PATIENT_HEALTH_CARE,
"Centre de transfert ou d'entreposage de déchets dangereux": cte.WAREHOUSE,
"Centre de tri postal": cte.WAREHOUSE,
"Centre de vérification technique d'automobiles et d'estimation": cte.WAREHOUSE,
"Centre local de services communautaires (C.L.S.C.)": cte.OFFICE_AND_ADMINISTRATION,
"Centre militaire de transport et d'entreposage": cte.WAREHOUSE,
"Centre récréatif en général (activités récréatives diversifiées pour tous groupes d'âge)": cte.EVENT_LOCATION,
"Centre sportif multidisciplinaire (couvert).": cte.SPORTS_LOCATION,
"Chalet ou maison de villégiature": cte.SINGLE_FAMILY_HOUSE,
"Chemin de fer (sauf train touristiqueaiguillage et cour de triage)": cte.WAREHOUSE,
"Cimetière": cte.WAREHOUSE,
"Cinéma": cte.EVENT_LOCATION,
"Clinique médicale (cabinet de médecins généralistes)": cte.OUT_PATIENT_HEALTH_CARE,
"Commission scolaire": cte.OFFICE_AND_ADMINISTRATION,
"Conserveriemarinagesaumurage et séchage de fruits et de légumes": cte.WAREHOUSE,
"Construction d'immeubles pour revente": cte.WAREHOUSE,
"Couvent": cte.EVENT_LOCATION,
"Dépanneur (sans vente d'essence)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Entreposage de tout genre": cte.WAREHOUSE,
"Entreposage du mobilier et d'appareils ménagersincluant les mini-entrepôts": cte.WAREHOUSE,
"Entreposage en vrac à l'extérieur": cte.WAREHOUSE,
"Entreposage frigorifique (sauf les armoires frigorifiques)": cte.WAREHOUSE,
"Entreprise d'excavationde nivellementde défrichage et installation de fosses septiques": cte.WAREHOUSE,
"Entrepôt pour le transport par camion": cte.WAREHOUSE,
"Entretien et équipement de chemins de fer": cte.WAREHOUSE,
"Espace de plancher inoccupé dont l'usage serait commercial autre": cte.NON_HEATED,
"Espace de plancher inoccupé dont l'usage serait industriel": cte.NON_HEATED,
"Espace de plancher inoccupé dont l'usage serait pour des fins culturelles": cte.NON_HEATED,
"Espace de plancher inoccupé dont l'usage serait pour services publics": cte.NON_HEATED,
"Espace de rangement (condo non résidentiel)": cte.NON_HEATED,
"Espace de rangement (condo)": cte.NON_HEATED,
"Espace de terrain non aménagé et non exploité (sauf l'exploitation non commerciale de la forêt)": cte.NON_HEATED,
"Espace pour le séchage des boues provenant de l'usine d'épuration": cte.WAREHOUSE,
"Fabrication de crème glacée et de desserts congelés": cte.INDUSTRY,
"Fondations et organismes de charité": cte.OFFICE_AND_ADMINISTRATION,
"Galerie d'art": cte.EVENT_LOCATION,
"Garage d'autobus et équipement d'entretien": cte.WAREHOUSE,
"Garage de stationnement pour automobiles (infrastructure)": cte.WAREHOUSE,
"Garage de stationnement pour véhicules lourds (Infrastructure)": cte.WAREHOUSE,
"Garage et équipement d'entretien pour le transport par camion (incluant garages municipaux)": cte.WAREHOUSE,
"Gare d'autobus pour passagers": cte.WAREHOUSE,
"Gare de chemins de fer": cte.WAREHOUSE,
"Gymnase et formation athlétique": cte.SPORTS_LOCATION,
"Hangar à avion": cte.WAREHOUSE,
"Hôtel (incluant les hôtels-motels)": "Hotel/Motel",
"Hôtel résidentiel": "Hotel/Motel",
"Immeuble commercial": cte.STAND_ALONE_RETAIL,
"Immeuble non résidentiel en construction": "Office",
"Immeuble résidentiel en construction": cte.RESIDENTIAL,
"Immeuble à bureaux": "Office",
"Immeuble à temps partagé («time share») Propriété ou copropriété ou groupe d'usufruitier ont chacun droit de jouissancepériodique et successif.": "Office",
"Incinérateur": cte.INDUSTRY,
"Industrie d'accessoires vestimentaires et d'autres vêtements": cte.INDUSTRY,
"Industrie d'alcools destinés à la consommation (distillerie)": cte.INDUSTRY,
"Industrie d'appareils d'éclairage (sauf ampoules et tubes)": cte.INDUSTRY,
"Industrie d'appareils orthopédiques et chirurgicaux": cte.INDUSTRY,
"Industrie d'armoires de placards de cuisine et de coiffeuses de salle de bains en bois": cte.INDUSTRY,
"Industrie d'articles de maison en textile et d'articles d'hygiène en textile": cte.INDUSTRY,
"Industrie d'articles de sport et d'athlétisme": cte.INDUSTRY,
"Industrie d'assaisonnements et de vinaigrettes": cte.INDUSTRY,
"Industrie d'autres produits de boulangerie et de pâtisseries": cte.INDUSTRY,
"Industrie d'autres vêtements coupés cousus pour hommes et garçons": cte.INDUSTRY,
"Industrie d'engrais chimique et d'engrais composé": cte.INDUSTRY,
"Industrie d'enseignes au néon (excluant les enseignes en bois) éclairage interne": cte.INDUSTRY,
"Industrie d'équipements de télécommunication": cte.INDUSTRY,
"Industrie de bas et de chaussettes": cte.INDUSTRY,
"Industrie de boissons gazeuses": cte.INDUSTRY,
"Industrie de boîtes en carton ondulé et en carton compact": cte.INDUSTRY,
"Industrie de boîtes pliantes et rigides": cte.INDUSTRY,
"Industrie de carrosseries de véhicules automobiles": cte.INDUSTRY,
"Industrie de chaudièresd'échangeurs de chaleur et de plaques métalliques": cte.INDUSTRY,
"Industrie de contenants en plastique (sauf en mousse)": cte.INDUSTRY,
"Industrie de contreplaqués en bois": cte.INDUSTRY,
"Industrie de fabrication de gaz industriel": cte.INDUSTRY,
"Industrie de fils et de câbles électriques": cte.INDUSTRY,
"Industrie de filés et de tissus tissés (coton)": cte.INDUSTRY,
"Industrie de garnitures et de raccords de plomberie en métal": cte.INDUSTRY,
"Industrie de jouets et de jeux": cte.INDUSTRY,
"Industrie de l'abattage et du conditionnement de la viande (sauf la volaille et le petit gibier)": cte.INDUSTRY,
"Industrie de l'abattage et du conditionnement de la volaille et du petit gibier": cte.INDUSTRY,
"Industrie de l'impression de formulaires commerciaux": cte.INDUSTRY,
"Industrie de l'équipement de manutention": cte.INDUSTRY,
"Industrie de l'étirage de l'extrusion et alliage de l'aluminiumfabriqué à partir d'aluminium acheté": cte.INDUSTRY,
"Industrie de la bijouterie et de l'orfèvrerie (sauf l'affinage secondaire de métaux précieux)": cte.INDUSTRY,
"Industrie de la bière": cte.INDUSTRY,
"Industrie de la chaussure": cte.INDUSTRY,
"Industrie de la confection à forfait de vêtements pour femmes et filles": cte.INDUSTRY,
"Industrie de la construction et de la réparation de navires": cte.INDUSTRY,
"Industrie de la fabrication de supports d'enregistrement de la reproduction du son et des instruments de musique": cte.INDUSTRY,
"Industrie de la glace": cte.INDUSTRY,
"Industrie de la machinerie pour la construction et du matériel d'entretien": cte.INDUSTRY,
"Industrie de la préparation et du conditionnement de poissons et de fruits de mer": cte.INDUSTRY,
"Industrie de la quincaillerie de base": cte.INDUSTRY,
"Industrie de la transformation de la viande et de la fonte des graisses animales": cte.INDUSTRY,
"Industrie de la tôlerie pour ventilation": cte.INDUSTRY,
"Industrie de lampes électriques (ampoules et tubes)": cte.INDUSTRY,
"Industrie de moteurs et de pièces de moteurs de véhicules automobiles": cte.INDUSTRY,
"Industrie de mélange de farine et de pâte": cte.INDUSTRY,
"Industrie de peinturede teinture et de vernis": cte.INDUSTRY,
"Industrie de pellicules et de feuilles non renforcées en plastique": cte.INDUSTRY,
"Industrie de pièces en plastique pour véhicules automobiles": cte.INDUSTRY,
"Industrie de pièces et de composantes électroniques": cte.INDUSTRY,
"Industrie de pneus et de chambres à air": cte.INDUSTRY,
"Industrie de portes et de fenêtres en métal": cte.INDUSTRY,
"Industrie de portes et fenêtres en plastique": cte.INDUSTRY,
"Industrie de produits chimiques inorganiques d'usage industriel": cte.INDUSTRY,
"Industrie de produits d'architecture en plastique": cte.INDUSTRY,
"Industrie de produits de boulangerie commerciale de produits de boulangerie congelés et de pâtisseries": cte.INDUSTRY,
"Industrie de produits de toilette": cte.INDUSTRY,
"Industrie de produits en pierre": cte.INDUSTRY,
"Industrie de produits en plastique stratifié sous pression ou renforcé": cte.INDUSTRY,
"Industrie de produits en verre fabriqué à partir de verre acheté": cte.INDUSTRY,
"Industrie de produits pharmaceutiques et de médicaments": cte.INDUSTRY,
"Industrie de produits pétrochimiques": cte.INDUSTRY,
"Industrie de produits pétroliers raffinés (sauf les huiles de graissage et les graisses lubrifiantes)": cte.INDUSTRY,
"Industrie de pâtes alimentaires sèches": cte.INDUSTRY,
"Industrie de récipients et de boîtes en métal": cte.INDUSTRY,
"Industrie de résines synthétiques et de caoutchouc synthétique": cte.INDUSTRY,
"Industrie de sacs et de poches en matière textile": cte.INDUSTRY,
"Industrie de sacs et de sachets en plastique": cte.INDUSTRY,
"Industrie de savons et de détachants pour le nettoyage": cte.INDUSTRY,
"Industrie de sommiers et de matelas": cte.INDUSTRY,
"Industrie de soupapes en métal": cte.INDUSTRY,
"Industrie de tapis carpettes et moquettes": cte.INDUSTRY,
"Industrie de tous les autres produits divers en bois": cte.INDUSTRY,
"Industrie de tous les autres produits en papier transformé (sauf pour le bureau)": cte.INDUSTRY,
"Industrie de ventilateursde soufflantes et de purificateurs d'air industriels et commerciaux": cte.INDUSTRY,
"Industrie de vêtements de sport pour femmes et filles": cte.INDUSTRY,
"Industrie de vêtements professionnels coupés cousus": cte.INDUSTRY,
"Industrie des pièces et accessoires d'aéronefs (incluant avions et hélicoptères)": cte.INDUSTRY,
"Industrie du béton préparé": cte.INDUSTRY,
"Industrie du cannabis": cte.INDUSTRY,
"Industrie du ciment": cte.INDUSTRY,
"Industrie du clichagede la composition de la reliure et de la lithographie": cte.INDUSTRY,
"Industrie du fromage": cte.INDUSTRY,
"Industrie du lait de consommation": cte.INDUSTRY,
"Industrie du laminagede l'étirage et de l'extrusion du cuivre et de ses alliages": cte.INDUSTRY,
"Industrie du matériel de chauffage et du matériel de réfrigération commerciale": cte.INDUSTRY,
"Industrie du matériel de transport": cte.INDUSTRY,
"Industrie du matériel ferroviaire roulant": cte.INDUSTRY,
"Industrie du matériel électrique de communication et de protection": cte.INDUSTRY,
"Industrie du meuble de maison en bois": cte.INDUSTRY,
"Industrie du meuble et d'articles d'ameublement pour hôtelsrestaurants et institutions": cte.INDUSTRY,
"Industrie du pain": cte.INDUSTRY,
"Industrie du revêtement métallique sur commande": cte.INDUSTRY,
"Industrie du sucre de canne et de betterave à sucre": cte.INDUSTRY,
"Industrie du thé et du café": cte.INDUSTRY,
"Industries des appareils d'aéronefs (incluant avions et hélicoptères)": cte.INDUSTRY,
"Installation d'équipements de réfrigération commerciale": cte.WAREHOUSE,
"Installation portuaire en général": cte.WAREHOUSE,
"Jardin botanique": cte.WAREHOUSE,
"Ligne de l'oléoduc": cte.WAREHOUSE,
"Local pour les associations fraternelles": "Office",
"Logement": cte.RESIDENTIAL,
"Logement vacant dans un bâtiment comportant plusieurs logements ou autres locaux": cte.RESIDENTIAL,
"Loisir et autres activités culturelles": "Office",
"Maison d'agentsde courtiers et de services d'administration des biens-fonds": "Office",
"Maison d'étudiants (collège et université)": "Office",
"Maison de chambres et pension": "Office",
"Maison de chambres pour personnes ayant une déficience intellectuelle": "Office",
"Maison de courtiers et de négociants de marchandises": "Office",
"Maison de réhabilitation": "Office",
"Maison des jeunes": "Office",
"Maison pour personnes en difficulté (séjours périodes limitées)": "Office",
"Maison pour personnes retraitées autonomes": cte.DORMITORY,
"Maison pour personnes retraitées non autonomes (inclus les CHLSD)": cte.DORMITORY,
"Marché public": cte.STRIP_MALL,
"Meunerie et minoterie": "Office",
"Monastère": cte.DORMITORY,
"Monument et site historique": cte.EVENT_LOCATION,
"Motel": "hotel/Motel",
"Musée": cte.EVENT_LOCATION,
"Organisme international et autres organismes extraterritoriaux": "Office",
"Parc d'amusement (extérieur)": cte.NON_HEATED,
"Parc de maisons mobiles (fonds de terre seulement)": cte.NON_HEATED,
"Parc pour la récréation en général": cte.NON_HEATED,
"Parc à caractère récréatif et ornemental": cte.NON_HEATED,
"Passage": cte.NON_HEATED,
"Piscine extérieure et activités connexes": cte.NON_HEATED,
"Piscine intérieure et activités connexes": cte.SPORTS_LOCATION,
"Pose et réparation de parement métalliques et autres (entrepreneur spécialisé)": cte.WAREHOUSE,
"Poste et bureau de douanes": cte.OFFICE_AND_ADMINISTRATION,
"Pouponnière ou garderie de nuit": cte.HOSPITAL,
"Presbytère": cte.OFFICE_AND_ADMINISTRATION,
"Prison provinciale": cte.DORMITORY,
"Protection contre l'incendie et activités connexes": cte.WAREHOUSE,
"Raffinerie de pétrole": cte.INDUSTRY,
"Restaurant et établissement avec service complet (avec terrasse) - Établissements avec permis alcool inclus pub café et brasserie": cte.FULL_SERVICE_RESTAURANT,
"Restaurant et établissement avec service complet (sans terrasse) -Établissements avec permis alcoolinclus pub café et brasserie": cte.FULL_SERVICE_RESTAURANT,
"Restaurant et établissement avec service restreint ( commande au comptoir ou par téléphone)": cte.QUICK_SERVICE_RESTAURANT,
"Restaurant et établissement offrant des repas à libre-service (cafétéria cantine)": cte.QUICK_SERVICE_RESTAURANT,
"Rue et avenue pour l'accès local": cte.NON_HEATED,
"Ruelle": cte.NON_HEATED,
"Récupération et triage de matières polluantes et toxiques": cte.WAREHOUSE,
"Récupération et triage de métaux": cte.WAREHOUSE,
"Réparation et entretien des avions": cte.WAREHOUSE,
"Réserve pour la protection de la faune": cte.NON_HEATED,
"Réservoir d'eau (installation d'emmagasinage de l'eau par retenue et réservoirs)": cte.NON_HEATED,
"Résidence de tourismeappartement maison ou chalet (meublé et équipé pour repas)": "hotel/Motel",
"Salle d'exposition": cte.EVENT_LOCATION,
"Salle et terrain de squash de racquetball et de tennis": cte.SPORTS_LOCATION,
"Salle ou salon de quilles": cte.NON_HEATED,
"Salon de beauté (maquillagemanucureetc..)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Salon de coiffure": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Salon funéraire": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Service bancaire (dépôts et prêtsincluant banque à charte)": cte.OFFICE_AND_ADMINISTRATION,
"Service d'ambulance": cte.WAREHOUSE,
"Service d'architecture": cte.OFFICE_AND_ADMINISTRATION,
"Service d'assainissement de l'environnement": cte.WAREHOUSE,
"Service d'emballage et de protection de marchandises": cte.WAREHOUSE,
"Service d'envoi de marchandises": cte.WAREHOUSE,
"Service d'hébergement des données (sites Web diffusion audio et vidéo en continu services d'application)": cte.WAREHOUSE,
"Service d'hôpital (inclus hôpitaux psychiatriques)": cte.HOSPITAL,
"Service d'optométrie": cte.OUT_PATIENT_HEALTH_CARE,
"Service de buanderie de nettoyage à sec et de teinture (sauf les tapis)": cte.WAREHOUSE,
"Service de comptabilitéde vérification et de tenue de livre": cte.OFFICE_AND_ADMINISTRATION,
"Service de construction de routesde rues et de pontsde trottoirs et de pistes (entrepreneur général)": cte.WAREHOUSE,
"Service de construction non résidentiellecommerciale et institutionnelle (entrepreneur général)": cte.WAREHOUSE,
"Service de construction non résidentielleindustrielle (entrepreneur général)": cte.WAREHOUSE,
"Service de construction résidentielle (entrepreneur)": cte.WAREHOUSE,
"Service de débosselage et de peinture d'automobiles": cte.WAREHOUSE,
"Service de garderie (prématernelle moins de 50 % de poupons)": cte.PRIMARY_SCHOOL,
"Service de génie": cte.OFFICE_AND_ADMINISTRATION,
"Service de holding et d'investissement et de fiducie": cte.OFFICE_AND_ADMINISTRATION,
"Service de laboratoire dentaire": cte.OUT_PATIENT_HEALTH_CARE,
"Service de laboratoire médical": cte.OUT_PATIENT_HEALTH_CARE,
"Service de lavage d'automobiles": cte.WAREHOUSE,
"Service de limousine": cte.WAREHOUSE,
"Service de lingerie et de buanderie industrielle": cte.WAREHOUSE,
"Service de location d'automobiles": cte.WAREHOUSE,
"Service de location d'outils ou d'équipements": cte.WAREHOUSE,
"Service de location d'équipements": cte.WAREHOUSE,
"Service de location de boites postales (sauf le publipostage) et centre de courrier privé": cte.OFFICE_AND_ADMINISTRATION,
"Service de location de camions de remorques utilitaires et de véhicules de plaisance": cte.WAREHOUSE,
"Service de maçonnerie (entrepreneur spécialisé)": cte.INDUSTRY,
"Service de messagers": "Office",
"Service de notaires": "Office",
"Service de paysagement ou de déneigement": cte.WAREHOUSE,
"Service de petite menuiserie et de finition (entrepreneur spécialisé)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Service de plomberie de chauffagede climatisation et de ventilation (entrepreneur spécialisé)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Service de police fédérale et activités connexes": cte.OFFICE_AND_ADMINISTRATION,
"Service de police municipale et activités connexes": cte.OFFICE_AND_ADMINISTRATION,
"Service de pose de portesde fenêtres et de panneaux de verre": cte.WAREHOUSE,
"Service de publicité en général": "Office",
"Service de recherche de développement et d'essais": cte.SECONDARY_SCHOOL,
"Service de remplacement de pièces et d'accessoires d'automobiles (amortisseurs silencieux toits ouvrants glacespare-brises...)": cte.WAREHOUSE,
"Service de revêtement en asphalte et en bitume": cte.WAREHOUSE,
"Service de réparation d'automobiles (garage) sans pompes à essence(5531)": cte.WAREHOUSE,
"Service de réparation d'autres véhicules légers": cte.WAREHOUSE,
"Service de réparation de véhicules légers motorisés (motocyclettemotoneige véhicule tout terrain)": cte.WAREHOUSE,
"Service de réparation et d'entretien de machines et de matériel d'usage commercial et industriel": "Office",
"Service de réparation et d'entretien de matériel informatique": "Office",
"Service de réparation et d'entretien de systèmes de plomberieschauffageventilation et climatisation.(entrepreneur spécialisé)": cte.WAREHOUSE,
"Service de réparation et d'entretien de véhicules lourds": cte.WAREHOUSE,
"Service de réparation et de rembourrage de meubles": cte.WAREHOUSE,
"Service de soudure": cte.WAREHOUSE,
"Service de toilettage pour animaux domestiques": cte.OUT_PATIENT_HEALTH_CARE,
"Service de traitement pour automobiles (antirouilleetc.)": cte.WAREHOUSE,
"Service de travaux d'électricité et installation de câblage (entrepreneur spécialisé)": cte.WAREHOUSE,
"Service de travaux de toiture (entrepreneur spécialisé)": cte.WAREHOUSE,
"Service de télécommunication sans fil (appareil mobile sauf par Internet)": cte.WAREHOUSE,
"Service de vétérinaires (animaux domestiques)": cte.OUT_PATIENT_HEALTH_CARE,
"Service de vétérinaires et d'hôpital pour animaux de ferme": cte.OUT_PATIENT_HEALTH_CARE,
"Service dentaire (inclus chirurgie et hygiène)": cte.OUT_PATIENT_HEALTH_CARE,
"Service en santé mentale (cabinet) (comprend tous services professionnelspsychiatre psychologuepsychanalyste)": cte.OUT_PATIENT_HEALTH_CARE,
"Service en travaux de fondation et de structures en béton (entrepreneur spécialisé)": "Office",
"Service informatique (location ou utilisation partagée services auxiliaires programmation planification et analyse de système)": "Office",
"Service médical (cabinet de médecins et chirurgiens spécialisés)": cte.OUT_PATIENT_HEALTH_CARE,
"Service photographique (incluant les services commerciaux)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Service pour l'entretien ménager": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Service éducationnel et de recherche scientifique": cte.SECONDARY_SCHOOL,
"Services spécialisés reliés à l'activité bancaire": cte.OFFICE_AND_ADMINISTRATION,
"Stade": cte.SPORTS_LOCATION,
"Station de contrôle de la pression de l'eau": cte.WAREHOUSE,
"Station de contrôle de la pression des eaux usées": cte.WAREHOUSE,
"Station de métro": cte.WAREHOUSE,
"Station libre-serviceou avec service et dépanneur sans réparation de véhicules automobiles": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Station libre-serviceou avec service sans réparation de véhicules automobiles": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Station-service avec réparation de véhicules automobiles": cte.WAREHOUSE,
"Stationnement extérieur (condo non résidentiel)": cte.NON_HEATED,
"Stationnement extérieur (condo)": cte.NON_HEATED,
"Stationnement intérieur ( condo non résidentiel)": cte.WAREHOUSE,
"Stationnement intérieur (condo)": cte.WAREHOUSE,
"Studio d'enregistrement du son (disque cassette et disque compact)": "Office",
"Studio de production de filmsde vidéos ou de publicités (ne comprends pas le laboratoire de production)": "Office",
"Studio de télévision (sans public)": "Office",
"Syndicat et organisation similaire": "Office",
"Terminus maritime (passagers) incluant les gares de traversiers": cte.WAREHOUSE,
"Terrain de golf (avec chalet et autres aménagements sportifs)": cte.NON_HEATED,
"Terrain de sport (jeux et pistes pour compétitions et sportgradins)": cte.NON_HEATED,
"Terrain de stationnement pour automobiles": cte.WAREHOUSE,
"Terrains de stationnement pour véhicules lourds": cte.WAREHOUSE,
"Théâtre": cte.EVENT_LOCATION,
"Tour de relais (micro-ondes)": cte.NON_HEATED,
"Tous les autres services d'information": cte.NON_HEATED,
"Transport et gestion d'électricité en bloc": cte.NON_HEATED,
"Transport et gestion du gaz par canalisation": cte.NON_HEATED,
"Université": cte.SECONDARY_SCHOOL,
"Usine de traitement des eaux (filtration)": cte.INDUSTRY,
"Usine de traitement des eaux usées (épuration)": cte.INDUSTRY,
"Vente au détail (fleuriste)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail d'accessoires pour femmes": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail d'animaux de maison (animalerie)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail d'antiquités (sauf le marché aux puces)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail d'appareils orthopédiques et articles spécialisés de santé": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail d'articles de sport": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail d'articles d'accessoires d'aménagement paysager et de jardin": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail d'instruments et de matériel médical": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail d'équipements de ferme": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail d'équipements de plomberie de chauffagede ventilationde climatisation et de foyer": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail d'équipements et d'accessoires de chasse et pêche": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de bicyclettes": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de boissons alcoolisées": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de chaussures": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de fruits et de légumes": cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD,
"Vente au détail de la viande": cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD,
"Vente au détail de livres et de papeterie": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de marchandises en général (sauf les marchés aux puces)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de matériaux de construction": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de matériaux de construction (cour à bois)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de matériel électrique": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de meubles": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de motocyclettes de motoneiges et de leurs accessoires": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de médicaments et d'articles divers (pharmacie)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de peinturede verre et de papier tenture": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de piscinesde spas et leurs accessoires": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de pièces de véhicules automobiles et d'accessoires usagés": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de pneus de batteries et d'accessoires": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de produits d'épicerie (avec boucherie)": cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD,
"Vente au détail de produits d'épicerie (sans boucherie)": cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD,
"Vente au détail de produits de la boulangerie et de la pâtisserie (manufacturés sur place en totalité ou non)": cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD,
"Vente au détail de quincaillerie": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de radiosde téléviseurssystèmes de son et appareils électroniques": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de revêtements de planchers et de murs (bois franc plancher flottant carreaux céramiques tapisserie)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de serruresde clés et d'accessoires": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de véhicules automobiles neufs et usagés": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de véhicules automobiles usagés seulement": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de vêtement prêt-à-porter pour femmes": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de vêtements et d'accessoires pour hommes": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de vêtements et d'articles usagésfriperies (sauf le marché aux puces)": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail de vêtements unisexes": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détail du cafédu théd'épices et d'aromates": cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD,
"Vente au détailclubs de gros et hypermarchés (entrepôt-club)": cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD,
"Vente au détailfournitures pour la maison et l'auto": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente au détailmagasin à rayons": cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD,
"Vente en gros d'ameublements de matériels de bureau et de magasin": cte.STRIP_MALL,
"Vente en gros d'appareils et d'équipements de plomberie et de chauffage": cte.STRIP_MALL,
"Vente en gros d'appareils et d'équipements électriques de fils et de matériel électronique de construction": cte.STRIP_MALL,
"Vente en gros d'appareils électriquesde téléviseurs et de radios": cte.STRIP_MALL,
"Vente en gros d'automobiles et autres véhicules automobiles neufs ou d'occasions incluent VR)": cte.STRIP_MALL,
"Vente en gros d'autres appareils ou matériels électriques et électroniques": cte.STRIP_MALL,
"Vente en gros d'autres médicaments de produits chimiques et de produits connexes": cte.STRIP_MALL,
"Vente en gros d'autres pièces d'équipement ou de machinerie (incluant machinerie lourde)": cte.STRIP_MALL,
"Vente en gros d'autres produits reliés à l'épicerie": cte.STRIP_MALL,
"Vente en gros d'équipements et de pièces de machinerie commercialeindustrielle ou agricole (incluant machinerie lourde)": cte.STRIP_MALL,
"Vente en gros d'équipements et de pièces pour la réfrigération ventilation la climatisation et le chauffage (système combiné)": cte.STRIP_MALL,
"Vente en gros d'équipements et de pièces pour les entreprises de services": cte.STRIP_MALL,
"Vente en gros de bois et de matériaux de construction": cte.STRIP_MALL,
"Vente en gros de chaussures": cte.STRIP_MALL,
"Vente en gros de fruits et de légumes frais": cte.STRIP_MALL,
"Vente en gros de médicaments et de produits médicamenteux": cte.STRIP_MALL,
"Vente en gros de pièces et d'accessoires neufs pour véhicules automobiles": cte.STRIP_MALL,
"Vente en gros de pièces et d'équipements électroniques": cte.STRIP_MALL,
"Vente en gros de pneus et de chambres à air": cte.STRIP_MALL,
"Vente en gros de poissons et de fruits de mer": cte.STRIP_MALL,
"Vente en gros de produits de beauté": cte.STRIP_MALL,
"Vente en gros de produits de boulangerie et de pâtisserie": cte.STRIP_MALL,
"Vente en gros de produits laitiers": cte.STRIP_MALL,
"Vente en gros de quincaillerie": cte.STRIP_MALL,
"Vente en gros de tissus et de textiles": cte.STRIP_MALL,
"Vente en gros de viandes et de produits de la viande": cte.STRIP_MALL,
"Vente en gros de vêtements de lingerie de bas et d'accessoires": cte.STRIP_MALL,
"Vente en gros pour l'épicerie en général": cte.STRIP_MALL,
"École commerciale et de secrétariat (non intégrée aux polyvalentes)": cte.SECONDARY_SCHOOL,
"École de beaux-arts et de musique (exclus arts publicitaires arts graphiques et photographie publicitaire)": cte.SECONDARY_SCHOOL,
"École de danse": cte.SECONDARY_SCHOOL,
"École de métiers (non intégrée aux polyvalentes)": cte.SECONDARY_SCHOOL,
"École maternelle": cte.SECONDARY_SCHOOL,
"École polyvalente": cte.SECONDARY_SCHOOL,
"École secondaire": cte.SECONDARY_SCHOOL,
"École à caractère familial (exploité par une personne physique dans sa résidence moins de 15 élèves)": cte.SECONDARY_SCHOOL,
"École élémentaire": cte.SECONDARY_SCHOOL,
"École élémentaire et secondaire": cte.SECONDARY_SCHOOL,
"Église synagogue mosquée et temple": cte.EVENT_LOCATION,
"Établissement avec salle de réception ou de banquet": cte.FULL_SERVICE_RESTAURANT,
"Établissement avec service de boissons alcoolisées (Bar)": cte.QUICK_SERVICE_RESTAURANT,
"Établissement dont l'activité principale est la danse (discothèque avec service alcool boite de nuit) sans alcool code 7397": cte.QUICK_SERVICE_RESTAURANT
}
@property
def dictionary(self) -> dict:
return self._dictionary

View File

@ -0,0 +1,217 @@
"""
Dictionaries module for Pluto function to hub 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 PlutoFunctionToHubFunction:
def __init__(self):
self._dictionary = {
'A0': cte.SINGLE_FAMILY_HOUSE,
'A1': cte.SINGLE_FAMILY_HOUSE,
'A2': cte.SINGLE_FAMILY_HOUSE,
'A3': cte.SINGLE_FAMILY_HOUSE,
'A4': cte.SINGLE_FAMILY_HOUSE,
'A5': cte.SINGLE_FAMILY_HOUSE,
'A6': cte.SINGLE_FAMILY_HOUSE,
'A7': cte.SINGLE_FAMILY_HOUSE,
'A8': cte.SINGLE_FAMILY_HOUSE,
'A9': cte.SINGLE_FAMILY_HOUSE,
'B1': cte.MULTI_FAMILY_HOUSE,
'B2': cte.MULTI_FAMILY_HOUSE,
'B3': cte.MULTI_FAMILY_HOUSE,
'B9': cte.MULTI_FAMILY_HOUSE,
'C0': cte.RESIDENTIAL,
'C1': cte.RESIDENTIAL,
'C2': cte.RESIDENTIAL,
'C3': cte.RESIDENTIAL,
'C4': cte.RESIDENTIAL,
'C5': cte.RESIDENTIAL,
'C6': cte.RESIDENTIAL,
'C7': cte.RESIDENTIAL,
'C8': cte.RESIDENTIAL,
'C9': cte.RESIDENTIAL,
'D0': cte.RESIDENTIAL,
'D1': cte.RESIDENTIAL,
'D2': cte.RESIDENTIAL,
'D3': cte.RESIDENTIAL,
'D4': cte.RESIDENTIAL,
'D5': cte.RESIDENTIAL,
'D6': cte.RESIDENTIAL,
'D7': cte.RESIDENTIAL,
'D8': cte.RESIDENTIAL,
'D9': cte.RESIDENTIAL,
'E1': cte.WAREHOUSE,
'E3': cte.WAREHOUSE,
'E4': cte.WAREHOUSE,
'E5': cte.WAREHOUSE,
'E7': cte.WAREHOUSE,
'E9': cte.WAREHOUSE,
'F1': cte.WAREHOUSE,
'F2': cte.WAREHOUSE,
'F4': cte.WAREHOUSE,
'F5': cte.WAREHOUSE,
'F8': cte.WAREHOUSE,
'F9': cte.WAREHOUSE,
'G0': cte.SMALL_OFFICE,
'G1': cte.SMALL_OFFICE,
'G2': cte.SMALL_OFFICE,
'G3': cte.SMALL_OFFICE,
'G4': cte.SMALL_OFFICE,
'G5': cte.SMALL_OFFICE,
'G6': cte.SMALL_OFFICE,
'G7': cte.SMALL_OFFICE,
'G8': cte.SMALL_OFFICE,
'G9': cte.SMALL_OFFICE,
'H1': cte.HOTEL,
'H2': cte.HOTEL,
'H3': cte.HOTEL,
'H4': cte.HOTEL,
'H5': cte.HOTEL,
'H6': cte.HOTEL,
'H7': cte.HOTEL,
'H8': cte.HOTEL,
'H9': cte.HOTEL,
'HB': cte.HOTEL,
'HH': cte.HOTEL,
'HR': cte.HOTEL,
'HS': cte.HOTEL,
'I1': cte.HOSPITAL,
'I2': cte.OUT_PATIENT_HEALTH_CARE,
'I3': cte.OUT_PATIENT_HEALTH_CARE,
'I4': cte.RESIDENTIAL,
'I5': cte.OUT_PATIENT_HEALTH_CARE,
'I6': cte.OUT_PATIENT_HEALTH_CARE,
'I7': cte.OUT_PATIENT_HEALTH_CARE,
'I9': cte.OUT_PATIENT_HEALTH_CARE,
'J1': cte.LARGE_OFFICE,
'J2': cte.LARGE_OFFICE,
'J3': cte.LARGE_OFFICE,
'J4': cte.LARGE_OFFICE,
'J5': cte.LARGE_OFFICE,
'J6': cte.LARGE_OFFICE,
'J7': cte.LARGE_OFFICE,
'J8': cte.LARGE_OFFICE,
'J9': cte.LARGE_OFFICE,
'K1': cte.STRIP_MALL,
'K2': cte.STRIP_MALL,
'K3': cte.STRIP_MALL,
'K4': cte.RESIDENTIAL,
'K5': cte.RESTAURANT,
'K6': cte.SUPERMARKET,
'K7': cte.SUPERMARKET,
'K8': cte.SUPERMARKET,
'K9': cte.SUPERMARKET,
'L1': cte.RESIDENTIAL,
'L2': cte.RESIDENTIAL,
'L3': cte.RESIDENTIAL,
'L8': cte.RESIDENTIAL,
'L9': cte.RESIDENTIAL,
'M1': cte.LARGE_OFFICE,
'M2': cte.LARGE_OFFICE,
'M3': cte.LARGE_OFFICE,
'M4': cte.LARGE_OFFICE,
'M9': cte.LARGE_OFFICE,
'N1': cte.RESIDENTIAL,
'N2': cte.RESIDENTIAL,
'N3': cte.RESIDENTIAL,
'N4': cte.RESIDENTIAL,
'N9': cte.RESIDENTIAL,
'O1': cte.SMALL_OFFICE,
'O2': cte.SMALL_OFFICE,
'O3': cte.SMALL_OFFICE,
'O4': cte.SMALL_OFFICE,
'O5': cte.SMALL_OFFICE,
'O6': cte.SMALL_OFFICE,
'O7': cte.SMALL_OFFICE,
'O8': cte.SMALL_OFFICE,
'O9': cte.SMALL_OFFICE,
'P1': cte.LARGE_OFFICE,
'P2': cte.HOTEL,
'P3': cte.SMALL_OFFICE,
'P4': cte.SMALL_OFFICE,
'P5': cte.SMALL_OFFICE,
'P6': cte.SMALL_OFFICE,
'P7': cte.LARGE_OFFICE,
'P8': cte.LARGE_OFFICE,
'P9': cte.SMALL_OFFICE,
'Q0': cte.SMALL_OFFICE,
'Q1': cte.SMALL_OFFICE,
'Q2': cte.SMALL_OFFICE,
'Q3': cte.SMALL_OFFICE,
'Q4': cte.SMALL_OFFICE,
'Q5': cte.SMALL_OFFICE,
'Q6': cte.SMALL_OFFICE,
'Q7': cte.SMALL_OFFICE,
'Q8': cte.SMALL_OFFICE,
'Q9': cte.SMALL_OFFICE,
'R0': cte.RESIDENTIAL,
'R1': cte.RESIDENTIAL,
'R2': cte.RESIDENTIAL,
'R3': cte.RESIDENTIAL,
'R4': cte.RESIDENTIAL,
'R5': cte.RESIDENTIAL,
'R6': cte.RESIDENTIAL,
'R7': cte.RESIDENTIAL,
'R8': cte.RESIDENTIAL,
'R9': cte.RESIDENTIAL,
'RA': cte.RESIDENTIAL,
'RB': cte.RESIDENTIAL,
'RC': cte.RESIDENTIAL,
'RD': cte.RESIDENTIAL,
'RG': cte.RESIDENTIAL,
'RH': cte.RESIDENTIAL,
'RI': cte.RESIDENTIAL,
'RK': cte.RESIDENTIAL,
'RM': cte.RESIDENTIAL,
'RR': cte.RESIDENTIAL,
'RS': cte.RESIDENTIAL,
'RW': cte.RESIDENTIAL,
'RX': cte.RESIDENTIAL,
'RZ': cte.RESIDENTIAL,
'S0': cte.RESIDENTIAL,
'S1': cte.RESIDENTIAL,
'S2': cte.RESIDENTIAL,
'S3': cte.RESIDENTIAL,
'S4': cte.RESIDENTIAL,
'S5': cte.RESIDENTIAL,
'S9': cte.RESIDENTIAL,
'U0': cte.WAREHOUSE,
'U1': cte.WAREHOUSE,
'U2': cte.WAREHOUSE,
'U3': cte.WAREHOUSE,
'U4': cte.WAREHOUSE,
'U5': cte.WAREHOUSE,
'U6': cte.WAREHOUSE,
'U7': cte.WAREHOUSE,
'U8': cte.WAREHOUSE,
'U9': cte.WAREHOUSE,
'W1': cte.PRIMARY_SCHOOL,
'W2': cte.PRIMARY_SCHOOL,
'W3': cte.SECONDARY_SCHOOL,
'W4': cte.EDUCATION,
'W5': cte.SECONDARY_SCHOOL,
'W6': cte.SECONDARY_SCHOOL,
'W7': cte.SECONDARY_SCHOOL,
'W8': cte.PRIMARY_SCHOOL,
'W9': cte.SECONDARY_SCHOOL,
'Y1': cte.LARGE_OFFICE,
'Y2': cte.LARGE_OFFICE,
'Y3': cte.LARGE_OFFICE,
'Y4': cte.LARGE_OFFICE,
'Y5': cte.LARGE_OFFICE,
'Y6': cte.LARGE_OFFICE,
'Y7': cte.LARGE_OFFICE,
'Y8': cte.LARGE_OFFICE,
'Y9': cte.LARGE_OFFICE,
'Z1': cte.LARGE_OFFICE
}
@property
def dictionary(self) -> dict:
return self._dictionary

View File

@ -5,591 +5,88 @@ Copyright © 2022 Concordia CERC group
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
import hub.helpers.constants as cte from hub.helpers.data.hft_function_to_hub_function import HftFunctionToHubFunction
from hub.helpers.data.montreal_function_to_hub_function import MontrealFunctionToHubFunction
from hub.helpers.data.alkis_function_to_hub_function import AlkisFunctionToHubFunction
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_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
class Dictionaries: class Dictionaries:
""" """
Dictionaries class Dictionaries class
""" """
_usage_to_hft_usage = {
cte.RESIDENTIAL: 'residential',
cte.SINGLE_FAMILY_HOUSE: 'single family house',
cte.MULTI_FAMILY_HOUSE: 'multifamily house',
cte.ROW_HOUSE: 'single family house',
cte.MID_RISE_APARTMENT: 'multifamily house',
cte.HIGH_RISE_APARTMENT: 'multifamily house',
cte.OFFICE_AND_ADMINISTRATION: 'office and administration',
cte.SMALL_OFFICE: 'office and administration',
cte.MEDIUM_OFFICE: 'office and administration',
cte.LARGE_OFFICE: 'office and administration',
cte.COURTHOUSE: 'office and administration',
cte.FIRE_STATION: 'office and administration',
cte.PENITENTIARY: 'school with shower',
cte.POLICE_STATION: 'office and administration',
cte.POST_OFFICE: 'office and administration',
cte.LIBRARY: 'office and administration',
cte.EDUCATION: 'education',
cte.PRIMARY_SCHOOL: 'school without shower',
cte.PRIMARY_SCHOOL_WITH_SHOWER: 'school with shower',
cte.SECONDARY_SCHOOL: 'education',
cte.UNIVERSITY: 'education',
cte.LABORATORY_AND_RESEARCH_CENTER: 'laboratory and research centers',
cte.STAND_ALONE_RETAIL: 'retail',
cte.HOSPITAL: 'health care',
cte.OUT_PATIENT_HEALTH_CARE: 'health care',
cte.HEALTH_CARE: 'health care',
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'Home for the aged or orphanage',
cte.COMMERCIAL: 'retail',
cte.STRIP_MALL: 'retail',
cte.SUPERMARKET: 'retail shop / refrigerated food',
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'retail',
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'retail shop / refrigerated food',
cte.RESTAURANT: 'restaurant',
cte.QUICK_SERVICE_RESTAURANT: 'restaurant',
cte.FULL_SERVICE_RESTAURANT: 'restaurant',
cte.HOTEL: 'hotel',
cte.HOTEL_MEDIUM_CLASS: 'hotel (Medium-class)',
cte.SMALL_HOTEL: 'hotel',
cte.LARGE_HOTEL: 'hotel',
cte.DORMITORY: 'dormitory',
cte.EVENT_LOCATION: 'event location',
cte.CONVENTION_CENTER: 'event location',
cte.HALL: 'hall',
cte.GREEN_HOUSE: 'green house',
cte.INDUSTRY: 'industry',
cte.WORKSHOP: 'industry',
cte.WAREHOUSE: 'industry',
cte.WAREHOUSE_REFRIGERATED: 'industry',
cte.SPORTS_LOCATION: 'sport location',
cte.SPORTS_ARENA: 'sport location',
cte.GYMNASIUM: 'sport location',
cte.MOTION_PICTURE_THEATRE: 'event location',
cte.MUSEUM: 'event location',
cte.PERFORMING_ARTS_THEATRE: 'event location',
cte.TRANSPORTATION: 'n/a',
cte.AUTOMOTIVE_FACILITY: 'n/a',
cte.PARKING_GARAGE: 'n/a',
cte.RELIGIOUS: 'event location',
cte.NON_HEATED: 'non-heated'
}
_usage_to_comnet_usage = {
cte.RESIDENTIAL: 'BA Multifamily',
cte.SINGLE_FAMILY_HOUSE: 'BA Multifamily',
cte.MULTI_FAMILY_HOUSE: 'BA Multifamily',
cte.ROW_HOUSE: 'BA Multifamily',
cte.MID_RISE_APARTMENT: 'BA Multifamily',
cte.HIGH_RISE_APARTMENT: 'BA Multifamily',
cte.OFFICE_AND_ADMINISTRATION: 'BA Office',
cte.SMALL_OFFICE: 'BA Office',
cte.MEDIUM_OFFICE: 'BA Office',
cte.LARGE_OFFICE: 'BA Office',
cte.COURTHOUSE: 'BA Courthouse',
cte.FIRE_STATION: 'BA Fire Station',
cte.PENITENTIARY: 'BA Penitentiary',
cte.POLICE_STATION: 'BA Police Station',
cte.POST_OFFICE: 'BA Post Office',
cte.LIBRARY: 'BA Library',
cte.EDUCATION: 'BA School/University',
cte.PRIMARY_SCHOOL: 'BA School/University',
cte.PRIMARY_SCHOOL_WITH_SHOWER: 'BA School/University',
cte.SECONDARY_SCHOOL: 'BA School/University',
cte.UNIVERSITY: 'BA School/University',
cte.LABORATORY_AND_RESEARCH_CENTER: 'BA School/University',
cte.STAND_ALONE_RETAIL: 'BA Retail',
cte.HOSPITAL: 'BA Hospital',
cte.OUT_PATIENT_HEALTH_CARE: 'BA Healthcare Clinic',
cte.HEALTH_CARE: 'BA Healthcare Clinic',
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'BA Healthcare Clinic',
cte.COMMERCIAL: 'BA Retail',
cte.STRIP_MALL: 'BA Retail',
cte.SUPERMARKET: 'BA Retail',
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'BA Retail',
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'BA Retail',
cte.RESTAURANT: 'BA Dining: Bar Lounge/Leisure',
cte.QUICK_SERVICE_RESTAURANT: 'BA Dining: Cafeteria/Fast Food',
cte.FULL_SERVICE_RESTAURANT: 'BA Dining: Bar Lounge/Leisure',
cte.HOTEL: 'BA Hotel',
cte.HOTEL_MEDIUM_CLASS: 'BA Motel',
cte.SMALL_HOTEL: 'BA Motel',
cte.LARGE_HOTEL: 'BA Hotel',
cte.DORMITORY: 'BA Dormitory',
cte.EVENT_LOCATION: 'BA Convention Center',
cte.CONVENTION_CENTER: 'BA Convention Center',
cte.HALL: 'BA Town Hall',
cte.GREEN_HOUSE: 'n/a',
cte.INDUSTRY: 'BA Manufacturing Facility',
cte.WORKSHOP: 'BA Workshop',
cte.WAREHOUSE: 'BA Warehouse',
cte.WAREHOUSE_REFRIGERATED: 'BA Warehouse',
cte.SPORTS_LOCATION: 'BA Exercise Center',
cte.SPORTS_ARENA: 'BA Sports Arena',
cte.GYMNASIUM: 'BA Gymnasium',
cte.MOTION_PICTURE_THEATRE: 'BA Motion Picture Theater',
cte.MUSEUM: 'BA Museum',
cte.PERFORMING_ARTS_THEATRE: 'BA Performing Arts Theater',
cte.TRANSPORTATION: 'BA Transportation',
cte.AUTOMOTIVE_FACILITY: 'BA Automotive Facility',
cte.PARKING_GARAGE: 'BA Parking Garage',
cte.RELIGIOUS: 'BA Religious Building',
cte.NON_HEATED: 'n/a'
}
_usage_to_nrcan_usage = {
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',
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',
cte.STRIP_MALL: 'Retail',
cte.SUPERMARKET: 'Retail',
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'Retail',
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'Retail',
cte.RESTAURANT: 'Dining - bar/lounge',
cte.QUICK_SERVICE_RESTAURANT: 'Dining - cafeteria',
cte.FULL_SERVICE_RESTAURANT: 'Dining - bar/lounge',
cte.HOTEL: 'Hotel',
cte.HOTEL_MEDIUM_CLASS: 'Motel',
cte.SMALL_HOTEL: 'Motel',
cte.LARGE_HOTEL: 'Hotel',
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 - refrigerated',
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',
cte.AUTOMOTIVE_FACILITY: 'Automotive facility',
cte.PARKING_GARAGE: 'Parking garage',
cte.RELIGIOUS: 'Religious',
cte.NON_HEATED: 'n/a'
}
_function_to_nrcan_construction_function = {
cte.RESIDENTIAL: 'MidriseApartment',
cte.SINGLE_FAMILY_HOUSE: 'MidriseApartment',
cte.MULTI_FAMILY_HOUSE: 'HighriseApartment',
cte.ROW_HOUSE: 'MidriseApartment',
cte.MID_RISE_APARTMENT: 'MidriseApartment',
cte.HIGH_RISE_APARTMENT: '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'
}
_function_to_nrel_construction_function = {
cte.RESIDENTIAL: 'residential',
cte.SINGLE_FAMILY_HOUSE: 'residential',
cte.MULTI_FAMILY_HOUSE: 'midrise apartment',
cte.ROW_HOUSE: 'midrise apartment',
cte.MID_RISE_APARTMENT: 'midrise apartment',
cte.HIGH_RISE_APARTMENT: 'high-rise apartment',
cte.OFFICE_AND_ADMINISTRATION: 'medium office',
cte.SMALL_OFFICE: 'small office',
cte.MEDIUM_OFFICE: 'medium office',
cte.LARGE_OFFICE: 'large office',
cte.COURTHOUSE: 'medium office',
cte.FIRE_STATION: 'n/a',
cte.PENITENTIARY: 'large hotel',
cte.POLICE_STATION: 'n/a',
cte.POST_OFFICE: 'medium office',
cte.LIBRARY: 'medium office',
cte.EDUCATION: 'secondary school',
cte.PRIMARY_SCHOOL: 'primary school',
cte.PRIMARY_SCHOOL_WITH_SHOWER: 'primary school',
cte.SECONDARY_SCHOOL: 'secondary school',
cte.UNIVERSITY: 'secondary school',
cte.LABORATORY_AND_RESEARCH_CENTER: 'secondary school',
cte.STAND_ALONE_RETAIL: 'stand-alone retail',
cte.HOSPITAL: 'hospital',
cte.OUT_PATIENT_HEALTH_CARE: 'outpatient healthcare',
cte.HEALTH_CARE: 'outpatient healthcare',
cte.RETIREMENT_HOME_OR_ORPHANAGE: 'small hotel',
cte.COMMERCIAL: 'strip mall',
cte.STRIP_MALL: 'strip mall',
cte.SUPERMARKET: 'supermarket',
cte.RETAIL_SHOP_WITHOUT_REFRIGERATED_FOOD: 'stand-alone retail',
cte.RETAIL_SHOP_WITH_REFRIGERATED_FOOD: 'stand-alone retail',
cte.RESTAURANT: 'full service restaurant',
cte.QUICK_SERVICE_RESTAURANT: 'quick service restaurant',
cte.FULL_SERVICE_RESTAURANT: 'full service restaurant',
cte.HOTEL: 'small hotel',
cte.HOTEL_MEDIUM_CLASS: 'small hotel',
cte.SMALL_HOTEL: 'small hotel',
cte.LARGE_HOTEL: 'large hotel',
cte.DORMITORY: 'small hotel',
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'
}
_pluto_function_to_hub_function = {
'A0': cte.SINGLE_FAMILY_HOUSE,
'A1': cte.SINGLE_FAMILY_HOUSE,
'A2': cte.SINGLE_FAMILY_HOUSE,
'A3': cte.SINGLE_FAMILY_HOUSE,
'A4': cte.SINGLE_FAMILY_HOUSE,
'A5': cte.SINGLE_FAMILY_HOUSE,
'A6': cte.SINGLE_FAMILY_HOUSE,
'A7': cte.SINGLE_FAMILY_HOUSE,
'A8': cte.SINGLE_FAMILY_HOUSE,
'A9': cte.SINGLE_FAMILY_HOUSE,
'B1': cte.MULTI_FAMILY_HOUSE,
'B2': cte.MULTI_FAMILY_HOUSE,
'B3': cte.MULTI_FAMILY_HOUSE,
'B9': cte.MULTI_FAMILY_HOUSE,
'C0': cte.RESIDENTIAL,
'C1': cte.RESIDENTIAL,
'C2': cte.RESIDENTIAL,
'C3': cte.RESIDENTIAL,
'C4': cte.RESIDENTIAL,
'C5': cte.RESIDENTIAL,
'C6': cte.RESIDENTIAL,
'C7': cte.RESIDENTIAL,
'C8': cte.RESIDENTIAL,
'C9': cte.RESIDENTIAL,
'D0': cte.RESIDENTIAL,
'D1': cte.RESIDENTIAL,
'D2': cte.RESIDENTIAL,
'D3': cte.RESIDENTIAL,
'D4': cte.RESIDENTIAL,
'D5': cte.RESIDENTIAL,
'D6': cte.RESIDENTIAL,
'D7': cte.RESIDENTIAL,
'D8': cte.RESIDENTIAL,
'D9': cte.RESIDENTIAL,
'E1': cte.WAREHOUSE,
'E3': cte.WAREHOUSE,
'E4': cte.WAREHOUSE,
'E5': cte.WAREHOUSE,
'E7': cte.WAREHOUSE,
'E9': cte.WAREHOUSE,
'F1': cte.WAREHOUSE,
'F2': cte.WAREHOUSE,
'F4': cte.WAREHOUSE,
'F5': cte.WAREHOUSE,
'F8': cte.WAREHOUSE,
'F9': cte.WAREHOUSE,
'G0': cte.SMALL_OFFICE,
'G1': cte.SMALL_OFFICE,
'G2': cte.SMALL_OFFICE,
'G3': cte.SMALL_OFFICE,
'G4': cte.SMALL_OFFICE,
'G5': cte.SMALL_OFFICE,
'G6': cte.SMALL_OFFICE,
'G7': cte.SMALL_OFFICE,
'G8': cte.SMALL_OFFICE,
'G9': cte.SMALL_OFFICE,
'H1': cte.HOTEL,
'H2': cte.HOTEL,
'H3': cte.HOTEL,
'H4': cte.HOTEL,
'H5': cte.HOTEL,
'H6': cte.HOTEL,
'H7': cte.HOTEL,
'H8': cte.HOTEL,
'H9': cte.HOTEL,
'HB': cte.HOTEL,
'HH': cte.HOTEL,
'HR': cte.HOTEL,
'HS': cte.HOTEL,
'I1': cte.HOSPITAL,
'I2': cte.OUT_PATIENT_HEALTH_CARE,
'I3': cte.OUT_PATIENT_HEALTH_CARE,
'I4': cte.RESIDENTIAL,
'I5': cte.OUT_PATIENT_HEALTH_CARE,
'I6': cte.OUT_PATIENT_HEALTH_CARE,
'I7': cte.OUT_PATIENT_HEALTH_CARE,
'I9': cte.OUT_PATIENT_HEALTH_CARE,
'J1': cte.LARGE_OFFICE,
'J2': cte.LARGE_OFFICE,
'J3': cte.LARGE_OFFICE,
'J4': cte.LARGE_OFFICE,
'J5': cte.LARGE_OFFICE,
'J6': cte.LARGE_OFFICE,
'J7': cte.LARGE_OFFICE,
'J8': cte.LARGE_OFFICE,
'J9': cte.LARGE_OFFICE,
'K1': cte.STRIP_MALL,
'K2': cte.STRIP_MALL,
'K3': cte.STRIP_MALL,
'K4': cte.RESIDENTIAL,
'K5': cte.RESTAURANT,
'K6': cte.SUPERMARKET,
'K7': cte.SUPERMARKET,
'K8': cte.SUPERMARKET,
'K9': cte.SUPERMARKET,
'L1': cte.RESIDENTIAL,
'L2': cte.RESIDENTIAL,
'L3': cte.RESIDENTIAL,
'L8': cte.RESIDENTIAL,
'L9': cte.RESIDENTIAL,
'M1': cte.LARGE_OFFICE,
'M2': cte.LARGE_OFFICE,
'M3': cte.LARGE_OFFICE,
'M4': cte.LARGE_OFFICE,
'M9': cte.LARGE_OFFICE,
'N1': cte.RESIDENTIAL,
'N2': cte.RESIDENTIAL,
'N3': cte.RESIDENTIAL,
'N4': cte.RESIDENTIAL,
'N9': cte.RESIDENTIAL,
'O1': cte.SMALL_OFFICE,
'O2': cte.SMALL_OFFICE,
'O3': cte.SMALL_OFFICE,
'O4': cte.SMALL_OFFICE,
'O5': cte.SMALL_OFFICE,
'O6': cte.SMALL_OFFICE,
'O7': cte.SMALL_OFFICE,
'O8': cte.SMALL_OFFICE,
'O9': cte.SMALL_OFFICE,
'P1': cte.LARGE_OFFICE,
'P2': cte.HOTEL,
'P3': cte.SMALL_OFFICE,
'P4': cte.SMALL_OFFICE,
'P5': cte.SMALL_OFFICE,
'P6': cte.SMALL_OFFICE,
'P7': cte.LARGE_OFFICE,
'P8': cte.LARGE_OFFICE,
'P9': cte.SMALL_OFFICE,
'Q0': cte.SMALL_OFFICE,
'Q1': cte.SMALL_OFFICE,
'Q2': cte.SMALL_OFFICE,
'Q3': cte.SMALL_OFFICE,
'Q4': cte.SMALL_OFFICE,
'Q5': cte.SMALL_OFFICE,
'Q6': cte.SMALL_OFFICE,
'Q7': cte.SMALL_OFFICE,
'Q8': cte.SMALL_OFFICE,
'Q9': cte.SMALL_OFFICE,
'R0': cte.RESIDENTIAL,
'R1': cte.RESIDENTIAL,
'R2': cte.RESIDENTIAL,
'R3': cte.RESIDENTIAL,
'R4': cte.RESIDENTIAL,
'R5': cte.RESIDENTIAL,
'R6': cte.RESIDENTIAL,
'R7': cte.RESIDENTIAL,
'R8': cte.RESIDENTIAL,
'R9': cte.RESIDENTIAL,
'RA': cte.RESIDENTIAL,
'RB': cte.RESIDENTIAL,
'RC': cte.RESIDENTIAL,
'RD': cte.RESIDENTIAL,
'RG': cte.RESIDENTIAL,
'RH': cte.RESIDENTIAL,
'RI': cte.RESIDENTIAL,
'RK': cte.RESIDENTIAL,
'RM': cte.RESIDENTIAL,
'RR': cte.RESIDENTIAL,
'RS': cte.RESIDENTIAL,
'RW': cte.RESIDENTIAL,
'RX': cte.RESIDENTIAL,
'RZ': cte.RESIDENTIAL,
'S0': cte.RESIDENTIAL,
'S1': cte.RESIDENTIAL,
'S2': cte.RESIDENTIAL,
'S3': cte.RESIDENTIAL,
'S4': cte.RESIDENTIAL,
'S5': cte.RESIDENTIAL,
'S9': cte.RESIDENTIAL,
'U0': cte.WAREHOUSE,
'U1': cte.WAREHOUSE,
'U2': cte.WAREHOUSE,
'U3': cte.WAREHOUSE,
'U4': cte.WAREHOUSE,
'U5': cte.WAREHOUSE,
'U6': cte.WAREHOUSE,
'U7': cte.WAREHOUSE,
'U8': cte.WAREHOUSE,
'U9': cte.WAREHOUSE,
'W1': cte.PRIMARY_SCHOOL,
'W2': cte.PRIMARY_SCHOOL,
'W3': cte.SECONDARY_SCHOOL,
'W4': cte.EDUCATION,
'W5': cte.SECONDARY_SCHOOL,
'W6': cte.SECONDARY_SCHOOL,
'W7': cte.SECONDARY_SCHOOL,
'W8': cte.PRIMARY_SCHOOL,
'W9': cte.SECONDARY_SCHOOL,
'Y1': cte.LARGE_OFFICE,
'Y2': cte.LARGE_OFFICE,
'Y3': cte.LARGE_OFFICE,
'Y4': cte.LARGE_OFFICE,
'Y5': cte.LARGE_OFFICE,
'Y6': cte.LARGE_OFFICE,
'Y7': cte.LARGE_OFFICE,
'Y8': cte.LARGE_OFFICE,
'Y9': cte.LARGE_OFFICE,
'Z1': cte.LARGE_OFFICE
}
_hft_function_to_hub_function = {
'residential': cte.RESIDENTIAL,
'single family house': cte.SINGLE_FAMILY_HOUSE,
'multifamily house': cte.MULTI_FAMILY_HOUSE,
'hotel': cte.HOTEL,
'hospital': cte.HOSPITAL,
'outpatient': cte.OUT_PATIENT_HEALTH_CARE,
'commercial': cte.SUPERMARKET,
'strip mall': cte.STRIP_MALL,
'warehouse': cte.WAREHOUSE,
'primary school': cte.PRIMARY_SCHOOL,
'secondary school': cte.EDUCATION,
'office': cte.MEDIUM_OFFICE,
'large office': cte.LARGE_OFFICE
}
@property @property
def hub_usage_to_hft_usage(self): def hub_usage_to_hft_usage(self) -> dict:
""" """
Get HfT usage from the given internal usage Hub usage to HfT usage, transformation dictionary
:return: dict :return: dict
""" """
return self._usage_to_hft_usage return HubUsageToHftUsage().dictionary
@property @property
def hub_usage_to_comnet_usage(self): def hub_usage_to_comnet_usage(self) -> dict:
""" """
Get Comnet usage from the given internal usage Hub usage to Comnet usage, transformation dictionary
:return: dict :return: dict
""" """
return self._usage_to_comnet_usage return HubUsageToComnetUsage().dictionary
@property @property
def hub_usage_to_nrcan_usage(self): def hub_usage_to_nrcan_usage(self) -> dict:
""" """
Get Nrcan usage from the given internal usage Get hub usage to NRCAN usage, transformation dictionary
:return: dict :return: dict
""" """
return self._usage_to_nrcan_usage return HubUsageToNrcanUsage().dictionary
@property @property
def hub_function_to_nrcan_construction_function(self): def hub_function_to_nrcan_construction_function(self) -> dict:
""" """
Get Nrcan construction function from the given internal function Get hub function to NRCAN construction function, transformation dictionary
:return: dict :return: dict
""" """
return self._function_to_nrcan_construction_function return HubFunctionToNrcanConstructionFunction().dictionary
@property @property
def hub_function_to_nrel_construction_function(self): def hub_function_to_nrel_construction_function(self) -> dict:
""" """
Get Nrel construction function from the given internal function Get hub function to NREL construction function, transformation dictionary
:return: dict :return: dict
""" """
return self._function_to_nrel_construction_function return HubFunctionToNrelConstructionFunction().dictionary
@property @property
def pluto_function_to_hub_function(self): def pluto_function_to_hub_function(self) -> dict:
""" """
Set internal function from pluto standard Get Pluto function to hub function, transformation dictionary
:return: dict :return: dict
""" """
return self._pluto_function_to_hub_function return PlutoFunctionToHubFunction().dictionary
@property @property
def hft_function_to_hub_function(self): def hft_function_to_hub_function(self) -> dict:
""" """
Set internal function from functions used in hft files Get Hft function to hub function, transformation dictionary
:return: dict :return: dict
""" """
return self._hft_function_to_hub_function return HftFunctionToHubFunction().dictionary
@property
def montreal_function_to_hub_function(self) -> dict:
"""
Get Montreal function to hub function, transformation dictionary
"""
return MontrealFunctionToHubFunction().dictionary
@property
def alkis_function_to_hub_function(self) -> dict:
"""
Get Alkis function to hub function, transformation dictionary
"""
return AlkisFunctionToHubFunction().dictionary

View File

@ -4,10 +4,9 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group Copyright © 2022 Concordia CERC group
Project CoderPeter Yefi peteryefi@gmail.com Project CoderPeter Yefi peteryefi@gmail.com
""" """
from hub.persistence import CityRepo
from hub.persistence import HeatPumpSimulationRepo
from typing import Dict
from hub.city_model_structure.city import City from hub.city_model_structure.city import City
from hub.persistence import City as CityRepository
from hub.persistence import SimulationResults
class DBFactory: class DBFactory:
@ -16,14 +15,17 @@ class DBFactory:
""" """
def __init__(self, db_name, dotenv_path, app_env): def __init__(self, db_name, dotenv_path, app_env):
self._city_repo = CityRepo(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env) self._city_repository = CityRepository(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env)
self._hp_simulation_repo = HeatPumpSimulationRepo(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env) self._simulation_results = SimulationResults(db_name=db_name, dotenv_path=dotenv_path, app_env=app_env)
def persist_city(self, user_id: int, city: City): def persist_city(self, city: City, application_id: int, user_id: int):
""" """
Persist city into postgres database Persist city into postgres database
:param city: City to be stored
:param application_id: Application id owning this city
:param user_id: User who create the city
""" """
return self._city_repo.insert(city, user_id) return self._city_repository.insert(city, application_id, user_id)
def update_city(self, city_id, city): def update_city(self, city_id, city):
""" """
@ -31,27 +33,21 @@ class DBFactory:
:param city_id: the id of the city to update :param city_id: the id of the city to update
:param city: the updated city object :param city: the updated city object
""" """
return self._city_repo.update(city_id, city) return self._city_repository.update(city_id, city)
def delete_city(self, city_id): def delete_city(self, city_id):
""" """
Deletes a single city from postgres Deletes a single city from postgres
:param city_id: the id of the city to get :param city_id: the id of the city to get
""" """
self._city_repo.delete_city(city_id) self._city_repository.delete(city_id)
def persist_hp_simulation(self, hp_simulation_data: Dict, city_id: int): def add_simulation_results(self, name, values, city_id=None, city_object_id=None):
""" """
Persist heat pump simulation results Add simulation results to the city or to the city_object
:param hp_simulation_data: the simulation results :param name: simulation and simulation engine name
:param city_id: the city object used in running the simulation :param values: simulation values in json format
:return: HeatPumpSimulation object :param city_id: city id or None
:param city_object_id: city object id or None
""" """
return self._hp_simulation_repo.insert(hp_simulation_data, city_id) self._simulation_results.insert(name, values,city_id, city_object_id)
def delete_hp_simulation(self, hp_sim_id):
"""
Deletes a single heat pump simulation from postgres
:param hp_sim_id: the id of the heat pump simulation to get
"""
self._hp_simulation_repo.delete_hp_simulation(hp_sim_id)

View File

@ -19,12 +19,18 @@ class CityGml:
""" """
CityGml class CityGml class
""" """
def __init__(self, path, extrusion_height_field=None, year_of_construction_field=None, function_field=None): def __init__(self,
path,
extrusion_height_field=None,
year_of_construction_field='yearOfConstruction',
function_field='function',
function_to_hub=None):
self._city = None self._city = None
self._lod = None self._lod = None
self._lod1_tags = ['lod1Solid', 'lod1MultiSurface'] self._lod1_tags = ['lod1Solid', 'lod1MultiSurface']
self._lod2_tags = ['lod2Solid', 'lod2MultiSurface', 'lod2MultiCurve'] self._lod2_tags = ['lod2Solid', 'lod2MultiSurface', 'lod2MultiCurve']
self._extrusion_height_field = extrusion_height_field self._extrusion_height_field = extrusion_height_field
self._function_to_hub = function_to_hub
self._year_of_construction_field = year_of_construction_field self._year_of_construction_field = year_of_construction_field
if function_field is None: if function_field is None:
function_field = 'function' function_field = 'function'
@ -110,12 +116,15 @@ class CityGml:
name = city_object['@id'] name = city_object['@id']
function = None function = None
year_of_construction = None year_of_construction = None
if 'yearOfConstruction' in city_object: if self._year_of_construction_field in city_object:
year_of_construction = city_object['yearOfConstruction'] year_of_construction = city_object[self._year_of_construction_field]
if 'function' in city_object: if self._function_field in city_object:
function = city_object[self._function_field] function = city_object[self._function_field]
if type(function) != str: if type(function) != str:
function = function['#text'] function = function['#text']
if self._function_to_hub is not None:
# use the transformation dictionary to retrieve the proper function
function = self._function_to_hub[function]
if any(key in city_object for key in self._lod1_tags): if any(key in city_object for key in self._lod1_tags):
if self._lod is None or self._lod > 1: if self._lod is None or self._lod > 1:

View File

@ -26,7 +26,12 @@ class Geojson:
X = 0 X = 0
Y = 1 Y = 1
def __init__(self, path, extrusion_height_field=None, year_of_construction_field=None, function_field=None): def __init__(self,
path,
extrusion_height_field=None,
year_of_construction_field=None,
function_field=None,
function_to_hub=None):
# todo: destination epsg should change according actual the location # todo: destination epsg should change according actual the location
self._transformer = Transformer.from_crs('epsg:4326', 'epsg:26911') self._transformer = Transformer.from_crs('epsg:4326', 'epsg:26911')
self._min_x = cte.MAX_FLOAT self._min_x = cte.MAX_FLOAT
@ -38,6 +43,7 @@ class Geojson:
self._extrusion_height_field = extrusion_height_field self._extrusion_height_field = extrusion_height_field
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
with open(path) as json_file: with open(path) as json_file:
self._geojson = json.loads(json_file.read()) self._geojson = json.loads(json_file.read())
@ -118,6 +124,9 @@ class Geojson:
function = None function = None
if self._function_field is not None: if self._function_field is not None:
function = feature['properties'][self._function_field] function = feature['properties'][self._function_field]
if self._function_to_hub is not None:
# use the transformation dictionary to retrieve the proper function
function = self._function_to_hub[function]
geometry = feature['geometry'] geometry = feature['geometry']
if 'id' in feature: if 'id' in feature:
building_name = feature['id'] building_name = feature['id']

View File

@ -26,7 +26,8 @@ class GeometryFactory:
data_frame=None, data_frame=None,
height_field=None, height_field=None,
year_of_construction_field=None, year_of_construction_field=None,
function_field=None): function_field=None,
function_to_hub=None):
self._file_type = '_' + file_type.lower() self._file_type = '_' + file_type.lower()
class_funcs = validate_import_export_type(GeometryFactory) class_funcs = validate_import_export_type(GeometryFactory)
if self._file_type not in class_funcs: if self._file_type not in class_funcs:
@ -38,6 +39,7 @@ class GeometryFactory:
self._height_field = height_field self._height_field = height_field
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
@property @property
def _citygml(self) -> City: def _citygml(self) -> City:
@ -45,7 +47,11 @@ class GeometryFactory:
Enrich the city by using CityGML information as data source Enrich the city by using CityGML information as data source
:return: City :return: City
""" """
return CityGml(self._path, self._height_field, self._year_of_construction_field, self._function_field).city return CityGml(self._path,
self._height_field,
self._year_of_construction_field,
self._function_field,
self._function_to_hub).city
@property @property
def _obj(self) -> City: def _obj(self) -> City:
@ -71,7 +77,11 @@ class GeometryFactory:
Enrich the city by using Geojson information as data source Enrich the city by using Geojson information as data source
:return: City :return: City
""" """
return Geojson(self._path, self._height_field, self._year_of_construction_field, self._function_field).city return Geojson(self._path,
self._height_field,
self._year_of_construction_field,
self._function_field,
self._function_to_hub).city
@property @property
def _osm_subway(self) -> City: def _osm_subway(self) -> City:

View File

@ -0,0 +1,53 @@
"""
Insel monthly energy balance
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guillermo.GutierrezMorote@concordia.ca
"""
from pathlib import Path
import pandas as pd
import csv
import hub.helpers.constants as cte
class InselMonthlyEnergyBalance:
"""
Import SRA results
"""
def __init__(self, city, base_path):
self._city = city
self._base_path = base_path
@staticmethod
def _demand(insel_output_file_path):
heating = []
cooling = []
with open(Path(insel_output_file_path).resolve()) as csv_file:
csv_reader = csv.reader(csv_file)
for line in csv_reader:
demand = str(line).replace("['", '').replace("']", '').split()
for i in range(0, 2):
if demand[i] != 'NaN':
aux = float(demand[i]) * 1000 # kWh to Wh
demand[i] = str(aux)
else:
demand[i] = '0'
heating.append(demand[0])
cooling.append(demand[1])
monthly_heating = pd.DataFrame(heating, columns=[cte.INSEL_MEB])
monthly_cooling = pd.DataFrame(cooling, columns=[cte.INSEL_MEB])
return monthly_heating, monthly_cooling
def enrich(self):
for building in self._city.buildings:
file_name = building.name + '.out'
insel_output_file_path = Path(self._base_path / file_name).resolve()
if insel_output_file_path.is_file():
building.heating[cte.MONTH], building.cooling[cte.MONTH] = self._demand(insel_output_file_path)
building.heating[cte.YEAR] = pd.DataFrame(
[building.heating[cte.MONTH][cte.INSEL_MEB].sum()], columns=[cte.INSEL_MEB]
)
building.cooling[cte.YEAR] = pd.DataFrame(
[building.cooling[cte.MONTH][cte.INSEL_MEB].sum()], columns=[cte.INSEL_MEB]
)

View File

@ -0,0 +1,97 @@
"""
Simplified Radiosity Algorithm
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guillermo.GutierrezMorote@concordia.ca
"""
import pandas as pd
import numpy as np
import calendar as cal
import hub.helpers.constants as cte
class SimplifiedRadiosityAlgorithm:
"""
Import SRA results
"""
def __init__(self, city, base_path):
self._city = city
self._base_path = base_path
self._input_file_path = (self._base_path / f'{self._city.name}_sra_SW.out')
self._month_hour = self._month_hour_data_frame
self._results = self._read_results()
self._radiation_list = []
@property
def _month_hour_data_frame(self):
array = []
for i in range(0, 12):
days_of_month = cal.monthrange(2015, i+1)[1]
total_hours = days_of_month * 24
array = np.concatenate((array, np.full(total_hours, i + 1)))
return pd.DataFrame(array, columns=[cte.MONTH])
def _get_monthly_mean_values(self, values):
out = None
if values is not None:
if cte.MONTH not in values.columns:
values = pd.concat([self._month_hour, pd.DataFrame(values)], axis=1)
out = values.groupby(cte.MONTH, as_index=False).mean()
del out[cte.MONTH]
return out
def _get_yearly_mean_values(self, values):
return values.mean()
def _read_results(self):
try:
return pd.read_csv(self._input_file_path, sep='\s+', header=0)
except Exception:
raise Exception('No SRA output file found')
@property
def _radiation(self) -> []:
if len(self._radiation_list) == 0:
id_building = ''
header_building = []
for column in self._results.columns.values:
if id_building != column.split(':')[1]:
id_building = column.split(':')[1]
if len(header_building) > 0:
self._radiation_list.append(pd.concat([self._month_hour, self._results[header_building]],axis=1))
header_building = [column]
else:
header_building.append(column)
self._radiation_list.append(pd.concat([self._month_hour, self._results[header_building]], axis=1))
return self._radiation_list
def enrich(self):
"""
saves in building surfaces the correspondent irradiance at different time-scales depending on the mode
if building is None, it saves all buildings' surfaces in file, if building is specified, it saves only that
specific building values
:return: none
"""
for radiation in self._radiation:
city_object_name = radiation.columns.values.tolist()[1].split(':')[1]
building = self._city.city_object(city_object_name)
for column in radiation.columns.values:
if column == cte.MONTH:
continue
header_id = column
surface_id = header_id.split(':')[2]
surface = building.surface_by_id(surface_id)
new_value = pd.DataFrame(radiation[[header_id]].to_numpy(), columns=[cte.SRA])
month_new_value = self._get_monthly_mean_values(new_value)
if cte.MONTH not in surface.global_irradiance:
surface.global_irradiance[cte.MONTH] = month_new_value
else:
pd.concat([surface.global_irradiance[cte.MONTH], month_new_value], axis=1)
if cte.HOUR not in surface.global_irradiance:
surface.global_irradiance[cte.HOUR] = new_value
else:
pd.concat([surface.global_irradiance[cte.HOUR], new_value], axis=1)
if cte.YEAR not in surface.global_irradiance:
surface.global_irradiance[cte.YEAR] = self._get_yearly_mean_values(new_value)
self._city.level_of_detail.surface_radiation = 2

View File

@ -0,0 +1,49 @@
"""
Result factory retrieve the specific tool results and store the data in the given city
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
"""
from pathlib import Path
from hub.helpers.utils import validate_import_export_type
from hub.hub_logger import logger
from hub.imports.results.simplified_radiosity_algorithm import SimplifiedRadiosityAlgorithm
from hub.imports.results.insel_monthly_energry_balance import InselMonthlyEnergyBalance
class ResultFactory:
"""
UsageFactory class
"""
def __init__(self, handler, city, base_path=None):
if base_path is None:
base_path = Path(Path(__file__).parent.parent / 'data/results')
self._handler = '_' + handler.lower().replace(' ', '_')
class_funcs = validate_import_export_type(ResultFactory)
if self._handler not in class_funcs:
err_msg = f"Wrong import type [{self._handler}]. Valid functions include {class_funcs}"
logger.error(err_msg)
raise Exception(err_msg)
self._city = city
self._base_path = base_path
def _sra(self):
"""
Enrich the city with Simplified Radiosity Algorithm results
"""
SimplifiedRadiosityAlgorithm(self._city, self._base_path).enrich()
def _insel_meb(self):
"""
Enrich the city with insel monthly energy balance results
"""
InselMonthlyEnergyBalance(self._city, self._base_path).enrich()
def enrich(self):
"""
Enrich the city given to the class using the usage factory given handler
:return: None
"""
getattr(self, self._handler, lambda: None)()

View File

@ -9,6 +9,7 @@ import sys
from pathlib import Path from pathlib import Path
import pandas as pd import pandas as pd
import hub.helpers.constants as cte import hub.helpers.constants as cte
from hub.imports.weather.helpers.weather import Weather as wh
class EpwWeatherParameters: class EpwWeatherParameters:
@ -110,3 +111,10 @@ class EpwWeatherParameters:
building.beam[cte.HOUR] = new_value building.beam[cte.HOUR] = new_value
else: else:
pd.concat([building.beam[cte.HOUR], new_value], axis=1) pd.concat([building.beam[cte.HOUR], new_value], axis=1)
# create the monthly and yearly values out of the hourly
for building in self._city.buildings:
if cte.MONTH not in building.external_temperature:
building.external_temperature[cte.MONTH] = wh().get_monthly_mean_values(building.external_temperature[cte.HOUR][['epw']])
if cte.YEAR not in building.external_temperature:
building.external_temperature[cte.YEAR] = wh(). get_yearly_mean_values(building.external_temperature[cte.HOUR][['epw']])
self._city.level_of_detail.weather = 2

View File

@ -6,6 +6,9 @@ Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
""" """
import math import math
import hub.helpers.constants as cte import hub.helpers.constants as cte
import pandas as pd
import calendar as cal
import numpy as np
class Weather: class Weather:
@ -28,3 +31,38 @@ class Weather:
+ 0.32 * (temperature + cte.KELVIN) - cte.KELVIN + 0.32 * (temperature + cte.KELVIN) - cte.KELVIN
values.append(value) values.append(value)
return values return values
def get_monthly_mean_values(self, values):
out = None
if values is not None:
if 'month' not in values.columns:
values = pd.concat([self.month_hour, pd.DataFrame(values)], axis=1)
out = values.groupby('month', as_index=False).mean()
del out['month']
return out
def get_yearly_mean_values(self, values):
return values.mean()
def get_total_month(self, values):
out = None
if values is not None:
if 'month' not in values.columns:
values = pd.concat([self.month_hour, pd.DataFrame(values)], axis=1)
out = pd.DataFrame(values).groupby('month', as_index=False).sum()
del out['month']
return out
@property
def month_hour(self):
"""
returns a DataFrame that has x values of the month number (January = 1, February = 2...),
being x the number of hours of the corresponding month
:return: DataFrame(int)
"""
array = []
for i in range(0, 12):
days_of_month = cal.monthrange(2015, i+1)[1]
total_hours = days_of_month * 24
array = np.concatenate((array, np.full(total_hours, i + 1)))
return pd.DataFrame(array, columns=['month'])

View File

@ -1,6 +1,8 @@
from .base_repo import BaseRepo from .repository import Repository
from .repositories.city_repo import CityRepo from .repositories.city import City
from .repositories.heat_pump_simulation_repo import HeatPumpSimulationRepo from .repositories.application import Application
from .repositories.simulation_results import SimulationResults
from .repositories.city_object import CityObject
from .db_setup import DBSetup from .db_setup import DBSetup
from .repositories.user_repo import UserRepo from .repositories.user import User
from .models.user import UserRoles from .models.user import UserRoles

View File

@ -10,12 +10,11 @@ from dotenv import load_dotenv
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from hub.hub_logger import logger from hub.hub_logger import logger
Base = declarative_base() Models = declarative_base()
class Configuration:
class BaseConfiguration(object):
""" """
Base configuration class to hold common persistence configuration Configuration class to hold common persistence configuration
""" """
def __init__(self, db_name: str, dotenv_path: str, app_env='TEST'): def __init__(self, db_name: str, dotenv_path: str, app_env='TEST'):

View File

@ -1,42 +1,67 @@
"""
Database setup
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
from hub.persistence import BaseRepo from hub.persistence import Repository
from hub.persistence.models import Application
from hub.persistence.models import City from hub.persistence.models import City
from hub.persistence.models import HeatPumpSimulation from hub.persistence.models import CityObject
from hub.persistence.models import User from hub.persistence.models import User
from hub.persistence.models import UserRoles from hub.persistence.models import UserRoles
from hub.persistence.models import Application from hub.persistence.models import SimulationResults
from hub.persistence.models import UserApplications from hub.persistence.repositories import User as UserRepository
from hub.persistence.repositories import UserRepo from hub.persistence.repositories import Application as ApplicationRepository
from hub.hub_logger import logger from hub.hub_logger import logger
class DBSetup: class DBSetup:
def __init__(self, db_name, app_env, dotenv_path): def __init__(self, db_name, app_env, dotenv_path, admin_password, application_uuid):
""" """
Creates database tables and a default admin user Creates database tables a default admin user and a default admin app with the given password and uuid
:param db_name: :param db_name:
:param app_env: :param app_env:
:param dotenv_path: :param dotenv_path:
""" """
repo = BaseRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path) repository = Repository(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
User.__table__.create(bind=repo.engine, checkfirst=True)
City.__table__.create(bind=repo.engine, checkfirst=True) # Create the tables using the models
Application.__table__.create(bind=repo.engine, checkfirst=True) Application.__table__.create(bind=repository.engine, checkfirst=True)
UserApplications.__table__.create(bind=repo.engine, checkfirst=True) User.__table__.create(bind=repository.engine, checkfirst=True)
HeatPumpSimulation.__table__.create(bind=repo.engine, checkfirst=True) City.__table__.create(bind=repository.engine, checkfirst=True)
self._user_repo = UserRepo(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path) CityObject.__table__.create(bind=repository.engine, checkfirst=True)
self._create_admin_user(self._user_repo) SimulationResults.__table__.create(bind=repository.engine, checkfirst=True)
self._user_repo = UserRepository(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
self._application_repo = ApplicationRepository(db_name=db_name, app_env=app_env, dotenv_path=dotenv_path)
application_id = self._create_admin_app(self._application_repo, application_uuid)
self._create_admin_user(self._user_repo, admin_password, application_id)
@staticmethod @staticmethod
def _create_admin_user(user_repo): def _create_admin_app(application_repo, application_uuid):
email = 'admin@hub.com' name = 'AdminTool'
password = 'HubAdmin#!98' description = 'Admin tool to control city persistence and to test the API v1.4'
print('Creating default admin tool application...')
application = application_repo.insert(name, description, application_uuid)
if type(application) is dict:
logger.info(application)
else:
msg = f'Created Admin tool with application_uuid: {application_uuid}'
print(msg)
logger.info(msg)
return application.id
@staticmethod
def _create_admin_user(user_repo, admin_password, application_id):
password = admin_password
print('Creating default admin user...') print('Creating default admin user...')
user = user_repo.insert('Administrator', email, password, UserRoles.Admin) user = user_repo.insert('Administrator', password, UserRoles.Admin, application_id)
if type(user) is dict: if type(user) is dict:
logger.info(user) logger.info(user)
else: else:
print(f'Created Admin user with email: {email}, password: {password} and role: {UserRoles.Admin.value}') print(f'Created Admin user')
logger.info(f'Created Admin user with email: {email}, password: {password} and role: {UserRoles.Admin.value}') logger.info(f'Created Admin user')
print('Remember to change the admin default password and email address with the UserFactory')

View File

@ -1,7 +1,5 @@
from .city import City
from .heat_pump_simulation import HeatPumpSimulation
from .heat_pump_simulation import SimulationTypes
from .heat_pump_simulation import HeatPumpTypes
from .user import User, UserRoles
from .user_applications import UserApplications
from .application import Application from .application import Application
from .city import City
from .city_object import CityObject
from .simulation_results import SimulationResults
from .user import User, UserRoles

View File

@ -7,23 +7,25 @@ Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
import datetime import datetime
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import Column, Integer, String, Sequence from sqlalchemy import Column, Integer, String, Sequence
from sqlalchemy import DateTime from sqlalchemy import DateTime
from hub.persistence.configuration import Models
from hub.persistence.db_config import Base
class Application(Base): class Application(Models):
""" """
A model representation of an application A model representation of an application
""" """
__tablename__ = "application" __tablename__ = 'application'
id = Column(Integer, Sequence('application_id_seq'), primary_key=True) id = Column(Integer, Sequence('application_id_seq'), primary_key=True)
name = Column(String, nullable=False) name = Column(String, nullable=False)
description = Column(String, nullable=False) description = Column(String, nullable=False)
application_uuid = Column(UUID(as_uuid=True), nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow) created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow) updated = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, name, description): def __init__(self, name, description, application_uuid):
self.name = name self.name = name
self.description = description self.description = description
self.application_uuid = application_uuid

View File

@ -5,44 +5,33 @@ Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com Project Coder Peter Yefi peteryefi@gmail.com
""" """
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey
from sqlalchemy import DateTime, PickleType, Float
from hub.persistence.db_config import Base
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.orm import relationship
import datetime import datetime
import numpy as np
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey
from sqlalchemy import DateTime, PickleType
from hub.persistence.configuration import Models
class City(Base): class City(Models):
"""A model representation of a city """A model representation of a city
""" """
__tablename__ = "city" __tablename__ = 'city'
id = Column(Integer, Sequence('city_id_seq'), primary_key=True) id = Column(Integer, Sequence('city_id_seq'), primary_key=True)
city = Column(PickleType, nullable=False) city = Column(PickleType, nullable=False)
name = Column(String, nullable=False) name = Column(String, nullable=False)
srs_name = Column(String, nullable=False) level_of_detail = Column(Integer, nullable=False)
climate_reference_city = Column(String, nullable=True) climate_file = Column(String, nullable=False)
time_zone = Column(String, nullable=True) application_id = Column(Integer, ForeignKey('application.id'), nullable=False)
country_code = Column(String, nullable=False) user_id = Column(Integer, ForeignKey('user.id'), nullable=True)
latitude = Column(Float)
longitude = Column(Float)
lower_corner = Column(JSONB, nullable=False)
upper_corner = Column(JSONB, nullable=False)
hub_release = Column(String, nullable=False) hub_release = Column(String, nullable=False)
city_version = Column(Integer, nullable=False)
user_id = Column(Integer, ForeignKey('user.id'))
user = relationship("User", back_populates="cities")
created = Column(DateTime, default=datetime.datetime.utcnow) created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow) updated = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, city, name, srs_name, country_code, l_corner, u_corner, user_id): def __init__(self, city, name, level_of_detail, climate_file, application_id, user_id, hub_release):
self.city = city self.city = city
self.user_id = user_id
self.name = name self.name = name
self.srs_name = srs_name self.level_of_detail = level_of_detail
self.country_code = country_code self.climate_file = climate_file
l_corner = l_corner.tolist() if type(l_corner) == np.ndarray else l_corner self.application_id = application_id
u_corner = u_corner.tolist() if type(u_corner) == np.ndarray else u_corner self.user_id = user_id
self.lower_corner = l_corner self.hub_release = hub_release
self.upper_corner = u_corner

View File

@ -0,0 +1,41 @@
"""
Model representation of a city object
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import datetime
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey, Float
from sqlalchemy import DateTime
from hub.persistence.configuration import Models
class CityObject(Models):
"""
A model representation of an application
"""
__tablename__ = 'city_object'
id = Column(Integer, Sequence('city_object_id_seq'), primary_key=True)
city_id = Column(Integer, ForeignKey('city.id'), nullable=False)
name = Column(String, nullable=False)
alias = Column(String, nullable=True)
type = Column(String, nullable=False)
year_of_construction = Column(Integer, nullable=True)
function = Column(String, nullable=True)
usage = Column(String, nullable=True)
volume = Column(Float, nullable=False)
area = Column(Float, nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, city_id, name, alias, object_type, year_of_construction, function, usage, volume, area):
self.city_id = city_id
self.name = name
self.alias = alias
self.type = object_type
self.year_of_construction = year_of_construction
self.function = function
self.usage = usage
self.volume = volume
self.area = area

View File

@ -1,83 +0,0 @@
"""
Model representation of the results of heat pump simulation
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
from sqlalchemy import Column, Integer, String, Sequence
from sqlalchemy import Enum, ForeignKey, Float, DateTime
from sqlalchemy.dialects.postgresql import JSONB
from hub.persistence.db_config import Base
import enum
import datetime
class SimulationTypes(enum.Enum):
Parallel = 'PARALLEL'
Series = 'SERIES'
class HeatPumpTypes(enum.Enum):
Air = 'Air Source'
Water = 'Water to Water'
class HeatPumpSimulation(Base):
"""A model representation of a building
Attributes:
city_id, A reference to the city which was used to run this simulation.
hourly_electricity_demand, A JSON object that has hours and their electricity demand
daily_electricity_demand, A JSON object that has days and their electricity demand
monthly_electricity_demand, A JSON object that has months and their electricity demand
daily_fossil_fuel_consumption, A JSON object that has days and fossil fuel consumption
monthly_fossil_fuel_consumption, A JSON object that has months and fossil fuel consumption
heat_pump_type, Water or air heat pump
simulation_type, The type of heat pump simulation (parallel or series)
heat_pump_model, The model of the heat pump (either water to water or air source)
start year, HP simulation start year
end year, HP simulation end year
max_hp_energy_input, Maximum heat pump energy input
max_demand_storage_hour, Hours of storage at maximum demand
building_supply_temp, building supply temperature
temp_difference, Difference in HP and building supply temperatures
fuel_lhv, The lower heating value of fuel
fuel_price, The price of fuel
fuel_efficiency, the efficiency of fuel
fuel_density, the density of fuel
hp_supply_temp, supply temperature of heat pump
"""
__tablename__ = "heat_pump_simulation"
id = Column(Integer, Sequence('hp_simulation_id_seq'), primary_key=True)
city_id = Column(Integer, ForeignKey('city.id'), nullable=False)
daily_electricity_demand = Column(JSONB, nullable=False)
hourly_electricity_demand = Column(JSONB, nullable=False)
daily_fossil_fuel_consumption = Column(JSONB, nullable=False)
monthly_fossil_fuel_consumption = Column(JSONB, nullable=False)
monthly_electricity_demand = Column(JSONB, nullable=False)
heat_pump_type = Column(Enum(HeatPumpTypes), nullable=False)
simulation_type = Column(Enum(SimulationTypes), nullable=False)
heat_pump_model = Column(String, nullable=False)
start_year = Column(Integer, nullable=False)
end_year = Column(Integer, nullable=False)
max_hp_energy_input = Column(Float, nullable=False)
max_demand_storage_hour = Column(Float, nullable=False)
building_supply_temp = Column(Float, nullable=False)
temp_difference = Column(Float, nullable=False)
fuel_lhv = Column(Float, nullable=False)
fuel_price = Column(Float, nullable=False)
fuel_efficiency = Column(Float, nullable=False)
fuel_density = Column(Float, nullable=False)
hp_supply_temp = Column(Float, nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, city_id, hourly_elec_demand, daily_elec_demand, monthly_elec_demand, daily_fossil, monthly_fossil):
self.city_id = city_id
self.hourly_electricity_demand = hourly_elec_demand
self.daily_electricity_demand = daily_elec_demand
self.monthly_electricity_demand = monthly_elec_demand
self.daily_fossil_fuel_consumption = daily_fossil
self.monthly_fossil_fuel_consumption = monthly_fossil

View File

@ -0,0 +1,32 @@
"""
Model representation of simulation results
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import datetime
from sqlalchemy import Column, Integer, String, Sequence, ForeignKey
from sqlalchemy import DateTime
from sqlalchemy.dialects.postgresql import JSONB
from hub.persistence.configuration import Models
class SimulationResults(Models):
"""
A model representation of an application
"""
__tablename__ = 'simulation_results'
id = Column(Integer, Sequence('simulation_results_id_seq'), primary_key=True)
city_id = Column(Integer, ForeignKey('city.id'), nullable=True)
city_object_id = Column(Integer, ForeignKey('city_object.id'), nullable=True)
name = Column(String, nullable=False)
values = Column(JSONB, nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow)
def __init__(self, name, values, city_id=None, city_object_id=None):
self.name = name
self.values = values
self.city_id = city_id
self.city_object_id = city_object_id

View File

@ -5,14 +5,13 @@ Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com Project Coder Peter Yefi peteryefi@gmail.com
""" """
import datetime
import enum
from sqlalchemy import Column, Integer, String, Sequence from sqlalchemy import Column, Integer, String, Sequence
from sqlalchemy import DateTime, Enum from sqlalchemy import DateTime, Enum
from hub.persistence.db_config import Base
import datetime from hub.persistence.configuration import Models
from sqlalchemy.orm import validates
import re
import enum
from sqlalchemy.orm import relationship
class UserRoles(enum.Enum): class UserRoles(enum.Enum):
@ -20,28 +19,21 @@ class UserRoles(enum.Enum):
Hub_Reader = 'Hub_Reader' Hub_Reader = 'Hub_Reader'
class User(Base): class User(Models):
"""A model representation of a city
""" """
__tablename__ = "user" A model representation of a city
"""
__tablename__ = 'user'
id = Column(Integer, Sequence('user_id_seq'), primary_key=True) id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
name = Column(String, nullable=False) name = Column(String, nullable=False)
email = Column(String, nullable=False, unique=True)
password = Column(String, nullable=False) password = Column(String, nullable=False)
role = Column(Enum(UserRoles), nullable=False, default=UserRoles.Hub_Reader) role = Column(Enum(UserRoles), nullable=False, default=UserRoles.Hub_Reader)
cities = relationship("City", back_populates="user") application_id = Column(Integer, nullable=False)
created = Column(DateTime, default=datetime.datetime.utcnow) created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow) updated = Column(DateTime, default=datetime.datetime.utcnow)
@validates("email") def __init__(self, name, password, role, application_id):
def validate_email(self, key, address):
pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
if not re.match(pattern, address):
raise ValueError("failed simple email validation")
return address
def __init__(self, name, email, password, role):
self.name = name self.name = name
self.email = email
self.password = password self.password = password
self.role = role self.role = role
self.application_id = application_id

View File

@ -1,30 +0,0 @@
"""
Model representation of the user applications
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import datetime
from sqlalchemy import Column, Integer, ForeignKey, PrimaryKeyConstraint
from sqlalchemy import DateTime
from hub.persistence.db_config import Base
class UserApplications(Base):
"""
A model representation of the user applications
"""
__tablename__ = "user_applications"
user_id = Column(Integer, ForeignKey('user.id'))
application_id = Column(Integer, ForeignKey('application.id'))
created = Column(DateTime, default=datetime.datetime.utcnow)
updated = Column(DateTime, default=datetime.datetime.utcnow)
__table_args__ = (PrimaryKeyConstraint(user_id, application_id),)
def __init__(self, user_id, application_id):
self.user_id = user_id
self.application_id = application_id

View File

@ -1 +1,2 @@
from .user_repo import UserRepo from .user import User
from .application import Application

View File

@ -0,0 +1,98 @@
"""
Application repository with database CRUD operations
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import datetime
from typing import Union, Dict
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from hub.hub_logger import logger
from hub.persistence import Repository
from hub.persistence.models import Application as Model
class Application(Repository):
_instance = None
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
super().__init__(db_name, dotenv_path, app_env)
def __new__(cls, db_name, dotenv_path, app_env):
"""
Implemented for a singleton pattern
"""
if cls._instance is None:
cls._instance = super(Application, cls).__new__(cls)
return cls._instance
def insert(self, name: str, description: str, application_uuid: str) -> Union[Model, Dict]:
"""
Inserts a new application
:param name: Application name
:param description: Application description
:param application_uuid: Unique identifier for the application
:return: application and dictionary
"""
application = self.get_by_uuid(application_uuid)
if application is None:
try:
application = Model(name=name, description=description, application_uuid=application_uuid)
self.session.add(application)
self.session.commit()
return application
except SQLAlchemyError as err:
logger.error(f'An error occurred while creating application: {err}')
else:
return {'message': f'An application with {application_uuid} application uuid, already exists'}
def update(self, application_uuid: str, name: str, description: str) -> Union[Dict, None]:
"""
Updates an application
:param application_uuid: the application uuid of the application to be updated
:param name: the application name
:param description: the application description
:return:
"""
try:
self.session.query(Model).filter(
Model.application_uuid == application_uuid
).update({'name': name, 'description': description, 'updated': datetime.datetime.utcnow()})
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while updating application: {err}')
return {'message': 'Error occurred while updating application'}
def delete(self, application_uuid: str):
"""
Deletes an application with the application_uuid
:param application_uuid: The application uuid
:return: None
"""
try:
self.session.query(Model).filter(Model.application_uuid == application_uuid).delete()
self.session.flush()
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while deleting application: {err}')
def get_by_uuid(self, application_uuid: str) -> Union[Model, None]:
"""
Fetch Application based on the application uuid
:param application_uuid: the application uuid
:return: Application with the provided application_uuid or None
"""
try:
result_set = self.session.execute(select(Model).where(
Model.application_uuid == application_uuid)
).first()
if result_set is None:
return None
return result_set[0]
except SQLAlchemyError as err:
logger.error(f'Error while fetching application by application_uuid: {err}')

View File

@ -0,0 +1,153 @@
"""
City repository with database CRUD operations
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
import datetime
import pickle
from typing import Union, Dict
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from hub.city_model_structure.city import City as CityHub
from hub.hub_logger import logger
from hub.persistence import Repository
from hub.persistence.models import City as Model
from hub.persistence.models import CityObject
from hub.version import __version__
class City(Repository):
_instance = None
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
super().__init__(db_name, dotenv_path, app_env)
def __new__(cls, db_name, dotenv_path, app_env):
"""
Implemented for a singleton pattern
"""
if cls._instance is None:
cls._instance = super(City, cls).__new__(cls)
return cls._instance
def insert(self, city: CityHub, application_id, user_id: int) -> Union[Model, Dict]:
"""
Inserts a city
:param city: The complete city instance
:param application_id: Application id owning the instance
:param user_id: User id owning the instance
:return: City and Dictionary
"""
try:
db_city = Model(
pickle.dumps(city),
city.name,
city.level_of_detail.geometry,
'None' if city.climate_file is None else str(city.climate_file),
application_id,
user_id,
__version__)
self.session.add(db_city)
self.session.flush()
for building in city.buildings:
object_usage = ''
for internal_zone in building.internal_zones:
for usage in internal_zone.usages:
object_usage = f'{object_usage}{usage.name}_{usage.percentage} '
object_usage = object_usage.rstrip()
db_city_object = CityObject(db_city.id,
building.name,
building.alias,
building.type,
building.year_of_construction,
building.function,
object_usage,
building.volume,
building.floor_area)
self.session.add(db_city_object)
self.session.flush()
self.session.commit()
return db_city
except SQLAlchemyError as err:
print(f'An error occurred while creating city: {err}')
logger.error(f'An error occurred while creating city: {err}')
def update(self, city_id: int, city: CityHub):
"""
Updates a city name (other updates makes no sense)
:param city_id: the id of the city to be updated
:param city: the city object
:return:
"""
try:
now = datetime.datetime.utcnow()
self.session.query(Model).filter(Model.id == city_id).update({'name': city.name,'updated': now})
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while updating city: {err}')
def delete(self, city_id: int):
"""
Deletes a City with the id
:param city_id: the city id
:return: a city
"""
try:
self.session.query(Model).filter(Model.id == city_id).delete()
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while fetching city: {err}')
def get_by_id(self, city_id: int) -> Model:
"""
Fetch a City based on the id
:param city_id: the city id
:return: a city
"""
try:
return self.session.execute(select(Model).where(Model.id == city_id)).first()[0]
except SQLAlchemyError as err:
logger.error(f'Error while fetching city: {err}')
def _get_by_hub_version_and_name(self, hub_release: str, city_name: str) -> Model:
"""
Fetch a City based on the name and hub project
:param hub_release: the hub release
:param city_name: the name of the city
:return: a city
"""
try:
return self.session.execute(select(Model)
.where(Model.hub_release == hub_release, Model.name == city_name)
).first()
except SQLAlchemyError as err:
logger.error(f'Error while fetching city: {err}')
def get_by_name(self, city_name: str) -> [Model]:
"""
Fetch city based on the name
:param city_name: the name of the building
:return: [ModelCity] with the provided name
"""
try:
result_set = self.session.execute(select(Model).where(Model.name == city_name))
return [building[0] for building in result_set]
except SQLAlchemyError as err:
logger.error(f'Error while fetching city by name: {err}')
def get_by_user(self, user_id: int) -> [Model]:
"""
Fetch city based on the user who created it
:param user_id: the id of the user
:return: [ModelCity] with the provided name
"""
try:
result_set = self.session.execute(select(Model).where(Model.user_id == user_id))
return [building[0] for building in result_set]
except SQLAlchemyError as err:
logger.error(f'Error while fetching city by name: {err}')

View File

@ -0,0 +1,124 @@
"""
City Object repository with database CRUD operations
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import datetime
from typing import Union, Dict
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from hub.hub_logger import logger
from hub.persistence import Repository
from hub.persistence.models import CityObject as Model
from hub.city_model_structure.building import Building
class CityObject(Repository):
_instance = None
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
super().__init__(db_name, dotenv_path, app_env)
def __new__(cls, db_name, dotenv_path, app_env):
"""
Implemented for a singleton pattern
"""
if cls._instance is None:
cls._instance = super(CityObject, cls).__new__(cls)
return cls._instance
def insert(self, city_id:int, building: Building) -> Union[Model, Dict]:
"""
Inserts a new city object
:param city_id: city id for the city owning this city object
:param building: the city object (only building for now) to be inserted
return CityObject model and dictionary
"""
city_object = self.get_by_name_and_city(building.name, city_id)
if city_object is None:
try:
object_usage = ''
for internal_zone in building.internal_zones:
for usage in internal_zone.usages:
object_usage = f'{object_usage}{usage.name}_{usage.percentage} '
object_usage = object_usage.rstrip()
city_object = Model(city_id=city_id,
name=building.name,
alias=building.alias,
object_type=building.type,
year_of_construction=building.year_of_construction,
function=building.function,
usage=object_usage,
volume=building.volume,
area=building.floor_area)
self.session.add(city_object)
self.session.flush()
self.session.commit()
return city_object
except SQLAlchemyError as err:
logger.error(f'An error occurred while creating city_object: {err}')
else:
return {'message': f'A city_object named {building.name} already exists in that city'}
def update(self,city_id: int, building: Building) -> Union[Dict, None]:
"""
Updates an application
:param city_id: the city id of the city owning the city object
:param building: the city object
:return:
"""
try:
object_usage = ''
for internal_zone in building.internal_zones:
for usage in internal_zone.usages:
object_usage = f'{object_usage}{usage.name}_{usage.percentage} '
object_usage = object_usage.rstrip()
self.session.query(Model).filter(Model.name == building.name, Model.city_id == city_id).update(
{'name': building.name,
'alias': building.alias,
'object_type': building.type,
'year_of_construction': building.year_of_construction,
'function': building.function,
'usage': object_usage,
'volume': building.volume,
'area': building.floor_area,
'updated': datetime.datetime.utcnow()})
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while updating city object: {err}')
return {'message': 'Error occurred while updating application'}
def delete(self, city_id: int, name: str):
"""
Deletes an application with the application_uuid
:param city_id: The id for the city owning the city object
:param name: The city object name
:return: None
"""
try:
self.session.query(Model).filter(Model.city_id == city_id, Model.name == name).delete()
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while deleting application: {err}')
def get_by_name_and_city(self, name, city_id) -> [Model]:
"""
Fetch a city object based on name and city id
:param name: city object name
:param city_id: a city identifier
:return: [CityObject] with the provided name belonging to the city with id city_id
"""
try:
_city_object = self.session.execute(select(Model).where(
Model.name == name, Model.city_id == city_id
)).first()
if _city_object is None:
return None
return _city_object[0]
except SQLAlchemyError as err:
print(err)
logger.error(f'Error while fetching application by application_uuid: {err}')

View File

@ -1,152 +0,0 @@
"""
City repository with database CRUD operations
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
from hub.city_model_structure.city import City
from hub.persistence import BaseRepo
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy import select
from hub.persistence.models import City as DBCity
import pickle
import requests
from urllib3.exceptions import HTTPError
from typing import Union, Dict
from hub.hub_logger import logger
import datetime
class CityRepo(BaseRepo):
_instance = None
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
super().__init__(db_name, dotenv_path, app_env)
def __new__(cls, db_name, dotenv_path, app_env):
"""
Implemented for a singleton pattern
"""
if cls._instance is None:
cls._instance = super(CityRepo, cls).__new__(cls)
return cls._instance
def insert(self, city: City, user_id: int) -> Union[City, Dict]:
db_city = DBCity(pickle.dumps(city), city.name, city.srs_name, city.country_code, city.lower_corner,
city.upper_corner, user_id)
db_city.climate_reference_city = city.climate_reference_city
db_city.longitude = city.longitude
db_city.latitude = city.latitude
db_city.time_zone = city.time_zone
try:
# Retrieve hub project latest release
response = requests.get("https://rs-loy-gitlab.concordia.ca/api/v4/projects/2/repository/branches/master",
headers={"PRIVATE-TOKEN": self.config.hub_token})
recent_commit = response.json()["commit"]["id"]
logger.info(f'Current commit of hub is {recent_commit}')
exiting_city = self._get_by_hub_version(recent_commit, city.name)
# Do not persist the same city for the same version of Hub
if exiting_city is None:
db_city.hub_release = recent_commit
cities = self.get_by_name(city.name)
# update version for the same city but different hub versions
if len(cities) == 0:
db_city.city_version = 0
else:
db_city.city_version = cities[-1].city_version + 1
# Persist city
self.session.add(db_city)
self.session.flush()
self.session.commit()
return db_city
else:
return {'message': f'Same version of {city.name} exist'}
except SQLAlchemyError as err:
logger.error(f'Error while adding city: {err}')
except HTTPError as err:
logger.error(f'Error retrieving Hub latest release: {err}')
def get_by_id(self, city_id: int) -> DBCity:
"""
Fetch a City based on the id
:param city_id: the city id
:return: a city
"""
try:
return self.session.execute(select(DBCity).where(DBCity.id == city_id)).first()[0]
except SQLAlchemyError as err:
logger.error(f'Error while fetching city: {err}')
def _get_by_hub_version(self, hub_commit: str, city_name: str) -> City:
"""
Fetch a City based on the name and hub project recent commit
:param hub_commit: the latest hub commit
:param city_name: the name of the city
:return: a city
"""
try:
return self.session.execute(select(DBCity)
.where(DBCity.hub_release == hub_commit, DBCity.name == city_name)).first()
except SQLAlchemyError as err:
logger.error(f'Error while fetching city: {err}')
def update(self, city_id: int, city: City):
"""
Updates a city
:param city_id: the id of the city to be updated
:param city: the city object
:return:
"""
try:
self.session.query(DBCity).filter(DBCity.id == city_id) \
.update({
'name': city.name, 'srs_name': city.srs_name, 'country_code': city.country_code, 'longitude': city.longitude,
'latitude': city.latitude, 'time_zone': city.time_zone, 'lower_corner': city.lower_corner.tolist(),
'upper_corner': city.upper_corner.tolist(), 'climate_reference_city': city.climate_reference_city,
'updated': datetime.datetime.utcnow()
})
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while updating city: {err}')
def get_by_name(self, city_name: str) -> [DBCity]:
"""
Fetch city based on the name
:param city_name: the name of the building
:return: [ModelCity] with the provided name
"""
try:
result_set = self.session.execute(select(DBCity).where(DBCity.name == city_name))
return [building[0] for building in result_set]
except SQLAlchemyError as err:
logger.error(f'Error while fetching city by name: {err}')
def get_by_user(self, user_id: int) -> [DBCity]:
"""
Fetch city based on the user who created it
:param user_id: the id of the user
:return: [ModelCity] with the provided name
"""
try:
result_set = self.session.execute(select(DBCity).where(DBCity.user_id == user_id))
return [building[0] for building in result_set]
except SQLAlchemyError as err:
logger.error(f'Error while fetching city by name: {err}')
def delete_city(self, city_id: int):
"""
Deletes a City with the id
:param city_id: the city id
:return: a city
"""
try:
self.session.query(DBCity).filter(DBCity.id == city_id).delete()
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while fetching city: {err}')

View File

@ -1,108 +0,0 @@
"""
Heat pump simulation repository with database CRUD operations
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
from hub.persistence import BaseRepo, CityRepo
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy import select
from hub.persistence.models import HeatPumpSimulation
from typing import Union, Dict
from hub.hub_logger import logger
class HeatPumpSimulationRepo(BaseRepo):
_instance = None
def __init__(self, db_name, dotenv_path, app_env):
super().__init__(db_name, dotenv_path, app_env)
self._city_repo = CityRepo(db_name, dotenv_path, app_env)
def __new__(cls, db_name, dotenv_path, app_env):
"""
Implemented for a singleton pattern
"""
if cls._instance is None:
cls._instance = super(HeatPumpSimulationRepo, cls).__new__(cls)
return cls._instance
def insert(self, hp_sim_data: Dict, city_id: int) -> Union[HeatPumpSimulation, Dict]:
"""
Inserts the results of heat pump simulation
:param hp_sim_data: dictionary with heatpump the simulation inputs and output
:param city_id: the city that was used in running the simulation
:return: HeatPumpSimulation
"""
city = self._city_repo.get_by_id(city_id)
if city is None:
return {'message': 'city not found in database'}
try:
hp_simulation = HeatPumpSimulation(city_id, hp_sim_data["HourlyElectricityDemand"],
hp_sim_data["DailyElectricityDemand"], hp_sim_data["MonthlyElectricityDemand"],
hp_sim_data["DailyFossilFuelConsumption"],
hp_sim_data["MonthlyFossilFuelConsumption"])
hp_simulation.city_id = city_id
hp_simulation.end_year = hp_sim_data["EndYear"]
hp_simulation.start_year = hp_sim_data["StartYear"]
hp_simulation.max_demand_storage_hour = hp_sim_data["HoursOfStorageAtMaxDemand"]
hp_simulation.max_hp_energy_input = hp_sim_data["MaximumHPEnergyInput"]
hp_simulation.building_supply_temp = hp_sim_data["BuildingSuppTemp"]
hp_simulation.temp_difference = hp_sim_data["TemperatureDifference"]
hp_simulation.fuel_lhv = hp_sim_data["FuelLHV"]
hp_simulation.fuel_price = hp_sim_data["FuelPrice"]
hp_simulation.fuel_efficiency = hp_sim_data["FuelEF"]
hp_simulation.fuel_density = hp_sim_data["FuelDensity"]
hp_simulation.hp_supply_temp = hp_sim_data["HPSupTemp"]
hp_simulation.simulation_type = hp_sim_data["SimulationType"]
hp_simulation.heat_pump_model = hp_sim_data["HeatPumpModel"]
hp_simulation.heat_pump_type = hp_sim_data["HeatPumpType"]
# Persist heat pump simulation data
self.session.add(hp_simulation)
self.session.flush()
self.session.commit()
return hp_simulation
except SQLAlchemyError as err:
logger.error(f'Error while saving heat pump simulation data: {err}')
except KeyError as err:
logger.error(f'A required field is missing in your heat pump simulation dictionary: {err}')
def get_by_id(self, hp_simulation_id: int) -> HeatPumpSimulation:
"""
Fetches heat pump simulation data
:param hp_simulation_id: the city id
:return: a HeatPumpSimulation
"""
try:
return self.session.execute(select(HeatPumpSimulation).where(HeatPumpSimulation.id == hp_simulation_id)).first()[
0]
except SQLAlchemyError as err:
logger.error(f'Error while fetching city: {err}')
def get_by_city(self, city_id: int) -> [HeatPumpSimulation]:
"""
Fetch heat pump simulation results by city
:param city_id: the name of the building
:return: [HeatPumpSimulation] with the provided name
"""
try:
result_set = self.session.execute(select(HeatPumpSimulation).where(HeatPumpSimulation.city_id == city_id))
return [sim_data[0] for sim_data in result_set]
except SQLAlchemyError as err:
logger.error(f'Error while fetching city by name: {err}')
def delete_hp_simulation(self, hp_simulation_id: int):
"""
Deletes a heat pump simulation results
:param hp_simulation_id: the heat pump simulation results id
:return:
"""
try:
self.session.query(HeatPumpSimulation).filter(HeatPumpSimulation.id == hp_simulation_id).delete()
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while fetching city: {err}')

View File

@ -0,0 +1,137 @@
"""
Simulation results repository with database CRUD operations
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Guille Gutierrez Guillermo.GutierrezMorote@concordia.ca
"""
import datetime
from typing import Union, Dict
from sqlalchemy import select
from sqlalchemy.exc import SQLAlchemyError
from hub.hub_logger import logger
from hub.persistence import Repository
from hub.persistence.models import SimulationResults as Model
from hub.persistence.models import City
from hub.persistence.models import CityObject
from hub.city_model_structure.building import Building
class SimulationResults(Repository):
_instance = None
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
super().__init__(db_name, dotenv_path, app_env)
def __new__(cls, db_name, dotenv_path, app_env):
"""
Implemented for a singleton pattern
"""
if cls._instance is None:
cls._instance = super(SimulationResults, cls).__new__(cls)
return cls._instance
def insert(self, name: str, values: str, city_id=None, city_object_id=None) -> Union[Model, Dict]:
"""
Inserts simulations results linked either with a city as a whole or with a city object
:param name: results name
:param values: the simulation results in json format
:param city_id: optional city id
:param city_object_id: optional city object id
:return SimulationResults or Dictionary
"""
if city_id is not None:
city = self.get_city(city_id)
if city is None:
return {'message': f'City does not exists'}
else:
city_object = self.get_city_object(city_object_id)
if city_object is None:
return {'message': f'City object does not exists'}
try:
simulation_result = Model(name=name,
values=values,
city_id=city_id,
city_object_id=city_object_id)
self.session.add(simulation_result)
self.session.flush()
self.session.commit()
return simulation_result
except SQLAlchemyError as err:
logger.error(f'An error occurred while creating city_object: {err}')
def update(self, name: str, values: str, city_id=None, city_object_id=None) -> Union[Dict, None]:
"""
Updates simulation results for a city or a city object
:param name: The simulation results tool and workflow name
:param values: the simulation results in json format
:param city_id: optional city id
:param city_object_id: optional city object id
:return: None or dictionary
"""
try:
if city_id is not None:
self.session.query(Model).filter(Model.name == name, Model.city_id == city_id).update(
{
'values': values,
'updated': datetime.datetime.utcnow()
})
self.session.commit()
elif city_object_id is not None:
self.session.query(Model).filter(Model.name == name, Model.city_object_id == city_object_id).update(
{
'values': values,
'updated': datetime.datetime.utcnow()
})
self.session.commit()
else:
return {'message': 'Missing either city_id or city_object_id'}
except SQLAlchemyError as err:
logger.error(f'Error while updating city object: {err}')
return {'message': 'Error occurred while updating application'}
def delete(self, name: str, city_id=None, city_object_id=None):
"""
Deletes an application with the application_uuid
:param name: The simulation results tool and workflow name
:param city_id: The id for the city owning the simulation results
:param city_object_id: the id for the city_object ownning these simulation results
:return: None
"""
try:
if city_id is not None:
self.session.query(Model).filter(Model.name == name, Model.city_id == city_id).delete()
self.session.commit()
elif city_object_id is not None:
self.session.query(Model).filter(Model.name == name, Model.city_object_id == city_object_id).delete()
self.session.commit()
else:
return {'message': 'Missing either city_id or city_object_id'}
except SQLAlchemyError as err:
logger.error(f'Error while deleting application: {err}')
def get_city(self, city_id) -> [City]:
"""
Fetch a city object based city id
:param city_id: a city identifier
:return: [City] with the provided city_id
"""
try:
return self.session.execute(select(City).where(City.id == city_id)).first()
except SQLAlchemyError as err:
logger.error(f'Error while fetching city by city_id: {err}')
def get_city_object(self, city_object_id) -> [CityObject]:
"""
Fetch a city object based city id
:param city_object_id: a city object identifier
:return: [CityObject] with the provided city_object_id
"""
try:
return self.session.execute(select(CityObject).where(CityObject.id == city_object_id)).first()
except SQLAlchemyError as err:
logger.error(f'Error while fetching city by city_id: {err}')

View File

@ -0,0 +1,120 @@
"""
User repository with database CRUD operations
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
from hub.persistence import Repository
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy import select
from hub.persistence.models import User as Model
from hub.persistence.models import UserRoles
from hub.helpers.auth import Auth
from typing import Union, Dict
from hub.hub_logger import logger
import datetime
class User(Repository):
_instance = None
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
super().__init__(db_name, dotenv_path, app_env)
def __new__(cls, db_name, dotenv_path, app_env):
"""
Implemented for a singleton pattern
"""
if cls._instance is None:
cls._instance = super(User, cls).__new__(cls)
return cls._instance
def insert(self, name: str, password: str, role: UserRoles, application_id: int) -> Union[Model, Dict]:
"""
Inserts a new user
:param name: user name
:param password: user password
:param role: user rol [Admin or Hub_Reader]
:param application_id: user application id
:return: [User, Dictionary]
"""
user = self.get_by_name_and_application(name, application_id)
if user is None:
try:
user = Model(name=name, password=Auth.hash_password(password), role=role, application_id=application_id)
self.session.add(user)
self.session.flush()
self.session.commit()
return user
except SQLAlchemyError as err:
logger.error(f'An error occurred while creating user: {err}')
else:
return {'message': f'user {name} already exists for that application'}
def update(self, user_id: int, name: str, password: str, role: UserRoles) -> Union[Dict, None]:
"""
Updates a user
:param user_id: the id of the user to be updated
:param name: the name of the user
:param password: the password of the user
:param role: the role of the user
:return:
"""
try:
self.session.query(Model).filter(Model.id == user_id).update({
'name': name,
'password': Auth.hash_password(password),
'role': role,
'updated': datetime.datetime.utcnow()
})
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while updating user: {err}')
return {'err_msg': 'Error occurred while updated user'}
def delete(self, user_id: int):
"""
Deletes a user with the id
:param user_id: the user id
:return: None
"""
try:
self.session.query(Model).filter(Model.id == user_id).delete()
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while fetching user: {err}')
def get_by_name_and_application(self, name: str, application_id: int) -> [Model]:
"""
Fetch user based on the email address
:param name: User name
:param application_id: User application name
:return: [User] matching the search criteria
"""
try:
return self.session.execute(
select(Model).where(Model.name == name, Model.application_id == application_id)
).first()
except SQLAlchemyError as err:
logger.error(f'Error while fetching user by name and application: {err}')
def get_by_name_application_and_password(self, name: str, password: str, application_id: int) -> [Model]:
"""
Fetch user based on the email and password
:param name: User name
:param password: User password
:param application_id: User password
:return: [User] with the provided email and password
"""
try:
user = self.session.execute(
select(Model).where(Model.name == name, Model.application_id == application_id)
).first()
if user:
if Auth.check_password(password, user[0].password):
return user[0]
return {'message': 'invalid login information'}
except SQLAlchemyError as err:
logger.error(f'Error while fetching user by email: {err}')

View File

@ -1,107 +0,0 @@
"""
City repository with database CRUD operations
SPDX - License - Identifier: LGPL - 3.0 - or -later
Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com
"""
from hub.persistence import BaseRepo
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy import select
from hub.persistence.models import User
from hub.persistence.models import UserRoles
from hub.helpers.auth import Auth
from typing import Union, Dict
from hub.hub_logger import logger
import datetime
class UserRepo(BaseRepo):
_instance = None
def __init__(self, db_name: str, dotenv_path: str, app_env: str):
super().__init__(db_name, dotenv_path, app_env)
def __new__(cls, db_name, dotenv_path, app_env):
"""
Implemented for a singleton pattern
"""
if cls._instance is None:
cls._instance = super(UserRepo, cls).__new__(cls)
return cls._instance
def insert(self, name: str, email: str, password: str, role: UserRoles) -> Union[User, Dict]:
user = self.get_by_email(email)
if user is None:
try:
if Auth.validate_password(password):
user = User(name=name, email=email, password=Auth.hash_password(password), role=role)
self.session.add(user)
self.session.flush()
self.session.commit()
return user
except SQLAlchemyError as err:
logger.error(f'An error occurred while creating user: {err}')
else:
return {'message': f'user with {email} email already exists'}
def update(self, user_id: int, name: str, email: str, password: str, role: UserRoles) -> Union[Dict, None]:
"""
Updates a user
:param user_id: the id of the user to be updated
:param name: the name of the user
:param email: the email of the user
:param password: the password of the user
:param role: the role of the user
:return:
"""
try:
if Auth.validate_password(password):
self.session.query(User).filter(User.id == user_id) \
.update({'name': name, 'email': email, 'password': Auth.hash_password(password), 'role': role,
'updated': datetime.datetime.utcnow()})
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while updating user: {err}')
return {'err_msg': 'Error occurred while updated user'}
def get_by_email(self, email: str) -> [User]:
"""
Fetch user based on the email address
:param email: the email of the user
:return: [User] with the provided email
"""
try:
return self.session.execute(select(User).where(User.email == email)).first()
except SQLAlchemyError as err:
logger.error(f'Error while fetching user by email: {err}')
def delete_user(self, user_id: int):
"""
Deletes a user with the id
:param user_id: the user id
:return: None
"""
try:
self.session.query(User).filter(User.id == user_id).delete()
self.session.commit()
except SQLAlchemyError as err:
logger.error(f'Error while fetching user: {err}')
def get_user_by_email_and_password(self, email: str, password: str) -> [User]:
"""
Fetch user based on the email and password
:param email: the email of the user
:param password: the password of the user
:return: [User] with the provided email and password
"""
try:
user = self.session.execute(select(User).where(User.email == email)).first()
if user:
if Auth.check_password(password, user[0].password):
return user
else:
return {'message': 'Wrong email/password combination'}
return {'message': 'user not found'}
except SQLAlchemyError as err:
logger.error(f'Error while fetching user by email: {err}')

View File

@ -5,17 +5,17 @@ Copyright © 2022 Concordia CERC group
Project Coder Peter Yefi peteryefi@gmail.com Project Coder Peter Yefi peteryefi@gmail.com
""" """
from hub.persistence.db_config import BaseConfiguration from hub.persistence.configuration import Configuration
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
class BaseRepo: class Repository:
def __init__(self, db_name, dotenv_path: str, app_env='TEST'): def __init__(self, db_name, dotenv_path: str, app_env='TEST'):
try: try:
self.config = BaseConfiguration(db_name, dotenv_path, app_env) self.configuration = Configuration(db_name, dotenv_path, app_env)
self.engine = create_engine(self.config.conn_string()) self.engine = create_engine(self.configuration.conn_string())
self.session = Session(self.engine) self.session = Session(self.engine)
except ValueError as err: except ValueError as err:
print(f'Missing value for credentials: {err}') print(f'Missing value for credentials: {err}')

View File

@ -1,6 +1,6 @@
xmltodict xmltodict
numpy numpy
trimesh trimesh[all]==3.12.0
pyproj pyproj
pandas pandas
requests requests
@ -22,4 +22,4 @@ bcrypt==4.0.1
shapely shapely
geopandas geopandas
triangle triangle
psycopg2-binary

View File

@ -104,7 +104,7 @@ class TestConstructionFactory(TestCase):
self.assertIsNone(building.households, 'building households is not none') self.assertIsNone(building.households, 'building households is not none')
self.assertFalse(building.is_conditioned, 'building is conditioned') self.assertFalse(building.is_conditioned, 'building is conditioned')
self.assertIsNotNone(building.shell, 'building shell is none') self.assertIsNotNone(building.shell, 'building shell is none')
self.assertIsNone(building.human_readable_name, 'building human_readable_name is not none') self.assertIsNone(building.alias, 'building alias is not none')
def _check_thermal_zones(self, internal_zone): def _check_thermal_zones(self, internal_zone):
for thermal_zone in internal_zone.thermal_zones: for thermal_zone in internal_zone.thermal_zones:

View File

@ -91,6 +91,7 @@ class TestExports(TestCase):
""" """
self._export_building_energy('energy_ade') self._export_building_energy('energy_ade')
def test_sra_export(self): def test_sra_export(self):
""" """
export to SRA export to SRA

1
hub/version.py Normal file
View File

@ -0,0 +1 @@
__version__ = '0.1.7.5'

View File

@ -4,49 +4,5 @@
requires = ["setuptools>=61.0.0", "wheel"] requires = ["setuptools>=61.0.0", "wheel"]
build-backend = "setuptools.build_meta" build-backend = "setuptools.build_meta"
[project] [options.packages.find_namespace]
name = "cerc_hub" where = "hub"
version = "0.1.7.3"
description = "CERC Hub consist in a set of classes (Central data model), importers and exporters to help researchers to create better and sustainable cities"
readme = "README.md"
authors = [{ name = "Guillermo Gutierrez", email = "Guillermo.GutierrezMorote@concordia.ca" }]
license = { file = "LICENSE.md" }
classifiers = [
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
]
keywords = ["city", "hub", "cerc"]
dependencies = [
"xmltodict",
"numpy",
"trimesh",
"pyproj",
"pandas",
"requests",
"esoreader",
"geomeppy",
"PyWavefront",
"xlrd",
"openpyxl",
"networkx",
"parseidf==1.0.0",
"ply",
"rhino3dm==7.7.0",
"scipy",
"PyYAML",
"pyecore==0.12.2",
"python-dotenv",
"SQLAlchemy",
"bcrypt==4.0.1",
"shapely",
"geopandas",
"triangle"
]
requires-python = ">=3.9"
[project.optional-dependencies]
dev = ["pip-tools", "pytest"]
[project.urls]
Homepage = "https://rs-loy-gitlab.concordia.ca/Guille/hub"

134
setup.py
View File

@ -1,32 +1,112 @@
from setuptools import setup, find_packages
import os.path
import glob import glob
import pathlib
from distutils.util import convert_path
import pkg_resources
from setuptools import setup
with pathlib.Path('hub/requirements.txt').open() as r:
install_requires = [
str(requirement)
for requirement
in pkg_resources.parse_requirements(r)
]
install_requires.append('setuptools')
main_ns = {}
version = convert_path('hub/version.py')
with open(version) as f:
exec(f.read(), main_ns)
setup( setup(
name='hub', name='cerc-hub',
version="0.1", version=main_ns['__version__'],
packages=find_packages(exclude="unittests"), description="CERC Hub consist in a set of classes (Central data model), importers and exporters to help researchers "
data_files=[ "to create better and sustainable cities",
('config', [os.path.join('hub/config', 'configuration.ini')]), long_description="CERC Hub consist in a set of classes (Central data model), importers and exporters to help "
('greenery', glob.glob('hub/catalog_factories/greenery/ecore_greenery/*.ecore')), "researchers to create better and sustainable cities.\n\nDevelop at Concordia university in canada "
('data', glob.glob('hub/data/construction/*.xml')), "as part of the research group from the next generation cities institute our aim among others it's "
('data', glob.glob('hub/data/customized_imports/*.xml')), "to provide a comprehensive set of tools to help researchers and urban developers to make decisions "
('data', glob.glob('hub/data/energy_systems/*.xml')), "to improve the livability and efficiency of our cities",
('data', glob.glob('hub/data/energy_systems/*.insel')), classifiers=[
('data', glob.glob('hub/data/energy_systems/*.xlsx')), "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
('data', glob.glob('hub/data/energy_systems/*.txt')), "Programming Language :: Python",
('data', glob.glob('hub/data/energy_systems/*.yaml')), "Programming Language :: Python :: 3",
('data', glob.glob('hub/data/greenery/*.xml')),
('data', glob.glob('hub/data/life_cycle_assessment/*.xml')),
('data', glob.glob('hub/data/schedules/*.xml')),
('data', glob.glob('hub/data/schedules/*.xlsx')),
('data', glob.glob('hub/data/schedules/idf_files/*.idf')),
('data', glob.glob('hub/data/sensors/*.json')),
('data', glob.glob('hub/data/usage/*.xml')),
('data', glob.glob('hub/data/usage/*.xlsx')),
('data', glob.glob('hub/data/weather/*.dat')),
('data', glob.glob('hub/data/weather/epw/*.epw')),
('data', glob.glob('hub/data/weather/*.dat'))
], ],
setup_requires=['setuptools'] include_package_data=True,
packages=['hub',
'hub.catalog_factories',
'hub.catalog_factories.construction',
'hub.catalog_factories.data_models',
'hub.catalog_factories.data_models.construction',
'hub.catalog_factories.data_models.greenery',
'hub.catalog_factories.data_models.usages',
'hub.catalog_factories.greenery',
'hub.catalog_factories.greenery.ecore_greenery',
'hub.catalog_factories.usage',
'hub.city_model_structure',
'hub.city_model_structure.attributes',
'hub.city_model_structure.building_demand',
'hub.city_model_structure.energy_systems',
'hub.city_model_structure.greenery',
'hub.city_model_structure.iot',
'hub.city_model_structure.transport',
'hub.config',
'hub.data',
'hub.exports',
'hub.exports.building_energy',
'hub.exports.building_energy.idf_files',
'hub.exports.building_energy.insel',
'hub.exports.energy_systems',
'hub.exports.formats',
'hub.helpers',
'hub.helpers.data',
'hub.hub_logger',
'hub.imports',
'hub.imports.construction',
'hub.imports.construction.helpers',
'hub.imports.construction.data_classes',
'hub.imports.energy_systems',
'hub.imports.geometry',
'hub.imports.geometry.citygml_classes',
'hub.imports.geometry.helpers',
'hub.imports.results',
'hub.imports.usage',
'hub.imports.weather',
'hub.imports.weather.helpers',
'hub.persistence',
'hub.persistence.models',
'hub.persistence.repositories',
'hub.imports'
],
setup_requires=install_requires,
data_files=[
('hub', glob.glob('hub/requirements.txt')),
('hub/config', glob.glob('hub/config/*.ini')),
('hub/catalog_factories/greenery/ecore_greenery', glob.glob('hub/catalog_factories/greenery/ecore_greenery/*.ecore')),
('hub/data/construction.', glob.glob('hub/data/construction/*.xml')),
('hub/data/customized_imports/', glob.glob('hub/data/customized_imports/*.xml')),
('hub/data/energy_systems/', glob.glob('hub/data/energy_systems/*.xml')),
('hub/data/energy_systems/', glob.glob('hub/data/energy_systems/*.insel')),
('hub/data/energy_systems/', glob.glob('hub/data/energy_systems/*.xlsx')),
('hub/data/energy_systems/*', glob.glob('hub/data/energy_systems/*.txt')),
('hub/data/energy_systems/*', glob.glob('hub/data/energy_systems/*.yaml')),
('hub/data/greenery/', glob.glob('hub/data/greenery/*.xml')),
('hub/data/life_cycle_assessment/', glob.glob('hub/data/life_cycle_assessment/*.xml')),
('hub/data/schedules/', glob.glob('hub/data/schedules/*.xml')),
('hub/data/schedules/', glob.glob('hub/data/schedules/*.xlsx')),
('hub/data/schedules/idf_files/', glob.glob('hub/data/schedules/idf_files/*.idf')),
('hub/data/sensors/', glob.glob('hub/data/sensors/*.json')),
('hub/data/usage/', glob.glob('hub/data/usage/*.xml')),
('hub/data/usage/', glob.glob('hub/data/usage/*.xlsx')),
('hub/data/weather/', glob.glob('hub/data/weather/*.dat')),
('hub/data/weather/epw/', glob.glob('hub/data/weather/epw/*.epw')),
('hub/data/weather/', glob.glob('hub/data/weather/*.dat')),
('hub/exports/building_energy/idf_files', glob.glob('hub/exports/building_energy/idf_files/*.idf')),
('hub/exports/building_energy/idf_files', glob.glob('hub/exports/building_energy/idf_files/*.idd')),
('hub/helpers/data', glob.glob('hub/helpers/data/quebec_to_hub.json'))
],
) )