""" HeatPump Service SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2022 Project Author Peter Yefi peteryefi@gmail.com """ import json from flask import send_file, request, make_response, Response from flask_apispec import use_kwargs, doc from flask_apispec.views import MethodResource from flask_restful import Resource from marshmallow import Schema, fields from hub_api.helpers.auth import role_required from hub_api.helpers.session_helper import refresh_session from utils import HeatPumpSimulator from utils import validate_hp_model from persistence.models import UserRoles class HeatPumpPostData(Schema): """ 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): pass @doc(description='Heat pump simulation run', tags=['HeatPump']) @use_kwargs(HeatPumpPostData) @role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value]) def post(self, **kwargs): session = refresh_session(request) if session is None: return Response(json.dumps({'error': 'invalid session'}), status=401) city = session.city if validate_hp_model(kwargs['HeatPumpType'], kwargs['HeatPumpModel']): try: # Run simulation and return output file here hp_simulator = HeatPumpSimulator(city, kwargs) result_file = hp_simulator.run_hp_simulation() response = self._send_response(result_file, session) return response except Exception as err: print(err) return Response(json.dumps({'error_message': 'Sorry an error occurred while running HP Simulation'})) else: 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