import json import threading from co2_emission.co2_emission import Co2Emission from costs.cost import Cost from flask import Response, request from flask_restful import Resource from hub_api.config import Config from hub_api.helpers.session_helper import session, refresh_session from hub_api.mockup.building import Building from hub_api.persistence.mock import dic class RetrofitResults(Resource, Config): def __init__(self): super().__init__() self._scenario_ids = {'current status': 0, 'skin retrofit': 1, 'system retrofit and pv': 2, 'skin and system retrofit with pv': 3 } def _calculate_building(self, building_results, user_id, application_id, scenario, scenario_id): building_info = self.database.building(building_results['building'], user_id, application_id, scenario) archetype = self.energy_systems_catalog.get_entry(building_info.system_name) mockup_building = Building(building_info, building_results, archetype) life_cycle = Cost(mockup_building, retrofit_scenario=scenario_id).life_cycle operational_co2 = Co2Emission(mockup_building).operational_co2 global_capital_costs = life_cycle[f'Scenario {scenario_id}']['global_capital_costs'] global_operational_costs = life_cycle[f'Scenario {scenario_id}']['global_operational_costs'] global_capital_incomes = life_cycle[f'Scenario {scenario_id}']['global_capital_incomes'] global_maintenance_costs = life_cycle[f'Scenario {scenario_id}']['global_maintenance_costs'] building_results['total_heating_area'] = building_info.total_heating_area building_results['year_of_construction'] = building_info.year_of_construction building_results['function'] = building_info.function building_results['costs'] = { 'total_capital_costs_skin': life_cycle[f'Scenario {scenario_id}']['total_capital_costs_skin'], 'total_capital_costs_systems': life_cycle[f'Scenario {scenario_id}']['total_capital_costs_systems'], 'end_of_life_costs': life_cycle[f'Scenario {scenario_id}']['end_of_life_costs'], 'total_operational_costs': life_cycle[f'Scenario {scenario_id}']['total_operational_costs'], 'total_maintenance_costs': life_cycle[f'Scenario {scenario_id}']['total_maintenance_costs'], 'operational_incomes': life_cycle[f'Scenario {scenario_id}']['operational_incomes'], 'capital_incomes': life_cycle[f'Scenario {scenario_id}']['capital_incomes'], 'global_capital_costs': { 'B2010_opaque_walls': global_capital_costs['B2010_opaque_walls'].tolist(), 'B2020_transparent': global_capital_costs['B2020_transparent'].tolist(), 'B3010_opaque_roof': global_capital_costs['B3010_opaque_roof'].tolist(), 'B10_superstructure': global_capital_costs['B10_superstructure'].tolist(), 'D3020_heat_generating_systems': global_capital_costs['D3020_heat_generating_systems'].tolist(), 'D3030_cooling_generation_systems': global_capital_costs['D3030_cooling_generation_systems'].tolist(), 'D3080_other_hvac_ahu': global_capital_costs['D3080_other_hvac_ahu'].tolist(), 'D5020_lighting_and_branch_wiring': global_capital_costs['D5020_lighting_and_branch_wiring'].tolist(), 'D301010_photovoltaic_system': global_capital_costs['D301010_photovoltaic_system'].tolist(), }, 'global_end_of_life_costs': life_cycle[f'Scenario {scenario_id}']['global_end_of_life_costs'][ 'End_of_life_costs'].tolist(), 'global_operational_costs': { 'fixed_costs_electricity_peak': global_operational_costs['Fixed_costs_electricity_peak'].tolist(), 'fixed_costs_electricity_monthly': global_operational_costs['Fixed_costs_electricity_monthly'].tolist(), 'variable_costs_electricity': global_operational_costs['Variable_costs_electricity'].tolist(), 'fixed_costs_gas': global_operational_costs['Fixed_costs_gas'].tolist(), 'variable_costs_gas': global_operational_costs['Variable_costs_gas'].tolist() }, 'global_maintenance_costs': { 'heating_maintenance': global_maintenance_costs['Heating_maintenance'].tolist(), 'cooling_maintenance': global_maintenance_costs['Cooling_maintenance'].tolist(), 'pv_maintenance': global_maintenance_costs['PV_maintenance'].tolist(), }, 'global_operational_incomes': life_cycle[f'Scenario {scenario_id}']['global_operational_incomes'][ 'Incomes electricity'].tolist(), 'global_capital_incomes': { 'subsidies_construction': global_capital_incomes['Subsidies construction'].tolist(), 'subsidies_hvac': global_capital_incomes['Subsidies HVAC'].tolist(), 'subsidies_pv': global_capital_incomes['Subsidies PV'].tolist() } } building_results['operational_co2'] = operational_co2 def post(self): """ API call for requesting a specified list of enriched persistence """ # todo: cost and co2 libs are using default canadians values, in the future need to be optionally API configurable session_id = request.headers.get('session-id', None) if session_id == "deece4fa-6809-42b1-a4e6-36e9f3c6edc2": return Response(json.dumps(dic), status=200) token = request.headers.get('token', None) application_uuid = request.headers.get('application-uuid', None) _session = refresh_session(session_id, token, application_uuid) if _session is None: return Response(json.dumps({'error': 'unauthorized'}), status=403) else: token = {'token': _session['token']} application_id = session(session_id)['application_id'] user_id = session(session_id)['user_id'] payload = request.get_json() if 'scenarios' not in payload: return Response(json.dumps({'error': 'Bad request'}), status=400, headers=token) results = self.database.results(user_id, application_id, payload) if results == {}: # no data found for the given parameters return Response(json.dumps({'result': 'succeed', 'results': results}), status=200, headers=token) # deserialize the response to return pure json t = [] for scenario in results: scenario_id = self._scenario_ids[scenario] for building_results in results[scenario]: f = threading.Thread( target=self._calculate_building, args=(building_results, user_id, application_id, scenario, scenario_id) ) t.append(f) f.start() for f in t: f.join() return Response(json.dumps({'result': 'succeed', 'results': results}), status=200, headers=token) def get(self): session_id = request.headers.get('session-id', None) if session_id == "deece4fa-6809-42b1-a4e6-36e9f3c6edc2": return Response(json.dumps(dic), status=200) token = request.headers.get('token', None) application_uuid = request.headers.get('application-uuid', None) _session = refresh_session(session_id, token, application_uuid) results = {'meb': []} if _session is None: return Response(json.dumps({'error': 'unauthorized'}), status=403) else: response_token = {'token': _session['token']} buildings = request.get_json()['buildings'] building_query = '' for building in buildings: building_query = f'{building_query} {{"alias": "{building}"}},' query = f'{{"$or": [{building_query[:-1]}]}}' cursor = self.mongodb_meb.find(json.loads(query)) for result in cursor: del result['_id'] results['meb'].append(result) return Response(json.dumps({'result': 'succeed', 'results': results}), status=200, headers=response_token)