""" ComnetUsageParameters model the usage properties SPDX - License - Identifier: LGPL - 3.0 - or -later Copyright © 2021 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca """ import sys from typing import Dict import pandas as pd import helpers.constants as cte from helpers.configuration_helper import ConfigurationHelper as ch from imports.geometry.helpers.geometry_helper import GeometryHelper from imports.usage.helpers.usage_helper import UsageHelper from city_model_structure.building_demand.usage_zone import UsageZone from city_model_structure.building_demand.internal_gains import InternalGains from imports.usage.data_classes.hft_usage_zone_archetype import HftUsageZoneArchetype as huza from imports.usage.data_classes.hft_internal_gains_archetype import HftInternalGainsArchetype as higa class ComnetUsageParameters: """ ComnetUsageParameters class """ def __init__(self, city, base_path): self._city = city self._base_path = str(base_path / 'comnet_archetypes.xlsx') self._usage_archetypes = [] data = self._read_file() for item in data['lighting']: for usage in UsageHelper.usage_to_comnet: comnet_usage = UsageHelper.usage_to_comnet[usage] if comnet_usage == item: usage_archetype = self._parse_zone_usage_type(comnet_usage, data) self._usage_archetypes.append(usage_archetype) def _read_file(self) -> Dict: """ reads xlsx file containing usage information into a dictionary :return : Dict """ number_usage_types = 33 xl_file = pd.ExcelFile(self._base_path) file_data = pd.read_excel(xl_file, sheet_name="Modeling Data", skiprows=[0, 1, 2], nrows=number_usage_types, usecols="A:Z") lighting_data = {} plug_loads_data = {} occupancy_data = {} ventilation_rate = {} water_heating = {} process_data = {} for j in range(0, number_usage_types): usage_parameters = file_data.iloc[j] usage_type = usage_parameters[0] lighting_data[usage_type] = usage_parameters[1:6].values.tolist() plug_loads_data[usage_type] = usage_parameters[8:13].values.tolist() occupancy_data[usage_type] = usage_parameters[17:20].values.tolist() ventilation_rate[usage_type] = usage_parameters[20:21].values.tolist() water_heating[usage_type] = usage_parameters[23:24].values.tolist() process_data[usage_type] = usage_parameters[24:26].values.tolist() return {'lighting': lighting_data, 'plug loads': plug_loads_data, 'occupancy': occupancy_data, 'ventilation rate': ventilation_rate, 'water heating': water_heating, 'process': process_data} @staticmethod def _parse_zone_usage_type(usage, data): if data['occupancy'][usage][0] <= 0: occupancy_density = 0 else: occupancy_density = 1 / data['occupancy'][usage][0] mechanical_air_change = data['ventilation rate'][usage][0] internal_gains = [] # lighting latent_fraction = ch().comnet_lighting_latent convective_fraction = ch().comnet_lighting_convective radiative_fraction = ch().comnet_lighting_radiant average_internal_gain = data['lighting'][usage][4] internal_gains.append(higa(internal_gains_type=cte.LIGHTING, average_internal_gain=average_internal_gain, convective_fraction=convective_fraction, radiative_fraction=radiative_fraction, latent_fraction=latent_fraction)) # occupancy latent_fraction = data['occupancy'][usage][2] / (data['occupancy'][usage][1] + data['occupancy'][usage][2]) sensible_fraction = float(1 - latent_fraction) convective_fraction = sensible_fraction * ch().comnet_occupancy_sensible_convective radiative_fraction = sensible_fraction * ch().comnet_occupancy_sensible_radiant average_internal_gain = (data['occupancy'][usage][1] + data['occupancy'][usage][2]) \ * occupancy_density * cte.BTU_H_TO_WATTS internal_gains.append(higa(internal_gains_type=cte.OCCUPANCY, average_internal_gain=average_internal_gain, convective_fraction=convective_fraction, radiative_fraction=radiative_fraction, latent_fraction=latent_fraction)) # plug loads if data['plug loads'][usage][0] != 'n.a.': latent_fraction = ch().comnet_plugs_latent convective_fraction = ch().comnet_plugs_convective radiative_fraction = ch().comnet_plugs_radiant average_internal_gain = data['plug loads'][usage][0] internal_gains.append(higa(internal_gains_type=cte.RECEPTACLE, average_internal_gain=average_internal_gain, convective_fraction=convective_fraction, radiative_fraction=radiative_fraction, latent_fraction=latent_fraction)) usage_zone_archetype = huza(usage=usage, internal_gains=internal_gains, occupancy_density=occupancy_density, mechanical_air_change=mechanical_air_change) return usage_zone_archetype def enrich_buildings(self): """ Returns the city with the usage parameters assigned to the buildings :return: """ city = self._city for building in city.buildings: usage = GeometryHelper.usage_from_function(building.function) height = building.average_storey_height if height is None: raise Exception('Average storey height not defined, ACH cannot be calculated') if height <= 0: raise Exception('Average storey height is zero, ACH cannot be calculated') archetype = self._search_archetype(UsageHelper.comnet_from_usage(usage)) if archetype is None: sys.stderr.write(f'Building {building.name} has unknown archetype for building function:' f' {building.function}, that assigns building usage as ' f'{GeometryHelper.usage_from_function(building.function)}\n') continue # just one usage_zone for thermal_zone in building.thermal_zones: usage_zone = UsageZone() usage_zone.usage = usage self._assign_values(usage_zone, archetype, height) usage_zone.volume = thermal_zone.volume thermal_zone.usage_zones = [usage_zone] def _search_archetype(self, building_usage): for building_archetype in self._usage_archetypes: if building_archetype.usage == building_usage: return building_archetype return None @staticmethod def _assign_values(usage_zone, archetype, height): # Due to the fact that python is not a typed language, the wrong object type is assigned to # usage_zone.internal_gains when writing usage_zone.internal_gains = archetype.internal_gains. # Therefore, this walk around has been done. internal_gains = [] for archetype_internal_gain in archetype.internal_gains: internal_gain = InternalGains() internal_gain.type = archetype_internal_gain.type internal_gain.average_internal_gain = archetype_internal_gain.average_internal_gain * cte.METERS_TO_FEET**2 internal_gain.convective_fraction = archetype_internal_gain.convective_fraction internal_gain.radiative_fraction = archetype_internal_gain.radiative_fraction internal_gain.latent_fraction = archetype_internal_gain.latent_fraction internal_gains.append(internal_gain) usage_zone.internal_gains = internal_gains usage_zone.occupancy_density = archetype.occupancy_density * cte.METERS_TO_FEET**2 usage_zone.mechanical_air_change = archetype.mechanical_air_change * usage_zone.occupancy_density \ * cte.HOUR_TO_MINUTES / cte.METERS_TO_FEET**3 / height