diff --git a/hub/helpers/constants.py b/hub/helpers/constants.py index f345b4f0..31711b7d 100644 --- a/hub/helpers/constants.py +++ b/hub/helpers/constants.py @@ -24,8 +24,7 @@ BTU_H_TO_WATTS = 0.29307107 KILO_WATTS_HOUR_TO_JULES = 3600000 WATTS_HOUR_TO_JULES = 3600 GALLONS_TO_QUBIC_METERS = 0.0037854117954011185 -INFILTRATION_75PA_TO_4PA = (4/75)**0.65 - +INFILTRATION_75PA_TO_4PA = (4 / 75) ** 0.65 # time SECOND = 'second' @@ -186,6 +185,19 @@ DAYS_A_MONTH = {JANUARY: 31, NOVEMBER: 30, DECEMBER: 31} +HOURS_A_MONTH = {JANUARY: 744, + FEBRUARY: 672, + MARCH: 744, + APRIL: 720, + MAY: 744, + JUNE: 720, + JULY: 744, + AUGUST: 744, + SEPTEMBER: 720, + OCTOBER: 744, + NOVEMBER: 720, + DECEMBER: 744} + # data types ANY_NUMBER = 'any_number' FRACTION = 'fraction' diff --git a/hub/imports/results/energy_plus.py b/hub/imports/results/energy_plus.py index 92649723..382c185b 100644 --- a/hub/imports/results/energy_plus.py +++ b/hub/imports/results/energy_plus.py @@ -5,101 +5,98 @@ Copyright © 2022 Concordia CERC group Project Coder Guille Guillermo.GutierrezMorote@concordia.ca Code contributors: Saeed Ranjbar saeed.ranjbar@concordia.ca """ -from pathlib import Path import csv +import hub.helpers.constants as cte + class EnergyPlus: """ Energy plus class """ + + def _extract_fields_from_headers(self, headers): + for header in headers: + header_parts = header.split(':') + building_name = header_parts[0] + variable = ':'.join(header_parts[1:]).strip() # concat the rest and ensure that : it's reintroduced just in case + if variable is '': + continue + if building_name not in self._summary_variables: + self._building_energy_demands[variable] = [] # initialize the list of variables + else: + self._building_energy_demands[header] = [] + def __init__(self, city, file_path): self._city = city + self._building_energy_demands = {} + self._lines = [] + self._summary_variables = ['DistrictCooling:Facility [J](Hourly)', + 'InteriorEquipment:Electricity [J](Hourly)', + 'InteriorLights:Electricity [J](Hourly) '] + with open(file_path, 'r', encoding='utf8') as csv_file: csv_output = csv.reader(csv_file) - headers = next(csv_output) - print('headers:', headers) - - """ - building_energy_demands = { - 'Heating (J)': [], - 'Cooling (J)': [], - 'DHW (J)': [], - 'Appliances (J)': [], - 'Lighting (J)': [] - } - heating_column_index = [] - cooling_column_index = [] - dhw_column_index = [] - appliance_column_index = [] - lighting_column_index = [] - for index, header in enumerate(headers): - if "Total Heating" in header: - heating_column_index.append(index) - elif "Total Cooling" in header: - cooling_column_index.append(index) - elif "DHW" in header: - dhw_column_index.append(index) - elif "InteriorEquipment" in header: - appliance_column_index.append(index) - elif "InteriorLights" in header: - lighting_column_index.append(index) - + self._headers = next(csv_output) + self._extract_fields_from_headers(self._headers) for line in csv_output: - total_heating_demand = 0 - total_cooling_demand = 0 - total_dhw_demand = 0 - total_appliance_demand = 0 - total_lighting_demand = 0 - for heating_index in heating_column_index: - total_heating_demand += float(line[heating_index]) - building_energy_demands['Heating (J)'].append(total_heating_demand) - for cooling_index in cooling_column_index: - total_cooling_demand += float(line[cooling_index]) - building_energy_demands['Cooling (J)'].append(total_cooling_demand) - for dhw_index in dhw_column_index: - total_dhw_demand += float(line[dhw_index]) * 3600 - building_energy_demands['DHW (J)'].append(total_dhw_demand) - for appliance_index in appliance_column_index: - total_appliance_demand += float(line[appliance_index]) - building_energy_demands['Appliances (J)'].append(total_appliance_demand) - for lighting_index in lighting_column_index: - total_lighting_demand += float(line[lighting_index]) - building_energy_demands['Lighting (J)'].append(total_lighting_demand) - - return building_energy_demands - """ + self._lines.append(line) def enrich(self): """ Enrich the city by using the energy plus workflow output files (J) :return: None """ - return - """ for building in self._city.buildings: - file_name = f'{building.name}_out.csv' - energy_plus_output_file_path = Path(self._base_path / file_name).resolve() - if energy_plus_output_file_path.is_file(): - building_energy_demands = self._building_energy_demands(energy_plus_output_file_path) - building.heating_demand[cte.HOUR] = building_energy_demands['Heating (J)'] - building.cooling_demand[cte.HOUR] = building_energy_demands['Cooling (J)'] - building.domestic_hot_water_heat_demand[cte.HOUR] = building_energy_demands['DHW (J)'] - building.appliances_electrical_demand[cte.HOUR] = building_energy_demands['Appliances (J)'] - building.lighting_electrical_demand[cte.HOUR] = building_energy_demands['Lighting (J)'] - # todo: @Saeed, this a list of ONE value with the total energy of the year, exactly the same as cte.YEAR. - # You have to use the method to add hourly values from helpers/monthly_values - building.heating_demand[cte.MONTH] = MonthlyValues.get_total_month(building.heating_demand[cte.HOUR]) - building.cooling_demand[cte.MONTH] = MonthlyValues.get_total_month(building.cooling_demand[cte.HOUR]) - building.domestic_hot_water_heat_demand[cte.MONTH] = ( - MonthlyValues.get_total_month(building.domestic_hot_water_heat_demand[cte.HOUR])) - building.appliances_electrical_demand[cte.MONTH] = ( - MonthlyValues.get_total_month(building.appliances_electrical_demand[cte.HOUR])) - building.lighting_electrical_demand[cte.MONTH] = ( - MonthlyValues.get_total_month(building.lighting_electrical_demand[cte.HOUR])) - building.heating_demand[cte.YEAR] = [sum(building.heating_demand[cte.MONTH])] - building.cooling_demand[cte.YEAR] = [sum(building.cooling_demand[cte.MONTH])] - building.domestic_hot_water_heat_demand[cte.YEAR] = [sum(building.domestic_hot_water_heat_demand[cte.MONTH])] - building.appliances_electrical_demand[cte.YEAR] = [sum(building.appliances_electrical_demand[cte.MONTH])] - building.lighting_electrical_demand[cte.YEAR] = [sum(building.lighting_electrical_demand[cte.MONTH])] - """ \ No newline at end of file + building_energy_demands = self._building_energy_demands.copy() + for header in self._building_energy_demands: + if header == 'Zone Ideal Loads Supply Air Total Heating Energy [J](Hourly)': + field_name = f'{building.name} IDEAL LOADS AIR SYSTEM:{header}' + else: + field_name = f'{building.name}:{header}' + position = -1 + if field_name in self._headers: + position = self._headers.index(field_name) + if position == -1: + continue + for line in self._lines: + building_energy_demands[header].append(line[position]) + EnergyPlus._set_building_demands(building, building_energy_demands) + + @staticmethod + def _set_building_demands(building, building_energy_demands): + print(building.name, building_energy_demands) + building.heating_demand[cte.HOUR] = [float(x) for x in building_energy_demands[ + 'Zone Ideal Loads Supply Air Total Heating Energy [J](Hourly)']] + building.cooling_demand[cte.HOUR] = [float(x) for x in building_energy_demands[ + 'Zone Ideal Loads Supply Air Total Cooling Energy [J](Hourly)']] + building.domestic_hot_water_heat_demand[cte.HOUR] = [float(x) * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[ + 'Water Use Equipment Heating Rate [W](Hourly)']] + building.appliances_electrical_demand[cte.HOUR] = [float(x) * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[ + 'Other Equipment Electricity Rate [W](Hourly)']] + building.lighting_electrical_demand[cte.HOUR] = [float(x) * cte.WATTS_HOUR_TO_JULES for x in building_energy_demands[ + 'Zone Lights Electricity Rate [W](Hourly)']] + building.heating_demand[cte.MONTH] = [] + building.cooling_demand[cte.MONTH] = [] + building.domestic_hot_water_heat_demand[cte.MONTH] = [] + building.appliances_electrical_demand[cte.MONTH] = [] + building.lighting_electrical_demand[cte.MONTH] = [] + + start = 0 + for hours in cte.HOURS_A_MONTH.values(): + end = hours + start + building.heating_demand[cte.MONTH].append(sum(building.heating_demand[cte.HOUR][start: end])) + building.cooling_demand[cte.MONTH].append(sum(building.cooling_demand[cte.HOUR][start: end])) + building.domestic_hot_water_heat_demand[cte.MONTH].append(sum(building.domestic_hot_water_heat_demand[cte.HOUR][start: end])) + building.appliances_electrical_demand[cte.MONTH].append(sum(building.appliances_electrical_demand[cte.HOUR][start: end])) + building.lighting_electrical_demand[cte.MONTH].append(sum(building.lighting_electrical_demand[cte.HOUR][start: end])) + start = end + + building.heating_demand[cte.YEAR] = [sum(building.heating_demand[cte.MONTH])] + building.cooling_demand[cte.YEAR] = [sum(building.cooling_demand[cte.MONTH])] + building.domestic_hot_water_heat_demand[cte.YEAR] = [sum(building.domestic_hot_water_heat_demand[cte.MONTH])] + building.appliances_electrical_demand[cte.YEAR] = [sum(building.appliances_electrical_demand[cte.MONTH])] + building.lighting_electrical_demand[cte.YEAR] = [sum(building.lighting_electrical_demand[cte.MONTH])] + + + diff --git a/tests/test_exports.py b/tests/test_exports.py index a12672f0..ed6d33cb 100644 --- a/tests/test_exports.py +++ b/tests/test_exports.py @@ -150,17 +150,18 @@ class TestExports(TestCase): csv_output_path = (self._output_path / f'{city.name}_out.csv').resolve() ResultFactory('cerc_idf', city, csv_output_path).enrich() self.assertTrue(csv_output_path.is_file()) - """ - for building in self._city.buildings: + for building in city.buildings: self.assertIsNotNone(building.heating_demand) self.assertIsNotNone(building.cooling_demand) self.assertIsNotNone(building.domestic_hot_water_heat_demand) self.assertIsNotNone(building.lighting_electrical_demand) self.assertIsNotNone(building.appliances_electrical_demand) total_demand = sum(building.heating_demand[cte.HOUR]) + total_demand_month = sum(building.heating_demand[cte.MONTH]) + print(building.heating_demand[cte.YEAR]) + print(building.heating_demand[cte.YEAR][0], total_demand_month, total_demand) self.assertAlmostEqual(total_demand, building.heating_demand[cte.YEAR][0], 2) total_demand = sum(building.heating_demand[cte.MONTH]) self.assertEqual(total_demand, building.heating_demand[cte.YEAR][0], 2) - """ except Exception: self.fail("Idf ExportsFactory raised ExceptionType unexpectedly!")