Little cosmetic changes and delete useless information.
This commit is contained in:
parent
e148ea6b91
commit
db443c559d
14
bootstrap.py
14
bootstrap.py
|
@ -15,9 +15,6 @@ from flask_restful import Api
|
|||
import threading
|
||||
|
||||
import hub_api.helpers.session_helper as sh
|
||||
from hub_api.catalogs.construction_catalog import ConstructionCatalogEntry, ConstructionCatalogEntries, ConstructionCatalogNames
|
||||
from hub_api.catalogs.greenery_catalog import GreeneryCatalogEntry, GreeneryCatalogEntries, GreeneryCatalogNames
|
||||
from hub_api.catalogs.usage_catalog import UsageCatalogEntry, UsageCatalogEntries, UsageCatalogNames
|
||||
from hub_api.session import SessionStart, SessionEnd, KeepSessionAlive
|
||||
from hub_api.uptime import Uptime
|
||||
|
||||
|
@ -29,17 +26,6 @@ api = Api(app)
|
|||
|
||||
api.add_resource(Uptime, '/v1.4/uptime')
|
||||
|
||||
# Catalogs.
|
||||
api.add_resource(GreeneryCatalogEntry, '/v1.4/greenery-catalog/entry')
|
||||
api.add_resource(GreeneryCatalogEntries, '/v1.4/greenery-catalog/entries')
|
||||
api.add_resource(GreeneryCatalogNames, '/v1.4/greenery-catalog/names')
|
||||
api.add_resource(ConstructionCatalogEntry, '/v1.4/construction-catalog/entry')
|
||||
api.add_resource(ConstructionCatalogEntries, '/v1.4/construction-catalog/entries')
|
||||
api.add_resource(ConstructionCatalogNames, '/v1.4/construction-catalog/names')
|
||||
api.add_resource(UsageCatalogEntry, '/v1.4/usage-catalog/entry')
|
||||
api.add_resource(UsageCatalogEntries, '/v1.4/usage-catalog/entries')
|
||||
api.add_resource(UsageCatalogNames, '/v1.4/usage-catalog/names')
|
||||
|
||||
# Session
|
||||
api.add_resource(SessionStart, '/v1.4/session/start')
|
||||
api.add_resource(SessionEnd, '/v1.4/session/end')
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
"""
|
||||
Construction catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from flask import request, Response
|
||||
from flask_restful import Resource
|
||||
from hub.catalog_factories.data_models.construction.archetype import Archetype
|
||||
from hub.catalog_factories.data_models.construction.construction import Construction
|
||||
from hub.catalog_factories.data_models.construction.material import Material
|
||||
from hub.catalog_factories.data_models.construction.window import Window
|
||||
from hub_api.helpers.session_helper import refresh_session
|
||||
from hub_api.helpers.auth import role_required
|
||||
from hub.persistence.models import UserRoles
|
||||
|
||||
|
||||
class ToJson:
|
||||
@staticmethod
|
||||
def archetype_to_json(archetype):
|
||||
constructions = []
|
||||
for construction in archetype.constructions:
|
||||
constructions.append(ToJson.construction_to_json(construction))
|
||||
dictionary = {
|
||||
'name': archetype.name,
|
||||
'function': archetype.function,
|
||||
'construction_period': archetype.construction_period,
|
||||
'average_storey_height': archetype.average_storey_height,
|
||||
'thermal_capacity': archetype.thermal_capacity,
|
||||
'extra_loses_due_to_thermal_bridges': archetype.extra_loses_due_to_thermal_bridges,
|
||||
'indirect_heated_ratio': archetype.indirect_heated_ratio,
|
||||
'infiltration_rate_for_ventilation_system_off': archetype.infiltration_rate_for_ventilation_system_off,
|
||||
'infiltration_rate_for_ventilation_system_on': archetype.infiltration_rate_for_ventilation_system_on,
|
||||
'constructions': constructions
|
||||
}
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def construction_to_json(construction):
|
||||
layers = []
|
||||
for layer in construction.layers:
|
||||
layers.append(ToJson.layer_to_json(layer))
|
||||
dictionary = {'name': construction.name,
|
||||
'type': construction.type,
|
||||
'layers': layers
|
||||
}
|
||||
if construction.window is not None:
|
||||
dictionary['window_ratio'] = construction.window_ratio
|
||||
dictionary['window'] = ToJson.window_to_json(construction.window)
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def window_to_json(window):
|
||||
if window is None:
|
||||
return {}
|
||||
dictionary = {
|
||||
'name': window.name,
|
||||
'frame_ratio': window.frame_ratio,
|
||||
'g_value': window.g_value,
|
||||
'overall_u_value': str(window.overall_u_value)
|
||||
}
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def layer_to_json(layer):
|
||||
dictionary = {'name': layer.name,
|
||||
'thickness': layer.thickness,
|
||||
'material': ToJson.material_to_json(layer.material),
|
||||
}
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def material_to_json(material):
|
||||
dictionary = {'id': material.id,
|
||||
'name': material.name,
|
||||
'solar_absorptance': material.solar_absorptance,
|
||||
'thermal_absorptance': material.thermal_absorptance,
|
||||
'visible_absorptance': material.visible_absorptance,
|
||||
'no_mass': str(material.no_mass),
|
||||
'thermal_resistance': '',
|
||||
'conductivity': '',
|
||||
'density': '',
|
||||
'specific_heat': ''
|
||||
}
|
||||
if material.no_mass:
|
||||
dictionary['thermal_resistance'] = material.thermal_resistance
|
||||
else:
|
||||
dictionary['conductivity'] = material.conductivity
|
||||
dictionary['density'] = material.density
|
||||
dictionary['specific_heat'] = material.specific_heat
|
||||
return dictionary
|
||||
|
||||
|
||||
class ConstructionCatalogEntry(Resource):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
||||
def post(self):
|
||||
session = refresh_session(request)
|
||||
if session is None:
|
||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
||||
headers = session.headers
|
||||
catalog = session.construction_catalog
|
||||
name = None
|
||||
if request.data == b'' or request.json['name'] is None:
|
||||
response = {'error': 'Mandatory parameter "name" is missing'}
|
||||
return Response(json.dumps(response), headers=headers, status=400)
|
||||
try:
|
||||
name = request.json['name']
|
||||
entry = catalog.get_entry(name)
|
||||
output = {}
|
||||
if isinstance(entry, Archetype):
|
||||
output['archetypes'] = ToJson.archetype_to_json(entry)
|
||||
if isinstance(entry, Construction):
|
||||
output['constructions'] = ToJson.construction_to_json(entry)
|
||||
if isinstance(entry, Material):
|
||||
output['materials'] = ToJson.material_to_json(entry)
|
||||
if isinstance(entry, Window):
|
||||
output['windows'] = ToJson.window_to_json(entry)
|
||||
return Response(json.dumps(output), headers=headers)
|
||||
except IndexError:
|
||||
response = {'error': f'Name "{name}" unknown'}
|
||||
return Response(json.dumps(response), headers=headers, status=400)
|
||||
|
||||
|
||||
class ConstructionCatalogEntries(Resource):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
||||
def post(self):
|
||||
session = refresh_session(request)
|
||||
if session is None:
|
||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
||||
headers = session.headers
|
||||
catalog = session.construction_catalog
|
||||
category = None
|
||||
if request.data != b'':
|
||||
category = request.json['category']
|
||||
output = {}
|
||||
if category is None:
|
||||
output = {'archetypes': [], 'constructions':[], 'materials':[], 'windows':[]}
|
||||
content = catalog.entries()
|
||||
for archetype in content.archetypes:
|
||||
output['archetypes'].append(ToJson.archetype_to_json(archetype))
|
||||
for construction in content.constructions:
|
||||
output['constructions'].append(ToJson.construction_to_json(construction))
|
||||
for material in content.materials:
|
||||
output['materials'].append(ToJson.material_to_json(material))
|
||||
for window in content.windows:
|
||||
output['windows'].append(ToJson.window_to_json(window))
|
||||
else:
|
||||
try:
|
||||
output[category] = []
|
||||
content = catalog.entries(category)
|
||||
for entry in content:
|
||||
if isinstance(entry, Archetype):
|
||||
output[category].append(ToJson.archetype_to_json(entry))
|
||||
if isinstance(entry, Construction):
|
||||
output[category].append(ToJson.construction_to_json(entry))
|
||||
if isinstance(entry, Material):
|
||||
output[category].append(ToJson.material_to_json(entry))
|
||||
if isinstance(entry, Window):
|
||||
output[category].append(ToJson.window_to_json(entry))
|
||||
except ValueError:
|
||||
output = {'error': f'Category "{category}" unknown'}
|
||||
return Response(json.dumps(output), headers=headers, status=400)
|
||||
return Response(json.dumps(output), headers=headers)
|
||||
|
||||
|
||||
class ConstructionCatalogNames(Resource):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def post():
|
||||
session = refresh_session(request)
|
||||
if session is None:
|
||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
||||
headers = session.headers
|
||||
catalog = session.construction_catalog
|
||||
category = None
|
||||
if request.data != b'':
|
||||
category = request.json['category']
|
||||
if category is None:
|
||||
return Response(json.dumps(catalog.names()), headers=headers)
|
||||
else:
|
||||
try:
|
||||
return Response(json.dumps(catalog.names(category)), headers=headers)
|
||||
except ValueError:
|
||||
response = {'error': f'Category "{category}" unknown'}
|
||||
return Response(json.dumps(response), headers=headers, status=400)
|
|
@ -1,178 +0,0 @@
|
|||
"""
|
||||
Greenery catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
import json
|
||||
from flask import request, Response
|
||||
from flask_restful import Resource
|
||||
from hub.catalog_factories.data_models.greenery.plant import Plant
|
||||
from hub.catalog_factories.data_models.greenery.soil import Soil
|
||||
from hub.catalog_factories.data_models.greenery.vegetation import Vegetation
|
||||
from hub_api.helpers.session_helper import refresh_session
|
||||
|
||||
|
||||
class ToJson:
|
||||
@staticmethod
|
||||
def plant_to_json(plant, percentage=None):
|
||||
dictionary = {
|
||||
'plant_percentage': percentage,
|
||||
'plant_name': plant.name,
|
||||
'plant_category': plant.category,
|
||||
'plant_height': plant.height,
|
||||
'plant_leaf_area_index': plant.leaf_area_index,
|
||||
'plant_leaf_reflectivity': plant.leaf_reflectivity,
|
||||
'plant_leaf_emissivity': plant.leaf_emissivity,
|
||||
'plant_minimal_stomatal_resistance': plant.minimal_stomatal_resistance,
|
||||
'plant_co2_sequestration': plant.co2_sequestration,
|
||||
'plant_grows_on': []
|
||||
}
|
||||
if percentage is None:
|
||||
dictionary.pop('plant_percentage')
|
||||
soils = []
|
||||
for soil in plant.grows_on:
|
||||
soil_dic = ToJson.soil_to_json(soil)
|
||||
soils.append(soil_dic)
|
||||
dictionary['plant_grows_on'] = soils
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def soil_to_json(soil):
|
||||
dictionary = {'soil_name': soil.name,
|
||||
'soil_roughness': str(soil.roughness),
|
||||
'soil_dry_conductivity': soil.dry_conductivity,
|
||||
'soil_dry_density': soil.dry_density,
|
||||
'soil_dry_specific_heat': soil.dry_specific_heat,
|
||||
'soil_thermal_absortance': soil.thermal_absorptance,
|
||||
'soil_solar_absortance': soil.solar_absorptance,
|
||||
'soil_visible_absortance': soil.visible_absorptance,
|
||||
'soil_saturation_volumetric_moisture_content': soil.saturation_volumetric_moisture_content,
|
||||
'soil_residual_volumetric_moisture_content': soil.residual_volumetric_moisture_content,
|
||||
'soil_initial_volumetric_moisture_content': soil.initial_volumetric_moisture_content
|
||||
}
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def vegetation_to_json(vegetation):
|
||||
|
||||
dictionary = {'vegetation_name': vegetation.name,
|
||||
'vegetation_category': vegetation.category,
|
||||
'soil_thickness': vegetation.soil_thickness,
|
||||
'management': str(vegetation.management),
|
||||
'air_gap': vegetation.air_gap,
|
||||
'soil_name': vegetation.soil_name,
|
||||
'soil_roughness': str(vegetation.soil_roughness),
|
||||
'dry_soil_conductivity': vegetation.dry_soil_conductivity,
|
||||
'dry_soil_density': vegetation.dry_soil_density,
|
||||
'dry_soil_specific_heat': vegetation.dry_soil_specific_heat,
|
||||
'soil_thermal_absorptance': vegetation.soil_thermal_absorptance,
|
||||
'soil_solar_absorptance': vegetation.soil_solar_absorptance,
|
||||
'soil_visible_absorptance': vegetation.soil_visible_absorptance,
|
||||
'soil_saturation_volumetric_moisture_content': vegetation.soil_saturation_volumetric_moisture_content,
|
||||
'soil_residual_volumetric_moisture_content': vegetation.soil_residual_volumetric_moisture_content,
|
||||
'soil_initial_volumetric_moisture_content': vegetation.soil_initial_volumetric_moisture_content,
|
||||
'plant_percentages': []
|
||||
}
|
||||
percentages = []
|
||||
for percentage in vegetation.plant_percentages:
|
||||
percentage_dic = ToJson.plant_to_json(percentage, percentage.percentage)
|
||||
percentages.append(percentage_dic)
|
||||
dictionary['plant_percentages'] = percentages
|
||||
return dictionary
|
||||
|
||||
|
||||
class GreeneryCatalogEntry(Resource):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def post():
|
||||
session = refresh_session(request)
|
||||
if session is None:
|
||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
||||
headers = session.headers
|
||||
catalog = session.greenery_catalog
|
||||
name = None
|
||||
if request.data == b'' or request.json['name'] is None:
|
||||
response = {'error': 'Mandatory parameter "name" is missing'}
|
||||
return Response(json.dumps(response), headers=headers, status=400)
|
||||
try:
|
||||
name = request.json['name']
|
||||
entry = catalog.get_entry(name)
|
||||
output = {}
|
||||
if isinstance(entry, Vegetation):
|
||||
output['vegetations'] = ToJson.vegetation_to_json(entry)
|
||||
if isinstance(entry, Plant):
|
||||
output['plants'] = ToJson.plant_to_json(entry)
|
||||
if isinstance(entry, Soil):
|
||||
output['soils'] = ToJson.soil_to_json(entry)
|
||||
return Response(json.dumps(output), headers=headers)
|
||||
except IndexError:
|
||||
response = {'error': f'Name "{name}" unknown'}
|
||||
return Response(json.dumps(response), headers=headers, status=400)
|
||||
|
||||
|
||||
class GreeneryCatalogEntries(Resource):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def post():
|
||||
session = refresh_session(request)
|
||||
if session is None:
|
||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
||||
headers = session.headers
|
||||
catalog = session.greenery_catalog
|
||||
category = None
|
||||
if request.data != b'':
|
||||
category = request.json['category']
|
||||
output = {}
|
||||
if category is None:
|
||||
content = catalog.entries()
|
||||
output = {'vegetations': [], 'plants': [], 'soils': []}
|
||||
for vegetation in content.vegetations:
|
||||
output['vegetations'].append(ToJson.vegetation_to_json(vegetation))
|
||||
for plant in content.plants:
|
||||
output['plants'].append(ToJson.plant_to_json(plant))
|
||||
for soil in content.soils:
|
||||
output['soils'].append(ToJson.soil_to_json(soil))
|
||||
else:
|
||||
try:
|
||||
content = catalog.entries(category)
|
||||
output[category] = []
|
||||
for entry in content:
|
||||
if isinstance(entry, Vegetation):
|
||||
output[category].append(ToJson.vegetation_to_json(entry))
|
||||
if isinstance(entry, Plant):
|
||||
output[category].append(ToJson.plant_to_json(entry))
|
||||
if isinstance(entry, Soil):
|
||||
output[category].append(ToJson.soil_to_json(entry))
|
||||
except ValueError:
|
||||
output = {'error': f'Category "{category}" unknown'}
|
||||
return Response(json.dumps(output), headers=headers, status=400)
|
||||
return Response(json.dumps(output), headers=headers)
|
||||
|
||||
|
||||
class GreeneryCatalogNames(Resource):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def post():
|
||||
session = refresh_session(request)
|
||||
if session is None:
|
||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
||||
headers = session.headers
|
||||
catalog = session.greenery_catalog
|
||||
category = None
|
||||
if request.data != b'':
|
||||
category = request.json['category']
|
||||
if category is None:
|
||||
return Response(json.dumps(catalog.names()), headers=headers)
|
||||
else:
|
||||
try:
|
||||
return Response(json.dumps(catalog.names(category)), headers=headers)
|
||||
except ValueError:
|
||||
response = {'error': f'Category "{category}" unknown'}
|
||||
return Response(json.dumps(response), headers=headers, status=400)
|
|
@ -1,156 +0,0 @@
|
|||
"""
|
||||
Construction catalog
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from flask import request, Response
|
||||
from flask_restful import Resource
|
||||
|
||||
from hub_api.helpers.session_helper import refresh_session
|
||||
|
||||
|
||||
class ToJson:
|
||||
@staticmethod
|
||||
def usage_to_json(usage):
|
||||
dictionary = {
|
||||
'usage': usage.usage,
|
||||
'hours_day': usage.hours_day,
|
||||
'days_year': usage.days_year,
|
||||
'mechanical_air_change': usage.mechanical_air_change if usage.mechanical_air_change is not None else '',
|
||||
'ventilation_rate': usage.ventilation_rate if usage.ventilation_rate is not None else '',
|
||||
'occupancy': ToJson.occupancy_to_json(usage.occupancy),
|
||||
'lighting': ToJson.lighting_to_json(usage.lighting),
|
||||
'appliances': ToJson.appliances_to_json(usage.appliances),
|
||||
'thermal_control': ToJson.thermal_control_to_json(usage.thermal_control)
|
||||
}
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def occupancy_to_json(occupancy):
|
||||
dictionary = {
|
||||
'occupancy_density': occupancy.occupancy_density,
|
||||
'sensible_convective_internal_gain': occupancy.sensible_convective_internal_gain,
|
||||
'sensible_radiative_internal_gain': occupancy.sensible_radiative_internal_gain,
|
||||
'latent_internal_gain': occupancy.latent_internal_gain,
|
||||
'schedules': []
|
||||
}
|
||||
for schedule in occupancy.schedules:
|
||||
dictionary['schedules'].append(ToJson.schedule_to_json(schedule))
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def lighting_to_json(lighting):
|
||||
dictionary = {
|
||||
'density': lighting.density,
|
||||
'convective_fraction': lighting.convective_fraction,
|
||||
'radiative_fraction': lighting.radiative_fraction,
|
||||
'latent_fraction': lighting.latent_fraction,
|
||||
'schedules': []
|
||||
}
|
||||
for schedule in lighting.schedules:
|
||||
dictionary['schedules'].append(ToJson.schedule_to_json(schedule))
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def appliances_to_json(appliances):
|
||||
dictionary = {
|
||||
'density': appliances.density,
|
||||
'convective_fraction': appliances.convective_fraction,
|
||||
'radiative_fraction': appliances.radiative_fraction,
|
||||
'latent_fraction': appliances.latent_fraction,
|
||||
'schedules': []
|
||||
}
|
||||
for schedule in appliances.schedules:
|
||||
dictionary['schedules'].append(ToJson.schedule_to_json(schedule))
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def thermal_control_to_json(thermal_control):
|
||||
dictionary = {
|
||||
'mean_heating_set_point': thermal_control.mean_heating_set_point,
|
||||
'heating_set_back': thermal_control.heating_set_back,
|
||||
'mean_cooling_set_point': thermal_control.mean_cooling_set_point,
|
||||
'hvac_availability_schedules': [],
|
||||
'heating_set_point_schedules': [],
|
||||
'cooling_set_point_schedules': [],
|
||||
}
|
||||
for schedule in thermal_control.hvac_availability_schedules:
|
||||
dictionary['hvac_availability_schedules'].append(ToJson.schedule_to_json(schedule))
|
||||
for schedule in thermal_control.heating_set_point_schedules:
|
||||
dictionary['heating_set_point_schedules'].append(ToJson.schedule_to_json(schedule))
|
||||
for schedule in thermal_control.cooling_set_point_schedules:
|
||||
dictionary['cooling_set_point_schedules'].append(ToJson.schedule_to_json(schedule))
|
||||
return dictionary
|
||||
|
||||
@staticmethod
|
||||
def schedule_to_json(schedule):
|
||||
schedule_dictionary = {
|
||||
'type': schedule.type,
|
||||
'data_type': schedule.data_type,
|
||||
'time_step': schedule.time_step,
|
||||
'time_range': schedule.time_range,
|
||||
'day_types': schedule.day_types,
|
||||
'values': schedule.values,
|
||||
}
|
||||
return schedule_dictionary
|
||||
|
||||
|
||||
class UsageCatalogEntry(Resource):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def post():
|
||||
session = refresh_session(request)
|
||||
if session is None:
|
||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
||||
headers = session.headers
|
||||
catalog = session.usage_catalog
|
||||
|
||||
name = None
|
||||
if request.data == b'' or request.json['name'] is None:
|
||||
response = {'error': 'Mandatory parameter "name" is missing'}
|
||||
return Response(json.dumps(response), headers=headers, status=400)
|
||||
try:
|
||||
name = request.json['name']
|
||||
entry = catalog.get_entry(name)
|
||||
output = {'usages': [ToJson.usage_to_json(entry)]}
|
||||
return Response(json.dumps(output), headers=headers)
|
||||
except IndexError:
|
||||
response = {'error': f'Name "{name}" unknown'}
|
||||
return Response(json.dumps(response), headers=headers, status=400)
|
||||
|
||||
|
||||
class UsageCatalogEntries(Resource):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def post():
|
||||
session = refresh_session(request)
|
||||
if session is None:
|
||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
||||
headers = session.headers
|
||||
catalog = session.usage_catalog
|
||||
output = {'usages': []}
|
||||
content = catalog.entries()
|
||||
for usage in content.usages:
|
||||
output['usages'].append(ToJson.usage_to_json(usage))
|
||||
return Response(json.dumps(output), headers=headers)
|
||||
|
||||
|
||||
class UsageCatalogNames(Resource):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def post():
|
||||
session = refresh_session(request)
|
||||
if session is None:
|
||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
||||
headers = session.headers
|
||||
catalog = session.usage_catalog
|
||||
return Response(json.dumps(catalog.names()), headers=headers)
|
|
@ -32,6 +32,8 @@ class CityInfo(Resource, Config):
|
|||
window_type = 'unknown'
|
||||
building_dic = {}
|
||||
for building in city.buildings:
|
||||
for internal_zone in building.internal_zones:
|
||||
poly = internal_zone.polyhedron
|
||||
|
||||
usages = [] # This is only valid for dompark project as all the building have the same usage
|
||||
if building.lower_corner[2] == 0:
|
||||
|
|
|
@ -3,12 +3,12 @@ Config
|
|||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2023 Project Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
import pickle
|
||||
from pathlib import Path
|
||||
|
||||
from hub.city_model_structure.city import City
|
||||
from hub.exports.db_factory import DBFactory as CityExportFactory
|
||||
from hub.imports.db_factory import DBFactory
|
||||
import os
|
||||
import pickle
|
||||
|
||||
|
||||
class Config:
|
||||
|
@ -23,7 +23,7 @@ class Config:
|
|||
self.import_db_factory = DBFactory(db_name=database_name, app_env=environment,
|
||||
dotenv_path=dotenv_path)
|
||||
|
||||
def get_city(self, city_id):
|
||||
def get_city(self, city_id) -> City:
|
||||
city_obj = self.export_db_factory.get_city(city_id)
|
||||
city = pickle.loads(city_obj.city)
|
||||
for building in city.buildings:
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
"""
|
||||
HeatPump Service
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2023 Project Author Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Dict
|
||||
from jwt import JWT, jwk_from_pem
|
||||
import os
|
||||
from jwt.utils import get_int_from_datetime
|
||||
from functools import wraps
|
||||
from flask import request, g
|
||||
from hub.hub_logger import logger
|
||||
from hub.persistence.models import UserRoles
|
||||
from jwt.exceptions import JWTException
|
||||
|
||||
instance = JWT()
|
||||
|
||||
|
||||
def generate_auth_token(user: Dict):
|
||||
private_key = "{}/rsa.pem".format(os.path.expanduser('~'))
|
||||
with open(private_key, 'rb') as fh:
|
||||
signing_key = jwk_from_pem(fh.read())
|
||||
user['exp'] = get_int_from_datetime(datetime.now(timezone.utc) + timedelta(hours=24))
|
||||
user['iat'] = get_int_from_datetime(datetime.now(timezone.utc))
|
||||
return instance.encode(user, signing_key, alg='RS256')
|
||||
|
||||
|
||||
def validate_auth_token(token: str):
|
||||
public_key = "{}/rsa.pub".format(os.path.expanduser('~'))
|
||||
with open(public_key, 'rb') as fh:
|
||||
verifying_key = jwk_from_pem(fh.read())
|
||||
return instance.decode(token, verifying_key, do_time_check=True)
|
||||
|
||||
|
||||
def role_required(roles: [str]):
|
||||
def auth_module(user):
|
||||
g.user = user
|
||||
for role in roles:
|
||||
if role == user['role']:
|
||||
return True
|
||||
return False
|
||||
|
||||
"""
|
||||
A wrapper to authorize specific roles for specific endpoints
|
||||
:param roles: a list of roles allowed
|
||||
:return:
|
||||
"""
|
||||
|
||||
def role_decorator(f):
|
||||
@wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
token = request.headers['Authorization'].split()[1]
|
||||
user = validate_auth_token(token)
|
||||
if user is None:
|
||||
return {'messages': 'You have not been authenticated'}, 401
|
||||
allowed = auth_module(user['user'])
|
||||
if user['user']['role'] == UserRoles.Admin.value and 'localhost' not in request.headers['Host']:
|
||||
allowed = False
|
||||
if not allowed:
|
||||
return {'messages': 'You are not authorized'}, 403
|
||||
return f(*args, **kwargs)
|
||||
except KeyError as err:
|
||||
# logger Error
|
||||
logger.error(err)
|
||||
return {'messages': 'Invalid payload'}, 400
|
||||
except JWTException as err:
|
||||
logger.error(err)
|
||||
return {'messages': 'Invalid token'}, 401
|
||||
except Exception as err:
|
||||
logger.error(err)
|
||||
return {'messages': 'Sorry, an error occurred while processing your request'}, 500
|
||||
|
||||
return wrapper
|
||||
|
||||
return role_decorator
|
||||
|
|
@ -57,8 +57,8 @@ class SessionData:
|
|||
|
||||
|
||||
def session_garbage_collector(session_timeout_duration):
|
||||
#loop through all sessions and remove expired sessions
|
||||
while(True):
|
||||
# loop through all sessions and remove expired sessions
|
||||
while True:
|
||||
if bool(sessions):
|
||||
for session in list(sessions):
|
||||
_expire = datetime.datetime.strptime(sessions[session]['expire'], '%Y-%m-%d %H:%M:%S.%f')
|
||||
|
@ -73,7 +73,7 @@ def _validate_session(session_id, token, application_uuid):
|
|||
if bool(sessions[session_id]) and sessions[session_id]['token'] == token and \
|
||||
sessions[session_id]['application_uuid'] == application_uuid:
|
||||
return True
|
||||
except:
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
import os
|
||||
from unittest import TestCase
|
||||
from bootstrap import app
|
||||
from hub.persistence.base_repo import BaseRepo
|
||||
from sqlalchemy import create_engine
|
||||
from hub.persistence.models import City
|
||||
from hub.persistence.models import User
|
||||
from sqlalchemy.exc import ProgrammingError
|
||||
|
||||
|
||||
# function to ensure tests run in order shown in fle
|
||||
def arrange():
|
||||
order = {}
|
||||
|
||||
def ordered(f):
|
||||
order[f.__name__] = len(order)
|
||||
return f
|
||||
|
||||
def compare(a, b):
|
||||
return [1, -1][order[a] < order[b]]
|
||||
|
||||
return ordered, compare
|
||||
|
||||
|
||||
class BaseTest(TestCase):
|
||||
"""
|
||||
Tests for payment resource
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
os.environ['FLASK_DEBUG'] = 'testing'
|
||||
cls.app = app
|
||||
cls.client = cls.app.test_client()
|
||||
|
||||
# Create test database
|
||||
repo = BaseRepo(db_name='test_db', app_env='TEST', dotenv_path="{}/.env".format(os.path.expanduser('~')))
|
||||
eng = create_engine(f'postgresql://{repo.config.get_db_user()}@/{repo.config.get_db_user()}')
|
||||
|
||||
try:
|
||||
# delete test database if it exists
|
||||
conn = eng.connect()
|
||||
conn.execute('commit')
|
||||
conn.execute('DROP DATABASE test_db')
|
||||
conn.close()
|
||||
except ProgrammingError as err:
|
||||
print(f'Database does not exist. Nothing to delete')
|
||||
|
||||
cnn = eng.connect()
|
||||
cnn.execute('commit')
|
||||
cnn.execute("CREATE DATABASE test_db")
|
||||
cnn.close()
|
||||
User.__table__.create(bind=repo.engine, checkfirst=True)
|
||||
City.__table__.create(bind=repo.engine, checkfirst=True)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls) -> None:
|
||||
pass
|
|
@ -1,125 +0,0 @@
|
|||
#!/bin/bash
|
||||
clear
|
||||
printf 'Uptime:\n'
|
||||
curl -i -X GET http://127.0.0.1:15789/v1.3/uptime
|
||||
printf '\n\nSession start:\n'
|
||||
curl -i -X PUT -H "Session: {'session_id': 'debug'}" http://127.0.0.1:15789/v1.3/session/start
|
||||
|
||||
printf '\n\nRepeat session start:\n'
|
||||
curl -i -X PUT -H "Session: {'session_id': 'debug'}" http://127.0.0.1:15789/v1.3/session/start
|
||||
|
||||
printf '\n\nKeep session alive:\n'
|
||||
curl -i -X PUT -H "Session: {'session_id': 'debug', 'token': 'debug'}" http://127.0.0.1:15789/v1.3/session/keep_alive
|
||||
|
||||
printf '\n\nCity info:\n'
|
||||
curl -i -X GET -H "Session: {'session_id': 'debug', 'token': 'debug'}" http://127.0.0.1:15789/v1.3/city_info
|
||||
|
||||
printf '\n\nGreenery catalog entry without parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery-catalog/entry
|
||||
|
||||
printf '\n\nGreenery catalog entry with wrong parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"name": "non_existing_name"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery-catalog/entry
|
||||
|
||||
printf '\n\nGreenery catalog entry with correct parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"name": "grass"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery-catalog/entry
|
||||
|
||||
printf '\n\nGreenery catalog names without parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery-catalog/names
|
||||
|
||||
printf '\n\nGreenery catalog names with wrong parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"category": "non_existing_name"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery-catalog/names
|
||||
|
||||
printf '\n\nGreenery catalog names with correct parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"category": "soils"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery-catalog/names
|
||||
|
||||
printf '\n\nGreenery catalog entries without parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery-catalog/entries
|
||||
|
||||
printf '\n\nGreenery catalog entries with wrong parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"category": "non_existing_category"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery-catalog/entries
|
||||
|
||||
printf '\n\nGreenery catalog entries with correct parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"category": "vegetations"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery-catalog/entries
|
||||
|
||||
printf '\n\nGeometry:\n'
|
||||
curl -i -X GET -H "Session: {'session_id': 'debug', 'token': 'debug'}" http://127.0.0.1:15789/v1.3/geometry
|
||||
|
||||
printf '\n\nHeat Pump:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"BuildingSuppTemp": 40, "EndYear": 2016, "FuelDensity": 0.717, "FuelEF": 1887, "FuelLHV": 47100, "FuelPrice": 0.3, "HPSupTemp": 60, "HeatPumpModel": "012", "HeatPumpType": "Air Source HP", "HoursOfStorageAtMaxDemand": 1, "MaximumHPEnergyInput": 8000, "SimType": 0, "StartYear": 2015, "TemperatureDifference": 15 }' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/heat-pump
|
||||
|
||||
printf '\n\Material LCA Catalog:\n'
|
||||
curl -i -X GET -H "Session: {'session_id': 'debug', 'token': 'debug'}" http://127.0.0.1:15789/v1.3/material_lca_catalog/entries
|
||||
|
||||
printf '\n\Material LCA Calculations:\n'
|
||||
curl -i -X GET -H "Session: {'session_id': 'debug', 'token': 'debug'}" http://127.0.0.1:15789/v1.3/material_lca_catalog/calculations
|
||||
|
||||
printf '\n\nConstruction catalog entry without parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction-catalog/entry
|
||||
|
||||
printf '\n\nConstruction catalog entry with wrong parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"name": "non_existing_name"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction-catalog/entry
|
||||
|
||||
printf '\n\nConstruction catalog entry with correct parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"name": "189.1-2009 Nonres 4B Ext Wall Mass"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction-catalog/entry
|
||||
|
||||
printf '\n\nConstruction catalog names without parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction-catalog/names
|
||||
|
||||
printf '\n\nConstruction catalog names with wrong parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"category": "non_existing_name"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction-catalog/names
|
||||
|
||||
printf '\n\nConstruction catalog names with correct parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"category": "materials"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction-catalog/names
|
||||
|
||||
printf '\n\nConstruction catalog entries without parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction-catalog/entries
|
||||
|
||||
printf '\n\nConstruction catalog entries with wrong parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"category": "non_existing_category"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction-catalog/entries
|
||||
|
||||
printf '\n\nConstruction catalog entries with correct parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"category": "archetypes"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction-catalog/entries
|
||||
|
||||
printf '\n\nSet Construction without building names:\n'
|
||||
curl -i -X PUT -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"extra_loses_due_to_thermal_bridges":"0.15","indirect_heated_ratio":"0.15","infiltration_rate_for_ventilation_system_off":"0.5","infiltration_rate_for_ventilation_system_on":"0","constructions":[{"type":"Wall","layers":[{"thickness":"0.0253","material":{"solar_absorptance":"0.92","thermal_absorptance":"0.9","visible_absorptance":"0.92","no_mass":"False","thermal_resistance":"","conductivity":"0.6918","density":"1858","specific_heat":"837"}},{"thickness":"0.2033","material":{"solar_absorptance":"0.65","thermal_absorptance":"0.9","visible_absorptance":"0.65","no_mass":"False","thermal_resistance":"","conductivity":"1.7296","density":"2243","specific_heat":"837"}},{"thickness":"0.0338606","material":{"solar_absorptance":"0.5","thermal_absorptance":"0.9","visible_absorptance":"0.5","no_mass":"False","thermal_resistance":"","conductivity":"0.0432","density":"91","specific_heat":"837"}},{"thickness":"0.01271","material":{"solar_absorptance":"0.92","thermal_absorptance":"0.9","visible_absorptance":"0.92","no_mass":"False","thermal_resistance":"","conductivity":"0.16","density":"784.9","specific_heat":"830"}}],"window":{"frame_ratio":"0","g_value":"0.36","overall_u_value":"4.491833333333333"}},{"type":"Ground","layers":[{"thickness":"0.1016","material":{"solar_absorptance":"0.7","thermal_absorptance":"0.9","visible_absorptance":"0.7","no_mass":"False","thermal_resistance":"","conductivity":"1.311","density":"2240","specific_heat":"836.8"}},{"thickness":0,"material":{"solar_absorptance":"0.7","thermal_absorptance":"0.9","visible_absorptance":"0.8","no_mass":"True","thermal_resistance":"0.21648","conductivity":"","density":"","specific_heat":""}}]},{"type":"Roof","layers":[{"thickness":"0.0178","material":{"solar_absorptance":"0.78","thermal_absorptance":"0.9","visible_absorptance":"0.78","no_mass":"False","thermal_resistance":"","conductivity":"0.115","density":"513","specific_heat":"1255"}},{"thickness":"0.0254","material":{"solar_absorptance":"0.78","thermal_absorptance":"0.9","visible_absorptance":"0.78","no_mass":"False","thermal_resistance":"","conductivity":"0.1211","density":"593","specific_heat":"2510"}},{"thickness":"0.221604","material":{"solar_absorptance":"0.7","thermal_absorptance":"0.9","visible_absorptance":"0.7","no_mass":"False","thermal_resistance":"","conductivity":"0.049","density":"265","specific_heat":"836.8"}},{"thickness":"0.01271","material":{"solar_absorptance":"0.92","thermal_absorptance":"0.9","visible_absorptance":"0.92","no_mass":"False","thermal_resistance":"","conductivity":"0.16","density":"784.9","specific_heat":"830"}}],"window":{"frame_ratio":"0","g_value":"0.36","overall_u_value":"4.491833333333333"}}]}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction
|
||||
|
||||
printf '\n\nSet Construction:\n'
|
||||
curl -i -X PUT -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"building_names":["Dompark"], "extra_loses_due_to_thermal_bridges":"0.15","indirect_heated_ratio":"0.15","infiltration_rate_for_ventilation_system_off":"0.5","infiltration_rate_for_ventilation_system_on":"0","constructions": [{"name": "189.1-2009 Res 4B Ext Wall Steel-Framed", "type": "Wall", "layers": [{"name": "Layer 1", "thickness": 0, "material": {"id": "12", "name": "MAT-SHEATH", "solar_absorptance": "0.7", "thermal_absorptance": "0.9", "visible_absorptance": "0.7", "no_mass": "True", "thermal_resistance": "0.36256", "conductivity": "", "density": "", "specific_heat": ""}}, {"name": "Layer 2", "thickness": "0.118387", "material": {"id": "3", "name": "Floor Insulation [4]", "solar_absorptance": "0.7", "thermal_absorptance": "0.9", "visible_absorptance": "0.7", "no_mass": "False", "thermal_resistance": "", "conductivity": "0.045", "density": "265", "specific_heat": "836.8"}}, {"name": "Layer 3", "thickness": "0.01271", "material": {"id": "7", "name": "1/2IN Gypsum", "solar_absorptance": "0.92", "thermal_absorptance": "0.9", "visible_absorptance": "0.92", "no_mass": "False", "thermal_resistance": "", "conductivity": "0.16", "density": "784.9", "specific_heat": "830"}}], "window_ratio": "0.3", "window": {"name": "189.1-2009 Nonres 4B Window Nonmetal framing", "frame_ratio": "0", "g_value": "0.35", "overall_u_value": "2.379966666666667"}}, {"name": "189.1-2009 Nonres 4B Ext Slab Unheated - 4in Slab with Carpet", "type": "Ground", "layers": [{"name": "Layer 1", "thickness": "0.1016", "material": {"id": "1", "name": "MAT-CC05 8 HW CONCRETE", "solar_absorptance": "0.7", "thermal_absorptance": "0.9", "visible_absorptance": "0.7", "no_mass": "False", "thermal_resistance": "", "conductivity": "1.311", "density": "2240", "specific_heat": "836.8"}}, {"name": "Layer 2", "thickness": 0, "material": {"id": "16", "name": "CP02 CARPET PAD", "solar_absorptance": "0.7", "thermal_absorptance": "0.9", "visible_absorptance": "0.8", "no_mass": "True", "thermal_resistance": "0.21648", "conductivity": "", "density": "", "specific_heat": ""}}]}, {"name": "189.1-2009 Nonres 4B Roof IEAD", "type": "Roof", "layers": [{"name": "Layer 1", "thickness": "0.0095", "material": {"id": "15", "name": "Roof Membrane", "solar_absorptance": "0.7", "thermal_absorptance": "0.9", "visible_absorptance": "0.7", "no_mass": "False", "thermal_resistance": "", "conductivity": "0.16", "density": "1121.29", "specific_heat": "1460"}}, {"name": "Layer 2", "thickness": "0.210538", "material": {"id": "11", "name": "Roof Insulation [23]", "solar_absorptance": "0.7", "thermal_absorptance": "0.9", "visible_absorptance": "0.7", "no_mass": "False", "thermal_resistance": "", "conductivity": "0.049", "density": "265", "specific_heat": "836.8"}}, {"name": "Layer 3", "thickness": "0.001524", "material": {"id": "14", "name": "Metal Decking", "solar_absorptance": "0.7", "thermal_absorptance": "0.9", "visible_absorptance": "0.3", "no_mass": "False", "thermal_resistance": "", "conductivity": "45.006", "density": "7680", "specific_heat": "418.4"}}]}]}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/construction
|
||||
|
||||
printf '\n\nEnergy Demand:\n'
|
||||
curl -i -X GET -H "Session: {'session_id': 'debug', 'token': 'debug'}" -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/energy-demand
|
||||
|
||||
printf '\n\nUsage catalog entry without parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/usage-catalog/entry
|
||||
|
||||
printf '\n\nUsage catalog entry with wrong parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"name": "non_existing_name"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/usage-catalog/entry
|
||||
|
||||
printf '\n\nUsage catalog entry with correct parameter:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"name": "BA Automotive Facility"}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/usage-catalog/entry
|
||||
|
||||
printf '\n\nUsage catalog names:\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/usage-catalog/names
|
||||
|
||||
printf '\n\nUsage catalog entries :\n'
|
||||
curl -i -X POST -H "Session: {'session_id': 'debug', 'token': 'debug'}" -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/usage-catalog/entries
|
||||
|
||||
printf '\n\nSet Greenery with missing parameters:\n'
|
||||
curl -i -X PUT --header "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"vegetation": {"vegetation_name": "Grass", "soil_thickness": "0.2", "air_gap": "0.0", "soil_name": "Loamy sand", "soil_roughness": "MediumRough", "dry_soil_conductivity": "0.35", "dry_soil_density": "1100", "dry_soil_specific_heat": "1200", "soil_thermal_absorptance": "0.9", "soil_solar_absorptance": "0.7", "soil_visible_absorptance": "0.75", "soil_saturation_volumetric_moisture_content": "0.41", "soil_residual_volumetric_moisture_content": "0.057", "plant_percentages": [{"plant_percentage": "100", "plant_name": "Lawn", "plant_height": "0.06", "plant_leaf_area_index": "1.4", "plant_leaf_reflectivity": "0.1", "plant_leaf_emissivity": "0.9", "plant_minimal_stomatal_resistance": "50", "plant_co2_sequestration": "0", "plant_grows_on": [{"soil_name": "Loam", "soil_roughness": "MediumRough", "soil_dry_conductivity": "0.67", "soil_dry_density": "1100", "soil_dry_specific_heat": "900", "soil_thermal_absortance": "0.9", "soil_solar_absortance": "0.7", "soil_visible_absortance": "0.75", "soil_saturation_volumetric_moisture_content": "0.43", "soil_residual_volumetric_moisture_content": "0.078", "soil_initial_volumetric_moisture_content": "0.1"}]}]}}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery
|
||||
|
||||
printf '\n\nSet Greenery:\n'
|
||||
curl -i -X PUT --header "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"building_names":["Dompark"], "greenery_percentage":"30", "vegetation": {"vegetation_name": "Grass", "soil_thickness": "0.2", "air_gap": "0.0", "soil_name": "Loamy sand", "soil_roughness": "MediumRough", "dry_soil_conductivity": "0.35", "dry_soil_density": "1100", "dry_soil_specific_heat": "1200", "soil_thermal_absorptance": "0.9", "soil_solar_absorptance": "0.7", "soil_visible_absorptance": "0.75", "soil_saturation_volumetric_moisture_content": "0.41", "soil_residual_volumetric_moisture_content": "0.057", "plant_percentages": [{"plant_percentage": "100", "plant_name": "Lawn", "plant_height": "0.06", "plant_leaf_area_index": "1.4", "plant_leaf_reflectivity": "0.1", "plant_leaf_emissivity": "0.9", "plant_minimal_stomatal_resistance": "50", "plant_co2_sequestration": "0", "plant_grows_on": [{"soil_name": "Loam", "soil_roughness": "MediumRough", "soil_dry_conductivity": "0.67", "soil_dry_density": "1100", "soil_dry_specific_heat": "900", "soil_thermal_absortance": "0.9", "soil_solar_absortance": "0.7", "soil_visible_absortance": "0.75", "soil_saturation_volumetric_moisture_content": "0.43", "soil_residual_volumetric_moisture_content": "0.078", "soil_initial_volumetric_moisture_content": "0.1"}]}]}}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/greenery
|
||||
|
||||
printf '\n\nSet Usages with missing parameters:\n'
|
||||
curl -i -X PUT --header "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"building_names":["Dompark"],"usages":[{"name": "BA Convention Center"}, {"name": "BA Multifamily", "percentage": "0.2"}, {"name": "BA Office", "percentage": "0.75"}]}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/usage
|
||||
|
||||
printf '\n\nSet Usages:\n'
|
||||
curl -i -X PUT --header "Session: {'session_id': 'debug', 'token': 'debug'}" -d '{"building_names":["Dompark"],"usages":[{"name": "BA Convention Center", "percentage": "0.05"}, {"name": "BA Multifamily", "percentage": "0.2"}, {"name": "BA Office", "percentage": "0.75"}]}' -H "Content-Type: application/json" http://127.0.0.1:15789/v1.3/usage
|
||||
|
||||
printf '\n\nSession end:\n'
|
||||
curl -i -X PUT -H "Session: {'session_id': 'debug', 'token': 'debug'}" http://127.0.0.1:15789/v1.3/session/end
|
||||
|
||||
printf '\n\nRepeat session end:\n'
|
||||
curl -i -X PUT -H "Session: {'session_id': 'debug', 'token': 'debug'}" http://127.0.0.1:15789/v1.3/session/end
|
||||
|
||||
printf '\n'
|
|
@ -1,124 +0,0 @@
|
|||
import json
|
||||
from .base_test import BaseTest, arrange
|
||||
import unittest
|
||||
from hub_api.helpers.auth import generate_auth_token
|
||||
|
||||
ordered, compare = arrange()
|
||||
unittest.defaultTestLoader.sortTestMethodsUsing = compare
|
||||
|
||||
|
||||
class UserTest(BaseTest):
|
||||
"""
|
||||
Tests for User API endpoints
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
# Call setUp from parent
|
||||
super().setUpClass()
|
||||
cls.user_dict = {"user": {
|
||||
"name": "Test User",
|
||||
"email": "testuser@gmail.com",
|
||||
"password": "TestUser@12345",
|
||||
"role": "Admin",
|
||||
}}
|
||||
cls.token = generate_auth_token(cls.user_dict)
|
||||
|
||||
@ordered
|
||||
def test_create_user_by_non_admin(self):
|
||||
# When
|
||||
res = self.client.post('/v1.4/user', data=json.dumps(self.user_dict['user']))
|
||||
# Then
|
||||
self.assertEqual('Invalid payload', res.json['messages'])
|
||||
self.assertEqual(400, res.status_code)
|
||||
|
||||
|
||||
@ordered
|
||||
def test_create_user_by_admin(self):
|
||||
# When
|
||||
res = self.client.post('/v1.4/user',
|
||||
headers={
|
||||
'Content-Type': 'application/json', 'Authorization': 'Bearer ' + str(self.token)
|
||||
},
|
||||
data=json.dumps(self.user_dict['user']))
|
||||
# Then
|
||||
user = res.json
|
||||
self.assertEqual(201, res.status_code)
|
||||
self.assertEqual(type(user['user']), dict)
|
||||
self.assertEqual(user['user']['email'], self.user_dict['user']['email'])
|
||||
self.assertEqual(user['user']['role'], self.user_dict['user']['role'])
|
||||
|
||||
@ordered
|
||||
def test_create_user_with_existing_email(self):
|
||||
# When
|
||||
res = self.client.post('/v1.4/user',
|
||||
headers={
|
||||
'Content-Type': 'application/json', 'Authorization': 'Bearer ' + str(self.token)
|
||||
},
|
||||
data=json.dumps(self.user_dict['user']))
|
||||
# Then
|
||||
self.assertEqual('user with testuser@gmail.com email already exists', res.json['message'])
|
||||
self.assertEqual(400, res.status_code)
|
||||
|
||||
@ordered
|
||||
def test_create_user_with_weak_password(self):
|
||||
# When
|
||||
self.user_dict['user']['password'] = '1234'
|
||||
self.user_dict['user']['email'] = 'new@gmail.com'
|
||||
res = self.client.post('/v1.4/user',
|
||||
headers={
|
||||
'Content-Type': 'application/json', 'Authorization': 'Bearer ' + str(self.token)
|
||||
},
|
||||
data=json.dumps(self.user_dict['user']))
|
||||
# Then
|
||||
self.assertEqual('Sorry an error occurred while creating user', res.json['err_msg'])
|
||||
self.assertEqual(400, res.status_code)
|
||||
|
||||
|
||||
@ordered
|
||||
def test_login_user_with_wrong_credential(self):
|
||||
# When
|
||||
res = self.client.post('/v1.4/user/login',
|
||||
headers={
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
data=json.dumps({'email': 'wrong@gmail.com', 'password': 'wrong'}))
|
||||
|
||||
# Then
|
||||
message = res.json
|
||||
self.assertEqual('user not found', message['message'])
|
||||
self.assertEqual(400, res.status_code)
|
||||
|
||||
@ordered
|
||||
def test_login_user_with_correct_credential(self):
|
||||
# When
|
||||
self.user_dict['user']['password'] = 'TestUser@12345'
|
||||
self.user_dict['user']['email'] = 'testuser@gmail.com'
|
||||
login_data = {
|
||||
"email": self.user_dict['user']['email'],
|
||||
"password": self.user_dict['user']['password']
|
||||
}
|
||||
res = self.client.post('/v1.4/user/login', headers={'Content-Type': 'application/json'},
|
||||
data=json.dumps(login_data))
|
||||
|
||||
# Then
|
||||
user = res.json
|
||||
self.assertEqual(user['user']['email'], self.user_dict['user']['email'])
|
||||
self.assertEqual(user['user']['role'], self.user_dict['user']['role'])
|
||||
self.assertIsNotNone(user['token'])
|
||||
self.assertEqual(200, res.status_code)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls) -> None:
|
||||
# Call tearDown from parent
|
||||
super().tearDownClass()
|
||||
|
||||
|
||||
def suite():
|
||||
test_suite = unittest.TestSuite()
|
||||
test_suite.addTest(unittest.TestLoader(
|
||||
).loadTestsFromTestCase(UserTest))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.TextTestRunner(verbosity=2).run(suite())
|
|
@ -1,3 +0,0 @@
|
|||
from .misc import validate_hp_model
|
||||
from .hp_simulator import HeatPumpSimulator
|
||||
from .misc import expand_energy_demand
|
|
@ -1,43 +0,0 @@
|
|||
"""
|
||||
HeatPumpSimulator: Module for running simulations
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
from pathlib import Path
|
||||
from typing import Dict
|
||||
|
||||
from exports.energy_systems_factory import EnergySystemsExportFactory
|
||||
from imports.energy_systems_factory import EnergySystemsFactory
|
||||
|
||||
|
||||
class HeatPumpSimulator:
|
||||
|
||||
def __init__(self, city, user_input: Dict):
|
||||
"""
|
||||
:param user_input: the user parameters for running simulation
|
||||
"""
|
||||
|
||||
|
||||
self._user_input = user_input
|
||||
self._hp_type = user_input['HeatPumpType'].replace(" ", "_").lower()
|
||||
# file to have results after simulation is run
|
||||
self._city = city
|
||||
EnergySystemsFactory(user_input['HeatPumpType'].lower(), self._city).enrich()
|
||||
|
||||
def run_hp_simulation(self) -> str:
|
||||
"""
|
||||
Runs heat pump simulation and dumps output
|
||||
in self._output_path
|
||||
:return: None
|
||||
"""
|
||||
hp_type = 'water' if 'water' in self._hp_type else 'air'
|
||||
del self._user_input['HeatPumpType']
|
||||
del self._user_input['EnergyDemand']
|
||||
model = self._user_input.pop('HeatPumpModel')
|
||||
energy_demand_path = Path(Path(__file__).parent.parent / "data/energy_demand.txt")
|
||||
return EnergySystemsExportFactory(city=self._city,
|
||||
user_input=self._user_input,
|
||||
hp_model=model,
|
||||
output_path=None,
|
||||
sim_type=self._user_input['SimType'],
|
||||
demand_path=energy_demand_path).export(hp_type)
|
|
@ -1,45 +0,0 @@
|
|||
"""
|
||||
Miscellaneous
|
||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||
Copyright © 2022 Project Author Peter Yefi peteryefi@gmail.com
|
||||
"""
|
||||
from typing import List
|
||||
from pathlib import Path
|
||||
import numpy as np
|
||||
|
||||
|
||||
hp_models = {
|
||||
'air_source': ['012', '015', '018', '023', '030', '033', '037', '044', '047', '057', '070', '087', '097', '102',
|
||||
'120', '130', '140'],
|
||||
'water_to_water': ['ClimateMaster 156 kW', 'ClimateMaster 256 kW', 'ClimateMaster 335 kW']
|
||||
}
|
||||
|
||||
|
||||
def validate_hp_model(hp_type: str, model: str) -> bool:
|
||||
"""
|
||||
Validates the HP model parameter provided by users
|
||||
for running insel simulation
|
||||
:param hp_type: the type of heat pump: air source or
|
||||
water to water
|
||||
:param model: the model of heat pump
|
||||
:return: bool
|
||||
"""
|
||||
if 'air' in hp_type.lower():
|
||||
if model in hp_models['air_source']:
|
||||
return True
|
||||
elif 'water' in hp_type.lower():
|
||||
if model in hp_models['water_to_water']:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def expand_energy_demand(hourly_energy_demand: List[float]):
|
||||
"""
|
||||
Replicates each value in the list 11 times and persist the values to a file
|
||||
:param hourly_energy_demand: a list of hourly energy demand data
|
||||
"""
|
||||
energy_demand = Path(Path(__file__).parent.parent / "data/energy_demand.txt")
|
||||
with open(energy_demand, 'w') as demand_file:
|
||||
repeated_demand_values = np.repeat(hourly_energy_demand, 12).tolist()
|
||||
for demand in repeated_demand_values:
|
||||
demand_file.write("%.6f\n" % demand)
|
Loading…
Reference in New Issue
Block a user