From 33ac71d5a62b5801ee00c959e7eda73aed9721f9 Mon Sep 17 00:00:00 2001 From: Pilar Date: Tue, 25 May 2021 13:34:57 -0400 Subject: [PATCH] added 'year' to 'minute' as constants in constants.py and adapted the code to that --- city_model_structure/attributes/occupants.py | 6 +- city_model_structure/attributes/polyhedron.py | 3 + city_model_structure/building.py | 10 +++ city_model_structure/city.py | 25 +++++- .../monthly_to_hourly_demand.py | 90 ++++++++++++++++--- data/physics/ca_archetypes_reduced.xml | 10 +-- data/physics/ca_constructions_reduced.xml | 28 +++--- exports/formats/energy_ade.py | 9 +- exports/formats/idf.py | 4 +- helpers/constants.py | 20 ++--- .../weather_feeders/dat_weather_parameters.py | 25 +++--- .../weather_feeders/epw_weather_parameters.py | 80 +++++++++-------- imports/weather_feeders/helpers/weather.py | 4 +- .../weather_feeders/xls_weather_parameters.py | 13 +-- tests/test_exports.py | 9 +- tests/test_imports.py | 2 +- tests/test_weather_factory.py | 28 ++---- 17 files changed, 227 insertions(+), 139 deletions(-) diff --git a/city_model_structure/attributes/occupants.py b/city_model_structure/attributes/occupants.py index 51d4ea57..95d17706 100644 --- a/city_model_structure/attributes/occupants.py +++ b/city_model_structure/attributes/occupants.py @@ -207,13 +207,13 @@ class Occupants: if self._complete_year_schedule is None: self._complete_year_schedule = [] for i in range(1, 13): - month_range = cal.monthrange(2018, i) + month_range = cal.monthrange(2015, i) for day in range(1, month_range[1]+1): - if cal.weekday(2018, i, day) < 5: + if cal.weekday(2015, i, day) < 5: for j in range(0, 24): week_schedule = schedules['WD'][j] self._complete_year_schedule.append(week_schedule) - elif cal.weekday(2018, i, day) == 5: + elif cal.weekday(2015, i, day) == 5: for j in range(0, 24): week_schedule = schedules['Sat'][j] self._complete_year_schedule.append(week_schedule) diff --git a/city_model_structure/attributes/polyhedron.py b/city_model_structure/attributes/polyhedron.py index ba21867a..50398164 100644 --- a/city_model_structure/attributes/polyhedron.py +++ b/city_model_structure/attributes/polyhedron.py @@ -215,6 +215,9 @@ class Polyhedron: :return: [x,y,z] """ if self._centroid is None: + trimesh = self.trimesh + if trimesh is None: + return None self._centroid = self.trimesh.centroid return self._centroid diff --git a/city_model_structure/building.py b/city_model_structure/building.py index cc6916e8..00b616ec 100644 --- a/city_model_structure/building.py +++ b/city_model_structure/building.py @@ -73,6 +73,8 @@ class Building(CityObject): else: self._internal_walls.append(surface) + self._pv_plus_hp_installation = None + @property def grounds(self) -> [Surface]: """ @@ -361,3 +363,11 @@ class Building(CityObject): if surface.type == 'Ground': self._floor_area += surface.perimeter_polygon.area return self._floor_area + + @property + def pv_plus_hp_installation(self): + return self._pv_plus_hp_installation + + @pv_plus_hp_installation.setter + def pv_plus_hp_installation(self, value): + self._pv_plus_hp_installation = value diff --git a/city_model_structure/city.py b/city_model_structure/city.py index 2fc54467..c90f2d6e 100644 --- a/city_model_structure/city.py +++ b/city_model_structure/city.py @@ -164,6 +164,20 @@ class City: self._buildings = [] self._buildings.append(new_city_object) + def remove_city_object(self, city_object): + """ + Remove a CityObject from the city + :param city_object:CityObject + :return: None + """ + if city_object.type != 'building': + raise NotImplementedError(city_object.type) + if self._buildings is None or self._buildings == []: + sys.stderr.write('Warning: impossible to remove city_object, the city is empty\n') + else: + if city_object in self._buildings: + self._buildings.remove(city_object) + @property def srs_name(self): """ @@ -210,12 +224,15 @@ class City: selected_region_lower_corner = [center[0] - radius, center[1] - radius, center[2] - radius] selected_region_upper_corner = [center[0] + radius, center[1] + radius, center[2] + radius] selected_region_city = City(selected_region_lower_corner, selected_region_upper_corner, srs_name=self.srs_name) + selected_region_city.climate_file = self.climate_file +# selected_region_city.climate_reference_city = self.climate_reference_city for city_object in self.city_objects: location = city_object.centroid - distance = math.sqrt(math.pow(location[0]-center[0], 2) + math.pow(location[1]-center[1], 2) - + math.pow(location[2]-center[2], 2)) - if distance < radius: - selected_region_city.add_city_object(city_object) + if location is not None: + distance = math.sqrt(math.pow(location[0]-center[0], 2) + math.pow(location[1]-center[1], 2) + + math.pow(location[2]-center[2], 2)) + if distance < radius: + selected_region_city.add_city_object(city_object) return selected_region_city @property diff --git a/city_model_structure/monthly_to_hourly_demand.py b/city_model_structure/monthly_to_hourly_demand.py index 6b8f2e01..bd90894a 100644 --- a/city_model_structure/monthly_to_hourly_demand.py +++ b/city_model_structure/monthly_to_hourly_demand.py @@ -6,6 +6,7 @@ Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es import pandas as pd from city_model_structure.attributes.occupants import Occupants import calendar as cal +import helpers.constants as cte class MonthlyToHourlyDemand: @@ -25,17 +26,17 @@ class MonthlyToHourlyDemand: :return: [hourly_heating] """ # todo: this method and the insel model have to be reviewed for more than one thermal zone - external_temp = self._building.external_temperature['hour'] - + external_temp = self._building.external_temperature[cte.HOUR] # todo: review index depending on how the schedules are defined, either 8760 or 24 hours for usage_zone in self._building.usage_zones: - temp_set = float(usage_zone.heating_setpoint) - temp_back = float(usage_zone.heating_setback) + temp_set = float(usage_zone.heating_setpoint)-3 + temp_back = float(usage_zone.heating_setback)-3 occupancy = Occupants().get_complete_year_schedule(usage_zone.schedules['Occupancy']) heating_schedule = self._conditioning_seasons['heating'] hourly_heating = [] i = 0 + j = 0 temp_grad_day = [] for month in range(1, 13): temp_grad_month = 0 @@ -47,9 +48,15 @@ class MonthlyToHourlyDemand: for hour in range(0, 24): if external_temp_med < temp_set and heating_schedule[month-1] == 1: if occupancy[hour] > 0: - temp_grad_day.append(temp_set - external_temp[key][i]) + hdd = temp_set - external_temp[key][i] + if hdd < 0: + hdd = 0 + temp_grad_day.append(hdd) else: - temp_grad_day.append(temp_back - external_temp[key][i]) + hdd = temp_back - external_temp[key][i] + if hdd < 0: + hdd = 0 + temp_grad_day.append(hdd) else: temp_grad_day.append(0) @@ -58,14 +65,71 @@ class MonthlyToHourlyDemand: for day in range(1, month_range[1] + 1): for hour in range(0, 24): - j = (day - 1) * 24 + hour - monthly_demand = self._building.heating['month']['INSEL'][month-1] - hourly_demand = float(monthly_demand)*float(temp_grad_day[j])/float(temp_grad_month) +# monthly_demand = self._building.heating[cte.MONTH]['INSEL'][month-1] + monthly_demand = self._building.heating[cte.MONTH][month-1] + if monthly_demand == 'NaN': + monthly_demand = 0 + if temp_grad_month == 0: + hourly_demand = 0 + else: + hourly_demand = float(monthly_demand)*float(temp_grad_day[j])/float(temp_grad_month) hourly_heating.append(hourly_demand) - + j += 1 self._hourly_heating = pd.DataFrame(data=hourly_heating, columns=['monthly to hourly']) return self._hourly_heating - @property - def hourly_cooling(self) -> NotImplementedError: - raise NotImplementedError + def hourly_cooling(self, key): + """ + hourly distribution of the monthly cooling of a building + :param key: string + :return: [hourly_cooling] + """ + # todo: this method and the insel model have to be reviewed for more than one thermal zone + external_temp = self._building.external_temperature[cte.HOUR] + # todo: review index depending on how the schedules are defined, either 8760 or 24 hours + for usage_zone in self._building.usage_zones: + temp_set = float(usage_zone.cooling_setpoint) + temp_back = 100 + occupancy = Occupants().get_complete_year_schedule(usage_zone.schedules['Occupancy']) + cooling_schedule = self._conditioning_seasons['cooling'] + + hourly_cooling = [] + i = 0 + j = 0 + temp_grad_day = [] + for month in range(1, 13): + temp_grad_month = 0 + month_range = cal.monthrange(2015, month) + for day in range(1, month_range[1] + 1): + for hour in range(0, 24): + if external_temp[key][i] > temp_set and cooling_schedule[month - 1] == 1: + if occupancy[hour] > 0: + cdd = external_temp[key][i] - temp_set + if cdd < 0: + cdd = 0 + temp_grad_day.append(cdd) + else: + cdd = external_temp[key][i] - temp_back + if cdd < 0: + cdd = 0 + temp_grad_day.append(cdd) + else: + temp_grad_day.append(0) + + temp_grad_month += temp_grad_day[i] + i += 1 + + for day in range(1, month_range[1] + 1): + for hour in range(0, 24): + # monthly_demand = self._building.heating[cte.MONTH]['INSEL'][month-1] + monthly_demand = self._building.cooling[cte.MONTH][month - 1] + if monthly_demand == 'NaN': + monthly_demand = 0 + if temp_grad_month == 0: + hourly_demand = 0 + else: + hourly_demand = float(monthly_demand) * float(temp_grad_day[j]) / float(temp_grad_month) + hourly_cooling.append(hourly_demand) + j += 1 + self._hourly_cooling = pd.DataFrame(data=hourly_cooling, columns=['monthly to hourly']) + return self._hourly_cooling diff --git a/data/physics/ca_archetypes_reduced.xml b/data/physics/ca_archetypes_reduced.xml index 54450ff0..02a34c04 100644 --- a/data/physics/ca_archetypes_reduced.xml +++ b/data/physics/ca_archetypes_reduced.xml @@ -4,7 +4,7 @@ - 0.13 + 0.2 33 @@ -22,7 +22,7 @@ - 0.13 + 0.2 34 @@ -40,7 +40,7 @@ - 0.13 + 0.2 34 @@ -58,7 +58,7 @@ - 0.13 + 0.2 34 @@ -87,7 +87,7 @@ 90 0.1 0.15 - 0.4 + 0.3 0 diff --git a/data/physics/ca_constructions_reduced.xml b/data/physics/ca_constructions_reduced.xml index 69557772..38a217d9 100644 --- a/data/physics/ca_constructions_reduced.xml +++ b/data/physics/ca_constructions_reduced.xml @@ -13,25 +13,31 @@ 0.3 2.7 + + 0.52 + 0.52 + 0.3 + 0.8 + - 0.202 + 0.18 0.8 0.2 - 0.187 + 0.17 0.8 0.2 - 0.217 + 0.17 0.8 0.2 - 0.236 + 0.253 0.8 0.2 @@ -46,12 +52,12 @@ 0.2 - 0.26 + 0.253 0.8 0.2 - 0.282 + 0.26 0.8 0.2 @@ -144,7 +150,7 @@ 0 - 0.512 + 0.67 0 0 @@ -159,22 +165,22 @@ 0 - 1.048 + 0.848 0 0 - 1.154 + 1.05 0 0 - 1.243 + 1.154 0 0 - 1.425 + 1.154 0 0 diff --git a/exports/formats/energy_ade.py b/exports/formats/energy_ade.py index a33ee73d..1c0f9bb8 100644 --- a/exports/formats/energy_ade.py +++ b/exports/formats/energy_ade.py @@ -7,6 +7,7 @@ import xmltodict import uuid import datetime from pathlib import Path +import helpers.constants as cte class EnergyAde: @@ -95,10 +96,10 @@ class EnergyAde: def _measures(building, building_dic): #todo: this method is only for year and insel need to be generalized measures = [] - measure = EnergyAde._measure(building.heating, 'year', 'Energy demand heating', 'INSEL') + measure = EnergyAde._measure(building.heating, cte.YEAR, 'Energy demand heating', 'INSEL') if measure is not None: measures.append(measure) - measure = EnergyAde._measure(building.cooling, 'year', 'Energy demand cooling', 'INSEL') + measure = EnergyAde._measure(building.cooling, cte.YEAR, 'Energy demand cooling', 'INSEL') if measure is not None: measures.append(measure) if len(measures) != 0: @@ -106,12 +107,12 @@ class EnergyAde: demands = [] for key in building.heating: - if key != 'year': + if key != cte.YEAR: demand = EnergyAde._demand(building.heating, key, 'Heating energy', 'INSEL') demands.append(demand) for key in building.cooling: - if key != 'year': + if key != cte.YEAR: demand = EnergyAde._demand(building.cooling, key, 'Cooling energy', 'INSEL') demands.append(demand) if len(demands) != 0: diff --git a/exports/formats/idf.py b/exports/formats/idf.py index d5758911..e20b45a2 100644 --- a/exports/formats/idf.py +++ b/exports/formats/idf.py @@ -45,7 +45,7 @@ class Idf: if layer.material.no_mass: self._idf.newidfobject(self._MATERIAL_NOMASS, Name=layer.material.name, - Roughness=cte.roughness, + Roughness=cte.ROUGHNESS, Thermal_Resistance=layer.material.thermal_resistance, Thermal_Absorptance=layer.material.thermal_absorptance, Solar_Absorptance=layer.material.solar_absorptance, @@ -54,7 +54,7 @@ class Idf: else: self._idf.newidfobject(self._MATERIAL, Name=layer.material.name, - Roughness=cte.roughness, + Roughness=cte.ROUGHNESS, Thickness=layer.thickness, Conductivity=layer.material.conductivity, Density=layer.material.density, diff --git a/helpers/constants.py b/helpers/constants.py index dafead3c..49ec5aef 100644 --- a/helpers/constants.py +++ b/helpers/constants.py @@ -1,12 +1,8 @@ -celsius_to_kelvin = 273.15 -days_of_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -# This dictionary is meant to force the way these variables are written -time_scale = { - 'minute': 'minute', - 'hour': 'hour', - 'day': 'day', - 'week': 'week', - 'month': 'month', - 'year': 'year' -} -roughness = "MediumRough" +KELVIN = 273.15 +MINUTE = 'minute' +HOUR = 'hour' +DAY = 'day' +WEEK = 'week' +MONTH = 'month' +YEAR = 'year' +ROUGHNESS = "MediumRough" diff --git a/imports/weather_feeders/dat_weather_parameters.py b/imports/weather_feeders/dat_weather_parameters.py index cac3b90e..5eaf80f1 100644 --- a/imports/weather_feeders/dat_weather_parameters.py +++ b/imports/weather_feeders/dat_weather_parameters.py @@ -7,6 +7,7 @@ Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es import pandas as pd from pathlib import Path import sys +import helpers.constants as cte class DatWeatherParameters: @@ -30,25 +31,25 @@ class DatWeatherParameters: for building in self._city.buildings: new_value = pd.DataFrame(self._weather_values[['temperature']].to_numpy(), columns=['inseldb']) - if 'hour' not in building.external_temperature: - building.external_temperature['hour'] = new_value + if cte.HOUR not in building.external_temperature: + building.external_temperature[cte.HOUR] = new_value else: - pd.concat([building.external_temperature['hour'], new_value], axis=1) + pd.concat([building.external_temperature[cte.HOUR], new_value], axis=1) new_value = pd.DataFrame(self._weather_values[['global_horiz']].to_numpy(), columns=['inseldb']) - if 'hour' not in building.global_horizontal: - building.global_horizontal['hour'] = new_value + if cte.HOUR not in building.global_horizontal: + building.global_horizontal[cte.HOUR] = new_value else: - pd.concat([building.global_horizontal['hour'], new_value], axis=1) + pd.concat([building.global_horizontal[cte.HOUR], new_value], axis=1) new_value = pd.DataFrame(self._weather_values[['diffuse']].to_numpy(), columns=['inseldb']) - if 'hour' not in building.diffuse: - building.diffuse['hour'] = new_value + if cte.HOUR not in building.diffuse: + building.diffuse[cte.HOUR] = new_value else: - pd.concat([building.diffuse['hour'], new_value], axis=1) + pd.concat([building.diffuse[cte.HOUR], new_value], axis=1) new_value = pd.DataFrame(self._weather_values[['beam']].to_numpy(), columns=['inseldb']) - if 'hour' not in building.beam: - building.beam['hour'] = new_value + if cte.HOUR not in building.beam: + building.beam[cte.HOUR] = new_value else: - pd.concat([building.beam['hour'], new_value], axis=1) + pd.concat([building.beam[cte.HOUR], new_value], axis=1) diff --git a/imports/weather_feeders/epw_weather_parameters.py b/imports/weather_feeders/epw_weather_parameters.py index 5268dafd..5c2af54f 100644 --- a/imports/weather_feeders/epw_weather_parameters.py +++ b/imports/weather_feeders/epw_weather_parameters.py @@ -7,6 +7,7 @@ Copyright © 2020 Project Author Pilar Monsalvete Alvarez de Uribarri pilar.mons import pandas as pd from pathlib import Path import sys +import helpers.constants as cte class EpwWeatherParameters: @@ -43,67 +44,68 @@ class EpwWeatherParameters: f'https://energyplus.net/weather and place it in folder data\weather\epw\n') sys.exit() - if self._weather_values is None: - try: - self._weather_values = pd.read_csv(self._path, header=0, skiprows=7, - names=['year', 'month', 'day', 'hour', 'minute', - 'data_source_and_uncertainty_flags', - 'dry_bulb_temperature_c', 'dew_point_temperature_c', - 'relative_humidity_perc', - 'atmospheric_station_pressure_pa', - 'extraterrestrial_horizontal_radiation_wh_m2', - 'extraterrestrial_direct_normal_radiation_wh_m2', - 'horizontal_infrared_radiation_intensity_wh_m2', - 'global_horizontal_radiation_wh_m2', 'direct_normal_radiation_wh_m2', - 'diffuse_horizontal_radiation_wh_m2', - 'global_horizontal_illuminance_lux', - 'direct_normal_illuminance_lux', 'diffuse_horizontal_illuminance_lux', - 'zenith_luminance_cd_m2', - 'wind_direction_deg', 'wind_speed_m_s', 'total_sky_cover', - 'opaque_sky_cover', 'visibility_km', - 'ceiling_heigh_m_s', 'present_weather_observation', - 'present_weather_codes', - 'precipitable_water_mm', 'aerosol_optical_depth_10_3_ths', - 'snow_depth_cm', - 'days_since_last_snowfall', 'albedo', 'liquid_precipitation_depth_mm', - 'liquid_precipitation_quality_hr']) - except SystemExit: - sys.stderr.write(f'Error: wrong formatting of weather file {self._path}\n') - sys.exit() + try: + self._weather_values = pd.read_csv(self._path, header=0, skiprows=7, + names=['year', 'month', 'day', 'hour', 'minute', + 'data_source_and_uncertainty_flags', + 'dry_bulb_temperature_c', 'dew_point_temperature_c', + 'relative_humidity_perc', + 'atmospheric_station_pressure_pa', + 'extraterrestrial_horizontal_radiation_wh_m2', + 'extraterrestrial_direct_normal_radiation_wh_m2', + 'horizontal_infrared_radiation_intensity_wh_m2', + 'global_horizontal_radiation_wh_m2', 'direct_normal_radiation_wh_m2', + 'diffuse_horizontal_radiation_wh_m2', + 'global_horizontal_illuminance_lux', + 'direct_normal_illuminance_lux', 'diffuse_horizontal_illuminance_lux', + 'zenith_luminance_cd_m2', + 'wind_direction_deg', 'wind_speed_m_s', 'total_sky_cover', + 'opaque_sky_cover', 'visibility_km', + 'ceiling_heigh_m_s', 'present_weather_observation', + 'present_weather_codes', + 'precipitable_water_mm', 'aerosol_optical_depth_10_3_ths', + 'snow_depth_cm', + 'days_since_last_snowfall', 'albedo', 'liquid_precipitation_depth_mm', + 'liquid_precipitation_quality_hr']) + except SystemExit: + sys.stderr.write(f'Error: wrong formatting of weather file {self._path}\n') + sys.exit() for building in self._city.buildings: + if cte.HOUR in building.external_temperature: + del building.external_temperature[cte.HOUR] new_value = pd.DataFrame(self._weather_values[['dry_bulb_temperature_c']].to_numpy(), columns=['epw']) number_invalid_records = new_value[new_value.epw == 99.9].count().epw if number_invalid_records > 0: sys.stderr.write(f'Warning: {self._path} invalid records (value of 99.9) in dry bulb temperature\n') - if 'hour' not in building.external_temperature: - building.external_temperature['hour'] = new_value + if cte.HOUR not in building.external_temperature: + building.external_temperature[cte.HOUR] = new_value else: - pd.concat([building.external_temperature['hour'], new_value], axis=1) + pd.concat([building.external_temperature[cte.HOUR], new_value], axis=1) new_value = pd.DataFrame(self._weather_values[['global_horizontal_radiation_wh_m2']].to_numpy(), columns=['epw']) number_invalid_records = new_value[new_value.epw == 9999].count().epw if number_invalid_records > 0: sys.stderr.write(f'Warning: {self._path} invalid records (value of 9999) in global horizontal radiation\n') - if 'hour' not in building.global_horizontal: - building.global_horizontal['hour'] = new_value + if cte.HOUR not in building.global_horizontal: + building.global_horizontal[cte.HOUR] = new_value else: - pd.concat([building.global_horizontal['hour'], new_value], axis=1) + pd.concat([building.global_horizontal[cte.HOUR], new_value], axis=1) new_value = pd.DataFrame(self._weather_values[['diffuse_horizontal_radiation_wh_m2']].to_numpy(), columns=['epw']) number_invalid_records = new_value[new_value.epw == 9999].count().epw if number_invalid_records > 0: sys.stderr.write(f'Warning: {self._path} invalid records (value of 9999) in diffuse horizontal radiation\n') - if 'hour' not in building.diffuse: - building.diffuse['hour'] = new_value + if cte.HOUR not in building.diffuse: + building.diffuse[cte.HOUR] = new_value else: - pd.concat([building.diffuse['hour'], new_value], axis=1) + pd.concat([building.diffuse[cte.HOUR], new_value], axis=1) new_value = pd.DataFrame(self._weather_values[['direct_normal_radiation_wh_m2']].to_numpy(), columns=['epw']) number_invalid_records = new_value[new_value.epw == 9999].count().epw if number_invalid_records > 0: sys.stderr.write(f'Warning: {self._path} invalid records (value of 9999) in direct horizontal radiation\n') - if 'hour' not in building.beam: - building.beam['hour'] = new_value + if cte.HOUR not in building.beam: + building.beam[cte.HOUR] = new_value else: - pd.concat([building.beam['hour'], new_value], axis=1) + pd.concat([building.beam[cte.HOUR], new_value], axis=1) diff --git a/imports/weather_feeders/helpers/weather.py b/imports/weather_feeders/helpers/weather.py index 311a9119..7a60800f 100644 --- a/imports/weather_feeders/helpers/weather.py +++ b/imports/weather_feeders/helpers/weather.py @@ -23,7 +23,7 @@ class Weather(object): # sky temperatures( in °C) values = [] for temperature in ambient_temperature: - value = 0.037536 * math.pow((temperature + cte.celsius_to_kelvin), 1.5) \ - + 0.32 * (temperature + cte.celsius_to_kelvin) - cte.celsius_to_kelvin + value = 0.037536 * math.pow((temperature + cte.KELVIN), 1.5) \ + + 0.32 * (temperature + cte.KELVIN) - cte.KELVIN values.append(value) return values diff --git a/imports/weather_feeders/xls_weather_parameters.py b/imports/weather_feeders/xls_weather_parameters.py index d8196b7d..1c90e379 100644 --- a/imports/weather_feeders/xls_weather_parameters.py +++ b/imports/weather_feeders/xls_weather_parameters.py @@ -8,6 +8,7 @@ Copyright © 2020 Project Author Pilar Monsalvete pilar_monsalvete@yahoo.es import pandas as pd from pathlib import Path import sys +import helpers.constants as cte class XlsWeatherParameters: @@ -34,13 +35,13 @@ class XlsWeatherParameters: for building in self._city.buildings: new_value = pd.DataFrame(self._weather_values[['temperature']].to_numpy(), columns=['iso52016']) - if 'hour' not in building.external_temperature: - building.external_temperature['hour'] = new_value + if cte.HOUR not in building.external_temperature: + building.external_temperature[cte.HOUR] = new_value else: - pd.concat([building.external_temperature['hour'], new_value], axis=1) + pd.concat([building.external_temperature[cte.HOUR], new_value], axis=1) new_value = pd.DataFrame(self._weather_values[['global_horiz']].to_numpy(), columns=['iso52016']) - if 'hour' not in building.global_horizontal: - building.global_horizontal['hour'] = new_value + if cte.HOUR not in building.global_horizontal: + building.global_horizontal[cte.HOUR] = new_value else: - pd.concat([building.global_horizontal['hour'], new_value], axis=1) + pd.concat([building.global_horizontal[cte.HOUR], new_value], axis=1) diff --git a/tests/test_exports.py b/tests/test_exports.py index d2762fbc..ba6a1e3f 100644 --- a/tests/test_exports.py +++ b/tests/test_exports.py @@ -13,6 +13,7 @@ from imports.physics_factory import PhysicsFactory from imports.schedules_factory import SchedulesFactory from imports.usage_factory import UsageFactory from exports.exports_factory import ExportsFactory +import helpers.constants as cte class TestExports(TestCase): @@ -40,10 +41,10 @@ class TestExports(TestCase): self._city_gml.climate_reference_city = 'Summerland' dummy_measures = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] for building in self._city_gml.buildings: - building.heating['month'] = pd.DataFrame({'INSEL': dummy_measures}) - building.cooling['month'] = pd.DataFrame({'INSEL': dummy_measures}) - building.heating['year'] = pd.DataFrame({'INSEL': [0.0]}) - building.cooling['year'] = pd.DataFrame({'INSEL': [0.0]}) + building.heating[cte.MONTH] = pd.DataFrame({'INSEL': dummy_measures}) + building.cooling[cte.MONTH] = pd.DataFrame({'INSEL': dummy_measures}) + building.heating[cte.YEAR] = pd.DataFrame({'INSEL': [0.0]}) + building.cooling[cte.YEAR] = pd.DataFrame({'INSEL': [0.0]}) return self._city_gml def _export(self, export_type): diff --git a/tests/test_imports.py b/tests/test_imports.py index 025c262c..60432cca 100644 --- a/tests/test_imports.py +++ b/tests/test_imports.py @@ -25,7 +25,7 @@ class MyTestCase(TestCase): def _get_city(self): if self._city_obj is None: file_path = (self._example_path / 'kelowna.obj').resolve() - self._city_obj = GeometryFactory('obj', file_path).city + self._city_obj = GeometryFactory('obj', file_path)._city_debug return self._city_obj def test_import_obj(self): diff --git a/tests/test_weather_factory.py b/tests/test_weather_factory.py index 91d69cce..ff1f1809 100644 --- a/tests/test_weather_factory.py +++ b/tests/test_weather_factory.py @@ -8,6 +8,7 @@ from unittest import TestCase from imports.geometry_factory import GeometryFactory from imports.weather_factory import WeatherFactory +import helpers.constants as cte class TestWeatherFactory(TestCase): @@ -29,40 +30,25 @@ class TestWeatherFactory(TestCase): self.assertIsNotNone(self._city_gml, 'city is none') return self._city_gml - def test_city_with_weather(self): - """ - Enrich the city with the weather information and verify it - :return: None - """ - file_path = (Path(__file__).parent / 'tests_data' / '20buildings.gml').resolve() - city = self._get_citygml(file_path) - for building in city.buildings: - values = building.external_temperature['hour'][['inseldb']] - self.assertFalse(values.empty, 'wrong value external_temperature') - values = building.global_horizontal['hour'][['inseldb']] - self.assertFalse(values.empty, 'wrong value global horizontal') - values = building.diffuse['hour'][['inseldb']] - self.assertFalse(values.empty, 'wrong value diffuse') - values = building.beam['hour'][['inseldb']] - self.assertFalse(values.empty, 'wrong value beam') - def test_weather_xls(self): file_path = (Path(__file__).parent / 'tests_data' / 'iso_52016_1_2017_lod2.gml').resolve() city_with_weather = self._get_citygml(file_path) WeatherFactory('xls', city_with_weather, base_path=self._example_path).enrich() for building in city_with_weather.buildings: - values = building.external_temperature['hour'][['iso52016']] + values = building.external_temperature[cte.HOUR][['iso52016']] self.assertFalse(values.empty, 'wrong value external_temperature') - values = building.global_horizontal['hour'][['iso52016']] + values = building.global_horizontal[cte.HOUR][['iso52016']] self.assertFalse(values.empty, 'wrong value global horizontal') def test_weather_epw(self): file_path = (Path(__file__).parent / 'tests_data' / 'one_building_in_kelowna.gml').resolve() city_with_weather = self._get_citygml(file_path) _file_name = 'CAN_BC_Summerland.717680_CWEC.epw' + print(len(city_with_weather.buildings)) WeatherFactory('epw', city_with_weather, base_path=self._example_path, file_name=_file_name).enrich() + print(len(city_with_weather.buildings)) for building in city_with_weather.buildings: - values = building.external_temperature['hour'][['epw']] + values = building.external_temperature[cte.HOUR][['epw']] self.assertFalse(values.empty, 'wrong value external_temperature') - values = building.global_horizontal['hour'][['epw']] + values = building.global_horizontal[cte.HOUR][['epw']] self.assertFalse(values.empty, 'wrong value global horizontal')