2020-10-19 10:07:03 -04:00
|
|
|
"""
|
|
|
|
monthly_to_hourly_demand module
|
|
|
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
2022-04-08 09:35:33 -04:00
|
|
|
Copyright © 2022 Concordia CERC group
|
|
|
|
Project Coder Pilar Monsalvete Alvarez de Uribarri pilar.monsalvete@concordia.ca
|
2020-10-19 10:07:03 -04:00
|
|
|
"""
|
2021-08-26 13:27:43 -04:00
|
|
|
import calendar as cal
|
2020-10-19 10:07:03 -04:00
|
|
|
import pandas as pd
|
2023-01-24 10:51:50 -05:00
|
|
|
from hub.city_model_structure.building_demand.occupant import Occupant
|
|
|
|
import hub.helpers.constants as cte
|
2020-10-19 10:07:03 -04:00
|
|
|
|
2020-11-26 06:34:11 -05:00
|
|
|
|
2020-10-19 10:07:03 -04:00
|
|
|
class MonthlyToHourlyDemand:
|
|
|
|
"""
|
|
|
|
MonthlyToHourlyDemand class
|
|
|
|
"""
|
2020-11-02 13:41:42 -05:00
|
|
|
def __init__(self, building, conditioning_seasons):
|
2020-10-19 10:07:03 -04:00
|
|
|
self._hourly_heating = pd.DataFrame()
|
|
|
|
self._hourly_cooling = pd.DataFrame()
|
|
|
|
self._building = building
|
2020-11-02 13:41:42 -05:00
|
|
|
self._conditioning_seasons = conditioning_seasons
|
2020-10-19 10:07:03 -04:00
|
|
|
|
2021-04-15 10:04:44 -04:00
|
|
|
def hourly_heating(self, key):
|
2020-10-26 08:26:31 -04:00
|
|
|
"""
|
|
|
|
hourly distribution of the monthly heating of a building
|
2021-04-15 10:04:44 -04:00
|
|
|
:param key: string
|
2020-10-26 08:26:31 -04:00
|
|
|
:return: [hourly_heating]
|
|
|
|
"""
|
2020-10-19 10:07:03 -04:00
|
|
|
# todo: this method and the insel model have to be reviewed for more than one thermal zone
|
2021-05-25 13:34:57 -04:00
|
|
|
external_temp = self._building.external_temperature[cte.HOUR]
|
2020-10-19 10:07:03 -04:00
|
|
|
# todo: review index depending on how the schedules are defined, either 8760 or 24 hours
|
2022-12-06 15:28:59 -05:00
|
|
|
for usage_zone in self._building.usages:
|
2021-05-25 13:34:57 -04:00
|
|
|
temp_set = float(usage_zone.heating_setpoint)-3
|
|
|
|
temp_back = float(usage_zone.heating_setback)-3
|
2021-06-03 10:17:36 -04:00
|
|
|
# todo: if these are data frames, then they should be called as (Occupancy should be in low case):
|
|
|
|
# usage_zone.schedules.Occupancy
|
|
|
|
# self._conditioning_seasons.heating
|
2022-03-08 19:19:52 -05:00
|
|
|
occupancy = Occupant().get_complete_year_schedule(usage_zone.schedules['Occupancy'])
|
2020-11-02 13:41:42 -05:00
|
|
|
heating_schedule = self._conditioning_seasons['heating']
|
2020-10-19 10:07:03 -04:00
|
|
|
|
2020-11-02 13:41:42 -05:00
|
|
|
hourly_heating = []
|
2020-10-19 10:07:03 -04:00
|
|
|
i = 0
|
2021-05-25 13:34:57 -04:00
|
|
|
j = 0
|
2020-11-02 13:41:42 -05:00
|
|
|
temp_grad_day = []
|
|
|
|
for month in range(1, 13):
|
2020-10-19 10:07:03 -04:00
|
|
|
temp_grad_month = 0
|
2021-05-28 11:53:23 -04:00
|
|
|
month_range = cal.monthrange(2015, month)[1]
|
2021-08-26 13:27:43 -04:00
|
|
|
for _ in range(1, month_range+1):
|
2020-10-19 10:07:03 -04:00
|
|
|
external_temp_med = 0
|
|
|
|
for hour in range(0, 24):
|
2021-04-15 10:04:44 -04:00
|
|
|
external_temp_med += external_temp[key][i]/24
|
2020-10-19 10:07:03 -04:00
|
|
|
for hour in range(0, 24):
|
2020-11-02 13:41:42 -05:00
|
|
|
if external_temp_med < temp_set and heating_schedule[month-1] == 1:
|
|
|
|
if occupancy[hour] > 0:
|
2021-05-25 13:34:57 -04:00
|
|
|
hdd = temp_set - external_temp[key][i]
|
|
|
|
if hdd < 0:
|
|
|
|
hdd = 0
|
|
|
|
temp_grad_day.append(hdd)
|
2020-10-19 10:07:03 -04:00
|
|
|
else:
|
2021-05-25 13:34:57 -04:00
|
|
|
hdd = temp_back - external_temp[key][i]
|
|
|
|
if hdd < 0:
|
|
|
|
hdd = 0
|
|
|
|
temp_grad_day.append(hdd)
|
2020-10-19 10:07:03 -04:00
|
|
|
else:
|
2020-11-02 13:41:42 -05:00
|
|
|
temp_grad_day.append(0)
|
2020-10-19 10:07:03 -04:00
|
|
|
|
2020-11-02 13:41:42 -05:00
|
|
|
temp_grad_month += temp_grad_day[i]
|
2020-10-19 10:07:03 -04:00
|
|
|
i += 1
|
|
|
|
|
2021-08-26 13:27:43 -04:00
|
|
|
for _ in range(1, month_range + 1):
|
2020-11-02 13:41:42 -05:00
|
|
|
for hour in range(0, 24):
|
2021-05-25 13:34:57 -04:00
|
|
|
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)
|
2020-11-02 13:41:42 -05:00
|
|
|
hourly_heating.append(hourly_demand)
|
2021-05-25 13:34:57 -04:00
|
|
|
j += 1
|
2020-11-02 13:41:42 -05:00
|
|
|
self._hourly_heating = pd.DataFrame(data=hourly_heating, columns=['monthly to hourly'])
|
2020-10-19 10:07:03 -04:00
|
|
|
return self._hourly_heating
|
|
|
|
|
2021-05-25 13:34:57 -04:00
|
|
|
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
|
2022-12-06 15:28:59 -05:00
|
|
|
for usage_zone in self._building.usages:
|
2021-05-25 13:34:57 -04:00
|
|
|
temp_set = float(usage_zone.cooling_setpoint)
|
|
|
|
temp_back = 100
|
2022-03-08 19:19:52 -05:00
|
|
|
occupancy = Occupant().get_complete_year_schedule(usage_zone.schedules['Occupancy'])
|
2021-05-25 13:34:57 -04:00
|
|
|
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
|
2021-05-28 11:53:23 -04:00
|
|
|
month_range = cal.monthrange(2015, month)[1]
|
2021-08-26 13:27:43 -04:00
|
|
|
for _ in range(1, month_range[1] + 1):
|
2021-05-25 13:34:57 -04:00
|
|
|
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
|
|
|
|
|
2021-08-26 13:27:43 -04:00
|
|
|
for _ in range(1, month_range[1] + 1):
|
2021-05-25 13:34:57 -04:00
|
|
|
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
|