import pandas as pd
from ..check import find_xor_hour
WEIGHT_NAME_REQUIRED = "weight"
BUILDING_FELT_TEMPERATURE_NAME = "felt_temperature"
[docs]
def basic_building_heating_profile(
felt_temperature: pd.DataFrame, non_heating_temperature: float, hourly_weight: pd.Series
) -> pd.Series:
r"""Create an hourly heating building consumption hourly profile adjusted to felt temperature. With sum over a month equals to 1.
Args:
felt_temperature (pd.DataFrame): Hourly felt temperature by building (to take into account inertia between outside cold and heating reactions)
non_heating_temperature (float): Temperature above which felt_temperature does not activate heating
hourly_weight (pd.Series): Initial profile
Raises:
ValueError: felt_temperature and hourly_weight should have same index
Returns:
pd.Series: Series with correct weight format
**Overview**
.. math::
P^{(\text{Heating building,adjusted})}_t =
\frac{\max(0,T^{(NH)}-T^{(\text{felt})}_t)\cdot P^{(\text{Heating building,raw})}_t}{\int_{t.month}\max(0,T^{(NH)}-T^{(\text{felt})}_t)\cdot P^{(\text{Heating building,raw})}_t}
where:
:math:`T^{(\text{felt})}_t` : Felt temperature by buildings different from external temperature because of inertia.
:math:`T^{(NH)}` : Temperature above which :math:`T^{(\text{felt})}_t` emperature does not activate heating.
:math:`P^{(\text{Heating building,raw})}_t` : Raw hourly profile (:math:`\int_{\text{day})}P^{(\text{Heating building,raw})}_t=1` but not mandatory because of normalisation)
:math:`P^{(\text{Heating building,adjusted})}_t` : Adjusted hourly profile.
:math:`t` is an instant (datetime) representing an hour, :math:`t.month` is month associated to instant :math:`t`
"""
if not find_xor_hour(felt_temperature, hourly_weight).empty:
raise ValueError(
f"felt_temperature and hourly_weight hours are not match\n Difference (head(10)\n {find_xor_hour(felt_temperature, hourly_weight).head(10)}"
)
felt_temperature.set_index(felt_temperature.index.to_period("h").start_time, inplace=True)
hourly_weight.index = hourly_weight.index.to_period("h").start_time
hourly_heating_profile = hourly_weight.copy()
_delta_felt_temperature_profile = (
non_heating_temperature - felt_temperature[BUILDING_FELT_TEMPERATURE_NAME]
).clip(0)
hourly_heating_profile = (
_delta_felt_temperature_profile
* hourly_weight
/ (_delta_felt_temperature_profile * hourly_weight)
.resample("MS")
.transform("sum")
)
hourly_heating_profile = hourly_heating_profile.fillna(0)
return hourly_heating_profile.rename(WEIGHT_NAME_REQUIRED)