|
1
|
|
|
#!/usr/bin/python3 |
|
2
|
|
|
# -*- coding: utf-8 -*- |
|
3
|
|
|
|
|
4
|
|
|
import os.path as path |
|
5
|
|
|
|
|
6
|
|
|
import pandas as pd |
|
7
|
|
|
|
|
8
|
|
|
from feedinlib import powerplants as pp |
|
9
|
|
|
|
|
10
|
|
|
from . import coastdat |
|
11
|
|
|
from . import powerplants as pg_pp |
|
12
|
|
|
from . import tools |
|
13
|
|
|
|
|
14
|
|
|
|
|
15
|
|
|
class Feedin: |
|
16
|
|
|
'' |
|
17
|
|
|
|
|
18
|
|
|
def __init__(self): |
|
19
|
|
|
'' |
|
20
|
|
|
pass |
|
21
|
|
|
|
|
22
|
|
|
def aggregate_cap_val(self, conn, **kwargs): |
|
23
|
|
|
''' |
|
24
|
|
|
Returns the normalised feedin profile and installed capacity for |
|
25
|
|
|
a given region. |
|
26
|
|
|
|
|
27
|
|
|
Parameters |
|
28
|
|
|
---------- |
|
29
|
|
|
region : Region instance |
|
30
|
|
|
region.geom : shapely.geometry object |
|
31
|
|
|
Geo-spatial data with information for location/region-shape. The |
|
32
|
|
|
geometry can be a polygon/multi-polygon or a point. |
|
33
|
|
|
|
|
34
|
|
|
Returns |
|
35
|
|
|
------- |
|
36
|
|
|
feedin_df : pandas dataframe |
|
37
|
|
|
Dataframe containing the normalised feedin profile of the given |
|
38
|
|
|
region. Index of the dataframe is the hour of the year; columns |
|
39
|
|
|
are 'pv_pwr' and 'wind_pwr'. |
|
40
|
|
|
cap : pandas series |
|
41
|
|
|
Series containing the installed capacity (in W) of PV and wind |
|
42
|
|
|
turbines of the given region. |
|
43
|
|
|
''' |
|
44
|
|
|
region = kwargs['region'] |
|
45
|
|
|
[pv_df, wind_df, cap] = self.get_timeseries( |
|
46
|
|
|
conn, geometry=region.geom, **kwargs |
|
47
|
|
|
) |
|
48
|
|
|
|
|
49
|
|
|
if kwargs.get('store', False): |
|
50
|
|
|
self.store_full_df(pv_df, wind_df, **kwargs) |
|
|
|
|
|
|
51
|
|
|
|
|
52
|
|
|
# Summerize the results to one column for pv and one for wind |
|
53
|
|
|
cap = cap.sum() |
|
|
|
|
|
|
54
|
|
|
df = pd.concat( |
|
55
|
|
|
[ |
|
56
|
|
|
pv_df.sum(axis=1) / cap['pv_pwr'], |
|
57
|
|
|
wind_df.sum(axis=1) / cap['wind_pwr'], |
|
58
|
|
|
], |
|
59
|
|
|
axis=1, |
|
60
|
|
|
) |
|
61
|
|
|
feedin_df = df.rename(columns={0: 'pv_pwr', 1: 'wind_pwr'}) |
|
62
|
|
|
|
|
63
|
|
|
return feedin_df, cap |
|
64
|
|
|
|
|
65
|
|
|
def get_timeseries(self, conn, **kwargs): |
|
66
|
|
|
'' |
|
67
|
|
|
weather = coastdat.get_weather( |
|
68
|
|
|
conn, kwargs['geometry'], kwargs['year'] |
|
69
|
|
|
) |
|
70
|
|
|
|
|
71
|
|
|
pv_df = 0 |
|
72
|
|
|
pv_cap = {} |
|
73
|
|
|
wind_df = 0 |
|
74
|
|
|
wind_cap = {} |
|
75
|
|
|
|
|
76
|
|
|
if not isinstance(weather, list): |
|
77
|
|
|
weather = [weather] |
|
78
|
|
|
|
|
79
|
|
|
for w_cell in weather: |
|
80
|
|
|
ee_pps = pg_pp.get_energymap_pps( |
|
81
|
|
|
conn, geometry1=w_cell.geometry, geometry2=kwargs['geometry'] |
|
82
|
|
|
) |
|
83
|
|
|
|
|
84
|
|
|
# Find type of wind turbine and its parameters according to the |
|
85
|
|
|
# windzone. |
|
86
|
|
|
wz = tools.get_windzone(conn, w_cell.geometry) |
|
87
|
|
|
|
|
88
|
|
|
kwargs['wind_conv_type'] = kwargs['wka_model_dc'].get( |
|
89
|
|
|
wz, kwargs['wka_model'] |
|
90
|
|
|
) |
|
91
|
|
|
kwargs['d_rotor'] = kwargs['d_rotor_dc'].get(wz, kwargs['d_rotor']) |
|
92
|
|
|
kwargs['h_hub'] = kwargs['h_hub_dc'].get(wz, kwargs['h_hub']) |
|
93
|
|
|
|
|
94
|
|
|
# Determine the feedin time series for the weather cell |
|
95
|
|
|
# Wind energy |
|
96
|
|
|
wind_peak_power = ee_pps[ee_pps.type == 'wind_power'].cap.sum() |
|
97
|
|
|
wind_power_plant = pp.WindPowerPlant(**kwargs) |
|
98
|
|
|
wind_series = wind_power_plant.feedin( |
|
99
|
|
|
weather=w_cell, installed_capacity=wind_peak_power |
|
100
|
|
|
) |
|
101
|
|
|
wind_series.name = w_cell.name |
|
102
|
|
|
wind_cap[w_cell.name] = wind_peak_power |
|
103
|
|
|
|
|
104
|
|
|
# PV |
|
105
|
|
|
pv_peak_power = ee_pps[ee_pps.type == 'solar_power'].cap.sum() |
|
106
|
|
|
pv_plant = pp.Photovoltaic(**kwargs) |
|
107
|
|
|
pv_series = pv_plant.feedin( |
|
108
|
|
|
weather=w_cell, peak_power=pv_peak_power |
|
109
|
|
|
) |
|
110
|
|
|
pv_series.name = w_cell.name |
|
111
|
|
|
pv_cap[w_cell.name] = pv_peak_power |
|
112
|
|
|
|
|
113
|
|
|
# Combine the results to a DataFrame |
|
114
|
|
|
try: |
|
115
|
|
|
pv_df = pd.concat([pv_df, pv_series], axis=1) |
|
116
|
|
|
wind_df = pd.concat([wind_df, wind_series], axis=1) |
|
117
|
|
|
except Exception: |
|
118
|
|
|
pv_df = pv_series.to_frame() |
|
119
|
|
|
wind_df = wind_series.to_frame() |
|
120
|
|
|
|
|
121
|
|
|
# Write capacity into a dataframe |
|
122
|
|
|
capw = pd.Series(pd.DataFrame.from_dict(wind_cap, orient='index')[0]) |
|
123
|
|
|
capw.name = 'wind_pwr' |
|
124
|
|
|
cappv = pd.Series(pd.DataFrame.from_dict(pv_cap, orient='index')[0]) |
|
125
|
|
|
cappv.name = 'pv_pwr' |
|
126
|
|
|
cap = pd.concat([capw, cappv], axis=1) |
|
127
|
|
|
|
|
128
|
|
|
return pv_df, wind_df, cap |
|
129
|
|
|
|
|
130
|
|
|
def store_full_df(self, pv_df, wind_df, **kwargs): |
|
131
|
|
|
'' |
|
132
|
|
|
dpath = kwargs.get('dpath', path.join(path.expanduser("~"), '.oemof')) |
|
133
|
|
|
filename = kwargs.get('filename', 'feedin_' + kwargs['region'].name) |
|
134
|
|
|
fullpath = path.join(dpath, filename) |
|
135
|
|
|
|
|
136
|
|
|
if kwargs['store'] == 'hf5': |
|
137
|
|
|
pv_df.to_hdf(fullpath + '.hf5', 'pv_pwr') |
|
138
|
|
|
wind_df.to_hdf(fullpath + '.hf5', 'wind_pwr') |
|
139
|
|
|
|
|
140
|
|
|
if kwargs['store'] == 'csv': |
|
141
|
|
|
pv_df.to_csv(fullpath + '_pv.csv') |
|
142
|
|
|
wind_df.to_csv(fullpath + '_wind.csv') |
|
143
|
|
|
|