Skip to content

Commit f93bcc4

Browse files
teschmittajdonnison
authored andcommitted
Added get_generation method to EUClient (#98)
* Added get_generation method to eu.py * Added "latest"-option for date-range * Added EU.get_generation
1 parent fa7524c commit f93bcc4

File tree

2 files changed

+199
-58
lines changed

2 files changed

+199
-58
lines changed

docs/source/options.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ method ``latest`` ``start_at`` and ``end_at`` pair ``yeste
2020
``EIA.get_trade`` yes yes yes no
2121
``ERCOT.get_generation`` yes no no no
2222
``ERCOT.get_load`` yes yes no yes
23+
``EU.get_generation`` yes yes yes no
2324
``EU.get_load`` yes yes no yes
2425
``IESO.get_generation`` yes yes yes yes
2526
``IESO.get_load`` yes yes yes yes

pyiso/eu.py

Lines changed: 198 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -14,103 +14,174 @@ class EUClient(BaseClient):
1414
NAME = 'EU'
1515
TZ_NAME = 'UTC'
1616
base_url = 'https://transparency.entsoe.eu/'
17-
export_endpoint = 'load-domain/r2/totalLoadR2/export'
17+
export_endpoint_load = 'load-domain/r2/totalLoadR2/export'
18+
export_endpoint_gen = 'generation/r2/actualGenerationPerProductionType/export'
1819

1920
CONTROL_AREAS = {
2021
'AL': {'country': 'Albania', 'Code': 'CTA|AL',
21-
'ENTSOe_ID': 'CTY|10YAL-KESH-----5!CTA|10YAL-KESH-----5'},
22+
'ENTSOe_ID': 'CTY|10YAL-KESH-----5!CTA|10YAL-KESH-----5',
23+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
2224
'AT': {'country': 'Austria', 'Code': 'CTA|AT',
23-
'ENTSOe_ID': 'CTY|10YAT-APG------L!CTA|10YAT-APG------L'},
25+
'ENTSOe_ID': 'CTY|10YAT-APG------L!CTA|10YAT-APG------L',
26+
'gen_freq': '15m', 'gen_market': 'RTPD'},
2427
'BE': {'country': 'Belgium', 'Code': 'CTA|BE',
25-
'ENTSOe_ID': 'CTY|10YBE----------2!CTA|10YBE----------2'},
28+
'ENTSOe_ID': 'CTY|10YBE----------2!CTA|10YBE----------2',
29+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
2630
'BA': {'country': 'Bosnia and Herz. ', 'Code': 'CTA|BA',
27-
'ENTSOe_ID': 'CTY|10YBA-JPCC-----D!CTA|10YBA-JPCC-----D'},
31+
'ENTSOe_ID': 'CTY|10YBA-JPCC-----D!CTA|10YBA-JPCC-----D',
32+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
2833
'BG': {'country': 'Bulgaria', 'Code': 'CTA|BG',
29-
'ENTSOe_ID': 'CTY|10YCA-BULGARIA-R!CTA|10YCA-BULGARIA-R'},
34+
'ENTSOe_ID': 'CTY|10YCA-BULGARIA-R!CTA|10YCA-BULGARIA-R',
35+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
3036
'HR': {'country': 'Croatia', 'Code': 'CTA|HR',
31-
'ENTSOe_ID': 'CTY|10YHR-HEP------M!CTA|10YHR-HEP------M'},
37+
'ENTSOe_ID': 'CTY|10YHR-HEP------M!CTA|10YHR-HEP------M',
38+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
3239
'CY': {'country': 'Cyprus', 'Code': 'CTA|CY',
33-
'ENTSOe_ID': 'CTY|10YCY-1001A0003J!CTA|10YCY-1001A0003J'},
40+
'ENTSOe_ID': 'CTY|10YCY-1001A0003J!CTA|10YCY-1001A0003J',
41+
'gen_freq': '30m', 'gen_market': 'RT5M'},
3442
'CZ': {'country': 'Czech Republic', 'Code': 'CTA|CZ',
35-
'ENTSOe_ID': 'CTY|10YCZ-CEPS-----N!CTA|10YCZ-CEPS-----N'},
43+
'ENTSOe_ID': 'CTY|10YCZ-CEPS-----N!CTA|10YCZ-CEPS-----N',
44+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
3645
'PL-CZ': {'country': 'Czech Republic', 'Code': 'CTA|PL-CZ',
37-
'ENTSOe_ID': 'CTY|10YCZ-CEPS-----N!CTA|10YDOM-1001A082L'},
46+
'ENTSOe_ID': 'CTY|10YCZ-CEPS-----N!CTA|10YDOM-1001A082L',
47+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
3848
'DK': {'country': 'Denmark', 'Code': 'CTA|DK',
39-
'ENTSOe_ID': 'CTY|10Y1001A1001A65H!CTA|10Y1001A1001A796'},
49+
'ENTSOe_ID': 'CTY|10Y1001A1001A65H!CTA|10Y1001A1001A796',
50+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
4051
'EE': {'country': 'Estonia', 'Code': 'CTA|EE',
41-
'ENTSOe_ID': 'CTY|10Y1001A1001A39I!CTA|10Y1001A1001A39I'},
52+
'ENTSOe_ID': 'CTY|10Y1001A1001A39I!CTA|10Y1001A1001A39I',
53+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
4254
'MK': {'country': 'FYR Macedonia', 'Code': 'CTA|MK',
43-
'ENTSOe_ID': 'CTY|10YMK-MEPSO----8!CTA|10YMK-MEPSO----8'},
55+
'ENTSOe_ID': 'CTY|10YMK-MEPSO----8!CTA|10YMK-MEPSO----8',
56+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
4457
'FI': {'country': 'Finland', 'Code': 'CTA|FI',
45-
'ENTSOe_ID': 'CTY|10YFI-1--------U!CTA|10YFI-1--------U'},
58+
'ENTSOe_ID': 'CTY|10YFI-1--------U!CTA|10YFI-1--------U',
59+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
4660
'FR': {'country': 'France', 'Code': 'CTA|FR',
47-
'ENTSOe_ID': 'CTY|10YFR-RTE------C!CTA|10YFR-RTE------C'},
61+
'ENTSOe_ID': 'CTY|10YFR-RTE------C!CTA|10YFR-RTE------C',
62+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
4863
'DE(50HzT)': {'country': 'Germany', 'Code': 'CTA|DE(50HzT)',
49-
'ENTSOe_ID': 'CTY|10Y1001A1001A83F!CTA|10YDE-VE-------2'},
64+
'ENTSOe_ID': 'CTY|10Y1001A1001A83F!CTA|10YDE-VE-------2',
65+
'gen_freq': '15m', 'gen_market': 'RTPD'},
5066
'DE(Amprion)': {'country': 'Germany', 'Code': 'CTA|DE(Amprion)',
51-
'ENTSOe_ID': 'CTY|10Y1001A1001A83F!CTA|10YDE-RWENET---I'},
67+
'ENTSOe_ID': 'CTY|10Y1001A1001A83F!CTA|10YDE-RWENET---I',
68+
'gen_freq': '15m', 'gen_market': 'RTPD'},
5269
'DE(TenneT GER)': {'country': 'Germany', 'Code': 'CTA|DE(TenneT GER)',
53-
'ENTSOe_ID': 'CTY|10Y1001A1001A83F!CTA|10YDE-EON------1&'},
70+
'ENTSOe_ID': 'CTY|10Y1001A1001A83F!CTA|10YDE-EON------1&',
71+
'gen_freq': '15m', 'gen_market': 'RTPD'},
5472
'DE(TransnetBW)': {'country': 'Germany', 'Code': 'CTA|DE(TransnetBW)',
55-
'ENTSOe_ID': 'CTY|10Y1001A1001A83F!CTA|10YDE-ENBW-----N'},
73+
'ENTSOe_ID': 'CTY|10Y1001A1001A83F!CTA|10YDE-ENBW-----N',
74+
'gen_freq': '15m', 'gen_market': 'RTPD'},
5675
'GR': {'country': 'Greece', 'Code': 'CTA|GR',
57-
'ENTSOe_ID': 'CTY|10YGR-HTSO-----Y!CTA|10YGR-HTSO-----Y'},
76+
'ENTSOe_ID': 'CTY|10YGR-HTSO-----Y!CTA|10YGR-HTSO-----Y',
77+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
5878
'HU': {'country': 'Hungary', 'Code': 'CTA|HU',
59-
'ENTSOe_ID': 'CTY|10YHU-MAVIR----U!CTA|10YHU-MAVIR----U'},
79+
'ENTSOe_ID': 'CTY|10YHU-MAVIR----U!CTA|10YHU-MAVIR----U',
80+
'gen_freq': '15m', 'gen_market': 'RTPD'},
6081
'IE': {'country': 'Ireland', 'Code': 'CTA|IE',
61-
'ENTSOe_ID': 'CTY|10YIE-1001A00010!CTA|10YIE-1001A00010'},
82+
'ENTSOe_ID': 'CTY|10YIE-1001A00010!CTA|10YIE-1001A00010',
83+
'gen_freq': '30m', 'gen_market': 'RT5M'},
6284
'IT': {'country': 'Italy', 'Code': 'CTA|IT',
63-
'ENTSOe_ID': 'CTY|10YIT-GRTN-----B!CTA|10YIT-GRTN-----B'},
85+
'ENTSOe_ID': 'CTY|10YIT-GRTN-----B!CTA|10YIT-GRTN-----B',
86+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
6487
'LV': {'country': 'Latvia', 'Code': 'CTA|LV',
65-
'ENTSOe_ID': 'CTY|10YLV-1001A00074!CTA|10YLV-1001A00074'},
88+
'ENTSOe_ID': 'CTY|10YLV-1001A00074!CTA|10YLV-1001A00074',
89+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
6690
'LT': {'country': 'Lithuania', 'Code': 'CTA|LT',
67-
'ENTSOe_ID': 'CTY|10YLT-1001A0008Q!CTA|10YLT-1001A0008Q'},
91+
'ENTSOe_ID': 'CTY|10YLT-1001A0008Q!CTA|10YLT-1001A0008Q',
92+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
6893
'LU': {'country': 'Luxembourg', 'Code': 'CTA|LU',
69-
'ENTSOe_ID': 'CTY|10YLU-CEGEDEL-NQ!CTA|10YLU-CEGEDEL-NQ'},
94+
'ENTSOe_ID': 'CTY|10YLU-CEGEDEL-NQ!CTA|10YLU-CEGEDEL-NQ',
95+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
7096
'MT': {'country': 'Malta', 'Code': 'CTA|MT',
71-
'ENTSOe_ID': 'CTY|MT!CTA|Not+delivered+MT'},
97+
'ENTSOe_ID': 'CTY|MT!CTA|Not+delivered+MT',
98+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
7299
'MD': {'country': 'Moldavia', 'Code': 'CTA|MD',
73-
'ENTSOe_ID': 'CTY|MD!CTA|Not+delivered+MD'},
100+
'ENTSOe_ID': 'CTY|MD!CTA|Not+delivered+MD',
101+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
74102
'ME': {'country': 'Montenegro', 'Code': 'CTA|ME',
75-
'ENTSOe_ID': 'CTY|10YCS-CG-TSO---S!CTA|10YCS-CG-TSO---S'},
103+
'ENTSOe_ID': 'CTY|10YCS-CG-TSO---S!CTA|10YCS-CG-TSO---S',
104+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
76105
'NL': {'country': 'Netherlands', 'Code': 'CTA|NL',
77-
'ENTSOe_ID': 'CTY|10YNL----------L!CTA|10YNL----------L'},
106+
'ENTSOe_ID': 'CTY|10YNL----------L!CTA|10YNL----------L',
107+
'gen_freq': '15m', 'gen_market': 'RTPD'},
78108
'NO': {'country': 'Norway', 'Code': 'CTA|NO',
79-
'ENTSOe_ID': 'CTY|10YNO-0--------C!CTA|10YNO-0--------C'},
109+
'ENTSOe_ID': 'CTY|10YNO-0--------C!CTA|10YNO-0--------C',
110+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
80111
'PL': {'country': 'Poland', 'Code': 'CTA|PL',
81-
'ENTSOe_ID': 'CTY|10YPL-AREA-----S!CTA|10YPL-AREA-----S'},
112+
'ENTSOe_ID': 'CTY|10YPL-AREA-----S!CTA|10YPL-AREA-----S',
113+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
82114
'PT': {'country': 'Portugal', 'Code': 'CTA|PT',
83-
'ENTSOe_ID': 'CTY|10YPT-REN------W!CTA|10YPT-REN------W'},
115+
'ENTSOe_ID': 'CTY|10YPT-REN------W!CTA|10YPT-REN------W',
116+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
84117
'RO': {'country': 'Romania', 'Code': 'CTA|RO',
85-
'ENTSOe_ID': 'CTY|10YRO-TEL------P!CTA|10YRO-TEL------P'},
118+
'ENTSOe_ID': 'CTY|10YRO-TEL------P!CTA|10YRO-TEL------P',
119+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
86120
'RU': {'country': 'Russia', 'Code': 'CTA|RU',
87-
'ENTSOe_ID': 'CTY|10YRO-TEL------P!CTA|10YRO-TEL------P'},
121+
'ENTSOe_ID': 'CTY|10YRO-TEL------P!CTA|10YRO-TEL------P',
122+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
88123
'RU-KGD': {'country': 'Russia', 'Code': 'CTA|RU-KGD',
89-
'ENTSOe_ID': 'CTY|RU!CTA|10Y1001A1001A50U'},
124+
'ENTSOe_ID': 'CTY|RU!CTA|10Y1001A1001A50U',
125+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
90126
'RS': {'country': 'Serbia', 'Code': 'CTA|RS',
91-
'ENTSOe_ID': 'CTY|10YCS-SERBIATSOV!CTA|10YCS-SERBIATSOV'},
127+
'ENTSOe_ID': 'CTY|10YCS-SERBIATSOV!CTA|10YCS-SERBIATSOV',
128+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
92129
'SK': {'country': 'Slovakia', 'Code': 'CTA|SK',
93-
'ENTSOe_ID': 'CTY|10YSK-SEPS-----K!CTA|10YSK-SEPS-----K'},
130+
'ENTSOe_ID': 'CTY|10YSK-SEPS-----K!CTA|10YSK-SEPS-----K',
131+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
94132
'SI': {'country': 'Slovenia', 'Code': 'CTA|SI',
95-
'ENTSOe_ID': 'CTY|10YSI-ELES-----O!CTA|10YSI-ELES-----O'},
133+
'ENTSOe_ID': 'CTY|10YSI-ELES-----O!CTA|10YSI-ELES-----O',
134+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
96135
'ES': {'country': 'Spain', 'Code': 'CTA|ES',
97-
'ENTSOe_ID': 'CTY|10YES-REE------0!CTA|10YES-REE------0'},
136+
'ENTSOe_ID': 'CTY|10YES-REE------0!CTA|10YES-REE------0',
137+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
98138
'SE': {'country': 'Sweden', 'Code': 'CTA|SE',
99-
'ENTSOe_ID': 'CTY|10YSE-1--------K!CTA|10YSE-1--------K'},
139+
'ENTSOe_ID': 'CTY|10YSE-1--------K!CTA|10YSE-1--------K',
140+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
100141
'CH': {'country': 'Switzerland', 'Code': 'CTA|CH',
101-
'ENTSOe_ID': 'CTY|10YCH-SWISSGRIDZ!CTA|10YCH-SWISSGRIDZ'},
142+
'ENTSOe_ID': 'CTY|10YCH-SWISSGRIDZ!CTA|10YCH-SWISSGRIDZ',
143+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
102144
'TR': {'country': 'Turkey', 'Code': 'CTA|TR',
103-
'ENTSOe_ID': 'CTY|TR!CTA|10YTR-TEIAS----W'},
145+
'ENTSOe_ID': 'CTY|TR!CTA|10YTR-TEIAS----W',
146+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
104147
'UA': {'country': 'Ukraine', 'Code': 'CTA|UA',
105-
'ENTSOe_ID': 'CTY|UA!CTA|10Y1001A1001A869'},
148+
'ENTSOe_ID': 'CTY|UA!CTA|10Y1001A1001A869',
149+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
106150
'UA-WEPS': {'country': 'Ukraine', 'Code': 'CTA|UA-WEPS',
107-
'ENTSOe_ID': 'CTY|UA!CTA|10YUA-WEPS-----0'},
151+
'ENTSOe_ID': 'CTY|UA!CTA|10YUA-WEPS-----0',
152+
'gen_freq': '1hr', 'gen_market': 'RTHR'},
108153
'NIE': {'country': 'United Kingdom', 'Code': 'CTA|NIE',
109-
'ENTSOe_ID': 'CTY|GB!CTA|10Y1001A1001A016'},
154+
'ENTSOe_ID': 'CTY|GB!CTA|10Y1001A1001A016',
155+
'gen_freq': '30m', 'gen_market': 'RT5M'},
110156
'National Grid': {'country': 'United Kingdom', 'Code': 'CTA|National Grid',
111-
'ENTSOe_ID': 'CTY|GB!CTA|10YGB----------A'},
157+
'ENTSOe_ID': 'CTY|GB!CTA|10YGB----------A',
158+
'gen_freq': '30m', 'gen_market': 'RT5M'},
112159
}
113160

161+
fuels = {
162+
'Biomass - Actual Aggregated [MW]': 'biomass',
163+
'Fossil Brown coal/Lignite - Actual Aggregated [MW]': 'coal_brown',
164+
'Fossil Coal-derived gas - Actual Aggregated [MW]': 'coal_gas',
165+
'Fossil Gas - Actual Aggregated [MW]': 'natgas',
166+
'Fossil Hard coal - Actual Aggregated [MW]': 'coal_hard',
167+
'Fossil Oil - Actual Aggregated [MW]': 'oil',
168+
'Fossil Oil shale - Actual Aggregated [MW]': 'oil_shale',
169+
'Fossil Peat - Actual Aggregated [MW]': 'peat',
170+
'Geothermal - Actual Aggregated [MW]': 'geo',
171+
'Hydro Pumped Storage - Actual Aggregated [MW]' : 'hydro_ps',
172+
'Hydro Run-of-river and poundage - Actual Aggregated [MW]': 'hydro_rorp',
173+
'Hydro Water Reservoir - Actual Aggregated [MW]': 'hydro_wr',
174+
'Marine - Actual Aggregated [MW]': 'marine',
175+
'Nuclear - Actual Aggregated [MW]': 'nuclear',
176+
'Other renewable - Actual Aggregated [MW]': 'renewable',
177+
'Solar - Actual Aggregated [MW]': 'solar',
178+
'Waste - Actual Aggregated [MW]': 'waste',
179+
'Wind Offshore - Actual Aggregated [MW]': 'wind_offsh',
180+
'Wind Onshore - Actual Aggregated [MW]': 'wind_onsh',
181+
'Other - Actual Aggregated [MW]': 'other'
182+
}
183+
184+
114185
def get_load(self, control_area=None, latest=False, start_at=None, end_at=None,
115186
forecast=False, **kwargs):
116187
self.handle_options(data='load', start_at=start_at, end_at=end_at, forecast=forecast,
@@ -119,7 +190,7 @@ def get_load(self, control_area=None, latest=False, start_at=None, end_at=None,
119190
pieces = []
120191
for date in self.dates():
121192
payload = self.construct_payload(date)
122-
url = self.base_url + self.export_endpoint
193+
url = self.base_url + self.export_endpoint_load
123194
response = self.fetch_entsoe(url, payload)
124195
day_df = self.parse_load_response(response)
125196
pieces.append(day_df)
@@ -128,6 +199,25 @@ def get_load(self, control_area=None, latest=False, start_at=None, end_at=None,
128199
sliced = self.slice_times(df)
129200
return self.serialize_faster(sliced)
130201

202+
203+
def get_generation(self, control_area=None, latest=False, yesterday=False, start_at=False,
204+
end_at=False, forecast=False, **kwargs):
205+
self.handle_options(data='gen', start_at=start_at, end_at=end_at, yesterday=yesterday,
206+
latest=latest, control_area=control_area, forecast=False, **kwargs)
207+
208+
pieces = []
209+
for date in self.dates():
210+
payload = self.construct_payload(date)
211+
url = self.base_url + self.export_endpoint_gen
212+
response = self.fetch_entsoe(url, payload)
213+
day_df = self.parse_gen_response(response)
214+
pieces.append(day_df)
215+
216+
df = pd.concat(pieces)
217+
sliced = self.slice_times(df)
218+
return self.serialize_faster(sliced)
219+
220+
131221
def handle_options(self, **kwargs):
132222
# regular handle options
133223
super(EUClient, self).handle_options(**kwargs)
@@ -172,6 +262,7 @@ def fetch_entsoe(self, url, payload, count=0):
172262

173263
r = self.request(url, params=payload)
174264
# TODO error checking
265+
175266
if len(r.text) == 0:
176267
if count > 3: # try 3 times to get response
177268
LOGGER.warn('Request failed, no response found after %i attempts' % count)
@@ -186,31 +277,37 @@ def fetch_entsoe(self, url, payload, count=0):
186277

187278
def construct_payload(self, date):
188279
# format date
280+
payload = {}
189281
format_str = '%d.%m.%Y'
190282
date_str = date.strftime(format_str) + ' 00:00|UTC|DAY'
191283

192-
# TSO ID from control area code
193-
try:
194-
TSO_ID = self.CONTROL_AREAS[self.options['control_area']]['ENTSOe_ID']
195-
except KeyError:
196-
msg = 'Control area code not found for %s. Options are %s' % (self.options['control_area'],
197-
sorted(self.CONTROL_AREAS.keys()))
198-
raise ValueError(msg)
284+
TSO_ID = self.get_tso_id()
285+
286+
if self.options['data'] == 'load':
287+
payload.update({'biddingZone.values': TSO_ID,})
288+
elif self.options['data'] == 'gen':
289+
date_str += 'TIMERANGE'
290+
payload.update({
291+
'productionType.values': 'B01, B02, B03, B04, B05, B06, B07, B08, B09, B10, B11, B12, B13, B14, B15, B16, B17, B18, B19, B20',
292+
'datepicker-day-offset-select-dv-date-from_input': 'D',
293+
'dateTime.endDateTime': date_str,
294+
'area.values': TSO_ID,
295+
})
199296

200-
payload = {
297+
payload.update({
201298
'name': '',
202299
'defaultValue': 'false',
203300
'viewType': 'TABLE',
204301
'areaType': 'CTA',
205302
'atch': 'false',
206303
'dateTime.dateTime': date_str,
207-
'biddingZone.values': TSO_ID,
208304
'dateTime.timezone': 'UTC',
209305
'dateTime.timezone_input': 'UTC',
210306
'exportType': 'CSV',
211307
'dataItem': 'ALL',
212308
'timeRange': 'DEFAULT',
213-
}
309+
})
310+
214311
return payload
215312

216313
def parse_load_response(self, response):
@@ -251,3 +348,46 @@ def parse_load_response(self, response):
251348
df['market'] = 'RTHR' # not necessarily appropriate terminology
252349

253350
return df
351+
352+
def parse_gen_response(self, response):
353+
df = pd.read_csv(StringIO(response))
354+
355+
# get START_TIME_UTC as tz-aware datetime
356+
df['START_TIME_UTC'], df['END_TIME_UTC'] = zip(*df['MTU'].apply(lambda x: x.split('-')))
357+
df.set_index('START_TIME_UTC', inplace=True)
358+
df.index = pd.to_datetime(df.index, utc=True, format='%d.%m.%Y %H:%M ')
359+
df.index.set_names('timestamp', inplace=True)
360+
361+
# rename all columns
362+
df.rename(columns=self.fuels, inplace=True)
363+
drop_col = ['MTU', 'END_TIME_UTC', 'Area']
364+
df.drop(drop_col, axis=1, inplace=True)
365+
366+
# filter out consumption columns
367+
fuel_columns = [self.fuels[x] for x in self.fuels]
368+
allowed_cols = ['timestamp']
369+
allowed_cols.extend(fuel_columns)
370+
df = df.filter(allowed_cols, axis=1)
371+
372+
# drop nan rows
373+
print('Dropping emtpy rows in columns: %s' % fuel_columns)
374+
df.replace('-', np.nan, inplace=True)
375+
df.dropna(subset=fuel_columns, how='all', inplace=True)
376+
377+
# Add columns
378+
df['ba_name'] = self.options['control_area']
379+
df['freq'] = self.CONTROL_AREAS[self.options['control_area']]['gen_freq']
380+
df['market'] = self.CONTROL_AREAS[self.options['control_area']]['gen_market']
381+
382+
return df
383+
384+
def get_tso_id(self):
385+
# TSO ID from control area code
386+
try:
387+
return self.CONTROL_AREAS[self.options['control_area']]['ENTSOe_ID']
388+
except KeyError:
389+
msg = 'Control area code not found for %s. Options are %s' % (self.options['control_area'],
390+
sorted(self.CONTROL_AREAS.keys()))
391+
raise ValueError(msg)
392+
393+

0 commit comments

Comments
 (0)