""" LCA SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2021 Project Author name Atiya Code contributors: Peter Yefi peteryefi@gmail.com """ import json from flask import Response from flask_restful import Resource from lca_calculations import LcaCalculations from itertools import groupby 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, Config): def __init__(self): super().__init__() @staticmethod def get_lca_value(city, nrel_id = None): nrel_material = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "14", "15", "16", "18", "20", "21", "22", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111", "112", "113", "114"] lca_material = ["12", "32", "21", "25", "11", "20", "40", "27", "29", "28", "19", "40", "41", "25", "32", "32", "32", "21", "41", "21", "11", "33", "28", "11", "40", "1", "28", "41", "0", "0", "0", "0", "0", ] keys = ['nrel_material_id', 'lca_material_id'] material_mapping = [dict(zip(keys, i)) for i in zip(nrel_material, lca_material)] if nrel_id is None: materials_lca = {"material_lca_catalog": []} for mat in material_mapping: if mat["nrel_material_id"] not in ("110", "111", "112", "113", "114"): for material in city.lca_materials: if(int(mat["lca_material_id"]) == material.id): material_lca_catalog = {} material_lca_catalog['nrel_material_id'] = mat["nrel_material_id"] material_lca_catalog['embodied_carbon'] = material.embodied_carbon mat_end_of_life = LcaCalculations(city).end_life_carbon(material.type) material_lca_catalog['end_of_life_carbon'] = mat_end_of_life materials_lca["material_lca_catalog"].append(material_lca_catalog) else: material_lca_catalog = {} material_lca_catalog['nrel_material_id'] = mat["nrel_material_id"] material_lca_catalog['embodied_carbon'] = 0.0 material_lca_catalog['end_of_life_carbon'] = 0.0 materials_lca["material_lca_catalog"].append(material_lca_catalog) return materials_lca else: for mat in material_mapping: if mat["nrel_material_id"] == str(nrel_id): for material in city.lca_materials: if (material.id == int(mat["lca_material_id"])): return material.embodied_carbon, material.id, material.type, material.name, material.density # return material.embodied_carbon @role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value]) def get(self, city_id): city = self.get_city(city_id) try: return Response(json.dumps(self.get_lca_value(city)), status=200) except ValueError: response = {'err_msg': f'No Catalog Available'} return Response(json.dumps(response), status=400) class MaterialLCACalculations(Resource, Config): """ LCA class """ def __init__(self): super().__init__() @role_required([UserRoles.Admin.value, UserRoles.Hub_Reader.value]) def get(self, city_id): """ Auto-method for processing the lca request :return: lca demand """ city = self.get_city(city_id) materials_lca = {'Wall': [], 'Ground': [], 'Roof': []} for building in city.buildings: for internal_zone in building.internal_zones: for thermal_zone in internal_zone.thermal_zones: for thermal_boundary in thermal_zone.thermal_boundaries: for i, layer in enumerate(thermal_boundary.layers): material_layers_lca = {} if layer.material.no_mass == False: embodied_carbon, mat_id, mat_type, mat_name, mat_density = MaterialLCACatalog.get_lca_value(city, layer.material.id) material_layers_lca['layer_name'] = f'Layer {i+1}' material_layers_lca['nrel_material_id'] = layer.material.id material_layers_lca['lca_material_id'] = mat_id material_layers_lca['embodied_carbon'] = (layer.thickness * thermal_boundary.opaque_area) * mat_density * embodied_carbon mat_end_of_life = LcaCalculations(city).end_life_carbon(mat_type) material_end_of_life = mat_end_of_life * (layer.thickness * thermal_boundary.opaque_area) * mat_density material_layers_lca['end_of_life_per_layer'] = material_end_of_life materials_lca[thermal_boundary.type].append(material_layers_lca) else: material_layers_lca['layer_name'] = f'Layer {i+1}' material_layers_lca['nrel_material_id'] = layer.material.id material_layers_lca['lca_material_id'] = mat_id material_layers_lca['embodied_carbon'] = (layer.thickness * thermal_boundary.opaque_area) * mat_density * embodied_carbon material_layers_lca['end_of_life_per_layer'] = 0.0 materials_lca[thermal_boundary.type].append(material_layers_lca) materials_embodied_carbon = {'Wall': [], 'Ground': [], 'Roof': []} for key, value in materials_lca.items(): boundary_layers = sorted(value, key=itemgetter('layer_name')) for b_layer, layer_properties in groupby(boundary_layers, key=itemgetter('layer_name')): sum_embodied = 0.0 sum_end_of_life = 0.0 total_embodied_carbon = {} for k in layer_properties: sum_embodied += k["embodied_carbon"] sum_end_of_life += k["end_of_life_per_layer"] total_embodied_carbon['layer_name'] = b_layer total_embodied_carbon['embodied_carbon'] = sum_embodied total_embodied_carbon['end_of_life_carbon'] = sum_end_of_life materials_embodied_carbon[key].append(total_embodied_carbon) return Response(json.dumps(materials_embodied_carbon), status=200)