Passed
Push — master ( f838a5...02e3b3 )
by
unknown
01:00
created

scenario_builder.emobpy_processing   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 175
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
eloc 87
dl 0
loc 175
rs 10
c 0
b 0
f 0

3 Functions

Rating   Name   Duplication   Size   Complexity  
B get_charging_profiles_from_database() 0 76 6
A return_normalized_charging_series() 0 41 1
B return_sum_charging_power() 0 46 5
1
from emobpy import DataBase
2
import pandas as pd
3
import os
4
import numpy as np
5
from reegis import config as cfg
6
7
8
def get_charging_profiles_from_database(path):
9
    """
10
    This function can be used to process results obtained with the library emobpy by DIW Berlin.
11
    It takes a path to data as input and returns the summed charging power.
12
13
    Parameters
14
    ----------
15
    path: String
16
        Path to a folder with stored driving, availability and charging profiles
17
18
    Returns: DataFrame
19
        Summed charging power for 4 different charging strategies
20
    -------
21
    """
22
23
    # Load profiles from Files
24
    manager = DataBase(path)
25
    manager.update()
26
27
    # Liste mit Availability Profilen
28
    keys_driving = [k for k, v in manager.db.items() if v['kind'] == 'driving']
29
    keys_availability = [k for k, v in manager.db.items() if v['kind'] == 'availability']
30
    keys_charging = [k for k, v in manager.db.items() if v['kind'] == 'charging']
31
    keys_immediate = [k for k, v in manager.db.items() if v['kind'] == 'charging' and v['option'] == 'immediate' ]
32
    keys_balanced = [k for k, v in manager.db.items() if v['kind'] == 'charging' and v['option'] == 'balanced' ]
33
    keys_23to8 = [k for k, v in manager.db.items() if v['kind'] == 'charging' and v['option'] == 'from_23_to_8_at_home']
34
    keys_0to24 = [k for k, v in manager.db.items() if v['kind'] == 'charging' and v['option'] == 'from_0_to_24_at_home']
35
36
    # Summenprofil für Fahrleistung in kmd
37
    driving_profiles = pd.DataFrame()
38
    for k in keys_driving:
39
        test = manager.db[k]["timeseries"]["consumption"]
40
        driving_profiles = pd.concat([driving_profiles, test], axis=1)
41
42
    #cum_profile = driving_profiles.sum(axis=1)
43
44
45
    # Summenprofil für Ladeleistung (immediate)
46
    ch_profiles_immediate = pd.DataFrame()
47
    for k in keys_immediate:
48
        tmp = manager.db[k]["timeseries"]["charge_grid"]
49
        ch_profiles_immediate = pd.concat([ch_profiles_immediate, tmp], axis=1)
50
51
    P_immediate = ch_profiles_immediate.sum(axis=1)
52
53
54
    # Summenprofil für Ladeleistung (balanced)
55
    ch_profiles_balanced = pd.DataFrame()
56
    for k in keys_balanced:
57
        tmp = manager.db[k]["timeseries"]["charge_grid"]
58
        ch_profiles_balanced = pd.concat([ch_profiles_balanced, tmp], axis=1)
59
60
    P_balanced = ch_profiles_balanced.sum(axis=1)
61
62
63
    # Summenprofil für Ladeleistung (23 to 8)
64
    ch_profiles_23to8 = pd.DataFrame()
65
    for k in keys_23to8:
66
        tmp = manager.db[k]["timeseries"]["charge_grid"]
67
        ch_profiles_23to8 = pd.concat([ch_profiles_23to8, tmp], axis=1)
68
69
    P_23to8 = ch_profiles_23to8.sum(axis=1)
70
71
72
    # Summenprofil für Ladeleistung (0 to 24)
73
    ch_profiles_0to24 = pd.DataFrame()
74
    for k in keys_0to24:
75
        tmp = manager.db[k]["timeseries"]["charge_grid"]
76
        ch_profiles_0to24 = pd.concat([ch_profiles_0to24, tmp], axis=1)
77
78
    P_0to24 = ch_profiles_0to24.sum(axis=1)
79
80
    P_sum = pd.concat([P_immediate, P_balanced, P_23to8, P_0to24], axis=1)
81
    P_sum.columns = ['immediate', 'balanced', '23to8', '0to24']
82
83
    return P_sum
84
85
86
def return_normalized_charging_series(df):
87
    """
88
    This function normalizes profiles so that the sum of the timeseries is 1. The profiles can then be scaled to
89
    a user defined energy consumption of BEV charging.
90
91
    Parameters
92
    ----------
93
    df: DataFrame
94
        Dataframe with 4 charging timereries
95
96
    Returns: DataFrame
97
        Normalized charging series
98
    -------
99
    """
100
101
    # Cut off initial charging
102
    df.iloc[0:48] = df.iloc[48:96].values
103
    idx = pd.DatetimeIndex(df.index, freq='30min')
104
    df.set_index(idx, inplace=True)
105
    p_immediate = df['immediate']
106
    p_balanced = df['balanced']
107
    p_23to8 = df['23to8']
108
    p_0to24 = df['0to24']
109
110
    # Resample to hourly values
111
    immediate_hourly = p_immediate.resample('H').sum()
112
    balanced_hourly = p_balanced.resample('H').sum()
113
    hourly_23to8 = p_23to8.resample('H').sum()
114
    hourly_0to24 = p_0to24.resample('H').sum()
115
116
    # Normalize Yearly energy use to 1
117
    immediate_norm = immediate_hourly * (1 / immediate_hourly.sum())
118
    balanced_norm = balanced_hourly * (1 / balanced_hourly.sum())
119
    norm_23to8 =  hourly_23to8  * (1 / hourly_23to8 .sum())
120
    norm_0to24 = hourly_0to24 * (1 / hourly_0to24.sum())
121
122
    P_sum_norm = pd.concat([immediate_norm, balanced_norm, norm_23to8, norm_0to24], axis=1)
123
    smaller_zero = P_sum_norm < 0
124
    P_sum_norm[smaller_zero] = 0
125
126
    return P_sum_norm
127
128
129
def return_sum_charging_power(path=None):
130
    """
131
    This function returns a DataFrame with summed charging power series. Prerequisite is the calculation of profiles
132
    with the library emobpy by DIW Berlin. If the function is run for the first time a path to data must be provided.
133
134
    Parameters
135
    ----------
136
    path: String
137
        Path to a directory containing at least one folder with charging power series files.
138
139
    Returns: DataFrame
140
        Summed charging profiles
141
    -------
142
    """
143
    fn = os.path.join(cfg.get("paths", "scenario_data"), 'sum_charging_power.csv')
144
145
    if not os.path.isfile(fn):
146
        os.chdir(path)
147
        dirs = os.listdir(os.getcwd())
148
        result_dict = dict.fromkeys(dirs)
149
150
        for dir in result_dict.keys():
151
            path = os.path.join(os.getcwd(), dir)
152
            result_dict[dir] = get_charging_profiles_from_database(path)
153
154
        charging_types = result_dict[dir].columns
0 ignored issues
show
introduced by
The variable dir does not seem to be defined in case the for loop on line 150 is not entered. Are you sure this can never be the case?
Loading history...
155
        idx = result_dict[dir].index
156
        P_sum = pd.DataFrame(index=idx, columns=charging_types)
157
        len_series = len(result_dict[list(result_dict.keys())[0]]['immediate'])
158
159
        for ch_type in charging_types:
160
            sum_temp = pd.Series(np.zeros(shape=len_series), index=idx)
161
162
            for key in result_dict.keys():
163
                P_tmp = result_dict[key][ch_type]
164
                sum_temp = sum_temp.add(P_tmp, fill_value=0)
165
166
            P_sum[ch_type] = sum_temp
167
168
        P_sum.to_csv(fn)
169
170
    else:
171
        P_sum = pd.read_csv(fn)
172
        P_sum.set_index('Unnamed: 0', drop=True, inplace=True)
173
174
    return P_sum
175