Removed city attachment to session. City is read from the DB
This commit is contained in:
parent
025fe02f71
commit
f893959c78
|
@ -2,11 +2,11 @@
|
||||||
City info
|
City info
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||||
|
Code contributors: Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
from flask import Response, request, g
|
from flask import Response, request, g
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
from hub_api.helpers.session_helper import refresh_session
|
|
||||||
from hub_api.helpers.auth import role_required
|
from hub_api.helpers.auth import role_required
|
||||||
from persistence.models import UserRoles
|
from persistence.models import UserRoles
|
||||||
from hub_logger import logger
|
from hub_logger import logger
|
||||||
|
@ -14,21 +14,17 @@ from imports.geometry_factory import GeometryFactory
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from imports.db_factory import DBFactory
|
from imports.db_factory import DBFactory
|
||||||
import os
|
import os
|
||||||
|
from hub_api.config import Config
|
||||||
|
|
||||||
|
|
||||||
class CityInfo(Resource):
|
class CityInfo(Resource, Config):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
super().__init__()
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
@role_required([UserRoles.Admin.value])
|
@role_required([UserRoles.Admin.value])
|
||||||
def get():
|
def get(self, city_id):
|
||||||
session = refresh_session(request)
|
city = self.get_city(city_id)
|
||||||
if session is None:
|
|
||||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
|
||||||
headers = session.headers
|
|
||||||
|
|
||||||
city = session.city
|
|
||||||
# TODO: this is only for dompark project and need to be removed in future versions.
|
# TODO: this is only for dompark project and need to be removed in future versions.
|
||||||
floor_area = 0
|
floor_area = 0
|
||||||
wall_construction = 'unknown'
|
wall_construction = 'unknown'
|
||||||
|
@ -71,11 +67,11 @@ class CityInfo(Resource):
|
||||||
}
|
}
|
||||||
|
|
||||||
buildings = [building_dic]
|
buildings = [building_dic]
|
||||||
response = {'city_name': 'Montreal',
|
response = {'city_name': city.name,
|
||||||
'climate_reference_city': str(city.climate_reference_city),
|
'climate_reference_city': str(city.climate_reference_city),
|
||||||
'buildings': buildings
|
'buildings': buildings
|
||||||
}
|
}
|
||||||
return Response(json.dumps(response), headers=headers)
|
return Response(json.dumps(response), status=200)
|
||||||
|
|
||||||
|
|
||||||
class City(Resource):
|
class City(Resource):
|
||||||
|
@ -83,7 +79,7 @@ class City(Resource):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@role_required([UserRoles.Admin.value])
|
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
||||||
def post(self):
|
def post(self):
|
||||||
allowed_ext = {'gml', '3dm', 'xml', 'obj', 'rhino'}
|
allowed_ext = {'gml', '3dm', 'xml', 'obj', 'rhino'}
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
"""
|
||||||
|
Config
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2023 Project Peter Yefi peteryefi@gmail.com
|
||||||
|
"""
|
||||||
|
from exports.db_factory import DBFactory as CityExportFactory
|
||||||
|
import os
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.factory = CityExportFactory(db_name='hub_prod', app_env='PROD',
|
||||||
|
dotenv_path="{}/.env".format(os.path.expanduser('~')))
|
||||||
|
|
||||||
|
def get_city(self, city_id):
|
||||||
|
city_obj = self.factory.get_city(city_id)
|
||||||
|
city = pickle.loads(city_obj.city)
|
||||||
|
for building in city.buildings:
|
||||||
|
building.heated = True
|
||||||
|
building.cooled = True
|
||||||
|
building.attic_heated = 0
|
||||||
|
building.basement_heated = 0
|
||||||
|
for surface in building.surfaces:
|
||||||
|
surface.swr = 0.2
|
||||||
|
return city
|
|
@ -2,29 +2,27 @@
|
||||||
Construction
|
Construction
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||||
|
Code contributors: Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from flask import Response, request
|
from flask import Response, request
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
|
from hub_api.config import Config
|
||||||
from city_model_structure.building_demand.layer import Layer
|
from city_model_structure.building_demand.layer import Layer
|
||||||
from city_model_structure.building_demand.material import Material
|
from city_model_structure.building_demand.material import Material
|
||||||
from hub_api.helpers.session_helper import refresh_session
|
from persistence.models import UserRoles
|
||||||
|
from hub_api.helpers.auth import role_required
|
||||||
|
|
||||||
|
|
||||||
class Construction(Resource):
|
class Construction(Resource, Config):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
super().__init__()
|
||||||
|
|
||||||
@staticmethod
|
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
||||||
def put():
|
def put(self, city_id):
|
||||||
session = refresh_session(request)
|
city = self.get_city(city_id)
|
||||||
if session is None:
|
|
||||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
|
||||||
headers = session.headers
|
|
||||||
city = session.city
|
|
||||||
try:
|
try:
|
||||||
building_names = request.json['building_names']
|
building_names = request.json['building_names']
|
||||||
constructions = request.json['constructions']
|
constructions = request.json['constructions']
|
||||||
|
@ -73,6 +71,6 @@ class Construction(Resource):
|
||||||
response = {'result': 'succeed'}
|
response = {'result': 'succeed'}
|
||||||
except KeyError as ex:
|
except KeyError as ex:
|
||||||
response = {'error': f'Mandatory parameter {ex} is missing'}
|
response = {'error': f'Mandatory parameter {ex} is missing'}
|
||||||
return Response(json.dumps(response), headers=headers, status=400)
|
return Response(json.dumps(response), status=400)
|
||||||
|
|
||||||
return Response(json.dumps(response), headers=headers)
|
return Response(json.dumps(response), status=200)
|
||||||
|
|
|
@ -78,7 +78,131 @@ paths:
|
||||||
$ref: '#/components/schemas/ApiResponse'
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
security:
|
security:
|
||||||
- BearerAuth: []
|
- BearerAuth: []
|
||||||
|
/v1.4/heat-pump/{city_id}:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- heatpump
|
||||||
|
summary: Create a heat pump simulation
|
||||||
|
operationId: createHeatpump
|
||||||
|
description: heatpump simulation with existing catalog data
|
||||||
|
parameters:
|
||||||
|
- in: header
|
||||||
|
name: appId
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: the Id of the application access this API
|
||||||
|
- in: path
|
||||||
|
name: city_id
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
required: true
|
||||||
|
description: Numeric ID of the city to get
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: '#/components/schemas/HeatPump'
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: Heatpump simulation created successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/HeatPumpRes'
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
'404':
|
||||||
|
description: Not found
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
'403':
|
||||||
|
description: Forbidden
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
'401':
|
||||||
|
description: Unauthorized
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
'500':
|
||||||
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: [ ]
|
||||||
|
/v1.4/city/{city_id}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- city
|
||||||
|
summary: Get a city
|
||||||
|
operationId: getCity
|
||||||
|
description: Retrieve a city with a given city ID
|
||||||
|
parameters:
|
||||||
|
- in: header
|
||||||
|
name: appId
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
description: the ID of the application access this API
|
||||||
|
- in: path
|
||||||
|
name: city_id
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
required: true
|
||||||
|
description: Numeric ID of the city to get
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: City created successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/City'
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
'404':
|
||||||
|
description: City not found
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
'403':
|
||||||
|
description: Forbidden
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
'401':
|
||||||
|
description: Unauthorized
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
'500':
|
||||||
|
description: Internal server error
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ApiResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: [ ]
|
||||||
/v1.4/user:
|
/v1.4/user:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
|
@ -268,6 +392,86 @@ components:
|
||||||
updated:
|
updated:
|
||||||
type: string
|
type: string
|
||||||
example: 2023-01-15 18:40:54.64877
|
example: 2023-01-15 18:40:54.64877
|
||||||
|
HeatPump:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
StartYear:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 10
|
||||||
|
EndYear:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 10
|
||||||
|
MaximumHPEnergyInput:
|
||||||
|
type: float
|
||||||
|
example: 9.8382
|
||||||
|
HoursOfStorageAtMaxDemand:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 9
|
||||||
|
BuildingSuppTemp:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 40
|
||||||
|
TemperatureDifference:
|
||||||
|
type: float
|
||||||
|
example: 9.8382
|
||||||
|
FuelLHV:
|
||||||
|
type: float
|
||||||
|
example: 9.8382
|
||||||
|
FuelPrice:
|
||||||
|
type: float
|
||||||
|
example: 9.8382
|
||||||
|
FuelEF:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
example: 40
|
||||||
|
FuelDensity:
|
||||||
|
type: float
|
||||||
|
example: 9.8382
|
||||||
|
HPSupTemp:
|
||||||
|
type: float
|
||||||
|
example: 9.8382
|
||||||
|
HeatPumpType:
|
||||||
|
type: string
|
||||||
|
example: Water to Water HP
|
||||||
|
enum:
|
||||||
|
- Water to Water HP
|
||||||
|
- Air Source HP
|
||||||
|
HeatPumpModel:
|
||||||
|
type: string
|
||||||
|
example: Water to Water HP
|
||||||
|
enum:
|
||||||
|
- ClimateMaster 156 kW
|
||||||
|
- ClimateMaster 256 kW
|
||||||
|
- ClimateMaster 335 kW
|
||||||
|
- 012
|
||||||
|
- 015
|
||||||
|
- 018
|
||||||
|
- 023
|
||||||
|
- 030
|
||||||
|
- 033
|
||||||
|
- 037
|
||||||
|
- 044
|
||||||
|
- 047
|
||||||
|
- 057
|
||||||
|
- 070
|
||||||
|
- 087
|
||||||
|
- 097
|
||||||
|
- 102
|
||||||
|
- 120
|
||||||
|
- 130
|
||||||
|
- 140
|
||||||
|
SimType:
|
||||||
|
type: int
|
||||||
|
example: 1
|
||||||
|
format: int64
|
||||||
|
EnergyDemand:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: float
|
||||||
|
example: [ 610.610, 754.746, 288.338 ]
|
||||||
User:
|
User:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -289,6 +493,29 @@ components:
|
||||||
enum:
|
enum:
|
||||||
- Admin
|
- Admin
|
||||||
- Hub_Reader
|
- Hub_Reader
|
||||||
|
HeatPumpRes:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
hourly_electricity_demand:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
daily_electricity_demand:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
monthly_electricity_demand:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
daily_fossil_consumption:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
monthly_fossil_consumption:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
Login:
|
Login:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -325,14 +552,14 @@ components:
|
||||||
application/xml:
|
application/xml:
|
||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/User'
|
$ref: '#/components/schemas/User'
|
||||||
UserArray:
|
CityArray:
|
||||||
description: List of user object
|
description: List of city object
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/User'
|
$ref: '#/components/schemas/City'
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
BearerAuth:
|
BearerAuth:
|
||||||
type: http
|
type: http
|
||||||
|
|
|
@ -5,13 +5,15 @@ from pathlib import Path
|
||||||
from geomeppy import IDF
|
from geomeppy import IDF
|
||||||
import os
|
import os
|
||||||
import glob
|
import glob
|
||||||
from hub_api.helpers.session_helper import refresh_session
|
|
||||||
import hub_api.helpers.session_helper as sh
|
import hub_api.helpers.session_helper as sh
|
||||||
import helpers.constants as cte
|
import helpers.constants as cte
|
||||||
import csv
|
import csv
|
||||||
|
from hub_api.helpers.auth import role_required
|
||||||
|
from persistence.models import UserRoles
|
||||||
|
from hub_api.config import Config
|
||||||
|
|
||||||
|
|
||||||
class EnergyDemand(Resource):
|
class EnergyDemand(Resource, Config):
|
||||||
_THERMOSTAT = 'HVACTEMPLATE:THERMOSTAT'
|
_THERMOSTAT = 'HVACTEMPLATE:THERMOSTAT'
|
||||||
_IDEAL_LOAD_AIR_SYSTEM = 'HVACTEMPLATE:ZONE:IDEALLOADSAIRSYSTEM'
|
_IDEAL_LOAD_AIR_SYSTEM = 'HVACTEMPLATE:ZONE:IDEALLOADSAIRSYSTEM'
|
||||||
_SURFACE = 'BUILDINGSURFACE:DETAILED'
|
_SURFACE = 'BUILDINGSURFACE:DETAILED'
|
||||||
|
@ -92,6 +94,7 @@ class EnergyDemand(Resource):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# this class is mostly hardcoded, as is intended to be used only for Dompark project,
|
# this class is mostly hardcoded, as is intended to be used only for Dompark project,
|
||||||
# other projects should use the normal idf workflow instead.
|
# other projects should use the normal idf workflow instead.
|
||||||
|
super().__init__()
|
||||||
self._output_path = Path(Path(__file__).parent.parent / 'tmp').resolve()
|
self._output_path = Path(Path(__file__).parent.parent / 'tmp').resolve()
|
||||||
self._data_path = Path(Path(__file__).parent.parent / 'data').resolve()
|
self._data_path = Path(Path(__file__).parent.parent / 'data').resolve()
|
||||||
self._city = None
|
self._city = None
|
||||||
|
@ -314,13 +317,12 @@ class EnergyDemand(Resource):
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def get(self):
|
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
||||||
session = refresh_session(request)
|
def get(self, city_id):
|
||||||
if session is None:
|
payload = request.get_json()
|
||||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
self._city = self.get_city(city_id)
|
||||||
headers = session.headers
|
|
||||||
self._city = session.city
|
self._greenery_percentage = round(float(payload['greenery_percentage']) / 10) * 10
|
||||||
self._greenery_percentage = round(float(session.greenery_percentage) / 10) * 10
|
|
||||||
output_file = str((self._output_path / 'dompark.idf').resolve())
|
output_file = str((self._output_path / 'dompark.idf').resolve())
|
||||||
idd_file = str((self._data_path / 'energy+.idd').resolve())
|
idd_file = str((self._data_path / 'energy+.idd').resolve())
|
||||||
epw_file = str((self._data_path / 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve())
|
epw_file = str((self._data_path / 'CAN_PQ_Montreal.Intl.AP.716270_CWEC.epw').resolve())
|
||||||
|
@ -391,4 +393,4 @@ class EnergyDemand(Resource):
|
||||||
'lighting_demand': lighting,
|
'lighting_demand': lighting,
|
||||||
'appliances_demand': appliances
|
'appliances_demand': appliances
|
||||||
}
|
}
|
||||||
return Response(json.dumps(response), headers=headers)
|
return Response(json.dumps(response), status=200)
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
Geometry
|
Geometry
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||||
|
Code contributors: Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
from flask import make_response, send_file
|
||||||
from flask import make_response, send_file, request, Response
|
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from hub_api.helpers.auth import role_required
|
||||||
from hub_api.helpers.session_helper import refresh_session
|
from persistence.models import UserRoles
|
||||||
|
|
||||||
|
|
||||||
class Geometry(Resource):
|
class Geometry(Resource):
|
||||||
|
@ -17,13 +17,9 @@ class Geometry(Resource):
|
||||||
data_path = (Path(__file__).parent.parent / 'data').resolve()
|
data_path = (Path(__file__).parent.parent / 'data').resolve()
|
||||||
self._gtlf_path = (Path(data_path / 'DomparkBuilding.gltf')).resolve()
|
self._gtlf_path = (Path(data_path / 'DomparkBuilding.gltf')).resolve()
|
||||||
|
|
||||||
|
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
||||||
def get(self):
|
def get(self):
|
||||||
session = refresh_session(request)
|
|
||||||
if session is None:
|
|
||||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
|
||||||
response = make_response(send_file(self._gtlf_path,
|
response = make_response(send_file(self._gtlf_path,
|
||||||
as_attachment=True,
|
as_attachment=True,
|
||||||
mimetype='model/gltf+json, model/gltf-binary'))
|
mimetype='model/gltf+json, model/gltf-binary'))
|
||||||
response.headers['session_id'] = session.id
|
|
||||||
response.headers['token'] = session.token
|
|
||||||
return response
|
return response
|
||||||
|
|
|
@ -2,36 +2,35 @@
|
||||||
Greenery
|
Greenery
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
Copyright © 2022 Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
||||||
|
Code contributors: Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from flask import Response, request
|
from flask import Response, request
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
|
from hub_api.config import Config
|
||||||
from city_model_structure.greenery.vegetation import Vegetation
|
from city_model_structure.greenery.vegetation import Vegetation
|
||||||
from city_model_structure.greenery.soil import Soil
|
from city_model_structure.greenery.soil import Soil
|
||||||
from city_model_structure.greenery.plant import Plant
|
from city_model_structure.greenery.plant import Plant
|
||||||
import helpers.constants as cte
|
import helpers.constants as cte
|
||||||
from hub_api.helpers.session_helper import refresh_session
|
from persistence.models import UserRoles
|
||||||
|
from hub_api.helpers.auth import role_required
|
||||||
|
|
||||||
|
|
||||||
class Greenery(Resource):
|
class Greenery(Resource, Config):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
super().__init__()
|
||||||
|
|
||||||
@staticmethod
|
@role_required([UserRoles.Admin.value])
|
||||||
def put():
|
def put(self, city_id):
|
||||||
session = refresh_session(request)
|
|
||||||
if session is None:
|
city = self.get_city(city_id)
|
||||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
|
||||||
headers = session.headers
|
|
||||||
city = session.city
|
|
||||||
try:
|
try:
|
||||||
session.greenery_percentage = request.json['greenery_percentage']
|
greenery_percentage = request.json['greenery_percentage']
|
||||||
if session.greenery_percentage == 0:
|
if greenery_percentage == 0:
|
||||||
response = {'result': 'succeed'}
|
response = {'result': 'succeed'}
|
||||||
return Response(json.dumps(response), headers=headers)
|
return Response(json.dumps(response), status=200)
|
||||||
|
|
||||||
building_names = request.json['building_names']
|
building_names = request.json['building_names']
|
||||||
vegetation_requested = request.json['vegetation']
|
vegetation_requested = request.json['vegetation']
|
||||||
|
@ -80,6 +79,6 @@ class Greenery(Resource):
|
||||||
response = {'result': 'succeed'}
|
response = {'result': 'succeed'}
|
||||||
except KeyError as ex:
|
except KeyError as ex:
|
||||||
response = {'error': f'Mandatory parameter {ex} is missing'}
|
response = {'error': f'Mandatory parameter {ex} is missing'}
|
||||||
return Response(json.dumps(response), headers=headers, status=400)
|
return Response(json.dumps(response), status=400)
|
||||||
|
|
||||||
return Response(json.dumps(response), headers=headers)
|
return Response(json.dumps(response))
|
||||||
|
|
|
@ -5,10 +5,8 @@ Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from flask import request, Response
|
from flask import request, Response
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
|
|
||||||
from catalog_factories.data_models.greenery.plant import Plant
|
from catalog_factories.data_models.greenery.plant import Plant
|
||||||
from catalog_factories.data_models.greenery.soil import Soil
|
from catalog_factories.data_models.greenery.soil import Soil
|
||||||
from catalog_factories.data_models.greenery.vegetation import Vegetation
|
from catalog_factories.data_models.greenery.vegetation import Vegetation
|
||||||
|
|
|
@ -5,77 +5,35 @@ Copyright © 2022 Project Author Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from flask import send_file, request, make_response, Response
|
from flask import request, Response
|
||||||
from flask_apispec import use_kwargs, doc
|
from hub_api.config import Config
|
||||||
from flask_apispec.views import MethodResource
|
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
from marshmallow import Schema, fields
|
|
||||||
from hub_api.helpers.auth import role_required
|
from hub_api.helpers.auth import role_required
|
||||||
from hub_api.helpers.session_helper import refresh_session
|
|
||||||
from utils import HeatPumpSimulator
|
from utils import HeatPumpSimulator
|
||||||
from utils import validate_hp_model
|
from utils import validate_hp_model
|
||||||
from persistence.models import UserRoles
|
from persistence.models import UserRoles
|
||||||
|
from utils import expand_energy_demand
|
||||||
|
from hub_logger import logger
|
||||||
|
|
||||||
|
|
||||||
class HeatPumpPostData(Schema):
|
class HeatPump(Config, Resource):
|
||||||
"""
|
|
||||||
Defines post data for heat-pump simulation
|
|
||||||
"""
|
|
||||||
StartYear = fields.Integer(required=True, description='Start year for simulation data')
|
|
||||||
EndYear = fields.Integer(required=True, description='End year for simulation data')
|
|
||||||
MaximumHPEnergyInput = fields.Float(required=True, description='Maximum heat pump energy input')
|
|
||||||
HoursOfStorageAtMaxDemand = fields.Integer(required=True, description='Hours of storage at maximum demand')
|
|
||||||
BuildingSuppTemp = fields.Integer(required=True, description='Building supply temperature')
|
|
||||||
TemperatureDifference = fields.Float(required=True, description='Temperature difference')
|
|
||||||
FuelLHV = fields.Float(required=True, description='Fuel LHV')
|
|
||||||
FuelPrice = fields.Float(required=True, description='Fuel price')
|
|
||||||
FuelEF = fields.Integer(required=True, description='Fuel EF')
|
|
||||||
FuelDensity = fields.Float(required=True, description='Fuel Density')
|
|
||||||
HPSupTemp = fields.Float(required=True, description='Heat pump supply temperature')
|
|
||||||
HeatPumpType = fields.String(required=True, description='Type of Heat pump',
|
|
||||||
enum=['Water to Water HP', 'Air Source HP'])
|
|
||||||
HeatPumpModel = fields.String(required=True, description='Model of heat pump to run simulation for',
|
|
||||||
enum=['ClimateMaster 156 kW', 'ClimateMaster 256 kW', 'ClimateMaster 335 kW',
|
|
||||||
'012', '015', '018', '023', '030', '033', '037', '044', '047', '057', '070',
|
|
||||||
'087', '097', '102', '120', '130', '140'])
|
|
||||||
SimType = fields.Integer(required=True, description='Series or Parallel simulation [0 for series, 1 for parallel',
|
|
||||||
enum=[0, 1])
|
|
||||||
|
|
||||||
|
|
||||||
class HeatPump(MethodResource, Resource):
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
super().__init__()
|
||||||
|
|
||||||
@doc(description='Heat pump simulation run', tags=['HeatPump'])
|
|
||||||
@use_kwargs(HeatPumpPostData)
|
|
||||||
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
||||||
def post(self, **kwargs):
|
def post(self, city_id):
|
||||||
session = refresh_session(request)
|
payload = request.get_json()
|
||||||
if session is None:
|
city = self.get_city(city_id)
|
||||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
if validate_hp_model(payload['HeatPumpType'], payload['HeatPumpModel']):
|
||||||
city = session.city
|
# expand energy demand values
|
||||||
if validate_hp_model(kwargs['HeatPumpType'], kwargs['HeatPumpModel']):
|
expand_energy_demand(payload['EnergyDemand'])
|
||||||
try:
|
try:
|
||||||
# Run simulation and return output file here
|
# Run simulation and return output file here
|
||||||
hp_simulator = HeatPumpSimulator(city, kwargs)
|
hp_simulator = HeatPumpSimulator(city, payload)
|
||||||
result_file = hp_simulator.run_hp_simulation()
|
results = hp_simulator.run_hp_simulation()
|
||||||
response = self._send_response(result_file, session)
|
return Response(json.dumps(results), status=200)
|
||||||
return response
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print(err)
|
logger.error(err)
|
||||||
return Response(json.dumps({'error_message': 'Sorry an error occurred while running HP Simulation'}))
|
return Response(json.dumps({'error_message': 'Sorry an error occurred while running HP Simulation'}))
|
||||||
else:
|
else:
|
||||||
return Response(json.dumps({'error_message': 'Wrong heat pump type/model combination'}), status=400)
|
return Response(json.dumps({'error_message': 'Wrong heat pump type/model combination'}), status=400)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _send_response(result_file, session):
|
|
||||||
"""
|
|
||||||
Sends insel results file after simulation
|
|
||||||
:param result_file: the insel output file
|
|
||||||
:param session: session variable
|
|
||||||
:return CSV output file
|
|
||||||
"""
|
|
||||||
response = make_response(send_file(result_file, as_attachment=True, mimetype='text/csv'))
|
|
||||||
response.headers['session_id'] = session.id
|
|
||||||
response.headers['token'] = session.token
|
|
||||||
return response
|
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
"""
|
||||||
|
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 datetime import datetime, timedelta, timezone
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from jwt import JWT, jwk_from_pem
|
from jwt import JWT, jwk_from_pem
|
||||||
|
@ -48,14 +54,11 @@ def role_required(roles: [str]):
|
||||||
try:
|
try:
|
||||||
token = request.headers['Authorization'].split()[1]
|
token = request.headers['Authorization'].split()[1]
|
||||||
user = validate_auth_token(token)
|
user = validate_auth_token(token)
|
||||||
|
|
||||||
if user is None:
|
if user is None:
|
||||||
return {'messages': 'You have not been authenticated'}, 401
|
return {'messages': 'You have not been authenticated'}, 401
|
||||||
allowed = auth_module(user['user'])
|
allowed = auth_module(user['user'])
|
||||||
|
|
||||||
if user['user']['role'] == UserRoles.Admin.value and 'localhost' not in request.headers['Host']:
|
if user['user']['role'] == UserRoles.Admin.value and 'localhost' not in request.headers['Host']:
|
||||||
allowed = False
|
allowed = False
|
||||||
|
|
||||||
if not allowed:
|
if not allowed:
|
||||||
return {'messages': 'You are not authorized'}, 403
|
return {'messages': 'You are not authorized'}, 403
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
|
|
|
@ -2,19 +2,23 @@
|
||||||
LCA
|
LCA
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2021 Project Author name Atiya
|
Copyright © 2021 Project Author name Atiya
|
||||||
|
Code contributors: Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
from flask import request, Response
|
from flask import Response
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
from lca_calculations import LcaCalculations
|
from lca_calculations import LcaCalculations
|
||||||
from hub_api.helpers.session_helper import refresh_session
|
|
||||||
from itertools import groupby
|
from itertools import groupby
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
from hub_api.helpers.auth import role_required
|
||||||
|
from hub_api.config import Config
|
||||||
|
from persistence.models import UserRoles
|
||||||
|
|
||||||
|
|
||||||
class MaterialLCACatalog(Resource):
|
|
||||||
|
class MaterialLCACatalog(Resource, Config):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
super().__init__()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_lca_value(city, nrel_id = None):
|
def get_lca_value(city, nrel_id = None):
|
||||||
|
@ -56,40 +60,30 @@ class MaterialLCACatalog(Resource):
|
||||||
return material.embodied_carbon, material.id, material.type, material.name, material.density
|
return material.embodied_carbon, material.id, material.type, material.name, material.density
|
||||||
# return material.embodied_carbon
|
# return material.embodied_carbon
|
||||||
|
|
||||||
|
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
||||||
|
def get(self, city_id):
|
||||||
def get(self):
|
city = self.get_city(city_id)
|
||||||
session = refresh_session(request)
|
|
||||||
if session is None:
|
|
||||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
|
||||||
headers = session.headers
|
|
||||||
city = session.city
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return Response(json.dumps(self.get_lca_value(city)), headers=headers)
|
return Response(json.dumps(self.get_lca_value(city)), status=200)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
response = {'error': f'No Catalog Available'}
|
response = {'err_msg': f'No Catalog Available'}
|
||||||
return Response(json.dumps(response), headers=headers, status=400)
|
return Response(json.dumps(response), status=400)
|
||||||
|
|
||||||
|
|
||||||
class MaterialLCACalculations(Resource):
|
class MaterialLCACalculations(Resource, Config):
|
||||||
"""
|
"""
|
||||||
LCA class
|
LCA class
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
super().__init__()
|
||||||
|
|
||||||
@staticmethod
|
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
||||||
def get():
|
def get(self, city_id):
|
||||||
"""
|
"""
|
||||||
Auto-method for processing the lca request
|
Auto-method for processing the lca request
|
||||||
:return: lca demand
|
:return: lca demand
|
||||||
"""
|
"""
|
||||||
session = refresh_session(request)
|
city = self.get_city(city_id)
|
||||||
if session is None:
|
|
||||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
|
||||||
headers = session.headers
|
|
||||||
city = session.city
|
|
||||||
|
|
||||||
materials_lca = {'Wall': [], 'Ground': [], 'Roof': []}
|
materials_lca = {'Wall': [], 'Ground': [], 'Roof': []}
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
|
@ -131,4 +125,4 @@ class MaterialLCACalculations(Resource):
|
||||||
total_embodied_carbon['end_of_life_carbon'] = sum_end_of_life
|
total_embodied_carbon['end_of_life_carbon'] = sum_end_of_life
|
||||||
materials_embodied_carbon[key].append(total_embodied_carbon)
|
materials_embodied_carbon[key].append(total_embodied_carbon)
|
||||||
|
|
||||||
return Response(json.dumps(materials_embodied_carbon), headers=headers)
|
return Response(json.dumps(materials_embodied_carbon), status=200)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
Usage
|
Usage
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||||
|
Code contributors: Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
@ -14,22 +15,22 @@ from city_model_structure.building_demand.lighting import Lighting
|
||||||
from city_model_structure.building_demand.occupancy import Occupancy
|
from city_model_structure.building_demand.occupancy import Occupancy
|
||||||
from city_model_structure.building_demand.thermal_control import ThermalControl
|
from city_model_structure.building_demand.thermal_control import ThermalControl
|
||||||
from city_model_structure.building_demand.usage_zone import UsageZone
|
from city_model_structure.building_demand.usage_zone import UsageZone
|
||||||
from hub_api.helpers.session_helper import refresh_session
|
|
||||||
import helpers.constants as cte
|
import helpers.constants as cte
|
||||||
|
from hub_api.helpers.auth import role_required
|
||||||
|
from hub_api.config import Config
|
||||||
|
from persistence.models import UserRoles
|
||||||
|
|
||||||
|
|
||||||
class Usage(Resource):
|
class Usage(Resource, Config):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
super().__init__()
|
||||||
|
|
||||||
|
@role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value])
|
||||||
|
def put(self, city_id):
|
||||||
|
|
||||||
|
city = self.get_city(city_id)
|
||||||
|
catalog = request.json['usage_catalog']
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def put():
|
|
||||||
session = refresh_session(request)
|
|
||||||
if session is None:
|
|
||||||
return Response(json.dumps({'error': 'invalid session'}), status=401)
|
|
||||||
headers = session.headers
|
|
||||||
city = session.city
|
|
||||||
catalog = session.usage_catalog
|
|
||||||
usage_name = None
|
usage_name = None
|
||||||
try:
|
try:
|
||||||
building_names = request.json['building_names']
|
building_names = request.json['building_names']
|
||||||
|
@ -146,8 +147,8 @@ class Usage(Resource):
|
||||||
response = {'result': 'succeed'}
|
response = {'result': 'succeed'}
|
||||||
except KeyError as ex:
|
except KeyError as ex:
|
||||||
response = {'error': f'Mandatory parameter {ex} is missing'}
|
response = {'error': f'Mandatory parameter {ex} is missing'}
|
||||||
return Response(json.dumps(response), headers=headers, status=400)
|
return Response(json.dumps(response), status=400)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
response = {'error': f'Name "{usage_name}" unknown'}
|
response = {'error': f'Name "{usage_name}" unknown'}
|
||||||
return Response(json.dumps(response), headers=headers, status=400)
|
return Response(json.dumps(response), status=400)
|
||||||
return Response(json.dumps(response), headers=headers)
|
return Response(json.dumps(response))
|
||||||
|
|
|
@ -97,6 +97,7 @@ class ToJson:
|
||||||
}
|
}
|
||||||
return schedule_dictionary
|
return schedule_dictionary
|
||||||
|
|
||||||
|
|
||||||
class UsageCatalogEntry(Resource):
|
class UsageCatalogEntry(Resource):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"""
|
"""
|
||||||
HeatPump Service
|
HeatPump Service
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Project Author Peter Yefi peteryefi@gmail.com
|
Copyright © 2023 Project Author Peter Yefi peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
from flask import Response, request
|
from flask import Response, request
|
||||||
|
|
Loading…
Reference in New Issue
Block a user