import helpers.library_codes import numpy as np from pathlib import Path import pandas as pd import csv from imports.weather_feeders.helpers.weather import Weather as wt class MonthlyEnergyBalance: @staticmethod def generate_meb_template(building, insel_outputs_path, key): lc = helpers.library_codes.LibraryCodes() file = "" file += "s 1 do\r\n" file += "p 1 1 12 1\r\n" file += "\r\n" file += "s 4 d18599 1.1 20.1 21.1\r\n" surfaces = building.surfaces for i in range(1, len(surfaces) + 1): file += str(100 + i) + '.1 % Radiation surface ' + str(i) + '\n' file += 'p 4' + '\n' # BUILDING PARAMETERS file += str(0.85*building.volume) + ' % BP(1) Heated Volume (vBrutto)\n' file += str(building.average_storey_height) + ' % BP(2) Average storey height / m\n' file += str(building.storeys_above_ground) + ' % BP(3) Number of storeys above ground\n' file += str(building.attic_heated) + ' % BP(4) Attic heating type (0=no room, 1=unheated, 2=heated)\n' file += str(building.basement_heated) + ' % BP(5) Cellar heating type (0=no room, 1=unheated, ' \ '2=heated, 99=invalid)\n' # todo: this method and the insel model have to be reviewed for more than one thermal zone thermal_zone = building.thermal_zones[0] file += str(thermal_zone.indirectly_heated_area_ratio) + ' % BP(6) Indirectly heated area ratio\n' file += str(thermal_zone.effective_thermal_capacity) + ' % BP(7) Effective heat capacity\n' file += str(thermal_zone.additional_thermal_bridge_u_value) + ' % BP(8) Additional U-value for heat bridge\n' file += '0 % BP(9) Usage type (0=standard, 1=IWU)\n' # ZONES AND SURFACES # todo: is this actually number of thermal zones or of usage zones? file += str(len(building.thermal_zones)) + ' % BP(10) Number $z$ of zones\n' i = 0 for usage_zone in building.usage_zones: percentage_usage = 1 file += str(float(building.floor_area) * percentage_usage) + ' % BP(11) #1 Area of zone ' + \ str(i + 1) + ' (sqm)' + '\n' total_internal_gains = 0 for ig in usage_zone.internal_gains: total_internal_gains += float(ig.average_internal_gain) * \ (float(ig.convective_fraction) + float(ig.radiative_fraction)) file += str(total_internal_gains) + ' % BP(12) #2 Internal gains of zone ' + str(i + 1) + '\n' file += str(usage_zone.heating_setpoint) + ' % BP(13) #3 Heating setpoint temperature zone ' + \ str(i + 1) + ' (tSetHeat)' + '\n' file += str(usage_zone.heating_setback) + ' % BP(14) #4 Heating setback temperature zone ' + \ str(i + 1) + ' (tSetbackHeat)' + '\n' file += str(usage_zone.cooling_setpoint) + ' % BP(15) #5 Cooling setpoint temperature zone ' + \ str(i + 1) + ' (tSetCool)' + '\n' file += str(usage_zone.hours_day) + ' % BP(16) #6 Usage hours per day zone ' + str(i + 1) + '\n' file += str(usage_zone.days_year) + ' % BP(17) #7 Usage days per year zone ' + str(i + 1) + '\n' if usage_zone.mechanical_air_change is None: if thermal_zone.infiltration_rate_system_off is None: raise Exception('Ventilation air rate is not initialized') else: file += str(thermal_zone.infiltration_rate_system_off) + ' % BP(18) #8 Minimum air change rate zone ' + \ str(i + 1) + ' (h^-1)' + '\n' else: file += str(usage_zone.mechanical_air_change) + ' % BP(18) #8 Minimum air change rate zone ' + \ str(i + 1) + ' (h^-1)' + '\n' i += 1 file += str(len(surfaces)) + ' % Number of surfaces = BP(11+8z)\n' file += '% 1. Surface type (1=wall, 2=ground 3=roof, 4=flat roof)' + '\n' file += '% 2. Areas above ground' + '\n' file += '% 3. Areas below ground' + '\n' file += '% 4. U-value' + '\n' file += '% 5. Window area' + '\n' file += '% 6. Window frame fraction' + '\n' file += '% 7. Window U-value' + '\n' file += '% 8. Window g-value' + '\n' file += '% 9. Short-wave reflectance' + '\n' file += '% #1 #2 #3 #4 #5 #6 #7 #8 #9' + '\n' # todo: this method has to be reviewed for more than one thermal opening per thermal boundary for thermal_boundary in building.thermal_zones[0].bounded: type_code = lc.construction_types_to_code(thermal_boundary.type) if thermal_boundary.surface.holes_polygons is None: window_area = float(thermal_boundary.surface.perimeter_polygon.area) * float(thermal_boundary.window_ratio) else: window_area = 0 for hole_polygon in thermal_boundary.surface.holes_polygons: window_area += hole_polygon.area string = type_code + ' ' + str(0.85*thermal_boundary.area_above_ground) + ' ' + \ str(thermal_boundary.area_below_ground) + ' ' + str(thermal_boundary.u_value) + ' ' + \ str(0.85*window_area) + ' ' if window_area <= 0.001: string = string + '0 0 0 ' else: string = string + str(thermal_boundary.thermal_openings[0].frame_ratio) + ' ' + \ str(thermal_boundary.thermal_openings[0].overall_u_value) + ' ' + \ str(thermal_boundary.thermal_openings[0].g_value) + ' ' if thermal_boundary.outside_solar_absorptance is not None: string += str(thermal_boundary.shortwave_reflectance) + '\r\n' else: string += '0 \r\n' file += string file += '\r\n' file += 's 20 polyg 1\r\n' file += 'p 20 12 % Monthly ambient temperature\r\n' external_temperature = building.external_temperature['month'] for i in range(0, len(external_temperature)): file += str(i+1) + ' ' + str(external_temperature.at[i, key]) + '\r\n' file += '\r\n' file += 's 21 polyg 1\r\n' file += 'p 21 12 % Monthly sky temperature\r\n' i = 1 sky_temperature = wt.sky_temperature(external_temperature[[key]].to_numpy().T[0]) for temperature in sky_temperature: file += str(i) + ' ' + str(temperature) + '\r\n' i += 1 i = 0 for surface in surfaces: file += '\r\n' file += 's ' + str(101 + i) + ' polyg 1 % Monthly surface radiation (W/sqm)\r\n' file += 'p ' + str(101 + i) + ' 12 % Azimuth ' + str(np.rad2deg(surface.azimuth)) + \ ', inclination ' + str(np.rad2deg(surface.inclination)) + ' degrees\r\n' if surface.type != 'Ground': global_irradiance = surface.global_irradiance['month'] for j in range(0, len(global_irradiance)): file += str(j + 1) + ' ' + str(global_irradiance.at[j, 'sra']) + '\r\n' else: for j in range(0, 12): file += str(j + 1) + ' 0\r\n' i += 1 file += '\r\n' file += '% ONE YEAR\r\n' file += 's 300 cum 4.1 4.2\r\n' file += 's 303 atend 300.1 300.2\r\n' file += '\r\n' file += 's ' + str(310) + ' WRITE\r\n' file += '4.1 4.2\r\n' file += 'p ' + str(310) + '\r\n' file += '1 % Mode\r\n' file += '0 % Suppress FNQ inputs\r\n' file += "'" + str(insel_outputs_path) + "' % File name\r\n" file += "'*' % Fortran format\r\n" return file @staticmethod def demand(insel_outputs_path): heating = [] cooling = [] with open(Path(insel_outputs_path).resolve()) as csv_file: csv_reader = csv.reader(csv_file) for line in csv_reader: demand = str(line).replace("['", '').replace("']", '').split() for i in range(0, 2): if demand[i] != 'NaN': aux = float(demand[i])*1000 # kWh to Wh demand[i] = str(aux) heating.append(demand[0]) cooling.append(demand[1]) monthly_heating = pd.DataFrame(heating, columns=['INSEL']) monthly_cooling = pd.DataFrame(cooling, columns=['INSEL']) return monthly_heating, monthly_cooling