Passed
Pull Request — dev (#1226)
by Uwe
01:53
created

shared.prepare_input_data()   B

Complexity

Conditions 4

Size

Total Lines 107
Code Lines 67

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 67
dl 0
loc 107
rs 8.08
c 0
b 0
f 0
cc 4
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
"""
2
SPDX-FileCopyrightText: Patrik Schönfeldt
3
SPDX-FileCopyrightText: DLR e.V.
4
5
SPDX-License-Identifier: MIT
6
"""
7
8
from pathlib import Path
9
10
import demandlib
11
import pandas as pd
12
import numpy as np
13
from urllib.request import urlretrieve
14
from workalendar.europe import Germany
15
16
17
def prepare_input_data():
18
    data = {}
19
20
    url_temperature = (
21
        "https://oemof.org/wp-content/uploads/2025/12/temperature.csv"
22
    )
23
    url_energy = "https://oemof.org/wp-content/uploads/2025/12/energy.csv"
24
25
    print(
26
        "Data is licensed from M. Schlemminger, T. Ohrdes, E. Schneider,"
27
        " and M. Knoop. Under Creative Commons Attribution 4.0 International"
28
        " License. It is also available at doi: 10.5281/zenodo.5642902."
29
        " (We use single family home 26 plus the south-facing PV"
30
        " from that dataset.)"
31
    )
32
33
    file_path = Path(__file__).parent
34
35
    temperature_file = Path(file_path, "temperature.csv")
36
    if not temperature_file.exists():
37
        urlretrieve(url_temperature, temperature_file)
38
    temperature = pd.read_csv(
39
        temperature_file,
40
        index_col="Unix Epoch",
41
    )
42
    timedelta = np.empty(len(temperature))
43
    timedelta[:-1] = (temperature.index[1:] - temperature.index[:-1]) / 3600
44
    timedelta[-1] = np.nan
45
46
    temperature.index = pd.to_datetime(
47
        temperature.index,
48
        unit="s",
49
        utc=True,
50
    )
51
52
    building_area = 120  # m² (from publication)
53
    specific_heat_demand = 60  #  kWh/m²/a  (educated guess)
54
    holidays = dict(Germany().holidays(2019))
55
56
    # We estimate the heat demand from the ambient temperature using demandlib.
57
    # This returns energy per time step in units of kWh.
58
    temperature["heat demand (kWh)"] = demandlib.bdew.HeatBuilding(
59
        temperature.index,
60
        holidays=holidays,
61
        temperature=temperature["Air Temperature (°C)"],
62
        shlp_type="EFH",
63
        building_class=1,
64
        wind_class=1,
65
        annual_heat_demand=building_area * specific_heat_demand,
66
        name="EFH",
67
    ).get_bdew_profile()
68
69
    temperature["heat demand (W)"] = (
70
        temperature["heat demand (kWh)"] * 1e3 / timedelta
71
    )
72
73
    energy_file = Path(file_path, "energy.csv")
74
    if not energy_file.exists():
75
        urlretrieve(url_energy, energy_file)
76
77
    energy = pd.read_csv(
78
        energy_file,
79
        index_col=0,
80
    )
81
    energy.index = pd.to_datetime(
82
        energy.index,
83
        unit="s",
84
        utc=True,
85
    )
86
87
    energy[energy == np.inf] = np.nan
88
    # ToDo: Auf 1 Minuten samplen und Nan-Werte interpolieren (linear)
89
    #  Daten in W
90
    #  demand ist absolut
91
    #  COP einfügen
92
    #  Mobilitätszeitreihe, die zu den Daten passt.
93
    #  Zeitstempel beachten ohne Offset!
94
95
    energy = (
96
        energy.resample("1 min")
97
        .mean()
98
    )
99
    temperature[temperature == np.inf] = np.nan
100
    temperature = (
101
        temperature[10:].resample("1 min")
102
        .mean()
103
    )
104
    df = pd.concat([energy, temperature], axis=1)
105
    df = df.interpolate()
106
107
    # **************** COP calculation **********************************
108
    t_supply = 60
109
    efficiency = 0.5  # source?
110
    cop_max = 7  # source???
111
112
    cop_hp = (t_supply + 273.15 * efficiency) / (
113
        t_supply - df["Air Temperature (°C)"]
114
    )
115
    cop_hp.loc[cop_hp > cop_max] = cop_max
116
117
    df["cop"] = cop_hp
118
119
    df["PV (kW/kWp)"] = df["PV (W)"].div(df["PV (W)"].sum()/60000)
120
    for key in ["heat demand (W)", "electricity demand (W)"]:
121
        df[key.replace("(W)", "(kW)")] = df[key].div(1000)
122
123
    return df
124
125
126
if __name__ == "__main__":
127
    print(prepare_input_data())
128