Source code for tssm.calculation_models.profile_generation.bdew_electrical

"""
classes for BDEW electrical profile generation
"""
from __future__ import annotations

import datetime
from abc import abstractmethod
from typing import TYPE_CHECKING

import numpy as np
import pandas as pd

from tssm.utils.BDEW_class import BDEWElectrical
from tssm.utils.BDEW_day import BDEWDAY
from tssm.utils.seasons import Season

if TYPE_CHECKING:
    from numpy.typing import NDArray


class Seasons:
    __slots__ = "start", "end", "season"

    @abstractmethod
    def __init__(self):
        self.start: datetime.datetime = datetime.datetime(0, 0, 0)
        self.end: datetime.datetime = datetime.datetime(0, 0, 0)
        self.season: Season = Season.Winter

    def set_year(self, year: int):
        self.start = self.start.replace(year=year)
        self.end = self.end.replace(year=year)


class Summer(Seasons):
    def __init__(self):
        self.start: datetime.datetime = datetime.datetime(2000, 5, 15, 0, 0)
        self.end: datetime.datetime = datetime.datetime(2000, 9, 14, 23, 59)
        self.season: Season = Season.Summer


class Spring(Seasons):
    def __init__(self):
        self.start: datetime.datetime = datetime.datetime(2000, 3, 21, 0, 0)
        self.end: datetime.datetime = datetime.datetime(2000, 5, 14, 23, 59)
        self.season: Season = Season.Rest


class Autumn(Seasons):
    def __init__(self):
        self.start: datetime.datetime = datetime.datetime(2000, 9, 15, 0, 0)
        self.end: datetime.datetime = datetime.datetime(2000, 10, 31, 23, 59)
        self.season: Season = Season.Rest


class WinterStart(Seasons):
    def __init__(self):
        self.start: datetime.datetime = datetime.datetime(2000, 1, 1, 0, 0)
        self.end: datetime.datetime = datetime.datetime(2000, 3, 21, 23, 59)
        self.season: Season = Season.Winter


class WinterEnd(Seasons):
    def __init__(self):
        self.start: datetime.datetime = datetime.datetime(2000, 11, 1, 0, 0)
        self.end: datetime.datetime = datetime.datetime(2000, 12, 31, 23, 59)
        self.season: Season = Season.Winter


list_seasons = [WinterStart(), Spring(), Summer(), Autumn(), WinterEnd()]

hour_minute_to_index: dict[int, dict[int, int]] = {}

count: int = 0
for i in range(24):
    hour_minute_to_index[i] = {}
    for j in range(4):
        hour_minute_to_index[i][j * 15] = count
        count += 1


[docs]def create_bdew_electrical_profile( profile_name: str, year: int, *, holidays_as_sundays: list[datetime.datetime] | None = None, holidays_as_saturdays: list[datetime.datetime] | None = None, dynamic: bool = False, ) -> NDArray[np.float64]: """ create an electrical BDEW profile https://www.bdew.de/energie/standardlastprofile-strom/ Parameters ---------- profile_name: str building type in list ["H0", "L0", "L1", "L2", "G0", "G1", "G2", "G3", "G4", "G5", "G6"] year: int year for the creation holidays_as_sundays: list[datetime] holidays which should be considered as sundays holidays_as_saturdays: list[datetime] holidays which should be considered as saturdays dynamic: bool should the H0 profile be dynamic to time Returns ------- NDArray[np.float64] """ date = pd.DatetimeIndex(pd.date_range(datetime.datetime(year, 1, 1, 0), datetime.datetime(year, 12, 31, 23, 59), freq="15Min")) bdew = BDEWElectrical() _ = [seas.set_year(date[0].year) for seas in list_seasons] list_seasons_i = list_seasons.copy() seasons = np.zeros(len(date)).astype(object) for seas in list_seasons_i: seasons[np.logical_and(seas.start <= date, date < seas.end)] = seas.season sunday_holidays = [day.timetuple().tm_yday for day in holidays_as_sundays] if holidays_as_sundays is not None else [] saturday_holidays = [day.timetuple().tm_yday for day in holidays_as_saturdays] if holidays_as_saturdays is not None else [] days = [ BDEWDAY.Sunday if date_i.isoweekday() == 7 or date_i.dayofyear in sunday_holidays else BDEWDAY.Saturday if date_i.isoweekday() == 6 or date_i.dayofyear in saturday_holidays else BDEWDAY.Workday for date_i in date ] hour_idx = np.array([hour_minute_to_index[date_i.hour][date_i.minute] for date_i in date]).astype(np.int64) profile = getattr(bdew, profile_name) results = np.array([profile[seas][day][idx] for seas, day, idx in zip(seasons, days, hour_idx)]) if dynamic: days_of_year = np.array([date_i.dayofyear for date_i in date]) a_4, a_3, a_2, a_1, a_0 = -3.92e-10, 3.20e-07, -7.02e-05, 2.10e-03, 1.24 results = results * ((((a_4 * days_of_year + a_3) * days_of_year + a_2) * days_of_year + a_1) * days_of_year + a_0) return results