hub/helpers/monthly_to_hourly_demand.py

140 lines
5.4 KiB
Python

"""
monthly_to_hourly_demand module
SPDX - License - Identifier: LGPL - 3.0 - or -later
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:
"""
MonthlyToHourlyDemand class
"""
def __init__(self, building, conditioning_seasons):
self._hourly_heating = pd.DataFrame()
self._hourly_cooling = pd.DataFrame()
self._building = building
self._conditioning_seasons = conditioning_seasons
def hourly_heating(self, key):
"""
hourly distribution of the monthly heating of a building
:param key: string
: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[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)-3
temp_back = float(usage_zone.heating_setback)-3
# 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
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
month_range = cal.monthrange(2015, month)[1]
for day in range(1, month_range[1]+1):
external_temp_med = 0
for hour in range(0, 24):
external_temp_med += external_temp[key][i]/24
for hour in range(0, 24):
if external_temp_med < temp_set and heating_schedule[month-1] == 1:
if occupancy[hour] > 0:
hdd = temp_set - external_temp[key][i]
if hdd < 0:
hdd = 0
temp_grad_day.append(hdd)
else:
hdd = temp_back - external_temp[key][i]
if hdd < 0:
hdd = 0
temp_grad_day.append(hdd)
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] or maybe:
# 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
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)[1]
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